aimeat 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (412) hide show
  1. package/dist/locales/en.json +35 -1
  2. package/dist/locales/fi.json +35 -1
  3. package/dist/public/components/LinkPreview.js +101 -0
  4. package/dist/public/components/NotificationBell.js +18 -1
  5. package/dist/public/css/theme.css +57 -7
  6. package/dist/public/css/views/admin.css +8 -1
  7. package/dist/public/css/views/app-grant.css +18 -0
  8. package/dist/public/css/views/inbox.css +46 -0
  9. package/dist/public/css/views/portfolio.css +46 -0
  10. package/dist/public/css/views/profile.css +29 -4
  11. package/dist/public/js/services/apps.js +19 -3
  12. package/dist/public/js/services/messages-ai-prompts.js +38 -0
  13. package/dist/public/js/services/messages.js +26 -4
  14. package/dist/public/js/services/notebook.js +76 -0
  15. package/dist/public/js/services/unfurl.js +43 -0
  16. package/dist/public/lib/samples/LICENSE.md +11 -0
  17. package/dist/public/lib/samples/bass/A1.mp3 +0 -0
  18. package/dist/public/lib/samples/bass/B2.mp3 +0 -0
  19. package/dist/public/lib/samples/bass/D2.mp3 +0 -0
  20. package/dist/public/lib/samples/bass/E1.mp3 +0 -0
  21. package/dist/public/lib/samples/bass/E3.mp3 +0 -0
  22. package/dist/public/lib/samples/bass/G2.mp3 +0 -0
  23. package/dist/public/lib/samples/epiano/C2.mp3 +0 -0
  24. package/dist/public/lib/samples/epiano/C3.mp3 +0 -0
  25. package/dist/public/lib/samples/epiano/C4.mp3 +0 -0
  26. package/dist/public/lib/samples/epiano/C5.mp3 +0 -0
  27. package/dist/public/lib/samples/epiano/C6.mp3 +0 -0
  28. package/dist/public/lib/samples/epiano/G2.mp3 +0 -0
  29. package/dist/public/lib/samples/epiano/G3.mp3 +0 -0
  30. package/dist/public/lib/samples/epiano/G4.mp3 +0 -0
  31. package/dist/public/lib/samples/epiano/G5.mp3 +0 -0
  32. package/dist/public/lib/samples/guitar-steel/A2.mp3 +0 -0
  33. package/dist/public/lib/samples/guitar-steel/A4.mp3 +0 -0
  34. package/dist/public/lib/samples/guitar-steel/B3.mp3 +0 -0
  35. package/dist/public/lib/samples/guitar-steel/D3.mp3 +0 -0
  36. package/dist/public/lib/samples/guitar-steel/E2.mp3 +0 -0
  37. package/dist/public/lib/samples/guitar-steel/E4.mp3 +0 -0
  38. package/dist/public/lib/samples/guitar-steel/E5.mp3 +0 -0
  39. package/dist/public/lib/samples/guitar-steel/G3.mp3 +0 -0
  40. package/dist/public/lib/samples/organ/C2.mp3 +0 -0
  41. package/dist/public/lib/samples/organ/C3.mp3 +0 -0
  42. package/dist/public/lib/samples/organ/C4.mp3 +0 -0
  43. package/dist/public/lib/samples/organ/C5.mp3 +0 -0
  44. package/dist/public/lib/samples/organ/C6.mp3 +0 -0
  45. package/dist/public/lib/samples/organ/G2.mp3 +0 -0
  46. package/dist/public/lib/samples/organ/G3.mp3 +0 -0
  47. package/dist/public/lib/samples/organ/G4.mp3 +0 -0
  48. package/dist/public/lib/samples/organ/G5.mp3 +0 -0
  49. package/dist/public/lib/samples/strings/C2.mp3 +0 -0
  50. package/dist/public/lib/samples/strings/C3.mp3 +0 -0
  51. package/dist/public/lib/samples/strings/C4.mp3 +0 -0
  52. package/dist/public/lib/samples/strings/C5.mp3 +0 -0
  53. package/dist/public/lib/samples/strings/C6.mp3 +0 -0
  54. package/dist/public/lib/samples/strings/G2.mp3 +0 -0
  55. package/dist/public/lib/samples/strings/G3.mp3 +0 -0
  56. package/dist/public/lib/samples/strings/G4.mp3 +0 -0
  57. package/dist/public/lib/samples/strings/G5.mp3 +0 -0
  58. package/dist/public/lib/samples/trumpet/A3.mp3 +0 -0
  59. package/dist/public/lib/samples/trumpet/A4.mp3 +0 -0
  60. package/dist/public/lib/samples/trumpet/A5.mp3 +0 -0
  61. package/dist/public/lib/samples/trumpet/C4.mp3 +0 -0
  62. package/dist/public/lib/samples/trumpet/C5.mp3 +0 -0
  63. package/dist/public/lib/samples/trumpet/E3.mp3 +0 -0
  64. package/dist/public/lib/samples/trumpet/E4.mp3 +0 -0
  65. package/dist/public/lib/samples/trumpet/E5.mp3 +0 -0
  66. package/dist/public/spa.html +2 -0
  67. package/dist/public/views/app-grant.js +24 -4
  68. package/dist/public/views/portfolio.js +61 -6
  69. package/dist/public/views/profile/apps-tab.js +18 -1
  70. package/dist/public/views/profile/inbox-tab/ai-actions.js +86 -0
  71. package/dist/public/views/profile/inbox-tab/components.js +124 -9
  72. package/dist/public/views/profile/inbox-tab/helpers.js +26 -0
  73. package/dist/public/views/profile/inbox-tab/panels.js +18 -3
  74. package/dist/public/views/profile/inbox-tab/use-thread-ux.js +18 -1
  75. package/dist/public/views/profile/inbox-tab.js +46 -49
  76. package/dist/public/views/profile/landing-page.cards.js +7 -0
  77. package/dist/public/views/profile/landing-page.js +12 -1
  78. package/dist/public/views/profile/skills-tab.js +1 -1
  79. package/dist/public/views/public-workspace-viewer.js +1 -1
  80. package/dist/public/views/start.js +2 -1
  81. package/dist/scripts/build-sdk-libs.d.ts +16 -0
  82. package/dist/scripts/build-sdk-libs.d.ts.map +1 -0
  83. package/dist/scripts/build-sdk-libs.js +112 -0
  84. package/dist/scripts/build-sdk-libs.js.map +1 -0
  85. package/dist/src/cli/connect/auth.d.ts +15 -0
  86. package/dist/src/cli/connect/auth.d.ts.map +1 -1
  87. package/dist/src/cli/connect/auth.js +25 -6
  88. package/dist/src/cli/connect/auth.js.map +1 -1
  89. package/dist/src/cli/connect/keychain.d.ts +9 -0
  90. package/dist/src/cli/connect/keychain.d.ts.map +1 -1
  91. package/dist/src/cli/connect/keychain.js +21 -8
  92. package/dist/src/cli/connect/keychain.js.map +1 -1
  93. package/dist/src/cli/connect/mcp/tools/exchange.d.ts +18 -0
  94. package/dist/src/cli/connect/mcp/tools/exchange.d.ts.map +1 -0
  95. package/dist/src/cli/connect/mcp/tools/exchange.js +170 -0
  96. package/dist/src/cli/connect/mcp/tools/exchange.js.map +1 -0
  97. package/dist/src/cli/connect/mcp/tools/index.d.ts.map +1 -1
  98. package/dist/src/cli/connect/mcp/tools/index.js +2 -0
  99. package/dist/src/cli/connect/mcp/tools/index.js.map +1 -1
  100. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts +3 -0
  101. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts.map +1 -0
  102. package/dist/src/cli/connect/tool-call-defs-exchange.js +146 -0
  103. package/dist/src/cli/connect/tool-call-defs-exchange.js.map +1 -0
  104. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  105. package/dist/src/cli/connect/tool-call.js +2 -0
  106. package/dist/src/cli/connect/tool-call.js.map +1 -1
  107. package/dist/src/commerce/session-service.d.ts +14 -0
  108. package/dist/src/commerce/session-service.d.ts.map +1 -1
  109. package/dist/src/commerce/session-service.js +1 -1
  110. package/dist/src/commerce/session-service.js.map +1 -1
  111. package/dist/src/data/app-templates/shells.d.ts +7 -3
  112. package/dist/src/data/app-templates/shells.d.ts.map +1 -1
  113. package/dist/src/data/app-templates/shells.js +10 -6
  114. package/dist/src/data/app-templates/shells.js.map +1 -1
  115. package/dist/src/data/appdev-pitfalls.d.ts +2 -0
  116. package/dist/src/data/appdev-pitfalls.d.ts.map +1 -1
  117. package/dist/src/data/appdev-pitfalls.js +24 -1
  118. package/dist/src/data/appdev-pitfalls.js.map +1 -1
  119. package/dist/src/generated/api-types.d.ts +1565 -9
  120. package/dist/src/generated/api-types.d.ts.map +1 -1
  121. package/dist/src/mcp/annotations.d.ts.map +1 -1
  122. package/dist/src/mcp/annotations.js +20 -0
  123. package/dist/src/mcp/annotations.js.map +1 -1
  124. package/dist/src/mcp/apps.d.ts.map +1 -1
  125. package/dist/src/mcp/apps.js +8 -4
  126. package/dist/src/mcp/apps.js.map +1 -1
  127. package/dist/src/mcp/catalog/definitions/exchange.d.ts +18 -0
  128. package/dist/src/mcp/catalog/definitions/exchange.d.ts.map +1 -0
  129. package/dist/src/mcp/catalog/definitions/exchange.js +182 -0
  130. package/dist/src/mcp/catalog/definitions/exchange.js.map +1 -0
  131. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  132. package/dist/src/mcp/catalog/definitions.js +2 -0
  133. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  134. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  135. package/dist/src/mcp/catalog/scopes.js +22 -0
  136. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  137. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  138. package/dist/src/mcp/catalog/surfaces.js +14 -0
  139. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  140. package/dist/src/mcp/exchange-run.d.ts +5 -0
  141. package/dist/src/mcp/exchange-run.d.ts.map +1 -0
  142. package/dist/src/mcp/exchange-run.js +226 -0
  143. package/dist/src/mcp/exchange-run.js.map +1 -0
  144. package/dist/src/mcp/exchange.d.ts +5 -0
  145. package/dist/src/mcp/exchange.d.ts.map +1 -0
  146. package/dist/src/mcp/exchange.js +351 -0
  147. package/dist/src/mcp/exchange.js.map +1 -0
  148. package/dist/src/mcp/extensions.d.ts.map +1 -1
  149. package/dist/src/mcp/extensions.js +11 -0
  150. package/dist/src/mcp/extensions.js.map +1 -1
  151. package/dist/src/mcp/index.d.ts.map +1 -1
  152. package/dist/src/mcp/index.js +6 -2
  153. package/dist/src/mcp/index.js.map +1 -1
  154. package/dist/src/models/app-tool-schemas.d.ts +55 -1
  155. package/dist/src/models/app-tool-schemas.d.ts.map +1 -1
  156. package/dist/src/models/app-tool-schemas.js +20 -1
  157. package/dist/src/models/app-tool-schemas.js.map +1 -1
  158. package/dist/src/models/offer-schemas.d.ts +2 -2
  159. package/dist/src/models/schemas.d.ts +1 -0
  160. package/dist/src/models/schemas.d.ts.map +1 -1
  161. package/dist/src/models/schemas.js +3 -0
  162. package/dist/src/models/schemas.js.map +1 -1
  163. package/dist/src/routes/agents/device-auth.d.ts +4 -0
  164. package/dist/src/routes/agents/device-auth.d.ts.map +1 -1
  165. package/dist/src/routes/agents/device-auth.js +19 -4
  166. package/dist/src/routes/agents/device-auth.js.map +1 -1
  167. package/dist/src/routes/app-grants.d.ts +6 -0
  168. package/dist/src/routes/app-grants.d.ts.map +1 -1
  169. package/dist/src/routes/app-grants.js +35 -2
  170. package/dist/src/routes/app-grants.js.map +1 -1
  171. package/dist/src/routes/apps/fork-manage.d.ts.map +1 -1
  172. package/dist/src/routes/apps/fork-manage.js +24 -1
  173. package/dist/src/routes/apps/fork-manage.js.map +1 -1
  174. package/dist/src/routes/apps/publish.d.ts +2 -0
  175. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  176. package/dist/src/routes/apps/publish.js +27 -1
  177. package/dist/src/routes/apps/publish.js.map +1 -1
  178. package/dist/src/routes/apps-cost.d.ts +25 -0
  179. package/dist/src/routes/apps-cost.d.ts.map +1 -0
  180. package/dist/src/routes/apps-cost.js +107 -0
  181. package/dist/src/routes/apps-cost.js.map +1 -0
  182. package/dist/src/routes/exchange-market.d.ts +28 -0
  183. package/dist/src/routes/exchange-market.d.ts.map +1 -0
  184. package/dist/src/routes/exchange-market.js +454 -0
  185. package/dist/src/routes/exchange-market.js.map +1 -0
  186. package/dist/src/routes/exchange.d.ts +33 -0
  187. package/dist/src/routes/exchange.d.ts.map +1 -0
  188. package/dist/src/routes/exchange.js +395 -0
  189. package/dist/src/routes/exchange.js.map +1 -0
  190. package/dist/src/routes/extensions/entitlement-gate.d.ts +33 -0
  191. package/dist/src/routes/extensions/entitlement-gate.d.ts.map +1 -0
  192. package/dist/src/routes/extensions/entitlement-gate.js +143 -0
  193. package/dist/src/routes/extensions/entitlement-gate.js.map +1 -0
  194. package/dist/src/routes/extensions/manifest.d.ts +9 -0
  195. package/dist/src/routes/extensions/manifest.d.ts.map +1 -1
  196. package/dist/src/routes/extensions/manifest.js +33 -1
  197. package/dist/src/routes/extensions/manifest.js.map +1 -1
  198. package/dist/src/routes/extensions/paywall.d.ts.map +1 -1
  199. package/dist/src/routes/extensions/paywall.js +9 -0
  200. package/dist/src/routes/extensions/paywall.js.map +1 -1
  201. package/dist/src/routes/federation-sync/messaging.d.ts.map +1 -1
  202. package/dist/src/routes/federation-sync/messaging.js +3 -1
  203. package/dist/src/routes/federation-sync/messaging.js.map +1 -1
  204. package/dist/src/routes/ghii/recovery.d.ts +2 -0
  205. package/dist/src/routes/ghii/recovery.d.ts.map +1 -1
  206. package/dist/src/routes/ghii/recovery.js +7 -0
  207. package/dist/src/routes/ghii/recovery.js.map +1 -1
  208. package/dist/src/routes/ghii/register-login.d.ts +4 -0
  209. package/dist/src/routes/ghii/register-login.d.ts.map +1 -1
  210. package/dist/src/routes/ghii/register-login.js +45 -22
  211. package/dist/src/routes/ghii/register-login.js.map +1 -1
  212. package/dist/src/routes/ghii/web-verify.d.ts +5 -0
  213. package/dist/src/routes/ghii/web-verify.d.ts.map +1 -1
  214. package/dist/src/routes/ghii/web-verify.js +24 -3
  215. package/dist/src/routes/ghii/web-verify.js.map +1 -1
  216. package/dist/src/routes/libs/sdk-serve.d.ts +11 -0
  217. package/dist/src/routes/libs/sdk-serve.d.ts.map +1 -0
  218. package/dist/src/routes/libs/sdk-serve.js +53 -0
  219. package/dist/src/routes/libs/sdk-serve.js.map +1 -0
  220. package/dist/src/routes/libs.d.ts +7 -1
  221. package/dist/src/routes/libs.d.ts.map +1 -1
  222. package/dist/src/routes/libs.js +65 -146
  223. package/dist/src/routes/libs.js.map +1 -1
  224. package/dist/src/routes/messages.d.ts +3 -0
  225. package/dist/src/routes/messages.d.ts.map +1 -1
  226. package/dist/src/routes/messages.js +9 -0
  227. package/dist/src/routes/messages.js.map +1 -1
  228. package/dist/src/routes/notifications.d.ts +6 -3
  229. package/dist/src/routes/notifications.d.ts.map +1 -1
  230. package/dist/src/routes/notifications.js +32 -3
  231. package/dist/src/routes/notifications.js.map +1 -1
  232. package/dist/src/routes/organisms/workspace-access.d.ts.map +1 -1
  233. package/dist/src/routes/organisms/workspace-access.js +38 -20
  234. package/dist/src/routes/organisms/workspace-access.js.map +1 -1
  235. package/dist/src/routes/unfurl.d.ts +27 -0
  236. package/dist/src/routes/unfurl.d.ts.map +1 -0
  237. package/dist/src/routes/unfurl.js +180 -0
  238. package/dist/src/routes/unfurl.js.map +1 -0
  239. package/dist/src/routes/upload.d.ts +2 -0
  240. package/dist/src/routes/upload.d.ts.map +1 -1
  241. package/dist/src/routes/upload.js +7 -0
  242. package/dist/src/routes/upload.js.map +1 -1
  243. package/dist/src/routes/webmcp.d.ts +3 -0
  244. package/dist/src/routes/webmcp.d.ts.map +1 -1
  245. package/dist/src/routes/webmcp.js +55 -0
  246. package/dist/src/routes/webmcp.js.map +1 -1
  247. package/dist/src/server-bootstrap/routes-loader.d.ts +1 -0
  248. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  249. package/dist/src/server-bootstrap/routes-loader.js +8 -0
  250. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  251. package/dist/src/services/agent-face.d.ts +10 -2
  252. package/dist/src/services/agent-face.d.ts.map +1 -1
  253. package/dist/src/services/agent-face.js +10 -4
  254. package/dist/src/services/agent-face.js.map +1 -1
  255. package/dist/src/services/app-tool-interfaces.d.ts +37 -0
  256. package/dist/src/services/app-tool-interfaces.d.ts.map +1 -0
  257. package/dist/src/services/app-tool-interfaces.js +101 -0
  258. package/dist/src/services/app-tool-interfaces.js.map +1 -0
  259. package/dist/src/services/build-app-prompt.d.ts +3 -0
  260. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  261. package/dist/src/services/build-app-prompt.js +12 -1
  262. package/dist/src/services/build-app-prompt.js.map +1 -1
  263. package/dist/src/services/contacts.d.ts +25 -1
  264. package/dist/src/services/contacts.d.ts.map +1 -1
  265. package/dist/src/services/contacts.js +30 -0
  266. package/dist/src/services/contacts.js.map +1 -1
  267. package/dist/src/services/entitlement-money.d.ts +55 -0
  268. package/dist/src/services/entitlement-money.d.ts.map +1 -0
  269. package/dist/src/services/entitlement-money.js +68 -0
  270. package/dist/src/services/entitlement-money.js.map +1 -0
  271. package/dist/src/services/exchange-market.d.ts +247 -0
  272. package/dist/src/services/exchange-market.d.ts.map +1 -0
  273. package/dist/src/services/exchange-market.js +254 -0
  274. package/dist/src/services/exchange-market.js.map +1 -0
  275. package/dist/src/services/exchange-proposals.d.ts +47 -0
  276. package/dist/src/services/exchange-proposals.d.ts.map +1 -0
  277. package/dist/src/services/exchange-proposals.js +71 -0
  278. package/dist/src/services/exchange-proposals.js.map +1 -0
  279. package/dist/src/services/exchange-work.d.ts +30 -0
  280. package/dist/src/services/exchange-work.d.ts.map +1 -0
  281. package/dist/src/services/exchange-work.js +43 -0
  282. package/dist/src/services/exchange-work.js.map +1 -0
  283. package/dist/src/services/message-send.d.ts.map +1 -1
  284. package/dist/src/services/message-send.js +4 -1
  285. package/dist/src/services/message-send.js.map +1 -1
  286. package/dist/src/services/metered-entitlements.d.ts +203 -0
  287. package/dist/src/services/metered-entitlements.d.ts.map +1 -0
  288. package/dist/src/services/metered-entitlements.js +264 -0
  289. package/dist/src/services/metered-entitlements.js.map +1 -0
  290. package/dist/src/services/notify.d.ts +7 -0
  291. package/dist/src/services/notify.d.ts.map +1 -1
  292. package/dist/src/services/notify.js +35 -0
  293. package/dist/src/services/notify.js.map +1 -1
  294. package/dist/src/services/owner-memory.d.ts +16 -0
  295. package/dist/src/services/owner-memory.d.ts.map +1 -1
  296. package/dist/src/services/owner-memory.js +23 -0
  297. package/dist/src/services/owner-memory.js.map +1 -1
  298. package/dist/src/services/owner-provisioning.d.ts +5 -0
  299. package/dist/src/services/owner-provisioning.d.ts.map +1 -1
  300. package/dist/src/services/owner-provisioning.js +20 -2
  301. package/dist/src/services/owner-provisioning.js.map +1 -1
  302. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts +1 -0
  303. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts.map +1 -1
  304. package/dist/src/storage/providers/postgres-kysely/methods/apps.js +2 -0
  305. package/dist/src/storage/providers/postgres-kysely/methods/apps.js.map +1 -1
  306. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts +1 -0
  307. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts.map +1 -1
  308. package/dist/src/storage/providers/postgres-kysely/methods/identity.js +4 -0
  309. package/dist/src/storage/providers/postgres-kysely/methods/identity.js.map +1 -1
  310. package/dist/src/storage/providers/postgres-kysely/migrations/0011_unique_verified_email.sql +25 -0
  311. package/dist/src/storage/providers/sqlite/methods/apps.d.ts +1 -0
  312. package/dist/src/storage/providers/sqlite/methods/apps.d.ts.map +1 -1
  313. package/dist/src/storage/providers/sqlite/methods/apps.js +2 -0
  314. package/dist/src/storage/providers/sqlite/methods/apps.js.map +1 -1
  315. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts +1 -0
  316. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts.map +1 -1
  317. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js +4 -0
  318. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js.map +1 -1
  319. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  320. package/dist/src/storage/providers/sqlite/schema.js +20 -0
  321. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  322. package/dist/src/storage/repositories/app.repository.d.ts +0 -0
  323. package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
  324. package/dist/src/storage/repositories/identity.repository.d.ts +6 -0
  325. package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -1
  326. package/dist/src/storage/types/apps.d.ts +1 -0
  327. package/dist/src/storage/types/apps.d.ts.map +1 -1
  328. package/dist/src/storage/types/organisms-federation.d.ts +21 -0
  329. package/dist/src/storage/types/organisms-federation.d.ts.map +1 -1
  330. package/dist/src/utils/app-mobile-lint.d.ts +17 -0
  331. package/dist/src/utils/app-mobile-lint.d.ts.map +1 -0
  332. package/dist/src/utils/app-mobile-lint.js +40 -0
  333. package/dist/src/utils/app-mobile-lint.js.map +1 -0
  334. package/dist/static/app-catalog/_template.html +12 -77
  335. package/dist/static/app-catalog/js/apps-io.js +51 -165
  336. package/dist/static/app-catalog/js/cost.js +100 -0
  337. package/dist/static/app-catalog/js/db.js +23 -93
  338. package/dist/static/app-catalog/js/detail.js +158 -24
  339. package/dist/static/app-catalog/js/favorites.js +71 -0
  340. package/dist/static/app-catalog/js/i18n-data.js +90 -16
  341. package/dist/static/app-catalog/js/main.js +23 -103
  342. package/dist/static/app-catalog/js/migrate.js +88 -0
  343. package/dist/static/app-catalog/js/monetize.js +1 -1
  344. package/dist/static/app-catalog/js/promote.js +70 -0
  345. package/dist/static/app-catalog/js/render.js +26 -139
  346. package/dist/static/app-catalog/js/server-io.js +126 -223
  347. package/dist/static/app-catalog/js/settings.js +11 -204
  348. package/dist/static/app-catalog/styles/app-catalog.css +40 -0
  349. package/dist/static/app-catalog.html +790 -912
  350. package/dist/static/sdk-libs/_core/config.js +52 -0
  351. package/dist/static/sdk-libs/_core/http.js +52 -0
  352. package/dist/static/sdk-libs/_core/namespace.js +33 -0
  353. package/dist/static/sdk-libs/_core/sdk-globals.d.ts +50 -0
  354. package/dist/static/sdk-libs/_core/session.js +66 -0
  355. package/dist/static/sdk-libs/agentface/index.js +102 -0
  356. package/dist/static/sdk-libs/agents/index.js +267 -0
  357. package/dist/static/sdk-libs/ai/index.js +153 -0
  358. package/dist/static/sdk-libs/audio/core.js +111 -0
  359. package/dist/static/sdk-libs/audio/index.js +380 -0
  360. package/dist/static/sdk-libs/audio/instruments.js +369 -0
  361. package/dist/static/sdk-libs/auth/config.js +46 -0
  362. package/dist/static/sdk-libs/auth/crypto.js +166 -0
  363. package/dist/static/sdk-libs/auth/events.js +27 -0
  364. package/dist/static/sdk-libs/auth/i18n.js +64 -0
  365. package/dist/static/sdk-libs/auth/index.js +37 -0
  366. package/dist/static/sdk-libs/auth/modal.js +545 -0
  367. package/dist/static/sdk-libs/auth/pill.js +167 -0
  368. package/dist/static/sdk-libs/auth/session.js +792 -0
  369. package/dist/static/sdk-libs/auth/signup.js +232 -0
  370. package/dist/static/sdk-libs/auth/theme.js +96 -0
  371. package/dist/static/sdk-libs/capabilities/index.js +179 -0
  372. package/dist/static/sdk-libs/commerce/index.js +243 -0
  373. package/dist/static/sdk-libs/data/index.js +188 -0
  374. package/dist/static/sdk-libs/dist/aimeat-agentface.js +91 -0
  375. package/dist/static/sdk-libs/dist/aimeat-agents.js +315 -0
  376. package/dist/static/sdk-libs/dist/aimeat-ai.js +168 -0
  377. package/dist/static/sdk-libs/dist/aimeat-audio.js +979 -0
  378. package/dist/static/sdk-libs/dist/aimeat-auth.js +1831 -0
  379. package/dist/static/sdk-libs/dist/aimeat-capabilities.js +177 -0
  380. package/dist/static/sdk-libs/dist/aimeat-commerce.js +265 -0
  381. package/dist/static/sdk-libs/dist/aimeat-data.js +205 -0
  382. package/dist/static/sdk-libs/dist/aimeat-editor.js +299 -0
  383. package/dist/static/sdk-libs/dist/aimeat-header.js +270 -0
  384. package/dist/static/sdk-libs/dist/aimeat-intake.js +94 -0
  385. package/dist/static/sdk-libs/dist/aimeat-live.js +265 -0
  386. package/dist/static/sdk-libs/dist/aimeat-markdown.js +602 -0
  387. package/dist/static/sdk-libs/dist/aimeat-organism.js +394 -0
  388. package/dist/static/sdk-libs/dist/aimeat-portfolio-standalone.js +90 -0
  389. package/dist/static/sdk-libs/dist/aimeat-social.js +157 -0
  390. package/dist/static/sdk-libs/dist/aimeat-speech.js +300 -0
  391. package/dist/static/sdk-libs/dist/aimeat-storage.js +210 -0
  392. package/dist/static/sdk-libs/dist/aimeat-tunnel.js +383 -0
  393. package/dist/static/sdk-libs/dist/aimeat-wallet.js +118 -0
  394. package/dist/static/sdk-libs/dist/aimeat-webmcp.js +187 -0
  395. package/dist/static/sdk-libs/dist/aimeat-work.js +213 -0
  396. package/dist/static/sdk-libs/dist/aimeat-workflows.js +147 -0
  397. package/dist/static/sdk-libs/editor/index.js +229 -0
  398. package/dist/static/sdk-libs/header/index.js +249 -0
  399. package/dist/static/sdk-libs/intake/index.js +75 -0
  400. package/dist/static/sdk-libs/live/index.js +156 -0
  401. package/dist/static/sdk-libs/markdown/index.js +522 -0
  402. package/dist/static/sdk-libs/organism/index.js +381 -0
  403. package/dist/static/sdk-libs/portfolio-standalone/index.js +78 -0
  404. package/dist/static/sdk-libs/social/index.js +140 -0
  405. package/dist/static/sdk-libs/speech/index.js +321 -0
  406. package/dist/static/sdk-libs/storage/index.js +189 -0
  407. package/dist/static/sdk-libs/tunnel/index.js +428 -0
  408. package/dist/static/sdk-libs/wallet/index.js +115 -0
  409. package/dist/static/sdk-libs/webmcp/index.js +185 -0
  410. package/dist/static/sdk-libs/work/index.js +191 -0
  411. package/dist/static/sdk-libs/workflows/index.js +113 -0
  412. package/package.json +5 -2
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @file auth/index.js
3
+ * @description Entry for the aimeat-auth library (SDK-libs migration Phase 3). Assembles the auth
4
+ * surface from its modules (crypto/config/events/i18n/theme/session/pill/modal/signup), wires boot
5
+ * (first-time OIDC signup prompt on load; token refresh on tab focus/visibility), and exposes
6
+ * window.AIMEAT.auth + AIMEAT.version. esbuild bundles this + all imports into the classic IIFE
7
+ * served, unchanged, at /v1/libs/aimeat-auth.js. Replaces the ~2200-line JS-in-a-string monolith
8
+ * (auth-lib.ts + auth-lib-part1/2/3.ts).
9
+ * @structure imports auth + refreshOnFocus (session) + maybeShowGoogleSignup (signup) + attach; boot
10
+ * listeners; attach('auth', auth) + version.
11
+ * @usage <script src="/v1/libs/aimeat-auth.js"></script> const s = await AIMEAT.auth.login();
12
+ * @version-history
13
+ * v1.0.0 — 2026-07-19 — Componentized rewrite of src/routes/libs/auth-lib*.ts (SDK-libs migration Phase 3).
14
+ */
15
+ import { auth, refreshOnFocus } from './session.js';
16
+ import { maybeShowGoogleSignup } from './signup.js';
17
+ import { attach } from '../_core/namespace.js';
18
+
19
+ // ── Boot: first-time OIDC signup prompt (after the callback bounced back with ?aimeat_signup=1) ──
20
+ if (typeof document !== 'undefined' && document.addEventListener) {
21
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', maybeShowGoogleSignup);
22
+ else maybeShowGoogleSignup();
23
+ }
24
+
25
+ // ── Boot: refresh on focus / visibility (timers don't fire while asleep/frozen) ──
26
+ if (typeof document !== 'undefined' && document.addEventListener) {
27
+ document.addEventListener('visibilitychange', () => {
28
+ if (document.visibilityState === 'visible') refreshOnFocus();
29
+ });
30
+ }
31
+ if (typeof window !== 'undefined' && window.addEventListener) {
32
+ window.addEventListener('focus', refreshOnFocus);
33
+ }
34
+
35
+ // ── Expose globally ──
36
+ const ns = attach('auth', auth);
37
+ ns.version = '2026-07-02-001';
@@ -0,0 +1,545 @@
1
+ /**
2
+ * @file auth/modal.js
3
+ * @description aimeat-auth sign-in modal (SDK-libs migration Phase 3): the password + social login
4
+ * modal with its own EN/FI switcher, forgot-password / forgot-username sub-views, and the
5
+ * email-completion sub-view (legacy accounts + the register-under-email-gate flow). wireModal's
6
+ * submit tries register → NAME_TAKEN → loginWithPassword, branching on EMAIL_REQUIRED /
7
+ * EMAIL_NOT_VERIFIED into the email step. Delegates account creation to the AIMEAT.auth object.
8
+ * Extracted from auth-lib-part2/3.ts.
9
+ * @structure showLoginModal(opts, renderBtn) → { buildModalInner, wireModal, render, switchLang,
10
+ * openEmailCompletion, showView, capture/restoreInputs }.
11
+ * @usage import { showLoginModal } from './modal.js';
12
+ * @version-history
13
+ * v1.0.0 — 2026-07-19 — Extracted from src/routes/libs/auth-lib-part2/3.ts (SDK-libs migration Phase 3).
14
+ */
15
+ import { auth, api } from './session.js';
16
+ import { escHtml } from './theme.js';
17
+ import { currentModalLang, loadModalI18n, MODAL_LANG_KEY } from './i18n.js';
18
+ import { NODE_URL, NODE_ID, AUTH_PROVIDERS, PROVIDER_ICONS } from './config.js';
19
+
20
+ export function showLoginModal(opts, renderBtn) {
21
+ var i = opts.i18n || {};
22
+ var lang = currentModalLang();
23
+ // Remove existing modal
24
+ const old = document.getElementById('aimeat-modal');
25
+ if (old) old.remove();
26
+
27
+ const modal = document.createElement('div');
28
+ modal.id = 'aimeat-modal';
29
+
30
+ // Capture typed values so they survive a re-render (language change).
31
+ function captureInputs() {
32
+ var g = function (id) { var el = /** @type {any} */ (document.getElementById(id)); return el ? el.value : ''; };
33
+ return { u: g('aimeat-username'), p: g('aimeat-password'), d: g('aimeat-displayname') };
34
+ }
35
+ function restoreInputs(vals) {
36
+ var s = function (id, val) { var el = /** @type {any} */ (document.getElementById(id)); if (el && val) el.value = val; };
37
+ s('aimeat-username', vals.u); s('aimeat-password', vals.p); s('aimeat-displayname', vals.d);
38
+ }
39
+
40
+ // Switch language: persist the choice, reload translations, re-render in place (no page reload).
41
+ function switchLang(next) {
42
+ if (next === lang) return;
43
+ try {
44
+ localStorage.setItem(MODAL_LANG_KEY, next);
45
+ document.cookie = 'aimeat-lang=' + next + ';path=/;max-age=31536000;SameSite=Lax';
46
+ } catch { /* storage blocked */ }
47
+ var vals = captureInputs();
48
+ loadModalI18n(next).then(function (fresh) {
49
+ lang = next;
50
+ if (fresh && Object.keys(fresh).length) i = fresh;
51
+ render(false);
52
+ restoreInputs(vals);
53
+ });
54
+ }
55
+
56
+ function render(anim) {
57
+ modal.innerHTML = buildModalInner(i, lang, anim);
58
+ wireModal();
59
+ }
60
+
61
+ document.body.appendChild(modal);
62
+ render(true);
63
+
64
+ // Correct the language if the host passed opts.i18n in the wrong one (standalone modal).
65
+ loadModalI18n(lang).then(function (fresh) {
66
+ if (!fresh || !Object.keys(fresh).length) return;
67
+ if (fresh.signInBtn === i.signInBtn && fresh.descNew === i.descNew) return;
68
+ var vals = captureInputs();
69
+ i = fresh;
70
+ render(false);
71
+ restoreInputs(vals);
72
+ });
73
+
74
+ function buildModalInner(i, lang, anim) {
75
+ return '<style>'
76
+ + '.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}'
77
+ + '.aimeat-inp:focus{border-color:#E8564A;box-shadow:0 0 0 3px rgba(232,86,74,.1)}'
78
+ + '.aimeat-inp::placeholder{color:#9CA3AF}'
79
+ + '.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}'
80
+ + '.aimeat-go:hover{transform:translateY(-1px);box-shadow:0 4px 14px rgba(232,86,74,.35)}'
81
+ + '.aimeat-label{display:block;margin-bottom:5px;font-size:12px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:#6B7280}'
82
+ + '.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}'
83
+ + '.aimeat-cancel:hover{background:#F3F4F6}'
84
+ + '.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}'
85
+ + '.aimeat-langsw{position:absolute;top:24px;right:28px;display:flex;gap:5px}'
86
+ + '.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}'
87
+ + '.aimeat-lang:hover{border-color:#E8564A;color:#E8564A}'
88
+ + '.aimeat-lang.active{background:#E8564A;color:#fff;border-color:#E8564A;cursor:default}'
89
+ + '@keyframes aimeatModalIn{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}'
90
+ + '</style>'
91
+ + '<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">'
92
+ + '<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' : '') + '">'
93
+ + '<div style="padding:28px 32px 0;position:relative">'
94
+ + '<div class="aimeat-langsw">'
95
+ + '<button type="button" class="aimeat-lang' + (lang === 'en' ? ' active' : '') + '" data-lang="en">EN</button>'
96
+ + '<button type="button" class="aimeat-lang' + (lang === 'fi' ? ' active' : '') + '" data-lang="fi">FI</button>'
97
+ + '</div>'
98
+ + '<h2 style="margin:0;font-size:22px;font-weight:800;display:flex;align-items:center;gap:8px;color:#1A1A2E">'
99
+ + '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'
100
+ + '</h2>'
101
+ + '<p style="margin:8px 0 0;font-size:14px;color:#6B7280;line-height:1.5">' + escHtml(i.descNew || 'New? Pick a username and password to create an account.') + ' ' + escHtml(i.descReturning || 'Already have an account? Enter your username and password.') + '</p>'
102
+ + '</div>'
103
+ // Body
104
+ + '<div id="aimeat-modal-body" style="padding:24px 32px">'
105
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.usernameLabel || 'Username') + '</label>'
106
+ + '<input id="aimeat-username" class="aimeat-inp" placeholder="' + escHtml(i.usernamePlaceholder || 'Username') + '"></div>'
107
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.passwordLabel || 'Password') + '</label>'
108
+ + '<input id="aimeat-password" type="password" class="aimeat-inp" placeholder="' + escHtml(i.passwordPlaceholder || 'Password (min 4 chars)') + '"></div>'
109
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.displayNameLabel || 'Display Name') + ' <span style="font-weight:400;text-transform:none;letter-spacing:0">(' + escHtml(i.displayNameHint || 'optional, for new accounts') + ')</span></label>'
110
+ + '<input id="aimeat-displayname" class="aimeat-inp" placeholder="' + escHtml(i.displayNamePlaceholder || 'Display Name') + '"></div>'
111
+ + '<div style="display:flex;gap:10px;margin-top:20px">'
112
+ + '<button id="aimeat-go-btn" class="aimeat-go">' + escHtml(i.signInBtn || 'Sign In / Register') + '</button>'
113
+ + '<button id="aimeat-cancel-btn" class="aimeat-cancel">' + escHtml(i.cancelBtn || 'Cancel') + '</button>'
114
+ + '</div>'
115
+ + '<p id="aimeat-error" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p>'
116
+ // Social login — one button per enabled OIDC provider, baked from config
117
+ + (AUTH_PROVIDERS.length ? (
118
+ '<div style="display:flex;align-items:center;gap:12px;margin:18px 0 14px;color:#9CA3AF;font-size:12px;font-weight:600;letter-spacing:.5px">'
119
+ + '<span style="flex:1;height:1px;background:#E5E7EB"></span>' + escHtml(i.orLabel || 'OR') + '<span style="flex:1;height:1px;background:#E5E7EB"></span>'
120
+ + '</div>'
121
+ + AUTH_PROVIDERS.map(function (p) {
122
+ 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">'
123
+ + (PROVIDER_ICONS[p.id] || '')
124
+ + escHtml((i[p.i18nKey]) || p.label) + '</button>';
125
+ }).join('')
126
+ ) : '')
127
+ + '<div style="margin-top:14px;display:flex;gap:16px">'
128
+ + '<a href="#" id="aimeat-forgot-pw" style="font-size:13px;color:#6B7280;cursor:pointer;text-decoration:underline">' + escHtml(i.forgotPassword || 'Forgot password?') + '</a>'
129
+ + '<a href="#" id="aimeat-forgot-user" style="font-size:13px;color:#6B7280;cursor:pointer;text-decoration:underline">' + escHtml(i.forgotUsername || 'Forgot username?') + '</a>'
130
+ + '</div>'
131
+ + '</div>'
132
+ // Forgot password sub-view (hidden by default)
133
+ + '<div id="aimeat-forgot-pw-view" style="padding:24px 32px;display:none">'
134
+ + '<div id="aimeat-fpw-step1">'
135
+ + '<h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i.resetPasswordTitle || 'Reset Password') + '</h3>'
136
+ + '<p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i.resetPasswordDesc || 'Enter your username to receive a reset code by email.') + '</p>'
137
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.usernameLabel || 'Username') + '</label>'
138
+ + '<input id="aimeat-fpw-username" class="aimeat-inp" placeholder="' + escHtml(i.usernamePlaceholder || 'Username') + '"></div>'
139
+ + '<div style="display:flex;gap:10px">'
140
+ + '<button id="aimeat-fpw-send" class="aimeat-go">' + escHtml(i.sendResetCode || 'Send Reset Code') + '</button>'
141
+ + '<button id="aimeat-fpw-back" class="aimeat-cancel">' + escHtml(i.backToLogin || 'Back to Login') + '</button>'
142
+ + '</div>'
143
+ + '<p id="aimeat-fpw-msg" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p>'
144
+ + '<p id="aimeat-fpw-err" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p>'
145
+ + '</div>'
146
+ + '<div id="aimeat-fpw-step2" style="display:none">'
147
+ + '<h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i.enterNewPasswordTitle || 'Enter New Password') + '</h3>'
148
+ + '<p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i.resetCodeSent || 'A reset code was sent to your email. Enter it below with your new password.') + '</p>'
149
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.codeLabel || 'Reset Code') + '</label>'
150
+ + '<input id="aimeat-fpw-code" class="aimeat-inp" placeholder="123456" maxlength="6"></div>'
151
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.newPasswordLabel || 'New Password') + '</label>'
152
+ + '<input id="aimeat-fpw-newpass" type="password" class="aimeat-inp" placeholder="' + escHtml(i.newPasswordPlaceholder || 'New password (min 8 chars)') + '"></div>'
153
+ + '<div style="display:flex;gap:10px">'
154
+ + '<button id="aimeat-fpw-reset" class="aimeat-go">' + escHtml(i.resetPassword || 'Reset Password') + '</button>'
155
+ + '<button id="aimeat-fpw-back2" class="aimeat-cancel">' + escHtml(i.backToLogin || 'Back to Login') + '</button>'
156
+ + '</div>'
157
+ + '<p id="aimeat-fpw-msg2" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p>'
158
+ + '<p id="aimeat-fpw-err2" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p>'
159
+ + '</div>'
160
+ + '</div>'
161
+ // Forgot username sub-view (hidden by default)
162
+ + '<div id="aimeat-forgot-user-view" style="padding:24px 32px;display:none">'
163
+ + '<h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i.recoverUsernameTitle || 'Recover Username') + '</h3>'
164
+ + '<p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i.recoverUsernameDesc || 'Enter the email address associated with your account.') + '</p>'
165
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.emailLabel || 'Email') + '</label>'
166
+ + '<input id="aimeat-fu-email" class="aimeat-inp" type="email" placeholder="you@example.com"></div>'
167
+ + '<div style="display:flex;gap:10px">'
168
+ + '<button id="aimeat-fu-send" class="aimeat-go">' + escHtml(i.sendUsername || 'Send My Username') + '</button>'
169
+ + '<button id="aimeat-fu-back" class="aimeat-cancel">' + escHtml(i.backToLogin || 'Back to Login') + '</button>'
170
+ + '</div>'
171
+ + '<p id="aimeat-fu-msg" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p>'
172
+ + '</div>'
173
+ // Complete-account sub-view (hidden) — email verification (legacy accounts + register-under-gate).
174
+ + '<div id="aimeat-email-view" style="padding:24px 32px;display:none">'
175
+ + '<div id="aimeat-em-step1">'
176
+ + '<h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i.completeAccountTitle || 'One last step') + '</h3>'
177
+ + '<p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i.completeAccountDesc || 'Add an email to finish setting up your account. We’ll send a verification code to confirm it.') + '</p>'
178
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.emailLabel || 'Email') + '</label>'
179
+ + '<input id="aimeat-em-email" class="aimeat-inp" type="email" placeholder="you@example.com"></div>'
180
+ + '<div style="display:flex;gap:10px">'
181
+ + '<button id="aimeat-em-send" class="aimeat-go">' + escHtml(i.sendVerificationCode || 'Send Verification Code') + '</button>'
182
+ + '<button id="aimeat-em-back" class="aimeat-cancel">' + escHtml(i.backToLogin || 'Back to Login') + '</button>'
183
+ + '</div>'
184
+ + '<p id="aimeat-em-err" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p>'
185
+ + '</div>'
186
+ + '<div id="aimeat-em-step2" style="display:none">'
187
+ + '<h3 style="margin:0 0 8px;font-size:17px;font-weight:700;color:#1A1A2E">' + escHtml(i.enterCodeTitle || 'Enter Verification Code') + '</h3>'
188
+ + '<p style="font-size:13px;color:#6B7280;margin-bottom:14px">' + escHtml(i.enterCodeDesc || 'We sent a 6-digit code to your email. Enter it below to finish and sign in.') + '</p>'
189
+ + '<div style="margin-bottom:14px"><label class="aimeat-label">' + escHtml(i.codeLabel || 'Verification Code') + '</label>'
190
+ + '<input id="aimeat-em-code" class="aimeat-inp" placeholder="123456" maxlength="6" inputmode="numeric"></div>'
191
+ + '<div style="display:flex;gap:10px">'
192
+ + '<button id="aimeat-em-confirm" class="aimeat-go">' + escHtml(i.confirmAndSignIn || 'Confirm & Sign In') + '</button>'
193
+ + '<button id="aimeat-em-back2" class="aimeat-cancel">' + escHtml(i.backToLogin || 'Back to Login') + '</button>'
194
+ + '</div>'
195
+ + '<p id="aimeat-em-msg2" style="margin:8px 0 0;font-size:13px;color:#22C55E;display:none"></p>'
196
+ + '<p id="aimeat-em-err2" style="margin:8px 0 0;font-size:13px;color:#ef4444;display:none"></p>'
197
+ + '</div>'
198
+ + '</div>'
199
+ // Features footer
200
+ + '<div style="padding:20px 32px 28px;background:#F9FAFB;border-top:1px solid #E5E7EB">'
201
+ + '<h4 style="margin:0 0 12px;font-size:13px;font-weight:700;color:#1A1A2E;display:flex;align-items:center;gap:6px">✨ ' + escHtml(i.whyTitle || 'What do you get?') + '</h4>'
202
+ + '<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(i.whyGhii || 'A free GHII (Global Human Intelligence Identifier), your personal AI identity') + '</span></div>'
203
+ + '<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(i.whyPrivacy || 'Your own private memory space, protected by your password') + '</span></div>'
204
+ + '<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(i.whyAgents || 'Connect AI agents that remember you and work on your behalf') + '</span></div>'
205
+ + '<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(i.whyMorsels || 'Your own AI-built apps and agents work for you — a digital agency under your own roof.') + '</strong></span></div>'
206
+ + '</div>'
207
+ + '</div></div>';
208
+ } // end buildModalInner
209
+
210
+ function wireModal() {
211
+
212
+ // Language switcher (EN/FI) — persists choice + re-renders the modal in place
213
+ modal.querySelectorAll('.aimeat-lang').forEach(function (b) {
214
+ b.addEventListener('click', function () { switchLang(b.getAttribute('data-lang')); });
215
+ });
216
+
217
+ document.getElementById('aimeat-cancel-btn').addEventListener('click', () => modal.remove());
218
+
219
+ // Social sign-in — full-page navigation to the provider's OIDC start endpoint.
220
+ modal.querySelectorAll('.aimeat-oauth-btn').forEach(function (btn) {
221
+ btn.addEventListener('click', function () {
222
+ var id = btn.getAttribute('data-provider');
223
+ var back = encodeURIComponent(location.pathname + location.search + location.hash);
224
+ location.href = NODE_URL + '/v1/ghii/login/' + id + '?redirect=' + back;
225
+ });
226
+ });
227
+
228
+ // Helper to toggle between views
229
+ function showView(view) {
230
+ document.getElementById('aimeat-modal-body').style.display = view === 'login' ? '' : 'none';
231
+ document.getElementById('aimeat-forgot-pw-view').style.display = view === 'forgot-pw' ? '' : 'none';
232
+ document.getElementById('aimeat-forgot-user-view').style.display = view === 'forgot-user' ? '' : 'none';
233
+ document.getElementById('aimeat-email-view').style.display = view === 'email' ? '' : 'none';
234
+ }
235
+
236
+ // Credentials captured from the last correct-password attempt that hit the email gate.
237
+ var pendingEmailLogin = null;
238
+
239
+ // Open the email step. 'attach' — existing account needs a verified email. 'register' — brand-new
240
+ // account under the email gate: step1 POST /v1/ghii (with email) creates it. Both finish identically.
241
+ function openEmailCompletion(user, pass, hasEmail, mode, displayName) {
242
+ pendingEmailLogin = { username: user, password: pass, mode: mode || 'attach', displayName: displayName || user };
243
+ showView('email');
244
+ document.getElementById('aimeat-em-step1').style.display = '';
245
+ document.getElementById('aimeat-em-step2').style.display = 'none';
246
+ var emailInput = /** @type {any} */ (document.getElementById('aimeat-em-email'));
247
+ emailInput.value = '';
248
+ var titleEl = document.querySelector('#aimeat-em-step1 h3');
249
+ var desc = document.querySelector('#aimeat-em-step1 p');
250
+ if (pendingEmailLogin.mode === 'register') {
251
+ if (titleEl) titleEl.textContent = i.registerEmailTitle || 'Add your email';
252
+ if (desc) desc.textContent = i.registerEmailDesc || 'Enter your email to create your account. We’ll send a verification code to confirm it.';
253
+ } else {
254
+ if (titleEl) titleEl.textContent = i.completeAccountTitle || 'One last step';
255
+ if (desc) {
256
+ desc.textContent = hasEmail
257
+ ? (i.completeAccountDescResend || 'Confirm your email to finish signing in. We’ll send a verification code — edit the address if it’s wrong.')
258
+ : (i.completeAccountDesc || 'Add an email to finish setting up your account. We’ll send a verification code to confirm it.');
259
+ }
260
+ }
261
+ document.getElementById('aimeat-em-err').style.display = 'none';
262
+ setTimeout(function () { emailInput.focus(); }, 50);
263
+ }
264
+
265
+ // Forgot password link
266
+ document.getElementById('aimeat-forgot-pw').addEventListener('click', function (e) {
267
+ e.preventDefault();
268
+ showView('forgot-pw');
269
+ document.getElementById('aimeat-fpw-step1').style.display = '';
270
+ document.getElementById('aimeat-fpw-step2').style.display = 'none';
271
+ });
272
+
273
+ // Forgot username link
274
+ document.getElementById('aimeat-forgot-user').addEventListener('click', function (e) {
275
+ e.preventDefault();
276
+ showView('forgot-user');
277
+ });
278
+
279
+ // Back to login buttons
280
+ ['aimeat-fpw-back', 'aimeat-fpw-back2', 'aimeat-fu-back', 'aimeat-em-back', 'aimeat-em-back2'].forEach(function (id) {
281
+ document.getElementById(id).addEventListener('click', function () { showView('login'); });
282
+ });
283
+
284
+ // Complete-account step 1 — send a verification code (re-verifies password server-side).
285
+ document.getElementById('aimeat-em-send').addEventListener('click', async function () {
286
+ var email = /** @type {any} */ (document.getElementById('aimeat-em-email')).value.trim();
287
+ var errEl = document.getElementById('aimeat-em-err');
288
+ errEl.style.display = 'none';
289
+ if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
290
+ errEl.textContent = i.errEmailInvalid || 'Please enter a valid email address.';
291
+ errEl.style.display = 'block';
292
+ return;
293
+ }
294
+ if (!pendingEmailLogin) { showView('login'); return; }
295
+ var btn = /** @type {any} */ (document.getElementById('aimeat-em-send'));
296
+ btn.textContent = i.working || 'Working...';
297
+ btn.disabled = true;
298
+ try {
299
+ var res;
300
+ if (pendingEmailLogin.mode === 'register') {
301
+ // Brand-new account under the email gate: create it now WITH the email (returns verification_id).
302
+ res = await api('/v1/ghii', {
303
+ method: 'POST',
304
+ credentials: 'include',
305
+ body: JSON.stringify({
306
+ username: pendingEmailLogin.username,
307
+ display_name: pendingEmailLogin.displayName,
308
+ password: pendingEmailLogin.password,
309
+ email: email,
310
+ }),
311
+ });
312
+ } else {
313
+ res = await api('/v1/ghii/login/attach-email', {
314
+ method: 'POST',
315
+ body: JSON.stringify({ username: pendingEmailLogin.username, password: pendingEmailLogin.password, email: email }),
316
+ });
317
+ }
318
+ pendingEmailLogin.verificationId = res.data && res.data.verification_id;
319
+ document.getElementById('aimeat-em-step1').style.display = 'none';
320
+ document.getElementById('aimeat-em-step2').style.display = '';
321
+ setTimeout(function () { /** @type {any} */ (document.getElementById('aimeat-em-code')).focus(); }, 50);
322
+ } catch (e) {
323
+ errEl.textContent = e.message;
324
+ errEl.style.display = 'block';
325
+ } finally {
326
+ btn.textContent = i.sendVerificationCode || 'Send Verification Code';
327
+ btn.disabled = false;
328
+ }
329
+ });
330
+
331
+ // Complete-account step 2 — confirm the code, then re-run the password login for a normal session.
332
+ document.getElementById('aimeat-em-confirm').addEventListener('click', async function () {
333
+ var code = /** @type {any} */ (document.getElementById('aimeat-em-code')).value.trim();
334
+ var msgEl = document.getElementById('aimeat-em-msg2');
335
+ var errEl = document.getElementById('aimeat-em-err2');
336
+ msgEl.style.display = 'none';
337
+ errEl.style.display = 'none';
338
+ if (!code) { errEl.textContent = i.errCodeRequired || 'Enter the verification code.'; errEl.style.display = 'block'; return; }
339
+ if (!pendingEmailLogin) { showView('login'); return; }
340
+ var btn = /** @type {any} */ (document.getElementById('aimeat-em-confirm'));
341
+ btn.textContent = i.working || 'Working...';
342
+ btn.disabled = true;
343
+ try {
344
+ await api('/v1/ghii/verify-email', {
345
+ method: 'POST',
346
+ body: JSON.stringify({ verification_id: pendingEmailLogin.verificationId, code: code }),
347
+ });
348
+ msgEl.textContent = i.emailVerifiedSigningIn || 'Verified! Signing you in...';
349
+ msgEl.style.display = 'block';
350
+ var session = await auth.loginWithPassword(pendingEmailLogin.username, pendingEmailLogin.password);
351
+ pendingEmailLogin = null;
352
+ modal.remove();
353
+ renderBtn();
354
+ if (opts.onLogin) opts.onLogin(session);
355
+ } catch (e) {
356
+ errEl.textContent = e.message;
357
+ errEl.style.display = 'block';
358
+ btn.textContent = i.confirmAndSignIn || 'Confirm & Sign In';
359
+ btn.disabled = false;
360
+ }
361
+ });
362
+
363
+ // Send password reset code
364
+ document.getElementById('aimeat-fpw-send').addEventListener('click', async function () {
365
+ var username = /** @type {any} */ (document.getElementById('aimeat-fpw-username')).value.trim().toLowerCase();
366
+ var msgEl = document.getElementById('aimeat-fpw-msg');
367
+ var errEl = document.getElementById('aimeat-fpw-err');
368
+ msgEl.style.display = 'none';
369
+ errEl.style.display = 'none';
370
+ if (!username) { errEl.textContent = i.errUserShort || 'Username is required'; errEl.style.display = 'block'; return; }
371
+ try {
372
+ await api('/v1/ghii/password/reset-request', { method: 'POST', body: JSON.stringify({ username: username }) });
373
+ msgEl.textContent = i.resetCodeSent || 'If your account has a verified email, a reset code was sent.';
374
+ msgEl.style.display = 'block';
375
+ document.getElementById('aimeat-fpw-step1').style.display = 'none';
376
+ document.getElementById('aimeat-fpw-step2').style.display = '';
377
+ window.__aimeatResetUser = username;
378
+ } catch (e) {
379
+ errEl.textContent = e.message; errEl.style.display = 'block';
380
+ }
381
+ });
382
+
383
+ // Reset password with code
384
+ document.getElementById('aimeat-fpw-reset').addEventListener('click', async function () {
385
+ var code = /** @type {any} */ (document.getElementById('aimeat-fpw-code')).value.trim();
386
+ var newPass = /** @type {any} */ (document.getElementById('aimeat-fpw-newpass')).value;
387
+ var msgEl = document.getElementById('aimeat-fpw-msg2');
388
+ var errEl = document.getElementById('aimeat-fpw-err2');
389
+ msgEl.style.display = 'none';
390
+ errEl.style.display = 'none';
391
+ if (!code) { errEl.textContent = 'Code is required'; errEl.style.display = 'block'; return; }
392
+ if (!newPass || newPass.length < 8) { errEl.textContent = i.errPassWeak || 'Password must be at least 8 characters'; errEl.style.display = 'block'; return; }
393
+ try {
394
+ await api('/v1/ghii/password/reset', { method: 'POST', body: JSON.stringify({
395
+ username: window.__aimeatResetUser || '',
396
+ code: code,
397
+ newPassword: newPass,
398
+ }) });
399
+ msgEl.textContent = i.resetSuccess || 'Password reset successful! You can now sign in.';
400
+ msgEl.style.display = 'block';
401
+ setTimeout(function () { showView('login'); }, 2000);
402
+ } catch (e) {
403
+ errEl.textContent = e.message; errEl.style.display = 'block';
404
+ }
405
+ });
406
+
407
+ // Send username recovery
408
+ document.getElementById('aimeat-fu-send').addEventListener('click', async function () {
409
+ var email = /** @type {any} */ (document.getElementById('aimeat-fu-email')).value.trim();
410
+ var msgEl = document.getElementById('aimeat-fu-msg');
411
+ msgEl.style.display = 'none';
412
+ if (!email) return;
413
+ try {
414
+ await api('/v1/ghii/account/recover', { method: 'POST', body: JSON.stringify({ email: email }) });
415
+ } catch { /* always show success */ }
416
+ msgEl.textContent = i.usernameSent || 'If an account with that email exists, your username was sent.';
417
+ msgEl.style.display = 'block';
418
+ });
419
+
420
+ // Enter in any of the sign-in fields submits (unless the button is mid-request/disabled).
421
+ ['aimeat-username', 'aimeat-password', 'aimeat-displayname'].forEach(function (id) {
422
+ var el = document.getElementById(id);
423
+ if (!el) return;
424
+ el.addEventListener('keydown', function (e) {
425
+ if (e.key !== 'Enter') return;
426
+ e.preventDefault();
427
+ var btn = /** @type {any} */ (document.getElementById('aimeat-go-btn'));
428
+ if (btn && !btn.disabled) btn.click();
429
+ });
430
+ });
431
+
432
+ document.getElementById('aimeat-go-btn').addEventListener('click', async () => {
433
+ let username = /** @type {any} */ (document.getElementById('aimeat-username')).value.trim().toLowerCase();
434
+ const password = /** @type {any} */ (document.getElementById('aimeat-password')).value;
435
+ const errEl = document.getElementById('aimeat-error');
436
+
437
+ // Accept full GHII (e.g. "alice@node-id") — detect local vs federated
438
+ let isGhii = false;
439
+ let isFederated = false;
440
+ let fullUsername = username;
441
+ if (username.includes('@')) {
442
+ const atIdx = username.indexOf('@');
443
+ const nodePart = username.substring(atIdx + 1);
444
+ if (nodePart && nodePart !== NODE_ID) {
445
+ isFederated = true;
446
+ isGhii = true;
447
+ } else {
448
+ username = username.substring(0, atIdx);
449
+ isGhii = true;
450
+ }
451
+ }
452
+
453
+ const displayName = /** @type {any} */ (document.getElementById('aimeat-displayname')).value.trim() || username;
454
+
455
+ if (!username || username.length < 3) {
456
+ errEl.textContent = i.errUserShort || 'Username must be at least 3 characters';
457
+ errEl.style.display = 'block';
458
+ return;
459
+ }
460
+
461
+ if (!password || password.length < 4) {
462
+ errEl.textContent = i.errPassShort || 'Password must be at least 4 characters';
463
+ errEl.style.display = 'block';
464
+ return;
465
+ }
466
+
467
+ const btn = /** @type {any} */ (document.getElementById('aimeat-go-btn'));
468
+ btn.textContent = i.working || 'Working...';
469
+ btn.disabled = true;
470
+
471
+ // If input was a full GHII, skip register and go straight to login
472
+ if (isGhii) {
473
+ try {
474
+ if (isFederated) {
475
+ btn.textContent = i.connectingHome || 'Connecting to home node...';
476
+ }
477
+ const loginUser = isFederated ? fullUsername : username;
478
+ const session = await auth.loginWithPassword(loginUser, password);
479
+ modal.remove();
480
+ renderBtn();
481
+ if (opts.onLogin) opts.onLogin(session);
482
+ } catch (e2) {
483
+ // Password correct but the account still needs a verified email — open the completion flow.
484
+ if (e2.code === 'EMAIL_NOT_VERIFIED' && !isFederated) {
485
+ btn.textContent = i.signInBtn || 'Sign In / Register';
486
+ btn.disabled = false;
487
+ openEmailCompletion(username, password, !!(e2.details && e2.details.has_email));
488
+ return;
489
+ }
490
+ errEl.textContent = e2.message.includes('Invalid username or password')
491
+ ? (i.errWrongPass || 'Wrong password for that username.')
492
+ : e2.message;
493
+ errEl.style.display = 'block';
494
+ btn.textContent = i.signInBtn || 'Sign In / Register';
495
+ btn.disabled = false;
496
+ }
497
+ return;
498
+ }
499
+
500
+ try {
501
+ // Try registering first (new account)
502
+ const session = await auth.register(username, displayName, { password });
503
+ modal.remove();
504
+ renderBtn();
505
+ if (opts.onLogin) opts.onLogin(session);
506
+ } catch (e) {
507
+ // Email gate on + a genuinely new username → open the email step (register mode) to collect one.
508
+ if (e.code === 'EMAIL_REQUIRED') {
509
+ btn.textContent = i.signInBtn || 'Sign In / Register';
510
+ btn.disabled = false;
511
+ openEmailCompletion(username, password, false, 'register', displayName);
512
+ return;
513
+ }
514
+ // If NAME_TAKEN, try logging in with password
515
+ if (e.message.includes('already registered') || e.message.includes('NAME_TAKEN')) {
516
+ try {
517
+ const session = await auth.loginWithPassword(username, password);
518
+ modal.remove();
519
+ renderBtn();
520
+ if (opts.onLogin) opts.onLogin(session);
521
+ } catch (e2) {
522
+ if (e2.code === 'EMAIL_NOT_VERIFIED') {
523
+ btn.textContent = i.signInBtn || 'Sign In / Register';
524
+ btn.disabled = false;
525
+ openEmailCompletion(username, password, !!(e2.details && e2.details.has_email));
526
+ return;
527
+ }
528
+ errEl.textContent = e2.message.includes('Invalid username or password')
529
+ ? (i.errWrongPass || 'Wrong password for that username.')
530
+ : e2.message;
531
+ errEl.style.display = 'block';
532
+ btn.textContent = i.signInBtn || 'Sign In';
533
+ btn.disabled = false;
534
+ }
535
+ } else {
536
+ errEl.textContent = e.message;
537
+ errEl.style.display = 'block';
538
+ btn.textContent = i.signInBtn || 'Sign In / Register';
539
+ btn.disabled = false;
540
+ }
541
+ }
542
+ });
543
+
544
+ } // end wireModal
545
+ }