aimeat 2.1.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 (422) hide show
  1. package/dist/.env.example +9 -4
  2. package/dist/locales/en.json +28 -0
  3. package/dist/locales/fi.json +28 -0
  4. package/dist/public/cortex-bundled/aimeat-charts.js +158 -10
  5. package/dist/public/cortex-bundled/aimeat-charts.yaml +1 -1
  6. package/dist/public/cortex-bundled/aimeat-dag.js +515 -173
  7. package/dist/public/cortex-bundled/aimeat-dag.yaml +1 -1
  8. package/dist/public/cortex-bundled/aimeat-i18n.js +6 -1
  9. package/dist/public/cortex-bundled/aimeat-i18n.yaml +1 -1
  10. package/dist/public/cortex-bundled/aimeat-surface.js +577 -0
  11. package/dist/public/cortex-bundled/aimeat-surface.yaml +107 -0
  12. package/dist/public/cortex-bundled/aimeat-viewport.js +405 -0
  13. package/dist/public/cortex-bundled/aimeat-viewport.yaml +100 -0
  14. package/dist/public/css/views/inbox.css +1 -1
  15. package/dist/public/css/views/profile.css +9 -0
  16. package/dist/public/lib/VENDORED.md +6 -3
  17. package/dist/public/lib/aimeat-daisyui-bridge.css +39 -2
  18. package/dist/public/lib/aimeat-theme.css +538 -0
  19. package/dist/public/lib/fonts/LICENSE.md +11 -4
  20. package/dist/public/lib/fonts/fraunces-var-latin-ext.woff2 +0 -0
  21. package/dist/public/lib/fonts/fraunces-var-latin.woff2 +0 -0
  22. package/dist/public/lib/fonts/inter-var-latin-ext.woff2 +0 -0
  23. package/dist/public/lib/fonts/inter-var-latin.woff2 +0 -0
  24. package/dist/public/lib/fonts/jetbrains-mono-var-latin-ext.woff2 +0 -0
  25. package/dist/public/lib/fonts/jetbrains-mono-var-latin.woff2 +0 -0
  26. package/dist/public/lib/fonts/space-grotesk-var-latin-ext.woff2 +0 -0
  27. package/dist/public/lib/fonts/space-grotesk-var-latin.woff2 +0 -0
  28. package/dist/public/lib/samples/theme-check.html +92 -0
  29. package/dist/public/lib/samples/themes-boot.js +20 -0
  30. package/dist/public/lib/samples/themes.html +154 -0
  31. package/dist/public/lib/samples/themes.js +60 -0
  32. package/dist/public/views/profile/access-tab/connected-apps.js +81 -5
  33. package/dist/public/views/profile/extensions-tab.maturity.js +4 -1
  34. package/dist/public/views/profile/inbox-tab/components.js +17 -1
  35. package/dist/public/views/profile/inbox-tab/use-thread-ux.js +29 -2
  36. package/dist/public/views/profile/libraries-tab.js +10 -2
  37. package/dist/public/views/profile/wallet-tab.js +64 -0
  38. package/dist/scripts/check-openapi.d.ts +2 -0
  39. package/dist/scripts/check-openapi.d.ts.map +1 -0
  40. package/dist/scripts/check-openapi.js +139 -0
  41. package/dist/scripts/check-openapi.js.map +1 -0
  42. package/dist/scripts/embed-viewport.d.ts +23 -0
  43. package/dist/scripts/embed-viewport.d.ts.map +1 -0
  44. package/dist/scripts/embed-viewport.js +116 -0
  45. package/dist/scripts/embed-viewport.js.map +1 -0
  46. package/dist/src/auth/sse-domain-scopes.d.ts +50 -0
  47. package/dist/src/auth/sse-domain-scopes.d.ts.map +1 -0
  48. package/dist/src/auth/sse-domain-scopes.js +111 -0
  49. package/dist/src/auth/sse-domain-scopes.js.map +1 -0
  50. package/dist/src/cli/connect/mcp/tools/agent-tasks.d.ts.map +1 -1
  51. package/dist/src/cli/connect/mcp/tools/agent-tasks.js +4 -1
  52. package/dist/src/cli/connect/mcp/tools/agent-tasks.js.map +1 -1
  53. package/dist/src/cli/connect/mcp/tools/core.d.ts.map +1 -1
  54. package/dist/src/cli/connect/mcp/tools/core.js +14 -3
  55. package/dist/src/cli/connect/mcp/tools/core.js.map +1 -1
  56. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts +3 -0
  57. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts.map +1 -1
  58. package/dist/src/cli/connect/mcp/tools/workspaces.js +4 -2
  59. package/dist/src/cli/connect/mcp/tools/workspaces.js.map +1 -1
  60. package/dist/src/cli/connect/tool-call-defs-core.d.ts.map +1 -1
  61. package/dist/src/cli/connect/tool-call-defs-core.js +13 -1
  62. package/dist/src/cli/connect/tool-call-defs-core.js.map +1 -1
  63. package/dist/src/commerce/__tests__/x402-registry.test.d.ts +2 -0
  64. package/dist/src/commerce/__tests__/x402-registry.test.d.ts.map +1 -0
  65. package/dist/src/commerce/__tests__/x402-registry.test.js +105 -0
  66. package/dist/src/commerce/__tests__/x402-registry.test.js.map +1 -0
  67. package/dist/src/commerce/evm-address.d.ts +21 -0
  68. package/dist/src/commerce/evm-address.d.ts.map +1 -0
  69. package/dist/src/commerce/evm-address.js +94 -0
  70. package/dist/src/commerce/evm-address.js.map +1 -0
  71. package/dist/src/commerce/money.d.ts +18 -5
  72. package/dist/src/commerce/money.d.ts.map +1 -1
  73. package/dist/src/commerce/money.js +27 -6
  74. package/dist/src/commerce/money.js.map +1 -1
  75. package/dist/src/commerce/x402-facilitator.d.ts +64 -13
  76. package/dist/src/commerce/x402-facilitator.d.ts.map +1 -1
  77. package/dist/src/commerce/x402-facilitator.js +71 -19
  78. package/dist/src/commerce/x402-facilitator.js.map +1 -1
  79. package/dist/src/commerce/x402-handler.d.ts +13 -7
  80. package/dist/src/commerce/x402-handler.d.ts.map +1 -1
  81. package/dist/src/commerce/x402-handler.js +23 -10
  82. package/dist/src/commerce/x402-handler.js.map +1 -1
  83. package/dist/src/commerce/x402.d.ts +11 -6
  84. package/dist/src/commerce/x402.d.ts.map +1 -1
  85. package/dist/src/commerce/x402.js +10 -7
  86. package/dist/src/commerce/x402.js.map +1 -1
  87. package/dist/src/config-types.d.ts +12 -0
  88. package/dist/src/config-types.d.ts.map +1 -1
  89. package/dist/src/config.d.ts.map +1 -1
  90. package/dist/src/config.js +8 -0
  91. package/dist/src/config.js.map +1 -1
  92. package/dist/src/data/app-templates/shells.d.ts +11 -3
  93. package/dist/src/data/app-templates/shells.d.ts.map +1 -1
  94. package/dist/src/data/app-templates/shells.js +87 -6
  95. package/dist/src/data/app-templates/shells.js.map +1 -1
  96. package/dist/src/data/app-templates.js +2 -2
  97. package/dist/src/data/app-templates.js.map +1 -1
  98. package/dist/src/data/library-packs/cortex.d.ts.map +1 -1
  99. package/dist/src/data/library-packs/cortex.js +108 -5
  100. package/dist/src/data/library-packs/cortex.js.map +1 -1
  101. package/dist/src/data/library-packs/sdk.d.ts.map +1 -1
  102. package/dist/src/data/library-packs/sdk.js +32 -8
  103. package/dist/src/data/library-packs/sdk.js.map +1 -1
  104. package/dist/src/data/library-packs/vendored.d.ts.map +1 -1
  105. package/dist/src/data/library-packs/vendored.js +83 -6
  106. package/dist/src/data/library-packs/vendored.js.map +1 -1
  107. package/dist/src/generated/api-types.d.ts +478 -19
  108. package/dist/src/generated/api-types.d.ts.map +1 -1
  109. package/dist/src/mcp/agent-tasks.d.ts +4 -0
  110. package/dist/src/mcp/agent-tasks.d.ts.map +1 -1
  111. package/dist/src/mcp/agent-tasks.js +20 -2
  112. package/dist/src/mcp/agent-tasks.js.map +1 -1
  113. package/dist/src/mcp/capabilities.d.ts +7 -1
  114. package/dist/src/mcp/capabilities.d.ts.map +1 -1
  115. package/dist/src/mcp/capabilities.js +5 -2
  116. package/dist/src/mcp/capabilities.js.map +1 -1
  117. package/dist/src/mcp/catalog/definitions/commerce.d.ts.map +1 -1
  118. package/dist/src/mcp/catalog/definitions/commerce.js +4 -2
  119. package/dist/src/mcp/catalog/definitions/commerce.js.map +1 -1
  120. package/dist/src/mcp/catalog/definitions/discovery-work-boards.d.ts.map +1 -1
  121. package/dist/src/mcp/catalog/definitions/discovery-work-boards.js +4 -3
  122. package/dist/src/mcp/catalog/definitions/discovery-work-boards.js.map +1 -1
  123. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js +1 -1
  124. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js.map +1 -1
  125. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.d.ts.map +1 -1
  126. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.js +3 -2
  127. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.js.map +1 -1
  128. package/dist/src/mcp/catalog/output-schemas.d.ts +6 -1
  129. package/dist/src/mcp/catalog/output-schemas.d.ts.map +1 -1
  130. package/dist/src/mcp/catalog/output-schemas.js +6 -1
  131. package/dist/src/mcp/catalog/output-schemas.js.map +1 -1
  132. package/dist/src/mcp/commerce.d.ts.map +1 -1
  133. package/dist/src/mcp/commerce.js +15 -3
  134. package/dist/src/mcp/commerce.js.map +1 -1
  135. package/dist/src/mcp/core-storage.d.ts +23 -0
  136. package/dist/src/mcp/core-storage.d.ts.map +1 -0
  137. package/dist/src/mcp/core-storage.js +157 -0
  138. package/dist/src/mcp/core-storage.js.map +1 -0
  139. package/dist/src/mcp/core.d.ts +16 -0
  140. package/dist/src/mcp/core.d.ts.map +1 -1
  141. package/dist/src/mcp/core.js +75 -119
  142. package/dist/src/mcp/core.js.map +1 -1
  143. package/dist/src/mcp/dm-messages.d.ts +4 -0
  144. package/dist/src/mcp/dm-messages.d.ts.map +1 -1
  145. package/dist/src/mcp/dm-messages.js +43 -2
  146. package/dist/src/mcp/dm-messages.js.map +1 -1
  147. package/dist/src/mcp/exchange.d.ts.map +1 -1
  148. package/dist/src/mcp/exchange.js +3 -2
  149. package/dist/src/mcp/exchange.js.map +1 -1
  150. package/dist/src/mcp/extensions.d.ts.map +1 -1
  151. package/dist/src/mcp/extensions.js +6 -2
  152. package/dist/src/mcp/extensions.js.map +1 -1
  153. package/dist/src/mcp/index.d.ts +5 -0
  154. package/dist/src/mcp/index.d.ts.map +1 -1
  155. package/dist/src/mcp/index.js +23 -4
  156. package/dist/src/mcp/index.js.map +1 -1
  157. package/dist/src/mcp/memory-namespace-hints.d.ts +33 -0
  158. package/dist/src/mcp/memory-namespace-hints.d.ts.map +1 -0
  159. package/dist/src/mcp/memory-namespace-hints.js +60 -0
  160. package/dist/src/mcp/memory-namespace-hints.js.map +1 -0
  161. package/dist/src/mcp/workspaces.d.ts +5 -0
  162. package/dist/src/mcp/workspaces.d.ts.map +1 -1
  163. package/dist/src/mcp/workspaces.js +5 -3
  164. package/dist/src/mcp/workspaces.js.map +1 -1
  165. package/dist/src/models/agent-task-schemas.d.ts +25 -3
  166. package/dist/src/models/agent-task-schemas.d.ts.map +1 -1
  167. package/dist/src/models/agent-task-schemas.js +16 -0
  168. package/dist/src/models/agent-task-schemas.js.map +1 -1
  169. package/dist/src/models/app-tool-schemas.d.ts +518 -1
  170. package/dist/src/models/app-tool-schemas.d.ts.map +1 -1
  171. package/dist/src/models/app-tool-schemas.js +53 -1
  172. package/dist/src/models/app-tool-schemas.js.map +1 -1
  173. package/dist/src/models/odps-schemas.d.ts +305 -0
  174. package/dist/src/models/odps-schemas.d.ts.map +1 -0
  175. package/dist/src/models/odps-schemas.js +182 -0
  176. package/dist/src/models/odps-schemas.js.map +1 -0
  177. package/dist/src/models/offer-schemas.d.ts +357 -2
  178. package/dist/src/models/offer-schemas.d.ts.map +1 -1
  179. package/dist/src/models/offer-schemas.js +37 -0
  180. package/dist/src/models/offer-schemas.js.map +1 -1
  181. package/dist/src/models/schemas.d.ts +6 -3
  182. package/dist/src/models/schemas.d.ts.map +1 -1
  183. package/dist/src/models/schemas.js +10 -1
  184. package/dist/src/models/schemas.js.map +1 -1
  185. package/dist/src/models/webhook-schemas.d.ts +8 -8
  186. package/dist/src/routes/agent-tasks/create-read.d.ts +4 -0
  187. package/dist/src/routes/agent-tasks/create-read.d.ts.map +1 -1
  188. package/dist/src/routes/agent-tasks/create-read.js +20 -1
  189. package/dist/src/routes/agent-tasks/create-read.js.map +1 -1
  190. package/dist/src/routes/agent-tasks/lifecycle.d.ts.map +1 -1
  191. package/dist/src/routes/agent-tasks/lifecycle.js +10 -0
  192. package/dist/src/routes/agent-tasks/lifecycle.js.map +1 -1
  193. package/dist/src/routes/agents/offers.d.ts +2 -0
  194. package/dist/src/routes/agents/offers.d.ts.map +1 -1
  195. package/dist/src/routes/agents/offers.js +0 -0
  196. package/dist/src/routes/agents/offers.js.map +1 -1
  197. package/dist/src/routes/app-grants.d.ts +6 -0
  198. package/dist/src/routes/app-grants.d.ts.map +1 -1
  199. package/dist/src/routes/app-grants.js +55 -25
  200. package/dist/src/routes/app-grants.js.map +1 -1
  201. package/dist/src/routes/apps/drafts.d.ts +3 -0
  202. package/dist/src/routes/apps/drafts.d.ts.map +1 -1
  203. package/dist/src/routes/apps/drafts.js +63 -1
  204. package/dist/src/routes/apps/drafts.js.map +1 -1
  205. package/dist/src/routes/apps/publish.d.ts +2 -0
  206. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  207. package/dist/src/routes/apps/publish.js +17 -2
  208. package/dist/src/routes/apps/publish.js.map +1 -1
  209. package/dist/src/routes/commerce.d.ts.map +1 -1
  210. package/dist/src/routes/commerce.js +122 -2
  211. package/dist/src/routes/commerce.js.map +1 -1
  212. package/dist/src/routes/exchange-market.d.ts +6 -2
  213. package/dist/src/routes/exchange-market.d.ts.map +1 -1
  214. package/dist/src/routes/exchange-market.js +154 -28
  215. package/dist/src/routes/exchange-market.js.map +1 -1
  216. package/dist/src/routes/exchange.d.ts.map +1 -1
  217. package/dist/src/routes/exchange.js +5 -2
  218. package/dist/src/routes/exchange.js.map +1 -1
  219. package/dist/src/routes/extensions/actions.d.ts.map +1 -1
  220. package/dist/src/routes/extensions/actions.js +18 -0
  221. package/dist/src/routes/extensions/actions.js.map +1 -1
  222. package/dist/src/routes/extensions/crud.d.ts.map +1 -1
  223. package/dist/src/routes/extensions/crud.js +36 -3
  224. package/dist/src/routes/extensions/crud.js.map +1 -1
  225. package/dist/src/routes/extensions/entitlement-gate.d.ts.map +1 -1
  226. package/dist/src/routes/extensions/entitlement-gate.js +13 -0
  227. package/dist/src/routes/extensions/entitlement-gate.js.map +1 -1
  228. package/dist/src/routes/extensions/manifest.d.ts +6 -0
  229. package/dist/src/routes/extensions/manifest.d.ts.map +1 -1
  230. package/dist/src/routes/extensions/manifest.js +68 -1
  231. package/dist/src/routes/extensions/manifest.js.map +1 -1
  232. package/dist/src/routes/extensions/pacing.d.ts +31 -0
  233. package/dist/src/routes/extensions/pacing.d.ts.map +1 -0
  234. package/dist/src/routes/extensions/pacing.js +73 -0
  235. package/dist/src/routes/extensions/pacing.js.map +1 -0
  236. package/dist/src/routes/extensions/paywall.d.ts.map +1 -1
  237. package/dist/src/routes/extensions/paywall.js +17 -17
  238. package/dist/src/routes/extensions/paywall.js.map +1 -1
  239. package/dist/src/routes/memory/crud.d.ts.map +1 -1
  240. package/dist/src/routes/memory/crud.js +10 -0
  241. package/dist/src/routes/memory/crud.js.map +1 -1
  242. package/dist/src/routes/organisms/crud.d.ts +3 -0
  243. package/dist/src/routes/organisms/crud.d.ts.map +1 -1
  244. package/dist/src/routes/organisms/crud.js +5 -2
  245. package/dist/src/routes/organisms/crud.js.map +1 -1
  246. package/dist/src/routes/organisms/workspace-read.d.ts.map +1 -1
  247. package/dist/src/routes/organisms/workspace-read.js +7 -2
  248. package/dist/src/routes/organisms/workspace-read.js.map +1 -1
  249. package/dist/src/routes/public-stats.d.ts +7 -0
  250. package/dist/src/routes/public-stats.d.ts.map +1 -1
  251. package/dist/src/routes/public-stats.js +28 -7
  252. package/dist/src/routes/public-stats.js.map +1 -1
  253. package/dist/src/routes/sse.d.ts +7 -0
  254. package/dist/src/routes/sse.d.ts.map +1 -1
  255. package/dist/src/routes/sse.js +36 -6
  256. package/dist/src/routes/sse.js.map +1 -1
  257. package/dist/src/routes/storage-files.d.ts +11 -0
  258. package/dist/src/routes/storage-files.d.ts.map +1 -1
  259. package/dist/src/routes/storage-files.js +58 -51
  260. package/dist/src/routes/storage-files.js.map +1 -1
  261. package/dist/src/routes/subdomains.d.ts +4 -0
  262. package/dist/src/routes/subdomains.d.ts.map +1 -1
  263. package/dist/src/routes/subdomains.js +42 -5
  264. package/dist/src/routes/subdomains.js.map +1 -1
  265. package/dist/src/routes/upload.d.ts +11 -0
  266. package/dist/src/routes/upload.d.ts.map +1 -1
  267. package/dist/src/routes/upload.js +108 -28
  268. package/dist/src/routes/upload.js.map +1 -1
  269. package/dist/src/routes/webmcp.d.ts.map +1 -1
  270. package/dist/src/routes/webmcp.js +4 -0
  271. package/dist/src/routes/webmcp.js.map +1 -1
  272. package/dist/src/schemas/knowledge-package.d.ts +1 -1
  273. package/dist/src/server-bootstrap/static-files.d.ts +4 -0
  274. package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
  275. package/dist/src/server-bootstrap/static-files.js +11 -0
  276. package/dist/src/server-bootstrap/static-files.js.map +1 -1
  277. package/dist/src/services/build-app-prompt.d.ts +19 -0
  278. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  279. package/dist/src/services/build-app-prompt.js +97 -11
  280. package/dist/src/services/build-app-prompt.js.map +1 -1
  281. package/dist/src/services/call-timing.d.ts +51 -0
  282. package/dist/src/services/call-timing.d.ts.map +1 -0
  283. package/dist/src/services/call-timing.js +91 -0
  284. package/dist/src/services/call-timing.js.map +1 -0
  285. package/dist/src/services/capability-invoke.d.ts +2 -0
  286. package/dist/src/services/capability-invoke.d.ts.map +1 -1
  287. package/dist/src/services/capability-invoke.js +10 -0
  288. package/dist/src/services/capability-invoke.js.map +1 -1
  289. package/dist/src/services/config-schema.d.ts.map +1 -1
  290. package/dist/src/services/config-schema.js +6 -0
  291. package/dist/src/services/config-schema.js.map +1 -1
  292. package/dist/src/services/draft-token.d.ts +22 -2
  293. package/dist/src/services/draft-token.d.ts.map +1 -1
  294. package/dist/src/services/draft-token.js +52 -3
  295. package/dist/src/services/draft-token.js.map +1 -1
  296. package/dist/src/services/exchange-market.d.ts +41 -8
  297. package/dist/src/services/exchange-market.d.ts.map +1 -1
  298. package/dist/src/services/exchange-market.js +24 -2
  299. package/dist/src/services/exchange-market.js.map +1 -1
  300. package/dist/src/services/exchange-odps.d.ts +58 -0
  301. package/dist/src/services/exchange-odps.d.ts.map +1 -0
  302. package/dist/src/services/exchange-odps.js +400 -0
  303. package/dist/src/services/exchange-odps.js.map +1 -0
  304. package/dist/src/services/exchange-projection.d.ts +61 -0
  305. package/dist/src/services/exchange-projection.d.ts.map +1 -0
  306. package/dist/src/services/exchange-projection.js +504 -0
  307. package/dist/src/services/exchange-projection.js.map +1 -0
  308. package/dist/src/services/exchange-proposals.d.ts.map +1 -1
  309. package/dist/src/services/exchange-proposals.js +2 -0
  310. package/dist/src/services/exchange-proposals.js.map +1 -1
  311. package/dist/src/services/extension-files.d.ts +64 -0
  312. package/dist/src/services/extension-files.d.ts.map +1 -0
  313. package/dist/src/services/extension-files.js +88 -0
  314. package/dist/src/services/extension-files.js.map +1 -0
  315. package/dist/src/services/extension-runtime.d.ts +33 -0
  316. package/dist/src/services/extension-runtime.d.ts.map +1 -1
  317. package/dist/src/services/extension-runtime.js +52 -0
  318. package/dist/src/services/extension-runtime.js.map +1 -1
  319. package/dist/src/services/file-refs.d.ts +105 -0
  320. package/dist/src/services/file-refs.d.ts.map +1 -0
  321. package/dist/src/services/file-refs.js +106 -0
  322. package/dist/src/services/file-refs.js.map +1 -0
  323. package/dist/src/services/metered-entitlements.d.ts +7 -0
  324. package/dist/src/services/metered-entitlements.d.ts.map +1 -1
  325. package/dist/src/services/metered-entitlements.js +4 -0
  326. package/dist/src/services/metered-entitlements.js.map +1 -1
  327. package/dist/src/services/owner-memory.d.ts +14 -1
  328. package/dist/src/services/owner-memory.d.ts.map +1 -1
  329. package/dist/src/services/owner-memory.js +8 -14
  330. package/dist/src/services/owner-memory.js.map +1 -1
  331. package/dist/src/services/task-files.d.ts +51 -0
  332. package/dist/src/services/task-files.d.ts.map +1 -0
  333. package/dist/src/services/task-files.js +58 -0
  334. package/dist/src/services/task-files.js.map +1 -0
  335. package/dist/src/services/upload-token.d.ts +29 -0
  336. package/dist/src/services/upload-token.d.ts.map +1 -1
  337. package/dist/src/services/upload-token.js +37 -0
  338. package/dist/src/services/upload-token.js.map +1 -1
  339. package/dist/src/services/upload-zip.d.ts +2 -0
  340. package/dist/src/services/upload-zip.d.ts.map +1 -1
  341. package/dist/src/services/upload-zip.js +5 -1
  342. package/dist/src/services/upload-zip.js.map +1 -1
  343. package/dist/src/services/workspace-meta.d.ts +15 -0
  344. package/dist/src/services/workspace-meta.d.ts.map +1 -1
  345. package/dist/src/services/workspace-meta.js +17 -0
  346. package/dist/src/services/workspace-meta.js.map +1 -1
  347. package/dist/src/services/workspace-provision.d.ts +3 -0
  348. package/dist/src/services/workspace-provision.d.ts.map +1 -1
  349. package/dist/src/services/workspace-provision.js +5 -3
  350. package/dist/src/services/workspace-provision.js.map +1 -1
  351. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.d.ts +1 -0
  352. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.d.ts.map +1 -1
  353. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.js +10 -0
  354. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.js.map +1 -1
  355. package/dist/src/storage/providers/postgres-kysely/methods/memory.d.ts +2 -0
  356. package/dist/src/storage/providers/postgres-kysely/methods/memory.d.ts.map +1 -1
  357. package/dist/src/storage/providers/postgres-kysely/methods/memory.js +12 -1
  358. package/dist/src/storage/providers/postgres-kysely/methods/memory.js.map +1 -1
  359. package/dist/src/storage/providers/postgres-kysely/methods/organisms.d.ts.map +1 -1
  360. package/dist/src/storage/providers/postgres-kysely/methods/organisms.js +5 -1
  361. package/dist/src/storage/providers/postgres-kysely/methods/organisms.js.map +1 -1
  362. package/dist/src/storage/providers/postgres-kysely/migrations/0012_unique_live_app_grant.sql +29 -0
  363. package/dist/src/storage/providers/sqlite/methods/apps.d.ts +3 -0
  364. package/dist/src/storage/providers/sqlite/methods/apps.d.ts.map +1 -1
  365. package/dist/src/storage/providers/sqlite/methods/apps.js +7 -0
  366. package/dist/src/storage/providers/sqlite/methods/apps.js.map +1 -1
  367. package/dist/src/storage/providers/sqlite/methods/governance.d.ts +1 -0
  368. package/dist/src/storage/providers/sqlite/methods/governance.d.ts.map +1 -1
  369. package/dist/src/storage/providers/sqlite/methods/governance.js +4 -1
  370. package/dist/src/storage/providers/sqlite/methods/governance.js.map +1 -1
  371. package/dist/src/storage/providers/sqlite/methods/owner.d.ts +5 -0
  372. package/dist/src/storage/providers/sqlite/methods/owner.d.ts.map +1 -1
  373. package/dist/src/storage/providers/sqlite/methods/owner.js +8 -0
  374. package/dist/src/storage/providers/sqlite/methods/owner.js.map +1 -1
  375. package/dist/src/storage/providers/sqlite/schema.d.ts +3 -0
  376. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  377. package/dist/src/storage/providers/sqlite/schema.js +20 -0
  378. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  379. package/dist/src/storage/repositories/app-grant.repository.d.ts +9 -1
  380. package/dist/src/storage/repositories/app-grant.repository.d.ts.map +1 -1
  381. package/dist/src/storage/repositories/memory.repository.d.ts +14 -0
  382. package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
  383. package/dist/src/storage/repositories-impl/memory-repository.d.ts +8 -1
  384. package/dist/src/storage/repositories-impl/memory-repository.d.ts.map +1 -1
  385. package/dist/src/storage/repositories-impl/memory-repository.js +15 -4
  386. package/dist/src/storage/repositories-impl/memory-repository.js.map +1 -1
  387. package/dist/src/storage/types/agents-messaging.d.ts +19 -0
  388. package/dist/src/storage/types/agents-messaging.d.ts.map +1 -1
  389. package/dist/src/storage/types/agents-messaging.js.map +1 -1
  390. package/dist/src/storage/types/organisms-federation.d.ts +29 -0
  391. package/dist/src/storage/types/organisms-federation.d.ts.map +1 -1
  392. package/dist/src/utils/app-badge.d.ts.map +1 -1
  393. package/dist/src/utils/app-badge.js +7 -3
  394. package/dist/src/utils/app-badge.js.map +1 -1
  395. package/dist/static/app-catalog/_template.html +6 -5
  396. package/dist/static/app-catalog/js/cortex.js +3 -1
  397. package/dist/static/app-catalog/js/detail.js +411 -36
  398. package/dist/static/app-catalog/js/i18n-data.js +279 -3
  399. package/dist/static/app-catalog/js/main.js +28 -37
  400. package/dist/static/app-catalog/js/monetize.js +204 -16
  401. package/dist/static/app-catalog/js/odps.js +489 -0
  402. package/dist/static/app-catalog/js/render.js +3 -0
  403. package/dist/static/app-catalog/js/workcopy.js +198 -0
  404. package/dist/static/app-catalog/styles/app-catalog.css +60 -0
  405. package/dist/static/app-catalog.html +1450 -137
  406. package/dist/static/sdk-libs/agents/index.js +45 -7
  407. package/dist/static/sdk-libs/auth/cluster.js +97 -0
  408. package/dist/static/sdk-libs/auth/index.js +25 -1
  409. package/dist/static/sdk-libs/auth/locale.js +151 -0
  410. package/dist/static/sdk-libs/auth/modal.js +11 -2
  411. package/dist/static/sdk-libs/auth/palette.js +172 -0
  412. package/dist/static/sdk-libs/auth/pill.js +37 -6
  413. package/dist/static/sdk-libs/auth/theme.js +61 -20
  414. package/dist/static/sdk-libs/data/index.js +70 -8
  415. package/dist/static/sdk-libs/dist/aimeat-agents.js +41 -8
  416. package/dist/static/sdk-libs/dist/aimeat-auth.js +422 -21
  417. package/dist/static/sdk-libs/dist/aimeat-data.js +50 -8
  418. package/dist/static/sdk-libs/dist/aimeat-live.js +54 -2
  419. package/dist/static/sdk-libs/dist/aimeat-markdown.js +32 -1
  420. package/dist/static/sdk-libs/live/index.js +71 -4
  421. package/dist/static/sdk-libs/markdown/index.js +49 -1
  422. package/package.json +6 -2
@@ -1,13 +1,20 @@
1
1
  # Vendored font licenses
2
2
 
3
- Both families are licensed under the **SIL Open Font License 1.1** (OFL),
3
+ All families are licensed under the **SIL Open Font License 1.1** (OFL),
4
4
  full text: https://openfontlicense.org/open-font-license-official-text/
5
5
 
6
6
  | Family | Version | Files | Copyright | Source |
7
7
  |---|---|---|---|---|
8
8
  | Baloo 2 | v23 (variable wght 400–800) | `baloo2-latin.woff2`, `baloo2-latin-ext.woff2` | © Ek Type (https://ektype.in) | https://fonts.google.com/specimen/Baloo+2 |
9
9
  | Bangers | v25 | `bangers-latin.woff2`, `bangers-latin-ext.woff2` | © Vernon Adams | https://fonts.google.com/specimen/Bangers |
10
+ | Inter | v20 (variable wght 100–900) | `inter-var-latin.woff2`, `inter-var-latin-ext.woff2` | © The Inter Project Authors (https://github.com/rsms/inter) | https://fonts.google.com/specimen/Inter |
11
+ | Space Grotesk | v22 (variable wght 300–700) | `space-grotesk-var-latin.woff2`, `space-grotesk-var-latin-ext.woff2` | © Florian Karsten (https://floriankarsten.com) | https://fonts.google.com/specimen/Space+Grotesk |
12
+ | Fraunces | v38 (variable opsz 9–144, wght 100–900) | `fraunces-var-latin.woff2`, `fraunces-var-latin-ext.woff2` | © The Fraunces Project Authors (https://github.com/undercasetype/fraunces) | https://fonts.google.com/specimen/Fraunces |
13
+ | JetBrains Mono | v24 (variable wght 100–800) | `jetbrains-mono-var-latin.woff2`, `jetbrains-mono-var-latin-ext.woff2` | © The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) | https://fonts.google.com/specimen/JetBrains+Mono |
10
14
 
11
- Vendored 2026-07-19 from the Google Fonts CDN (latin + latin-ext subsets) for the
12
- self-hosted `fonts` capability pack — apps load `/lib/fonts.css`, never an external CDN
13
- (the app CSP forbids cross-origin font loads).
15
+ Baloo 2 + Bangers vendored 2026-07-19 for the self-hosted `fonts` capability pack
16
+ (game/display faces, loaded via `/lib/fonts.css`). Inter, Space Grotesk, Fraunces and
17
+ JetBrains Mono vendored 2026-07-25 for the AIMEAT theme system — `/lib/aimeat-theme.css`
18
+ declares their `@font-face` rules and each palette names its display/body/mono faces, so
19
+ apps load them implicitly and never from an external CDN (the app CSP forbids
20
+ cross-origin font loads). All subsets are latin + latin-ext, so Finnish ä/ö render.
@@ -0,0 +1,92 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ @file theme-check.html
4
+ @description Visual + computed proof that /lib/aimeat-theme.css reaches an app through the
5
+ bridge alone (the bridge @imports it), and that both themes resolve to the AIMEAT palette
6
+ rather than daisyUI's defaults. Loads ONLY the bridge on purpose — no explicit theme link —
7
+ because that is the path every already-published app is on.
8
+ @usage open /lib/samples/theme-check.html on any AIMEAT node; toggle the two themes.
9
+ window.THEME_CHECK.read() returns the computed tokens for an automated check.
10
+ @version-history
11
+ v1.0.0 — 2026-07-25 — Initial theme proof page.
12
+ -->
13
+ <html lang="en" data-theme="light">
14
+ <head>
15
+ <meta charset="UTF-8" />
16
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
17
+ <title>AIMEAT theme check</title>
18
+ <link href="/lib/daisyui@5.css" rel="stylesheet" type="text/css" />
19
+ <!-- Deliberately NOT linking aimeat-theme.css: the bridge must pull it in. -->
20
+ <link href="/lib/aimeat-daisyui-bridge.css" rel="stylesheet" type="text/css" />
21
+ <script src="/lib/tailwindcss@4.js"></script>
22
+ </head>
23
+ <body class="bg-base-100 text-base-content min-h-screen p-6 flex flex-col gap-5">
24
+ <div class="flex items-center gap-3 flex-wrap">
25
+ <h1 class="text-xl font-bold">AIMEAT theme check</h1>
26
+ <button id="toggle" class="btn btn-sm btn-primary" type="button">Toggle theme</button>
27
+ <span id="which" class="badge badge-soft"></span>
28
+ </div>
29
+
30
+ <section class="card bg-base-200 card-border border-base-300">
31
+ <div class="card-body gap-3">
32
+ <h2 class="card-title text-base">Cards must be tellable from the page</h2>
33
+ <p class="text-sm opacity-70">This card is <code>bg-base-200</code> with <code>card-border</code>.
34
+ The one below has no edge, which is what a bare card looks like.</p>
35
+ <div class="bg-base-200 rounded-box p-3 text-sm">No edge: relies on the surface step alone.</div>
36
+ </div>
37
+ </section>
38
+
39
+ <section class="card bg-base-200 card-border border-base-300">
40
+ <div class="card-body gap-3">
41
+ <h2 class="card-title text-base">Solid vs soft</h2>
42
+ <div class="flex flex-wrap gap-2 items-center">
43
+ <span class="badge badge-warning">badge-warning</span>
44
+ <span class="badge badge-soft badge-warning">badge-soft warning</span>
45
+ <span class="badge badge-success">badge-success</span>
46
+ <span class="badge badge-soft badge-success">badge-soft success</span>
47
+ <span class="badge badge-primary">badge-primary</span>
48
+ <span class="badge badge-soft badge-primary">badge-soft primary</span>
49
+ </div>
50
+ <div class="flex flex-wrap gap-2">
51
+ <button class="btn btn-primary btn-sm" type="button">btn-primary</button>
52
+ <button class="btn btn-soft btn-primary btn-sm" type="button">btn-soft</button>
53
+ <button class="btn btn-outline btn-primary btn-sm" type="button">btn-outline</button>
54
+ </div>
55
+ <div class="alert alert-soft alert-info text-sm">alert-soft info</div>
56
+ </div>
57
+ </section>
58
+
59
+ <section class="card bg-base-200 card-border border-base-300">
60
+ <div class="card-body gap-2">
61
+ <h2 class="card-title text-base">Resolved tokens</h2>
62
+ <pre id="tokens" class="text-xs overflow-x-auto"></pre>
63
+ </div>
64
+ </section>
65
+
66
+ <script>
67
+ var TOKENS = ['--color-base-100', '--color-base-200', '--color-base-300', '--color-base-content',
68
+ '--color-primary', '--color-primary-content', '--color-warning', '--color-warning-content'];
69
+
70
+ function read() {
71
+ var cs = getComputedStyle(document.documentElement);
72
+ var out = {};
73
+ TOKENS.forEach(function (t) { out[t] = cs.getPropertyValue(t).trim(); });
74
+ out.theme = document.documentElement.getAttribute('data-theme');
75
+ return out;
76
+ }
77
+ function render() {
78
+ var v = read();
79
+ document.getElementById('which').textContent = v.theme;
80
+ document.getElementById('tokens').textContent =
81
+ TOKENS.map(function (t) { return t.padEnd(26) + v[t]; }).join('\n');
82
+ }
83
+ document.getElementById('toggle').onclick = function () {
84
+ var next = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
85
+ document.documentElement.setAttribute('data-theme', next);
86
+ render();
87
+ };
88
+ window.THEME_CHECK = { read: read };
89
+ render();
90
+ </script>
91
+ </body>
92
+ </html>
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @file themes-boot.js
3
+ * @description Head-of-page restore for the theme showroom: applies the stored light/dark MODE and
4
+ * PALETTE before first paint. External file (not inline) because /lib/ pages are served under a
5
+ * `script-src 'self'` CSP with no inline allowance.
6
+ * @usage <script src="/lib/samples/themes-boot.js"></script> in the <head> of themes.html.
7
+ * @version-history
8
+ * v1.0.0 — 2026-07-25 — Born with the theme showroom.
9
+ */
10
+ (function () {
11
+ function mode(t) { document.documentElement.setAttribute('data-theme', t === 'dark' ? 'dark' : 'light'); }
12
+ function pal(p) {
13
+ if (p && p !== 'aimeat') document.documentElement.setAttribute('data-palette', p);
14
+ else document.documentElement.removeAttribute('data-palette');
15
+ }
16
+ try {
17
+ mode(localStorage.getItem('aimeat-theme') || (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'));
18
+ pal(localStorage.getItem('aimeat-palette'));
19
+ } catch (e) { /* storage blocked — defaults stand */ }
20
+ })();
@@ -0,0 +1,154 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ @file themes.html
4
+ @description The theme-system showroom: every AIMEAT palette in both modes, on real daisyUI
5
+ components — typography specimen, buttons, badges, alerts, stats, forms, table, elevation.
6
+ Loads the styling stack exactly as a published app does (daisyUI + theme + bridge) plus
7
+ aimeat-auth, whose login pill carries the REAL control cluster (language + mode + palette) —
8
+ so this page demos the controls users actually get, and the palette strip is read from
9
+ AIMEAT.auth.getPalettes() so it can never drift from the shipped registry.
10
+ @usage open /lib/samples/themes.html on any AIMEAT node; switch mode + palette from the pill
11
+ (or the in-page duplicates). window.THEME_CHECK.read() returns computed tokens for audits.
12
+ @version-history
13
+ v1.0.0 — 2026-07-25 — Born with the theme system (aimeat-theme.css v2).
14
+ -->
15
+ <html lang="en" data-theme="light">
16
+ <head>
17
+ <meta charset="UTF-8" />
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
19
+ <meta name="aimeat-locales" content="en fi" />
20
+ <title>AIMEAT themes</title>
21
+ <link href="/lib/daisyui@5.css" rel="stylesheet" type="text/css" />
22
+ <link href="/lib/aimeat-theme.css" rel="stylesheet" type="text/css" />
23
+ <link href="/lib/aimeat-daisyui-bridge.css" rel="stylesheet" type="text/css" />
24
+ <script src="/lib/tailwindcss@4.js"></script>
25
+ <!-- External (not inline): /lib/ pages run under a script-src 'self' CSP. -->
26
+ <script src="/lib/samples/themes-boot.js"></script>
27
+ <style>
28
+ /* Showroom-only helpers, all token-driven — no hardcoded colours. */
29
+ .sr-hero { font-size: var(--text-hero); font-weight: 700; line-height: 1.1;
30
+ font-family: var(--font-display); letter-spacing: var(--display-tracking, 0); }
31
+ .sr-fine { font-size: var(--text-fine); opacity: 0.65; }
32
+ .sr-card { box-shadow: var(--elev-card); transition: box-shadow var(--motion-base) var(--ease-out), transform var(--motion-base) var(--ease-out); }
33
+ .sr-card:hover { box-shadow: var(--elev-raise); transform: translateY(-2px); }
34
+ .sr-chip { width: 34px; height: 26px; border-radius: 6px; border: 1px solid var(--color-base-300); position: relative; overflow: hidden; flex: 0 0 auto; }
35
+ .sr-chip i { position: absolute; inset: 6px 6px 4px 6px; border-radius: 3px; display: block; }
36
+ .sr-chip b { position: absolute; right: 4px; bottom: 4px; width: 8px; height: 8px; border-radius: 50%; display: block; }
37
+ </style>
38
+ </head>
39
+ <body class="bg-base-100 text-base-content min-h-screen flex flex-col overflow-x-clip">
40
+ <nav class="navbar bg-base-200 px-4 shadow-sm sticky top-0 z-50 border-b border-base-300">
41
+ <div class="flex-1 min-w-0"><span class="text-lg font-bold">AIMEAT themes</span></div>
42
+ <div class="flex-none"><span id="login"></span></div>
43
+ </nav>
44
+
45
+ <main class="flex-1 w-full max-w-4xl mx-auto p-4 flex flex-col gap-5">
46
+ <!-- Hero: the display face + hero size of the ACTIVE palette. -->
47
+ <header class="pt-4">
48
+ <div class="sr-hero">Näin sovelluksesi näyttää<span class="text-primary">.</span></div>
49
+ <p class="mt-2 max-w-prose opacity-80">Five designed palettes, each with a light and a dark mode, its own
50
+ typeface, radii and verified contrast. Switch the look from the pill above — every AIMEAT app follows
51
+ the same choice. Ä and ö render in every face.</p>
52
+ <div class="sr-fine mt-1">Palette: <span id="which-pal" class="font-semibold"></span> · mode:
53
+ <span id="which-mode" class="font-semibold"></span></div>
54
+ </header>
55
+
56
+ <!-- All palettes, both modes, straight from the registry (never drifts). -->
57
+ <section class="card bg-base-200 card-border border-base-300 sr-card">
58
+ <div class="card-body gap-3">
59
+ <h2 class="card-title text-base">Every palette, both modes</h2>
60
+ <div id="pal-strip" class="flex flex-col gap-2"></div>
61
+ </div>
62
+ </section>
63
+
64
+ <!-- Typography specimen. -->
65
+ <section class="card bg-base-200 card-border border-base-300 sr-card">
66
+ <div class="card-body gap-2">
67
+ <h2 class="card-title text-base">Typography</h2>
68
+ <div class="sr-hero">Hero 123 äö</div>
69
+ <h3 style="font-size: var(--text-title)" class="font-semibold">Title — Otsikko käyttöliittymälle</h3>
70
+ <p style="font-size: var(--text-body)" class="max-w-prose">Body text is Inter in every palette, so
71
+ content stays quiet and legible while the display face above carries the personality.</p>
72
+ <p class="sr-fine">Fine print stays at a 13px floor, never smaller.</p>
73
+ <pre class="text-sm bg-base-100 rounded-box p-3 overflow-x-auto"><code>const mono = "JetBrains Mono — koodi näyttää koodilta";</code></pre>
74
+ </div>
75
+ </section>
76
+
77
+ <!-- Actions + status colours: quiet variants first, one solid shout. -->
78
+ <section class="card bg-base-200 card-border border-base-300 sr-card">
79
+ <div class="card-body gap-3">
80
+ <h2 class="card-title text-base">Actions and status</h2>
81
+ <div class="flex flex-wrap gap-2">
82
+ <button class="btn btn-primary btn-sm" type="button">Primary</button>
83
+ <button class="btn btn-soft btn-primary btn-sm" type="button">Soft</button>
84
+ <button class="btn btn-outline btn-primary btn-sm" type="button">Outline</button>
85
+ <button class="btn btn-secondary btn-sm" type="button">Secondary</button>
86
+ <button class="btn btn-accent btn-sm" type="button">Accent</button>
87
+ <button class="btn btn-ghost btn-sm" type="button">Ghost</button>
88
+ </div>
89
+ <div class="flex flex-wrap gap-2 items-center">
90
+ <span class="badge badge-soft badge-success badge-sm">valmis</span>
91
+ <span class="badge badge-soft badge-warning badge-sm">odottaa</span>
92
+ <span class="badge badge-soft badge-info badge-sm">tiedoksi</span>
93
+ <span class="badge badge-error badge-sm">virhe</span>
94
+ <span class="badge badge-outline badge-sm">neutraali</span>
95
+ </div>
96
+ <div class="alert alert-soft alert-info text-sm">Soft alerts read as information, not as alarms.</div>
97
+ </div>
98
+ </section>
99
+
100
+ <!-- Numbers that matter + a form + a table. -->
101
+ <section class="grid gap-5 md:grid-cols-2" style="grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr))">
102
+ <div class="card bg-base-200 card-border border-base-300 sr-card">
103
+ <div class="card-body gap-3">
104
+ <h2 class="card-title text-base">Stats</h2>
105
+ <div class="stats stats-vertical sm:stats-horizontal bg-base-100 border border-base-300 rounded-box">
106
+ <div class="stat py-3">
107
+ <div class="stat-title sr-fine">Jäseniä</div>
108
+ <div class="stat-value text-2xl tabular-nums">1 208</div>
109
+ </div>
110
+ <div class="stat py-3">
111
+ <div class="stat-title sr-fine">Tänään</div>
112
+ <div class="stat-value text-2xl tabular-nums text-primary">+37</div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ <div class="card bg-base-200 card-border border-base-300 sr-card">
118
+ <div class="card-body gap-3">
119
+ <h2 class="card-title text-base">Form controls</h2>
120
+ <input class="input input-bordered w-full" placeholder="Nimi tai sähköposti" />
121
+ <select class="select select-bordered w-full"><option>Suomi</option><option>English</option></select>
122
+ <label class="label cursor-pointer justify-start gap-3">
123
+ <input type="checkbox" class="toggle toggle-primary" checked />
124
+ <span class="label-text">Ilmoitukset päällä</span>
125
+ </label>
126
+ </div>
127
+ </div>
128
+ </section>
129
+
130
+ <section class="card bg-base-200 card-border border-base-300 sr-card">
131
+ <div class="card-body gap-2">
132
+ <h2 class="card-title text-base">Table</h2>
133
+ <div class="overflow-x-auto">
134
+ <table class="table table-zebra table-sm">
135
+ <thead><tr><th>Sovellus</th><th>Paletti</th><th class="text-right">Käyttäjiä</th></tr></thead>
136
+ <tbody>
137
+ <tr><td>ODPS</td><td><span class="badge badge-soft badge-sm">aimeat</span></td><td class="text-right tabular-nums">412</td></tr>
138
+ <tr><td>TILA</td><td><span class="badge badge-soft badge-sm">mist</span></td><td class="text-right tabular-nums">918</td></tr>
139
+ <tr><td>LOOM</td><td><span class="badge badge-soft badge-sm">circuit</span></td><td class="text-right tabular-nums">245</td></tr>
140
+ </tbody>
141
+ </table>
142
+ </div>
143
+ </div>
144
+ </section>
145
+ </main>
146
+
147
+ <footer class="footer footer-center p-4 sr-fine">
148
+ aimeat-theme.css v2 · verified by pnpm check:theme · fonts self-hosted (SIL OFL 1.1)
149
+ </footer>
150
+
151
+ <script src="/v1/libs/aimeat-auth.js"></script>
152
+ <script src="/lib/samples/themes.js"></script>
153
+ </body>
154
+ </html>
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @file themes.js
3
+ * @description Behaviour for the theme showroom (themes.html): mounts the real login pill (whose
4
+ * cluster carries the language/mode/palette controls), renders the every-palette-both-modes
5
+ * strip from AIMEAT.auth.getPalettes() (so it can never drift from the shipped registry), and
6
+ * exposes window.THEME_CHECK.read() for automated audits. External file because /lib/ pages run
7
+ * under a `script-src 'self'` CSP.
8
+ * @usage <script src="/lib/samples/themes.js"></script> after /v1/libs/aimeat-auth.js.
9
+ * @version-history
10
+ * v1.0.0 — 2026-07-25 — Born with the theme showroom.
11
+ */
12
+ /* global AIMEAT */
13
+ (function () {
14
+ AIMEAT.auth.mountLoginButton('#login', {});
15
+
16
+ function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
17
+
18
+ // The palette strip: one row per palette, its light + dark swatches, click-to-apply.
19
+ function renderStrip() {
20
+ var cur = AIMEAT.auth.getPalette();
21
+ var rows = AIMEAT.auth.getPalettes().map(function (p) {
22
+ var chips = ['light', 'dark'].map(function (m) {
23
+ var s = p.swatch[m];
24
+ return '<span class="sr-chip" title="' + esc(p.label + ' — ' + m) + '" style="background:' + esc(s.bg) + '">'
25
+ + '<i style="background:' + esc(s.card) + '"></i><b style="background:' + esc(s.accent) + '"></b></span>';
26
+ }).join('');
27
+ return '<button type="button" data-pal="' + esc(p.id) + '" class="btn btn-ghost btn-sm justify-start gap-3 w-full'
28
+ + (p.id === cur ? ' btn-active' : '') + '">' + chips
29
+ + '<span class="font-semibold">' + esc(p.label) + '</span>'
30
+ + (p.id === cur ? '<span class="badge badge-soft badge-primary badge-sm ml-auto">in use</span>' : '')
31
+ + '</button>';
32
+ }).join('');
33
+ document.getElementById('pal-strip').innerHTML = rows;
34
+ document.querySelectorAll('#pal-strip [data-pal]').forEach(function (b) {
35
+ b.addEventListener('click', function () { AIMEAT.auth.setPalette(b.getAttribute('data-pal')); });
36
+ });
37
+ }
38
+
39
+ function renderWhich() {
40
+ document.getElementById('which-pal').textContent = AIMEAT.auth.getPalette();
41
+ document.getElementById('which-mode').textContent =
42
+ document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';
43
+ }
44
+
45
+ renderStrip(); renderWhich();
46
+ window.addEventListener('aimeat-palette-change', function () { renderStrip(); renderWhich(); });
47
+ window.addEventListener('aimeat-theme-change', renderWhich);
48
+
49
+ // For automated audits (Playwright / the build-app audit snippet).
50
+ window.THEME_CHECK = {
51
+ read: function () {
52
+ var cs = getComputedStyle(document.documentElement);
53
+ var out = { theme: document.documentElement.getAttribute('data-theme'), palette: AIMEAT.auth.getPalette() };
54
+ ['--color-base-100', '--color-base-200', '--color-base-300', '--color-base-content',
55
+ '--color-primary', '--color-primary-content', '--font-display', '--font-body']
56
+ .forEach(function (t) { out[t] = cs.getPropertyValue(t).trim(); });
57
+ return out;
58
+ },
59
+ };
60
+ })();
@@ -3,11 +3,18 @@
3
3
  * @description Connected Apps section (H-2 app grants) — list + revoke the
4
4
  * scoped, user-approved access tokens published apps hold. Extracted from
5
5
  * access-tab.js to satisfy max-file-lines.
6
+ * @structure ConnectedAppsSection — loads GET /v1/app-grants, sorts by recency,
7
+ * renders one card per app (scopes collapsed behind their count), single revoke
8
+ * + a bulk revoke of grants unused for STALE_DAYS.
6
9
  * @version-history
7
10
  * v1.0.0 — 2026-07-13 — Extracted from access-tab.js (max-file-lines)
11
+ * v1.1.0 — 2026-07-25 — Readability pass: sort most-recently-used first, collapse the
12
+ * scope-badge wall behind its count, and add a bulk revoke for long-unused grants.
13
+ * (The duplicate rows that made this list unreadable are fixed server-side; this
14
+ * keeps it readable once an owner legitimately connects a couple dozen apps.)
8
15
  */
9
16
  import { h } from 'preact';
10
- import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
17
+ import { useState, useEffect, useCallback, useRef, useMemo } from 'preact/hooks';
11
18
  import htm from 'htm';
12
19
  const html = htm.bind(h);
13
20
  import { t } from '/js/i18n.js';
@@ -15,6 +22,17 @@ import { escHtml } from '/js/utils.js';
15
22
  import { useConfirm } from '/components/Modal.js';
16
23
  import { apiGet, apiDelete } from '/js/api.js';
17
24
 
25
+ // A grant untouched for this long is offered for bulk revoke. Long enough that a seasonal app
26
+ // (something used a few times a year) is not swept away without the owner meaning to.
27
+ const STALE_DAYS = 90;
28
+
29
+ /** ms since the grant was last used, falling back to when it was granted (never-used grants). */
30
+ function idleMs(g, now) {
31
+ const ts = g.last_used_at || g.granted_at;
32
+ const parsed = ts ? Date.parse(ts) : NaN;
33
+ return Number.isNaN(parsed) ? Infinity : now - parsed;
34
+ }
35
+
18
36
  // Apps the owner has explicitly granted scoped access to (the H-2 app-grant flow). Each
19
37
  // holds its OWN revocable token bound to a narrow scope set — never the login session.
20
38
  export function ConnectedAppsSection({ showToast, initial }) {
@@ -22,6 +40,8 @@ export function ConnectedAppsSection({ showToast, initial }) {
22
40
  // `initial` (the app-grants slice of GET /v1/access/overview) seeds us so the mount does no fetch of
23
41
  // its own; live-update + post-revoke still reload via the individual endpoint. Absent → self-load.
24
42
  const [grants, setGrants] = useState(initial?.grants ?? null);
43
+ const [expanded, setExpanded] = useState(() => new Set());
44
+ const [busy, setBusy] = useState(false);
25
45
 
26
46
  const load = useCallback(async () => {
27
47
  try { const r = await apiGet('/v1/app-grants'); setGrants(r.data?.grants || []); }
@@ -37,6 +57,22 @@ export function ConnectedAppsSection({ showToast, initial }) {
37
57
  return () => window.removeEventListener('aimeat-live-update', handler);
38
58
  }, []);
39
59
 
60
+ // Most recently used first (never-used sink to the bottom by their grant date), so the apps that
61
+ // actually touch the owner's data are the ones they see without scrolling.
62
+ const { sorted, stale } = useMemo(() => {
63
+ const now = Date.now();
64
+ const list = [...(grants || [])].sort((a, b) => idleMs(a, now) - idleMs(b, now));
65
+ return { sorted: list, stale: list.filter(g => idleMs(g, now) > STALE_DAYS * 86400000) };
66
+ }, [grants]);
67
+
68
+ const toggleScopes = useCallback((id) => {
69
+ setExpanded((prev) => {
70
+ const next = new Set(prev);
71
+ if (next.has(id)) next.delete(id); else next.add(id);
72
+ return next;
73
+ });
74
+ }, []);
75
+
40
76
  const handleRevoke = useCallback((id, name) => {
41
77
  confirm(
42
78
  (t('profile.access.agConfirmRevoke') || 'Revoke access for "{name}"? It loses access immediately.').replace('{name}', name),
@@ -51,26 +87,66 @@ export function ConnectedAppsSection({ showToast, initial }) {
51
87
  );
52
88
  }, [confirm, showToast, load]);
53
89
 
90
+ // Bulk revoke of the stale set. Sequential DELETEs against the existing per-grant endpoint (no new
91
+ // API surface); partial failures are reported with the count that did go through, never swallowed.
92
+ const handleRevokeStale = useCallback(() => {
93
+ confirm(
94
+ (t('profile.access.agConfirmRevokeUnused') || 'Revoke access for {count} apps unused for over {days} days? They lose access immediately.')
95
+ .replace('{count}', String(stale.length)).replace('{days}', String(STALE_DAYS)),
96
+ async () => {
97
+ setBusy(true);
98
+ let done = 0, failed = 0;
99
+ for (const g of stale) {
100
+ try { await apiDelete('/v1/app-grants/' + g.grant_id); done++; }
101
+ catch { failed++; }
102
+ }
103
+ setBusy(false);
104
+ showToast(failed
105
+ ? (t('profile.access.agRevokedSome') || '{done} revoked, {failed} failed').replace('{done}', String(done)).replace('{failed}', String(failed))
106
+ : (t('profile.access.agRevokedCount') || '{count} app grants revoked').replace('{count}', String(done)));
107
+ load();
108
+ },
109
+ { danger: true },
110
+ );
111
+ }, [confirm, showToast, load, stale]);
112
+
54
113
  return html`
55
114
  <h3 class="card-h3 access-h3 mt-section">${t('profile.access.agTitle') || 'Connected Apps'}</h3>
56
115
  <div class="section-desc">${t('profile.access.agDesc') || 'Published apps you have granted scoped access to your data. Each holds its own revocable token — never your login session.'}</div>
57
116
 
117
+ ${stale.length > 0 && html`
118
+ <div class="access-empty-row">
119
+ <span class="text-meta-sm">
120
+ ${(t('profile.access.agUnusedNote') || '{count} of these have not been used in over {days} days.')
121
+ .replace('{count}', String(stale.length)).replace('{days}', String(STALE_DAYS))}
122
+ </span>
123
+ <button class="btn-outline btn-sm" disabled=${busy} onClick=${handleRevokeStale}>
124
+ ${(t('profile.access.agRevokeUnused') || 'Revoke {count} unused').replace('{count}', String(stale.length))}
125
+ </button>
126
+ </div>
127
+ `}
128
+
58
129
  ${grants === null
59
130
  ? html`<div class="empty">${t('profile.access.agLoading') || 'Loading...'}</div>`
60
- : grants.length === 0
131
+ : sorted.length === 0
61
132
  ? html`<div class="access-empty-row"><span class="text-meta-sm">${t('profile.access.agEmpty') || 'No apps have access to your data.'}</span></div>`
62
- : grants.map(g => html`
133
+ : sorted.map(g => html`
63
134
  <div class="card" key=${g.grant_id}>
64
135
  <div class="flex-between">
65
136
  <div class="card-title">${escHtml(g.app_name || g.app)}</div>
66
- <span class="badge badge-info">${(g.scopes || []).length} ${t('profile.access.agScopes') || 'scopes'}</span>
137
+ <button
138
+ class="badge badge-info ag-scope-toggle"
139
+ aria-expanded=${expanded.has(g.grant_id) ? 'true' : 'false'}
140
+ title=${t('profile.access.agScopesToggle') || 'Show or hide the granted permissions'}
141
+ onClick=${() => toggleScopes(g.grant_id)}
142
+ >${(g.scopes || []).length} ${t('profile.access.agScopes') || 'scopes'}</button>
67
143
  </div>
68
144
  <div class="card-subtitle access-mono">${escHtml(g.app_origin || '')}</div>
69
145
  <div class="detail-grid">
70
146
  <div class="detail-item"><span class="detail-label">${t('profile.access.agGrantedAt') || 'Granted'}</span><span class="detail-value">${g.granted_at ? new Date(g.granted_at).toLocaleDateString() : '-'}</span></div>
71
147
  <div class="detail-item"><span class="detail-label">${t('profile.access.agLastUsed') || 'Last used'}</span><span class="detail-value">${g.last_used_at ? new Date(g.last_used_at).toLocaleString() : (t('profile.access.agNever') || 'never')}</span></div>
72
148
  </div>
73
- ${(g.scopes || []).length > 0 && html`
149
+ ${expanded.has(g.grant_id) && (g.scopes || []).length > 0 && html`
74
150
  <div class="flex-row-wrap mt-half">
75
151
  ${g.scopes.map(s => html`<span class="badge badge-muted" key=${s}>${escHtml(s)}</span>`)}
76
152
  </div>
@@ -36,5 +36,8 @@ export function maturityBadge(html, t, ledger, name) {
36
36
  const proven = proofs.map(pr => `${pr.model} → ${pr.verdict}${pr.tokens ? ' (' + Math.round(pr.tokens / 1000) + 'k)' : ''}`).join(', ');
37
37
  const title = t('profile.extensions.tier.' + p.modelTier)
38
38
  + ' · ' + (proofs.length ? t('profile.extensions.measuredOn') + ' ' + proven : t('profile.extensions.notMeasured'));
39
- return html`<span class="ext-tier ext-tier-${p.modelTier}${proofs.length ? ' ext-tier-measured' : ''}" title=${title}>${p.modelTier}${proofs.length ? ' ✓' : ''}</span>`;
39
+ // Show the instruction ("READ THE DOC"), not the raw key `needs-doc` reads as
40
+ // "documentation missing", which is the opposite of what the tier means.
41
+ const label = t('profile.extensions.tierLabel.' + p.modelTier) || p.modelTier;
42
+ return html`<span class="ext-tier ext-tier-${p.modelTier}${proofs.length ? ' ext-tier-measured' : ''}" title=${title}>${label}${proofs.length ? ' ✓' : ''}</span>`;
40
43
  }
@@ -6,6 +6,8 @@
6
6
  * chat.commands), SchedulePanel (own-agent scheduler), and ReplyWithAiPopover (TARGET-031). Each is
7
7
  * self-contained (owns its own hooks). Extracted from inbox-tab.js to satisfy max-file-lines.
8
8
  * @version-history
9
+ * v1.9.0 — 2026-07-25 — MessageBubble gets a ⧉ copy action next to the other bubble buttons: copies the
10
+ * message's raw markdown to the clipboard (✓ for ~1.6s as feedback).
9
11
  * v1.8.0 — 2026-07-21 — MessageBubble renders link-preview cards under the body (MessageLinkPreviews),
10
12
  * gated by the `showLinkPreviews` prop (the persisted thread-head toggle).
11
13
  * v1.0.0 — 2026-07-13 — Extracted from inbox-tab.js (max-file-lines)
@@ -35,7 +37,7 @@ import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
35
37
  import htm from 'htm';
36
38
  const html = htm.bind(h);
37
39
  import { t } from '/js/i18n.js';
38
- import { escHtml } from '/js/utils.js';
40
+ import { escHtml, copyToClipboard } from '/js/utils.js';
39
41
  import { Markdown } from '/components/Markdown.js';
40
42
  import { MessageLinkPreviews } from '/components/LinkPreview.js';
41
43
  import { minidenticon } from '/lib/minidenticons.min.js';
@@ -252,6 +254,17 @@ export function PollBuilder({ questions, setQuestions }) {
252
254
  }
253
255
 
254
256
  export function MessageBubble({ msg, mine, urlMap, starred, onStar, onTrack, onPark, onReplyAi, onQuote, quoted, quotedName, onJumpTo, domId, tracked, onOpenMarkdown, answeredWith, onAnswer, submitting, showLinkPreviews }) {
257
+ // Copy the message text to the clipboard (the raw markdown the sender wrote — that's what pastes
258
+ // usefully into an AI chat or a document; the rendered body's presigned image URLs are transient).
259
+ const [copied, setCopied] = useState(false);
260
+ const copyTimer = useRef(null);
261
+ useEffect(() => () => { if (copyTimer.current) clearTimeout(copyTimer.current); }, []);
262
+ const copyBody = async () => {
263
+ await copyToClipboard(String(msg.body || ''));
264
+ setCopied(true);
265
+ if (copyTimer.current) clearTimeout(copyTimer.current);
266
+ copyTimer.current = setTimeout(() => setCopied(false), 1600);
267
+ };
255
268
  const nonInline = (msg.attachments || []).filter(a => !a.inline);
256
269
  const expiredIds = new Set((msg.attachments || []).filter(a => a.expired).map(a => a.id));
257
270
  // urlMap is keyed by `${messageId}::${attachmentId}` because per-message attachment ids (at0, at1…)
@@ -270,6 +283,9 @@ export function MessageBubble({ msg, mine, urlMap, starred, onStar, onTrack, onP
270
283
  <div class="inbox-bubble-actions">
271
284
  ${onQuote ? html`<button class="inbox-bubble-act" title=${t('inbox.quoteReply')}
272
285
  onClick=${() => onQuote(msg)}>↩</button>` : null}
286
+ <button class=${`inbox-bubble-act${copied ? ' inbox-bubble-act--on' : ''}`}
287
+ title=${copied ? t('inbox.copied') : t('inbox.copyMessage')}
288
+ aria-label=${t('inbox.copyMessage')} onClick=${copyBody}>${copied ? '✓' : '⧉'}</button>
273
289
  <button class=${`inbox-bubble-act${starred ? ' inbox-bubble-act--on' : ''}`} title=${t('inbox.markImportant')}
274
290
  onClick=${() => onStar?.(msg)}>${starred ? '⭐' : '☆'}</button>
275
291
  <button class=${`inbox-bubble-act${tracked ? ' inbox-bubble-act--on' : ''}`}
@@ -7,6 +7,10 @@
7
7
  * Extracted from inbox-tab.js to satisfy max-file-lines.
8
8
  * @usage import { useThreadAutoScroll, useMobileComposerKeyboard } from './inbox-tab/use-thread-ux.js';
9
9
  * @version-history
10
+ * v1.4.0 — 2026-07-21 — useThreadAutoScroll: on OPEN, keep re-pinning to the bottom for ~2.5s while late
11
+ * content (images, link previews, long histories) grows the thread, instead of a single jump that left
12
+ * a big thread stuck partway up. Re-pins only on real height growth; aborts the moment the reader
13
+ * scrolls up.
10
14
  * v1.3.0 — 2026-07-21 — Add useLinkPreviewToggle: persisted global on/off for the message link-preview
11
15
  * cards (default ON); the ThreadPanel head button flips it.
12
16
  * v1.2.0 — 2026-07-19 — useThreadAutoScroll now suppresses the one-time new-message jump while the
@@ -47,7 +51,7 @@ export function useThreadAutoScroll(msgsRef, mode, thread, activeConv) {
47
51
  const lastMsgIdRef = useRef(null);
48
52
  useEffect(() => {
49
53
  const el = msgsRef.current;
50
- if (mode !== 'thread' || !el || thread.length === 0) return;
54
+ if (mode !== 'thread' || !el || thread.length === 0) return undefined;
51
55
  const convKey = activeConv?.peerGhii ?? activeConv?.id ?? null;
52
56
  const lastId = thread[thread.length - 1]?.id ?? null;
53
57
  const isNewOpen = lastScrolledConvRef.current !== convKey;
@@ -58,9 +62,32 @@ export function useThreadAutoScroll(msgsRef, mode, thread, activeConv) {
58
62
  // focused (near-bottom follow still applies: if you were already at the bottom you keep following).
59
63
  const ae = typeof document !== 'undefined' ? document.activeElement : null;
60
64
  const composing = ae instanceof HTMLElement && !!ae.closest('.inbox-composer');
61
- if (isNewOpen || nearBottom || (hasNewMsg && !composing)) el.scrollTop = el.scrollHeight;
62
65
  lastScrolledConvRef.current = convKey;
63
66
  lastMsgIdRef.current = lastId;
67
+
68
+ if (isNewOpen) {
69
+ // Opening a thread: jump to the newest message, then KEEP re-pinning to the bottom for a short
70
+ // window. The final bottom isn't known yet at this point — late content grows the thread (images,
71
+ // link-preview cards, markdown) AND the pane's own height changes as the composer/keyboard settle,
72
+ // either of which opens a gap the single jump can't catch (and the effect won't re-fire — urlMap
73
+ // isn't a dep). So each frame: if a gap has opened, re-pin. `expected` tracks our own set so a real
74
+ // user scroll (which moves away from it) aborts the loop instead of being fought.
75
+ el.scrollTop = el.scrollHeight;
76
+ let raf = 0, expected = el.scrollTop, aborted = false;
77
+ const deadline = performance.now() + 2500;
78
+ const onScroll = () => { if (Math.abs(el.scrollTop - expected) > 40) aborted = true; };
79
+ el.addEventListener('scroll', onScroll, { passive: true });
80
+ const stop = () => { cancelAnimationFrame(raf); el.removeEventListener('scroll', onScroll); };
81
+ const step = (now) => {
82
+ if (aborted) { stop(); return; }
83
+ if (el.scrollHeight - el.scrollTop - el.clientHeight > 4) { el.scrollTop = el.scrollHeight; expected = el.scrollTop; }
84
+ if (now < deadline) raf = requestAnimationFrame(step); else stop();
85
+ };
86
+ raf = requestAnimationFrame(step);
87
+ return stop; // cancel the pin loop if the thread changes / unmounts
88
+ }
89
+ if (nearBottom || (hasNewMsg && !composing)) el.scrollTop = el.scrollHeight;
90
+ return undefined;
64
91
  // msgsRef is a stable ref object — the content deps below are the real triggers.
65
92
  // eslint-disable-next-line react-hooks/exhaustive-deps
66
93
  }, [thread, mode, activeConv]);