aimeat 2.0.0 β†’ 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (722) hide show
  1. package/dist/.env.example +9 -4
  2. package/dist/locales/en.json +63 -1
  3. package/dist/locales/fi.json +63 -1
  4. package/dist/public/components/LinkPreview.js +101 -0
  5. package/dist/public/components/NotificationBell.js +18 -1
  6. package/dist/public/cortex-bundled/aimeat-charts.js +158 -10
  7. package/dist/public/cortex-bundled/aimeat-charts.yaml +1 -1
  8. package/dist/public/cortex-bundled/aimeat-dag.js +515 -173
  9. package/dist/public/cortex-bundled/aimeat-dag.yaml +1 -1
  10. package/dist/public/cortex-bundled/aimeat-i18n.js +6 -1
  11. package/dist/public/cortex-bundled/aimeat-i18n.yaml +1 -1
  12. package/dist/public/cortex-bundled/aimeat-surface.js +577 -0
  13. package/dist/public/cortex-bundled/aimeat-surface.yaml +107 -0
  14. package/dist/public/cortex-bundled/aimeat-viewport.js +405 -0
  15. package/dist/public/cortex-bundled/aimeat-viewport.yaml +100 -0
  16. package/dist/public/css/theme.css +57 -7
  17. package/dist/public/css/views/admin.css +8 -1
  18. package/dist/public/css/views/app-grant.css +18 -0
  19. package/dist/public/css/views/inbox.css +47 -1
  20. package/dist/public/css/views/portfolio.css +46 -0
  21. package/dist/public/css/views/profile.css +38 -4
  22. package/dist/public/js/services/apps.js +19 -3
  23. package/dist/public/js/services/messages-ai-prompts.js +38 -0
  24. package/dist/public/js/services/messages.js +26 -4
  25. package/dist/public/js/services/notebook.js +76 -0
  26. package/dist/public/js/services/unfurl.js +43 -0
  27. package/dist/public/lib/VENDORED.md +6 -3
  28. package/dist/public/lib/aimeat-daisyui-bridge.css +39 -2
  29. package/dist/public/lib/aimeat-theme.css +538 -0
  30. package/dist/public/lib/fonts/LICENSE.md +11 -4
  31. package/dist/public/lib/fonts/fraunces-var-latin-ext.woff2 +0 -0
  32. package/dist/public/lib/fonts/fraunces-var-latin.woff2 +0 -0
  33. package/dist/public/lib/fonts/inter-var-latin-ext.woff2 +0 -0
  34. package/dist/public/lib/fonts/inter-var-latin.woff2 +0 -0
  35. package/dist/public/lib/fonts/jetbrains-mono-var-latin-ext.woff2 +0 -0
  36. package/dist/public/lib/fonts/jetbrains-mono-var-latin.woff2 +0 -0
  37. package/dist/public/lib/fonts/space-grotesk-var-latin-ext.woff2 +0 -0
  38. package/dist/public/lib/fonts/space-grotesk-var-latin.woff2 +0 -0
  39. package/dist/public/lib/samples/LICENSE.md +11 -0
  40. package/dist/public/lib/samples/bass/A1.mp3 +0 -0
  41. package/dist/public/lib/samples/bass/B2.mp3 +0 -0
  42. package/dist/public/lib/samples/bass/D2.mp3 +0 -0
  43. package/dist/public/lib/samples/bass/E1.mp3 +0 -0
  44. package/dist/public/lib/samples/bass/E3.mp3 +0 -0
  45. package/dist/public/lib/samples/bass/G2.mp3 +0 -0
  46. package/dist/public/lib/samples/epiano/C2.mp3 +0 -0
  47. package/dist/public/lib/samples/epiano/C3.mp3 +0 -0
  48. package/dist/public/lib/samples/epiano/C4.mp3 +0 -0
  49. package/dist/public/lib/samples/epiano/C5.mp3 +0 -0
  50. package/dist/public/lib/samples/epiano/C6.mp3 +0 -0
  51. package/dist/public/lib/samples/epiano/G2.mp3 +0 -0
  52. package/dist/public/lib/samples/epiano/G3.mp3 +0 -0
  53. package/dist/public/lib/samples/epiano/G4.mp3 +0 -0
  54. package/dist/public/lib/samples/epiano/G5.mp3 +0 -0
  55. package/dist/public/lib/samples/guitar-steel/A2.mp3 +0 -0
  56. package/dist/public/lib/samples/guitar-steel/A4.mp3 +0 -0
  57. package/dist/public/lib/samples/guitar-steel/B3.mp3 +0 -0
  58. package/dist/public/lib/samples/guitar-steel/D3.mp3 +0 -0
  59. package/dist/public/lib/samples/guitar-steel/E2.mp3 +0 -0
  60. package/dist/public/lib/samples/guitar-steel/E4.mp3 +0 -0
  61. package/dist/public/lib/samples/guitar-steel/E5.mp3 +0 -0
  62. package/dist/public/lib/samples/guitar-steel/G3.mp3 +0 -0
  63. package/dist/public/lib/samples/organ/C2.mp3 +0 -0
  64. package/dist/public/lib/samples/organ/C3.mp3 +0 -0
  65. package/dist/public/lib/samples/organ/C4.mp3 +0 -0
  66. package/dist/public/lib/samples/organ/C5.mp3 +0 -0
  67. package/dist/public/lib/samples/organ/C6.mp3 +0 -0
  68. package/dist/public/lib/samples/organ/G2.mp3 +0 -0
  69. package/dist/public/lib/samples/organ/G3.mp3 +0 -0
  70. package/dist/public/lib/samples/organ/G4.mp3 +0 -0
  71. package/dist/public/lib/samples/organ/G5.mp3 +0 -0
  72. package/dist/public/lib/samples/strings/C2.mp3 +0 -0
  73. package/dist/public/lib/samples/strings/C3.mp3 +0 -0
  74. package/dist/public/lib/samples/strings/C4.mp3 +0 -0
  75. package/dist/public/lib/samples/strings/C5.mp3 +0 -0
  76. package/dist/public/lib/samples/strings/C6.mp3 +0 -0
  77. package/dist/public/lib/samples/strings/G2.mp3 +0 -0
  78. package/dist/public/lib/samples/strings/G3.mp3 +0 -0
  79. package/dist/public/lib/samples/strings/G4.mp3 +0 -0
  80. package/dist/public/lib/samples/strings/G5.mp3 +0 -0
  81. package/dist/public/lib/samples/theme-check.html +92 -0
  82. package/dist/public/lib/samples/themes-boot.js +20 -0
  83. package/dist/public/lib/samples/themes.html +154 -0
  84. package/dist/public/lib/samples/themes.js +60 -0
  85. package/dist/public/lib/samples/trumpet/A3.mp3 +0 -0
  86. package/dist/public/lib/samples/trumpet/A4.mp3 +0 -0
  87. package/dist/public/lib/samples/trumpet/A5.mp3 +0 -0
  88. package/dist/public/lib/samples/trumpet/C4.mp3 +0 -0
  89. package/dist/public/lib/samples/trumpet/C5.mp3 +0 -0
  90. package/dist/public/lib/samples/trumpet/E3.mp3 +0 -0
  91. package/dist/public/lib/samples/trumpet/E4.mp3 +0 -0
  92. package/dist/public/lib/samples/trumpet/E5.mp3 +0 -0
  93. package/dist/public/spa.html +2 -0
  94. package/dist/public/views/app-grant.js +24 -4
  95. package/dist/public/views/portfolio.js +61 -6
  96. package/dist/public/views/profile/access-tab/connected-apps.js +81 -5
  97. package/dist/public/views/profile/apps-tab.js +18 -1
  98. package/dist/public/views/profile/extensions-tab.maturity.js +4 -1
  99. package/dist/public/views/profile/inbox-tab/ai-actions.js +86 -0
  100. package/dist/public/views/profile/inbox-tab/components.js +141 -10
  101. package/dist/public/views/profile/inbox-tab/helpers.js +26 -0
  102. package/dist/public/views/profile/inbox-tab/panels.js +18 -3
  103. package/dist/public/views/profile/inbox-tab/use-thread-ux.js +47 -3
  104. package/dist/public/views/profile/inbox-tab.js +46 -49
  105. package/dist/public/views/profile/landing-page.cards.js +7 -0
  106. package/dist/public/views/profile/landing-page.js +12 -1
  107. package/dist/public/views/profile/libraries-tab.js +10 -2
  108. package/dist/public/views/profile/skills-tab.js +1 -1
  109. package/dist/public/views/profile/wallet-tab.js +64 -0
  110. package/dist/public/views/public-workspace-viewer.js +1 -1
  111. package/dist/public/views/start.js +2 -1
  112. package/dist/scripts/build-sdk-libs.d.ts +16 -0
  113. package/dist/scripts/build-sdk-libs.d.ts.map +1 -0
  114. package/dist/scripts/build-sdk-libs.js +112 -0
  115. package/dist/scripts/build-sdk-libs.js.map +1 -0
  116. package/dist/scripts/check-openapi.d.ts +2 -0
  117. package/dist/scripts/check-openapi.d.ts.map +1 -0
  118. package/dist/scripts/check-openapi.js +139 -0
  119. package/dist/scripts/check-openapi.js.map +1 -0
  120. package/dist/scripts/embed-viewport.d.ts +23 -0
  121. package/dist/scripts/embed-viewport.d.ts.map +1 -0
  122. package/dist/scripts/embed-viewport.js +116 -0
  123. package/dist/scripts/embed-viewport.js.map +1 -0
  124. package/dist/src/auth/sse-domain-scopes.d.ts +50 -0
  125. package/dist/src/auth/sse-domain-scopes.d.ts.map +1 -0
  126. package/dist/src/auth/sse-domain-scopes.js +111 -0
  127. package/dist/src/auth/sse-domain-scopes.js.map +1 -0
  128. package/dist/src/cli/connect/auth.d.ts +15 -0
  129. package/dist/src/cli/connect/auth.d.ts.map +1 -1
  130. package/dist/src/cli/connect/auth.js +25 -6
  131. package/dist/src/cli/connect/auth.js.map +1 -1
  132. package/dist/src/cli/connect/keychain.d.ts +9 -0
  133. package/dist/src/cli/connect/keychain.d.ts.map +1 -1
  134. package/dist/src/cli/connect/keychain.js +21 -8
  135. package/dist/src/cli/connect/keychain.js.map +1 -1
  136. package/dist/src/cli/connect/mcp/tools/agent-tasks.d.ts.map +1 -1
  137. package/dist/src/cli/connect/mcp/tools/agent-tasks.js +4 -1
  138. package/dist/src/cli/connect/mcp/tools/agent-tasks.js.map +1 -1
  139. package/dist/src/cli/connect/mcp/tools/core.d.ts.map +1 -1
  140. package/dist/src/cli/connect/mcp/tools/core.js +14 -3
  141. package/dist/src/cli/connect/mcp/tools/core.js.map +1 -1
  142. package/dist/src/cli/connect/mcp/tools/exchange.d.ts +18 -0
  143. package/dist/src/cli/connect/mcp/tools/exchange.d.ts.map +1 -0
  144. package/dist/src/cli/connect/mcp/tools/exchange.js +170 -0
  145. package/dist/src/cli/connect/mcp/tools/exchange.js.map +1 -0
  146. package/dist/src/cli/connect/mcp/tools/index.d.ts.map +1 -1
  147. package/dist/src/cli/connect/mcp/tools/index.js +2 -0
  148. package/dist/src/cli/connect/mcp/tools/index.js.map +1 -1
  149. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts +3 -0
  150. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts.map +1 -1
  151. package/dist/src/cli/connect/mcp/tools/workspaces.js +4 -2
  152. package/dist/src/cli/connect/mcp/tools/workspaces.js.map +1 -1
  153. package/dist/src/cli/connect/tool-call-defs-core.d.ts.map +1 -1
  154. package/dist/src/cli/connect/tool-call-defs-core.js +13 -1
  155. package/dist/src/cli/connect/tool-call-defs-core.js.map +1 -1
  156. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts +3 -0
  157. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts.map +1 -0
  158. package/dist/src/cli/connect/tool-call-defs-exchange.js +146 -0
  159. package/dist/src/cli/connect/tool-call-defs-exchange.js.map +1 -0
  160. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  161. package/dist/src/cli/connect/tool-call.js +2 -0
  162. package/dist/src/cli/connect/tool-call.js.map +1 -1
  163. package/dist/src/commerce/__tests__/x402-registry.test.d.ts +2 -0
  164. package/dist/src/commerce/__tests__/x402-registry.test.d.ts.map +1 -0
  165. package/dist/src/commerce/__tests__/x402-registry.test.js +105 -0
  166. package/dist/src/commerce/__tests__/x402-registry.test.js.map +1 -0
  167. package/dist/src/commerce/evm-address.d.ts +21 -0
  168. package/dist/src/commerce/evm-address.d.ts.map +1 -0
  169. package/dist/src/commerce/evm-address.js +94 -0
  170. package/dist/src/commerce/evm-address.js.map +1 -0
  171. package/dist/src/commerce/money.d.ts +18 -5
  172. package/dist/src/commerce/money.d.ts.map +1 -1
  173. package/dist/src/commerce/money.js +27 -6
  174. package/dist/src/commerce/money.js.map +1 -1
  175. package/dist/src/commerce/session-service.d.ts +14 -0
  176. package/dist/src/commerce/session-service.d.ts.map +1 -1
  177. package/dist/src/commerce/session-service.js +1 -1
  178. package/dist/src/commerce/session-service.js.map +1 -1
  179. package/dist/src/commerce/x402-facilitator.d.ts +64 -13
  180. package/dist/src/commerce/x402-facilitator.d.ts.map +1 -1
  181. package/dist/src/commerce/x402-facilitator.js +71 -19
  182. package/dist/src/commerce/x402-facilitator.js.map +1 -1
  183. package/dist/src/commerce/x402-handler.d.ts +13 -7
  184. package/dist/src/commerce/x402-handler.d.ts.map +1 -1
  185. package/dist/src/commerce/x402-handler.js +23 -10
  186. package/dist/src/commerce/x402-handler.js.map +1 -1
  187. package/dist/src/commerce/x402.d.ts +11 -6
  188. package/dist/src/commerce/x402.d.ts.map +1 -1
  189. package/dist/src/commerce/x402.js +10 -7
  190. package/dist/src/commerce/x402.js.map +1 -1
  191. package/dist/src/config-types.d.ts +12 -0
  192. package/dist/src/config-types.d.ts.map +1 -1
  193. package/dist/src/config.d.ts.map +1 -1
  194. package/dist/src/config.js +8 -0
  195. package/dist/src/config.js.map +1 -1
  196. package/dist/src/data/app-templates/shells.d.ts +15 -3
  197. package/dist/src/data/app-templates/shells.d.ts.map +1 -1
  198. package/dist/src/data/app-templates/shells.js +97 -12
  199. package/dist/src/data/app-templates/shells.js.map +1 -1
  200. package/dist/src/data/app-templates.js +2 -2
  201. package/dist/src/data/app-templates.js.map +1 -1
  202. package/dist/src/data/appdev-pitfalls.d.ts +2 -0
  203. package/dist/src/data/appdev-pitfalls.d.ts.map +1 -1
  204. package/dist/src/data/appdev-pitfalls.js +24 -1
  205. package/dist/src/data/appdev-pitfalls.js.map +1 -1
  206. package/dist/src/data/library-packs/cortex.d.ts.map +1 -1
  207. package/dist/src/data/library-packs/cortex.js +108 -5
  208. package/dist/src/data/library-packs/cortex.js.map +1 -1
  209. package/dist/src/data/library-packs/sdk.d.ts.map +1 -1
  210. package/dist/src/data/library-packs/sdk.js +32 -8
  211. package/dist/src/data/library-packs/sdk.js.map +1 -1
  212. package/dist/src/data/library-packs/vendored.d.ts.map +1 -1
  213. package/dist/src/data/library-packs/vendored.js +83 -6
  214. package/dist/src/data/library-packs/vendored.js.map +1 -1
  215. package/dist/src/generated/api-types.d.ts +2039 -24
  216. package/dist/src/generated/api-types.d.ts.map +1 -1
  217. package/dist/src/mcp/agent-tasks.d.ts +4 -0
  218. package/dist/src/mcp/agent-tasks.d.ts.map +1 -1
  219. package/dist/src/mcp/agent-tasks.js +20 -2
  220. package/dist/src/mcp/agent-tasks.js.map +1 -1
  221. package/dist/src/mcp/annotations.d.ts.map +1 -1
  222. package/dist/src/mcp/annotations.js +20 -0
  223. package/dist/src/mcp/annotations.js.map +1 -1
  224. package/dist/src/mcp/apps.d.ts.map +1 -1
  225. package/dist/src/mcp/apps.js +8 -4
  226. package/dist/src/mcp/apps.js.map +1 -1
  227. package/dist/src/mcp/capabilities.d.ts +7 -1
  228. package/dist/src/mcp/capabilities.d.ts.map +1 -1
  229. package/dist/src/mcp/capabilities.js +5 -2
  230. package/dist/src/mcp/capabilities.js.map +1 -1
  231. package/dist/src/mcp/catalog/definitions/commerce.d.ts.map +1 -1
  232. package/dist/src/mcp/catalog/definitions/commerce.js +4 -2
  233. package/dist/src/mcp/catalog/definitions/commerce.js.map +1 -1
  234. package/dist/src/mcp/catalog/definitions/discovery-work-boards.d.ts.map +1 -1
  235. package/dist/src/mcp/catalog/definitions/discovery-work-boards.js +4 -3
  236. package/dist/src/mcp/catalog/definitions/discovery-work-boards.js.map +1 -1
  237. package/dist/src/mcp/catalog/definitions/exchange.d.ts +18 -0
  238. package/dist/src/mcp/catalog/definitions/exchange.d.ts.map +1 -0
  239. package/dist/src/mcp/catalog/definitions/exchange.js +182 -0
  240. package/dist/src/mcp/catalog/definitions/exchange.js.map +1 -0
  241. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js +1 -1
  242. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js.map +1 -1
  243. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.d.ts.map +1 -1
  244. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.js +3 -2
  245. package/dist/src/mcp/catalog/definitions/schedules-tasks-memory.js.map +1 -1
  246. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  247. package/dist/src/mcp/catalog/definitions.js +2 -0
  248. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  249. package/dist/src/mcp/catalog/output-schemas.d.ts +6 -1
  250. package/dist/src/mcp/catalog/output-schemas.d.ts.map +1 -1
  251. package/dist/src/mcp/catalog/output-schemas.js +6 -1
  252. package/dist/src/mcp/catalog/output-schemas.js.map +1 -1
  253. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  254. package/dist/src/mcp/catalog/scopes.js +22 -0
  255. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  256. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  257. package/dist/src/mcp/catalog/surfaces.js +14 -0
  258. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  259. package/dist/src/mcp/commerce.d.ts.map +1 -1
  260. package/dist/src/mcp/commerce.js +15 -3
  261. package/dist/src/mcp/commerce.js.map +1 -1
  262. package/dist/src/mcp/core-storage.d.ts +23 -0
  263. package/dist/src/mcp/core-storage.d.ts.map +1 -0
  264. package/dist/src/mcp/core-storage.js +157 -0
  265. package/dist/src/mcp/core-storage.js.map +1 -0
  266. package/dist/src/mcp/core.d.ts +16 -0
  267. package/dist/src/mcp/core.d.ts.map +1 -1
  268. package/dist/src/mcp/core.js +75 -119
  269. package/dist/src/mcp/core.js.map +1 -1
  270. package/dist/src/mcp/dm-messages.d.ts +4 -0
  271. package/dist/src/mcp/dm-messages.d.ts.map +1 -1
  272. package/dist/src/mcp/dm-messages.js +43 -2
  273. package/dist/src/mcp/dm-messages.js.map +1 -1
  274. package/dist/src/mcp/exchange-run.d.ts +5 -0
  275. package/dist/src/mcp/exchange-run.d.ts.map +1 -0
  276. package/dist/src/mcp/exchange-run.js +226 -0
  277. package/dist/src/mcp/exchange-run.js.map +1 -0
  278. package/dist/src/mcp/exchange.d.ts +5 -0
  279. package/dist/src/mcp/exchange.d.ts.map +1 -0
  280. package/dist/src/mcp/exchange.js +352 -0
  281. package/dist/src/mcp/exchange.js.map +1 -0
  282. package/dist/src/mcp/extensions.d.ts.map +1 -1
  283. package/dist/src/mcp/extensions.js +17 -2
  284. package/dist/src/mcp/extensions.js.map +1 -1
  285. package/dist/src/mcp/index.d.ts +5 -0
  286. package/dist/src/mcp/index.d.ts.map +1 -1
  287. package/dist/src/mcp/index.js +26 -3
  288. package/dist/src/mcp/index.js.map +1 -1
  289. package/dist/src/mcp/memory-namespace-hints.d.ts +33 -0
  290. package/dist/src/mcp/memory-namespace-hints.d.ts.map +1 -0
  291. package/dist/src/mcp/memory-namespace-hints.js +60 -0
  292. package/dist/src/mcp/memory-namespace-hints.js.map +1 -0
  293. package/dist/src/mcp/workspaces.d.ts +5 -0
  294. package/dist/src/mcp/workspaces.d.ts.map +1 -1
  295. package/dist/src/mcp/workspaces.js +5 -3
  296. package/dist/src/mcp/workspaces.js.map +1 -1
  297. package/dist/src/models/agent-task-schemas.d.ts +25 -3
  298. package/dist/src/models/agent-task-schemas.d.ts.map +1 -1
  299. package/dist/src/models/agent-task-schemas.js +16 -0
  300. package/dist/src/models/agent-task-schemas.js.map +1 -1
  301. package/dist/src/models/app-tool-schemas.d.ts +573 -2
  302. package/dist/src/models/app-tool-schemas.d.ts.map +1 -1
  303. package/dist/src/models/app-tool-schemas.js +73 -2
  304. package/dist/src/models/app-tool-schemas.js.map +1 -1
  305. package/dist/src/models/odps-schemas.d.ts +305 -0
  306. package/dist/src/models/odps-schemas.d.ts.map +1 -0
  307. package/dist/src/models/odps-schemas.js +182 -0
  308. package/dist/src/models/odps-schemas.js.map +1 -0
  309. package/dist/src/models/offer-schemas.d.ts +359 -4
  310. package/dist/src/models/offer-schemas.d.ts.map +1 -1
  311. package/dist/src/models/offer-schemas.js +37 -0
  312. package/dist/src/models/offer-schemas.js.map +1 -1
  313. package/dist/src/models/schemas.d.ts +7 -3
  314. package/dist/src/models/schemas.d.ts.map +1 -1
  315. package/dist/src/models/schemas.js +13 -1
  316. package/dist/src/models/schemas.js.map +1 -1
  317. package/dist/src/models/webhook-schemas.d.ts +8 -8
  318. package/dist/src/routes/agent-tasks/create-read.d.ts +4 -0
  319. package/dist/src/routes/agent-tasks/create-read.d.ts.map +1 -1
  320. package/dist/src/routes/agent-tasks/create-read.js +20 -1
  321. package/dist/src/routes/agent-tasks/create-read.js.map +1 -1
  322. package/dist/src/routes/agent-tasks/lifecycle.d.ts.map +1 -1
  323. package/dist/src/routes/agent-tasks/lifecycle.js +10 -0
  324. package/dist/src/routes/agent-tasks/lifecycle.js.map +1 -1
  325. package/dist/src/routes/agents/device-auth.d.ts +4 -0
  326. package/dist/src/routes/agents/device-auth.d.ts.map +1 -1
  327. package/dist/src/routes/agents/device-auth.js +19 -4
  328. package/dist/src/routes/agents/device-auth.js.map +1 -1
  329. package/dist/src/routes/agents/offers.d.ts +2 -0
  330. package/dist/src/routes/agents/offers.d.ts.map +1 -1
  331. package/dist/src/routes/agents/offers.js +0 -0
  332. package/dist/src/routes/agents/offers.js.map +1 -1
  333. package/dist/src/routes/app-grants.d.ts +12 -0
  334. package/dist/src/routes/app-grants.d.ts.map +1 -1
  335. package/dist/src/routes/app-grants.js +90 -27
  336. package/dist/src/routes/app-grants.js.map +1 -1
  337. package/dist/src/routes/apps/drafts.d.ts +3 -0
  338. package/dist/src/routes/apps/drafts.d.ts.map +1 -1
  339. package/dist/src/routes/apps/drafts.js +63 -1
  340. package/dist/src/routes/apps/drafts.js.map +1 -1
  341. package/dist/src/routes/apps/fork-manage.d.ts.map +1 -1
  342. package/dist/src/routes/apps/fork-manage.js +24 -1
  343. package/dist/src/routes/apps/fork-manage.js.map +1 -1
  344. package/dist/src/routes/apps/publish.d.ts +4 -0
  345. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  346. package/dist/src/routes/apps/publish.js +44 -3
  347. package/dist/src/routes/apps/publish.js.map +1 -1
  348. package/dist/src/routes/apps-cost.d.ts +25 -0
  349. package/dist/src/routes/apps-cost.d.ts.map +1 -0
  350. package/dist/src/routes/apps-cost.js +107 -0
  351. package/dist/src/routes/apps-cost.js.map +1 -0
  352. package/dist/src/routes/commerce.d.ts.map +1 -1
  353. package/dist/src/routes/commerce.js +122 -2
  354. package/dist/src/routes/commerce.js.map +1 -1
  355. package/dist/src/routes/exchange-market.d.ts +32 -0
  356. package/dist/src/routes/exchange-market.d.ts.map +1 -0
  357. package/dist/src/routes/exchange-market.js +580 -0
  358. package/dist/src/routes/exchange-market.js.map +1 -0
  359. package/dist/src/routes/exchange.d.ts +33 -0
  360. package/dist/src/routes/exchange.d.ts.map +1 -0
  361. package/dist/src/routes/exchange.js +398 -0
  362. package/dist/src/routes/exchange.js.map +1 -0
  363. package/dist/src/routes/extensions/actions.d.ts.map +1 -1
  364. package/dist/src/routes/extensions/actions.js +18 -0
  365. package/dist/src/routes/extensions/actions.js.map +1 -1
  366. package/dist/src/routes/extensions/crud.d.ts.map +1 -1
  367. package/dist/src/routes/extensions/crud.js +36 -3
  368. package/dist/src/routes/extensions/crud.js.map +1 -1
  369. package/dist/src/routes/extensions/entitlement-gate.d.ts +33 -0
  370. package/dist/src/routes/extensions/entitlement-gate.d.ts.map +1 -0
  371. package/dist/src/routes/extensions/entitlement-gate.js +156 -0
  372. package/dist/src/routes/extensions/entitlement-gate.js.map +1 -0
  373. package/dist/src/routes/extensions/manifest.d.ts +15 -0
  374. package/dist/src/routes/extensions/manifest.d.ts.map +1 -1
  375. package/dist/src/routes/extensions/manifest.js +101 -2
  376. package/dist/src/routes/extensions/manifest.js.map +1 -1
  377. package/dist/src/routes/extensions/pacing.d.ts +31 -0
  378. package/dist/src/routes/extensions/pacing.d.ts.map +1 -0
  379. package/dist/src/routes/extensions/pacing.js +73 -0
  380. package/dist/src/routes/extensions/pacing.js.map +1 -0
  381. package/dist/src/routes/extensions/paywall.d.ts.map +1 -1
  382. package/dist/src/routes/extensions/paywall.js +20 -11
  383. package/dist/src/routes/extensions/paywall.js.map +1 -1
  384. package/dist/src/routes/federation-sync/messaging.d.ts.map +1 -1
  385. package/dist/src/routes/federation-sync/messaging.js +3 -1
  386. package/dist/src/routes/federation-sync/messaging.js.map +1 -1
  387. package/dist/src/routes/ghii/recovery.d.ts +2 -0
  388. package/dist/src/routes/ghii/recovery.d.ts.map +1 -1
  389. package/dist/src/routes/ghii/recovery.js +7 -0
  390. package/dist/src/routes/ghii/recovery.js.map +1 -1
  391. package/dist/src/routes/ghii/register-login.d.ts +4 -0
  392. package/dist/src/routes/ghii/register-login.d.ts.map +1 -1
  393. package/dist/src/routes/ghii/register-login.js +45 -22
  394. package/dist/src/routes/ghii/register-login.js.map +1 -1
  395. package/dist/src/routes/ghii/web-verify.d.ts +5 -0
  396. package/dist/src/routes/ghii/web-verify.d.ts.map +1 -1
  397. package/dist/src/routes/ghii/web-verify.js +24 -3
  398. package/dist/src/routes/ghii/web-verify.js.map +1 -1
  399. package/dist/src/routes/libs/sdk-serve.d.ts +11 -0
  400. package/dist/src/routes/libs/sdk-serve.d.ts.map +1 -0
  401. package/dist/src/routes/libs/sdk-serve.js +53 -0
  402. package/dist/src/routes/libs/sdk-serve.js.map +1 -0
  403. package/dist/src/routes/libs.d.ts +7 -1
  404. package/dist/src/routes/libs.d.ts.map +1 -1
  405. package/dist/src/routes/libs.js +65 -146
  406. package/dist/src/routes/libs.js.map +1 -1
  407. package/dist/src/routes/memory/crud.d.ts.map +1 -1
  408. package/dist/src/routes/memory/crud.js +10 -0
  409. package/dist/src/routes/memory/crud.js.map +1 -1
  410. package/dist/src/routes/messages.d.ts +3 -0
  411. package/dist/src/routes/messages.d.ts.map +1 -1
  412. package/dist/src/routes/messages.js +9 -0
  413. package/dist/src/routes/messages.js.map +1 -1
  414. package/dist/src/routes/notifications.d.ts +6 -3
  415. package/dist/src/routes/notifications.d.ts.map +1 -1
  416. package/dist/src/routes/notifications.js +32 -3
  417. package/dist/src/routes/notifications.js.map +1 -1
  418. package/dist/src/routes/organisms/crud.d.ts +3 -0
  419. package/dist/src/routes/organisms/crud.d.ts.map +1 -1
  420. package/dist/src/routes/organisms/crud.js +5 -2
  421. package/dist/src/routes/organisms/crud.js.map +1 -1
  422. package/dist/src/routes/organisms/workspace-access.d.ts.map +1 -1
  423. package/dist/src/routes/organisms/workspace-access.js +38 -20
  424. package/dist/src/routes/organisms/workspace-access.js.map +1 -1
  425. package/dist/src/routes/organisms/workspace-read.d.ts.map +1 -1
  426. package/dist/src/routes/organisms/workspace-read.js +7 -2
  427. package/dist/src/routes/organisms/workspace-read.js.map +1 -1
  428. package/dist/src/routes/public-stats.d.ts +7 -0
  429. package/dist/src/routes/public-stats.d.ts.map +1 -1
  430. package/dist/src/routes/public-stats.js +28 -7
  431. package/dist/src/routes/public-stats.js.map +1 -1
  432. package/dist/src/routes/sse.d.ts +7 -0
  433. package/dist/src/routes/sse.d.ts.map +1 -1
  434. package/dist/src/routes/sse.js +36 -6
  435. package/dist/src/routes/sse.js.map +1 -1
  436. package/dist/src/routes/storage-files.d.ts +11 -0
  437. package/dist/src/routes/storage-files.d.ts.map +1 -1
  438. package/dist/src/routes/storage-files.js +58 -51
  439. package/dist/src/routes/storage-files.js.map +1 -1
  440. package/dist/src/routes/subdomains.d.ts +4 -0
  441. package/dist/src/routes/subdomains.d.ts.map +1 -1
  442. package/dist/src/routes/subdomains.js +42 -5
  443. package/dist/src/routes/subdomains.js.map +1 -1
  444. package/dist/src/routes/unfurl.d.ts +27 -0
  445. package/dist/src/routes/unfurl.d.ts.map +1 -0
  446. package/dist/src/routes/unfurl.js +180 -0
  447. package/dist/src/routes/unfurl.js.map +1 -0
  448. package/dist/src/routes/upload.d.ts +13 -0
  449. package/dist/src/routes/upload.d.ts.map +1 -1
  450. package/dist/src/routes/upload.js +115 -28
  451. package/dist/src/routes/upload.js.map +1 -1
  452. package/dist/src/routes/webmcp.d.ts +3 -0
  453. package/dist/src/routes/webmcp.d.ts.map +1 -1
  454. package/dist/src/routes/webmcp.js +59 -0
  455. package/dist/src/routes/webmcp.js.map +1 -1
  456. package/dist/src/schemas/knowledge-package.d.ts +1 -1
  457. package/dist/src/server-bootstrap/routes-loader.d.ts +1 -0
  458. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  459. package/dist/src/server-bootstrap/routes-loader.js +8 -0
  460. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  461. package/dist/src/server-bootstrap/static-files.d.ts +4 -0
  462. package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
  463. package/dist/src/server-bootstrap/static-files.js +11 -0
  464. package/dist/src/server-bootstrap/static-files.js.map +1 -1
  465. package/dist/src/services/agent-face.d.ts +10 -2
  466. package/dist/src/services/agent-face.d.ts.map +1 -1
  467. package/dist/src/services/agent-face.js +10 -4
  468. package/dist/src/services/agent-face.js.map +1 -1
  469. package/dist/src/services/app-tool-interfaces.d.ts +37 -0
  470. package/dist/src/services/app-tool-interfaces.d.ts.map +1 -0
  471. package/dist/src/services/app-tool-interfaces.js +101 -0
  472. package/dist/src/services/app-tool-interfaces.js.map +1 -0
  473. package/dist/src/services/build-app-prompt.d.ts +22 -0
  474. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  475. package/dist/src/services/build-app-prompt.js +108 -11
  476. package/dist/src/services/build-app-prompt.js.map +1 -1
  477. package/dist/src/services/call-timing.d.ts +51 -0
  478. package/dist/src/services/call-timing.d.ts.map +1 -0
  479. package/dist/src/services/call-timing.js +91 -0
  480. package/dist/src/services/call-timing.js.map +1 -0
  481. package/dist/src/services/capability-invoke.d.ts +2 -0
  482. package/dist/src/services/capability-invoke.d.ts.map +1 -1
  483. package/dist/src/services/capability-invoke.js +10 -0
  484. package/dist/src/services/capability-invoke.js.map +1 -1
  485. package/dist/src/services/config-schema.d.ts.map +1 -1
  486. package/dist/src/services/config-schema.js +6 -0
  487. package/dist/src/services/config-schema.js.map +1 -1
  488. package/dist/src/services/contacts.d.ts +25 -1
  489. package/dist/src/services/contacts.d.ts.map +1 -1
  490. package/dist/src/services/contacts.js +30 -0
  491. package/dist/src/services/contacts.js.map +1 -1
  492. package/dist/src/services/draft-token.d.ts +22 -2
  493. package/dist/src/services/draft-token.d.ts.map +1 -1
  494. package/dist/src/services/draft-token.js +52 -3
  495. package/dist/src/services/draft-token.js.map +1 -1
  496. package/dist/src/services/entitlement-money.d.ts +55 -0
  497. package/dist/src/services/entitlement-money.d.ts.map +1 -0
  498. package/dist/src/services/entitlement-money.js +68 -0
  499. package/dist/src/services/entitlement-money.js.map +1 -0
  500. package/dist/src/services/exchange-market.d.ts +280 -0
  501. package/dist/src/services/exchange-market.d.ts.map +1 -0
  502. package/dist/src/services/exchange-market.js +276 -0
  503. package/dist/src/services/exchange-market.js.map +1 -0
  504. package/dist/src/services/exchange-odps.d.ts +58 -0
  505. package/dist/src/services/exchange-odps.d.ts.map +1 -0
  506. package/dist/src/services/exchange-odps.js +400 -0
  507. package/dist/src/services/exchange-odps.js.map +1 -0
  508. package/dist/src/services/exchange-projection.d.ts +61 -0
  509. package/dist/src/services/exchange-projection.d.ts.map +1 -0
  510. package/dist/src/services/exchange-projection.js +504 -0
  511. package/dist/src/services/exchange-projection.js.map +1 -0
  512. package/dist/src/services/exchange-proposals.d.ts +47 -0
  513. package/dist/src/services/exchange-proposals.d.ts.map +1 -0
  514. package/dist/src/services/exchange-proposals.js +73 -0
  515. package/dist/src/services/exchange-proposals.js.map +1 -0
  516. package/dist/src/services/exchange-work.d.ts +30 -0
  517. package/dist/src/services/exchange-work.d.ts.map +1 -0
  518. package/dist/src/services/exchange-work.js +43 -0
  519. package/dist/src/services/exchange-work.js.map +1 -0
  520. package/dist/src/services/extension-files.d.ts +64 -0
  521. package/dist/src/services/extension-files.d.ts.map +1 -0
  522. package/dist/src/services/extension-files.js +88 -0
  523. package/dist/src/services/extension-files.js.map +1 -0
  524. package/dist/src/services/extension-runtime.d.ts +33 -0
  525. package/dist/src/services/extension-runtime.d.ts.map +1 -1
  526. package/dist/src/services/extension-runtime.js +52 -0
  527. package/dist/src/services/extension-runtime.js.map +1 -1
  528. package/dist/src/services/file-refs.d.ts +105 -0
  529. package/dist/src/services/file-refs.d.ts.map +1 -0
  530. package/dist/src/services/file-refs.js +106 -0
  531. package/dist/src/services/file-refs.js.map +1 -0
  532. package/dist/src/services/message-send.d.ts.map +1 -1
  533. package/dist/src/services/message-send.js +4 -1
  534. package/dist/src/services/message-send.js.map +1 -1
  535. package/dist/src/services/metered-entitlements.d.ts +210 -0
  536. package/dist/src/services/metered-entitlements.d.ts.map +1 -0
  537. package/dist/src/services/metered-entitlements.js +268 -0
  538. package/dist/src/services/metered-entitlements.js.map +1 -0
  539. package/dist/src/services/notify.d.ts +7 -0
  540. package/dist/src/services/notify.d.ts.map +1 -1
  541. package/dist/src/services/notify.js +35 -0
  542. package/dist/src/services/notify.js.map +1 -1
  543. package/dist/src/services/owner-memory.d.ts +30 -1
  544. package/dist/src/services/owner-memory.d.ts.map +1 -1
  545. package/dist/src/services/owner-memory.js +31 -14
  546. package/dist/src/services/owner-memory.js.map +1 -1
  547. package/dist/src/services/owner-provisioning.d.ts +5 -0
  548. package/dist/src/services/owner-provisioning.d.ts.map +1 -1
  549. package/dist/src/services/owner-provisioning.js +20 -2
  550. package/dist/src/services/owner-provisioning.js.map +1 -1
  551. package/dist/src/services/task-files.d.ts +51 -0
  552. package/dist/src/services/task-files.d.ts.map +1 -0
  553. package/dist/src/services/task-files.js +58 -0
  554. package/dist/src/services/task-files.js.map +1 -0
  555. package/dist/src/services/upload-token.d.ts +29 -0
  556. package/dist/src/services/upload-token.d.ts.map +1 -1
  557. package/dist/src/services/upload-token.js +37 -0
  558. package/dist/src/services/upload-token.js.map +1 -1
  559. package/dist/src/services/upload-zip.d.ts +2 -0
  560. package/dist/src/services/upload-zip.d.ts.map +1 -1
  561. package/dist/src/services/upload-zip.js +5 -1
  562. package/dist/src/services/upload-zip.js.map +1 -1
  563. package/dist/src/services/workspace-meta.d.ts +15 -0
  564. package/dist/src/services/workspace-meta.d.ts.map +1 -1
  565. package/dist/src/services/workspace-meta.js +17 -0
  566. package/dist/src/services/workspace-meta.js.map +1 -1
  567. package/dist/src/services/workspace-provision.d.ts +3 -0
  568. package/dist/src/services/workspace-provision.d.ts.map +1 -1
  569. package/dist/src/services/workspace-provision.js +5 -3
  570. package/dist/src/services/workspace-provision.js.map +1 -1
  571. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.d.ts +1 -0
  572. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.d.ts.map +1 -1
  573. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.js +10 -0
  574. package/dist/src/storage/providers/postgres-kysely/methods/app-grants.js.map +1 -1
  575. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts +1 -0
  576. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts.map +1 -1
  577. package/dist/src/storage/providers/postgres-kysely/methods/apps.js +2 -0
  578. package/dist/src/storage/providers/postgres-kysely/methods/apps.js.map +1 -1
  579. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts +1 -0
  580. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts.map +1 -1
  581. package/dist/src/storage/providers/postgres-kysely/methods/identity.js +4 -0
  582. package/dist/src/storage/providers/postgres-kysely/methods/identity.js.map +1 -1
  583. package/dist/src/storage/providers/postgres-kysely/methods/memory.d.ts +2 -0
  584. package/dist/src/storage/providers/postgres-kysely/methods/memory.d.ts.map +1 -1
  585. package/dist/src/storage/providers/postgres-kysely/methods/memory.js +12 -1
  586. package/dist/src/storage/providers/postgres-kysely/methods/memory.js.map +1 -1
  587. package/dist/src/storage/providers/postgres-kysely/methods/organisms.d.ts.map +1 -1
  588. package/dist/src/storage/providers/postgres-kysely/methods/organisms.js +5 -1
  589. package/dist/src/storage/providers/postgres-kysely/methods/organisms.js.map +1 -1
  590. package/dist/src/storage/providers/postgres-kysely/migrations/0011_unique_verified_email.sql +25 -0
  591. package/dist/src/storage/providers/postgres-kysely/migrations/0012_unique_live_app_grant.sql +29 -0
  592. package/dist/src/storage/providers/sqlite/methods/apps.d.ts +4 -0
  593. package/dist/src/storage/providers/sqlite/methods/apps.d.ts.map +1 -1
  594. package/dist/src/storage/providers/sqlite/methods/apps.js +9 -0
  595. package/dist/src/storage/providers/sqlite/methods/apps.js.map +1 -1
  596. package/dist/src/storage/providers/sqlite/methods/governance.d.ts +1 -0
  597. package/dist/src/storage/providers/sqlite/methods/governance.d.ts.map +1 -1
  598. package/dist/src/storage/providers/sqlite/methods/governance.js +4 -1
  599. package/dist/src/storage/providers/sqlite/methods/governance.js.map +1 -1
  600. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts +1 -0
  601. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts.map +1 -1
  602. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js +4 -0
  603. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js.map +1 -1
  604. package/dist/src/storage/providers/sqlite/methods/owner.d.ts +5 -0
  605. package/dist/src/storage/providers/sqlite/methods/owner.d.ts.map +1 -1
  606. package/dist/src/storage/providers/sqlite/methods/owner.js +8 -0
  607. package/dist/src/storage/providers/sqlite/methods/owner.js.map +1 -1
  608. package/dist/src/storage/providers/sqlite/schema.d.ts +3 -0
  609. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  610. package/dist/src/storage/providers/sqlite/schema.js +40 -0
  611. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  612. package/dist/src/storage/repositories/app-grant.repository.d.ts +9 -1
  613. package/dist/src/storage/repositories/app-grant.repository.d.ts.map +1 -1
  614. package/dist/src/storage/repositories/app.repository.d.ts +0 -0
  615. package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
  616. package/dist/src/storage/repositories/identity.repository.d.ts +6 -0
  617. package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -1
  618. package/dist/src/storage/repositories/memory.repository.d.ts +14 -0
  619. package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
  620. package/dist/src/storage/repositories-impl/memory-repository.d.ts +8 -1
  621. package/dist/src/storage/repositories-impl/memory-repository.d.ts.map +1 -1
  622. package/dist/src/storage/repositories-impl/memory-repository.js +15 -4
  623. package/dist/src/storage/repositories-impl/memory-repository.js.map +1 -1
  624. package/dist/src/storage/types/agents-messaging.d.ts +19 -0
  625. package/dist/src/storage/types/agents-messaging.d.ts.map +1 -1
  626. package/dist/src/storage/types/agents-messaging.js.map +1 -1
  627. package/dist/src/storage/types/apps.d.ts +1 -0
  628. package/dist/src/storage/types/apps.d.ts.map +1 -1
  629. package/dist/src/storage/types/organisms-federation.d.ts +50 -0
  630. package/dist/src/storage/types/organisms-federation.d.ts.map +1 -1
  631. package/dist/src/utils/app-badge.d.ts.map +1 -1
  632. package/dist/src/utils/app-badge.js +7 -3
  633. package/dist/src/utils/app-badge.js.map +1 -1
  634. package/dist/src/utils/app-mobile-lint.d.ts +17 -0
  635. package/dist/src/utils/app-mobile-lint.d.ts.map +1 -0
  636. package/dist/src/utils/app-mobile-lint.js +40 -0
  637. package/dist/src/utils/app-mobile-lint.js.map +1 -0
  638. package/dist/static/app-catalog/_template.html +18 -82
  639. package/dist/static/app-catalog/js/apps-io.js +51 -165
  640. package/dist/static/app-catalog/js/cortex.js +3 -1
  641. package/dist/static/app-catalog/js/cost.js +100 -0
  642. package/dist/static/app-catalog/js/db.js +23 -93
  643. package/dist/static/app-catalog/js/detail.js +568 -59
  644. package/dist/static/app-catalog/js/favorites.js +71 -0
  645. package/dist/static/app-catalog/js/i18n-data.js +369 -19
  646. package/dist/static/app-catalog/js/main.js +50 -139
  647. package/dist/static/app-catalog/js/migrate.js +88 -0
  648. package/dist/static/app-catalog/js/monetize.js +205 -17
  649. package/dist/static/app-catalog/js/odps.js +489 -0
  650. package/dist/static/app-catalog/js/promote.js +70 -0
  651. package/dist/static/app-catalog/js/render.js +29 -139
  652. package/dist/static/app-catalog/js/server-io.js +126 -223
  653. package/dist/static/app-catalog/js/settings.js +11 -204
  654. package/dist/static/app-catalog/js/workcopy.js +198 -0
  655. package/dist/static/app-catalog/styles/app-catalog.css +100 -0
  656. package/dist/static/app-catalog.html +2220 -1029
  657. package/dist/static/sdk-libs/_core/config.js +52 -0
  658. package/dist/static/sdk-libs/_core/http.js +52 -0
  659. package/dist/static/sdk-libs/_core/namespace.js +33 -0
  660. package/dist/static/sdk-libs/_core/sdk-globals.d.ts +50 -0
  661. package/dist/static/sdk-libs/_core/session.js +66 -0
  662. package/dist/static/sdk-libs/agentface/index.js +102 -0
  663. package/dist/static/sdk-libs/agents/index.js +305 -0
  664. package/dist/static/sdk-libs/ai/index.js +153 -0
  665. package/dist/static/sdk-libs/audio/core.js +111 -0
  666. package/dist/static/sdk-libs/audio/index.js +380 -0
  667. package/dist/static/sdk-libs/audio/instruments.js +369 -0
  668. package/dist/static/sdk-libs/auth/cluster.js +97 -0
  669. package/dist/static/sdk-libs/auth/config.js +46 -0
  670. package/dist/static/sdk-libs/auth/crypto.js +166 -0
  671. package/dist/static/sdk-libs/auth/events.js +27 -0
  672. package/dist/static/sdk-libs/auth/i18n.js +64 -0
  673. package/dist/static/sdk-libs/auth/index.js +61 -0
  674. package/dist/static/sdk-libs/auth/locale.js +151 -0
  675. package/dist/static/sdk-libs/auth/modal.js +554 -0
  676. package/dist/static/sdk-libs/auth/palette.js +172 -0
  677. package/dist/static/sdk-libs/auth/pill.js +198 -0
  678. package/dist/static/sdk-libs/auth/session.js +792 -0
  679. package/dist/static/sdk-libs/auth/signup.js +232 -0
  680. package/dist/static/sdk-libs/auth/theme.js +137 -0
  681. package/dist/static/sdk-libs/capabilities/index.js +179 -0
  682. package/dist/static/sdk-libs/commerce/index.js +243 -0
  683. package/dist/static/sdk-libs/data/index.js +250 -0
  684. package/dist/static/sdk-libs/dist/aimeat-agentface.js +91 -0
  685. package/dist/static/sdk-libs/dist/aimeat-agents.js +348 -0
  686. package/dist/static/sdk-libs/dist/aimeat-ai.js +168 -0
  687. package/dist/static/sdk-libs/dist/aimeat-audio.js +979 -0
  688. package/dist/static/sdk-libs/dist/aimeat-auth.js +2232 -0
  689. package/dist/static/sdk-libs/dist/aimeat-capabilities.js +177 -0
  690. package/dist/static/sdk-libs/dist/aimeat-commerce.js +265 -0
  691. package/dist/static/sdk-libs/dist/aimeat-data.js +247 -0
  692. package/dist/static/sdk-libs/dist/aimeat-editor.js +299 -0
  693. package/dist/static/sdk-libs/dist/aimeat-header.js +270 -0
  694. package/dist/static/sdk-libs/dist/aimeat-intake.js +94 -0
  695. package/dist/static/sdk-libs/dist/aimeat-live.js +317 -0
  696. package/dist/static/sdk-libs/dist/aimeat-markdown.js +633 -0
  697. package/dist/static/sdk-libs/dist/aimeat-organism.js +394 -0
  698. package/dist/static/sdk-libs/dist/aimeat-portfolio-standalone.js +90 -0
  699. package/dist/static/sdk-libs/dist/aimeat-social.js +157 -0
  700. package/dist/static/sdk-libs/dist/aimeat-speech.js +300 -0
  701. package/dist/static/sdk-libs/dist/aimeat-storage.js +210 -0
  702. package/dist/static/sdk-libs/dist/aimeat-tunnel.js +383 -0
  703. package/dist/static/sdk-libs/dist/aimeat-wallet.js +118 -0
  704. package/dist/static/sdk-libs/dist/aimeat-webmcp.js +187 -0
  705. package/dist/static/sdk-libs/dist/aimeat-work.js +213 -0
  706. package/dist/static/sdk-libs/dist/aimeat-workflows.js +147 -0
  707. package/dist/static/sdk-libs/editor/index.js +229 -0
  708. package/dist/static/sdk-libs/header/index.js +249 -0
  709. package/dist/static/sdk-libs/intake/index.js +75 -0
  710. package/dist/static/sdk-libs/live/index.js +223 -0
  711. package/dist/static/sdk-libs/markdown/index.js +570 -0
  712. package/dist/static/sdk-libs/organism/index.js +381 -0
  713. package/dist/static/sdk-libs/portfolio-standalone/index.js +78 -0
  714. package/dist/static/sdk-libs/social/index.js +140 -0
  715. package/dist/static/sdk-libs/speech/index.js +321 -0
  716. package/dist/static/sdk-libs/storage/index.js +189 -0
  717. package/dist/static/sdk-libs/tunnel/index.js +428 -0
  718. package/dist/static/sdk-libs/wallet/index.js +115 -0
  719. package/dist/static/sdk-libs/webmcp/index.js +185 -0
  720. package/dist/static/sdk-libs/work/index.js +191 -0
  721. package/dist/static/sdk-libs/workflows/index.js +113 -0
  722. package/package.json +10 -3
@@ -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>
@@ -24,11 +24,12 @@ import { h } from 'preact';
24
24
  import { useState, useEffect, useRef, useCallback } from 'preact/hooks';
25
25
  import htm from 'htm';
26
26
  const html = htm.bind(h);
27
- import { t } from '/js/i18n.js';
27
+ import { t, getLocale } from '/js/i18n.js';
28
28
  import { escHtml, handleImgError, timeAgo } from '/js/utils.js';
29
29
  import { Spinner } from './shared.js';
30
30
  import { useConfirm } from '/components/Modal.js';
31
31
  import { listApps, uploadApp, deleteApp, patchApp, deployAppAgent, undeployAppAgent, appAgentStatus } from '/js/services/apps.js';
32
+ import { getMemory } from '/js/services/memory.js';
32
33
  import { listAgents } from '/js/services/agents.js';
33
34
  import { listOrganisms } from '/js/services/organisms.js';
34
35
  import * as skillsService from '/js/services/skills.js';
@@ -289,6 +290,8 @@ export default function AppsTab({ session, showToast, onStats }) {
289
290
  const [editDesc, setEditDesc] = useState('');
290
291
  const [editingAgents, setEditingAgents] = useState(null);
291
292
  const [agentsJson, setAgentsJson] = useState('');
293
+ // Promoted apps (from the owner's public app-catalog.promoted doc), keyed by "owner/filename".
294
+ const [promoted, setPromoted] = useState({});
292
295
 
293
296
  // Reload the app lists when the session becomes available / changes. loadData closes over the
294
297
  // optional onStats prop (not guaranteed memoized), so we key on session only to avoid re-running
@@ -306,6 +309,14 @@ export default function AppsTab({ session, showToast, onStats }) {
306
309
  setAllApps(list);
307
310
  onStats?.({ apps: own.length });
308
311
  } catch { setMyApps([]); setAllApps([]); }
312
+ // Promoted apps: read the owner's own app-catalog.promoted doc (soft = no 404 when unset).
313
+ try {
314
+ const res = await getMemory('app-catalog.promoted', { soft: true });
315
+ const items = res?.data?.value?.items;
316
+ const map = {};
317
+ if (Array.isArray(items)) items.forEach(it => { if (it && it.ref) map[it.ref] = it.text || {}; });
318
+ setPromoted(map);
319
+ } catch { setPromoted({}); }
309
320
  }
310
321
 
311
322
  async function handleUpload(file, description, screenshot, accessCode) {
@@ -480,12 +491,18 @@ export default function AppsTab({ session, showToast, onStats }) {
480
491
  ${a.protected ? html`<span class="badge badge-warn">\u{1F512}</span>` : ''}
481
492
  ${a.parked ? html`<span class="badge badge-dim">\u{1F17F}️ ${t('profile.apps.parkedBadge') || 'Parked'}</span>` : ''}
482
493
  ${a.manifest?.cortex?.agents?.length ? html`<span class="badge badge-info" title=${t('profile.apps.agentBadgeHint') || 'This app ships its own agent β€” deploy it onto your fleet below'}>\u{1F916} ${t('profile.apps.agentBadge') || 'Ships an agent'}</span>` : ''}
494
+ ${promoted[`${a.owner || session.owner}/${a.filename || a.name}`] ? html`<span class="badge badge-success" title=${t('profile.apps.promotedBadgeHint') || 'Promoted on your public profile β€” manage the pitch in the app catalog'}>\u{1F4E3} ${t('profile.apps.promotedBadge') || 'Promoted'}</span>` : ''}
483
495
  ${a.operator_hidden ? html`<span class="badge badge-danger">\u{1F6AB} ${t('profile.apps.operatorHiddenBadge') || 'Moderated by operator: hidden'}</span>` : ''}
484
496
  </div>
485
497
  </div>
486
498
  ${a.operator_hidden ? html`<div class="text-meta-sm mb-half">${t('profile.apps.operatorHiddenHint') || 'An operator has hidden this app from public view. Only you can still see it. Contact the operator to appeal.'}${a.operator_hide_reason ? ' β€” ' + escHtml(a.operator_hide_reason) : ''}</div>` : ''}
487
499
  ${a.parked ? html`<div class="text-meta-sm mb-half">${t('profile.apps.parkedHint') || 'Only you can see and use this β€” hidden from the public catalogue.'}</div>` : ''}
488
500
  ${a.manifest?.description ? html`<div class="text-meta mb-half">${escHtml(a.manifest.description)}</div>` : ''}
501
+ ${(() => {
502
+ const pt = promoted[`${a.owner || session.owner}/${a.filename || a.name}`];
503
+ const txt = pt ? (pt[getLocale()] || pt.en || pt.fi || '') : '';
504
+ return txt ? html`<div class="text-meta-sm mb-half">\u{1F4E3} ${escHtml(txt)}</div>` : '';
505
+ })()}
489
506
  <div class="card-subtitle">
490
507
  <a href="${NODE_URL}/v1/apps/${encodeURIComponent(a.owner || session.owner)}/${encodeURIComponent(a.filename || a.name)}" target="_blank">${t('profile.apps.download')}</a>
491
508
  ${a.size ? ' \u2022 ' + Math.round(a.size / 1024) + ' KB' : ''}
@@ -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
  }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @file public/views/profile/inbox-tab/ai-actions.js
3
+ * @description Builds the config objects behind the Inbox thread-head AI actions, so InboxTab's handlers
4
+ * stay one-liners (and the file stays under max-file-lines). Two families:
5
+ * - Reply with AI (TARGET-031): buildConversationReplyProps / buildMessageReplyProps β†’ { title, build }
6
+ * for ReplyWithAiPopover (build(mode) β†’ copy/mcp prompt).
7
+ * - Conversation β†’ Notebook: buildConversationNotebookProps β†’ { title, promptText, runServerSummary,
8
+ * parkConversation } for ConversationToNotebookPopover. runServerSummary calls /v1/ai/complete on the
9
+ * owner's own OpenRouter key (vision-aware, up to 8 images); parkConversation files the whole thread.
10
+ * @structure
11
+ * - collectThreadImages(thread, urlMap) β€” [{messageId,id,name,url}] for every image attachment
12
+ * - buildConversationReplyProps({ activeConv, thread, peerName, peerDisplayName })
13
+ * - buildMessageReplyProps({ activeConv, msg, peerName })
14
+ * - buildConversationNotebookProps({ activeConv, thread, urlMap, peerName, title })
15
+ * @usage
16
+ * import { buildConversationNotebookProps } from './inbox-tab/ai-actions.js';
17
+ * setNbConv(buildConversationNotebookProps({ activeConv, thread, urlMap, peerName, title }));
18
+ * @version-history
19
+ * v1.0.0 — 2026-07-19 — Initial: extracted the Reply-with-AI + Conversation→Notebook assembly from inbox-tab.js.
20
+ */
21
+ import { api } from '/js/api.js';
22
+ import { t } from '/js/i18n.js';
23
+ import { parkConversationToNotebook } from '/js/services/notebook.js';
24
+ import { buildConversationReplyPrompt, buildMessageReplyPrompt, buildConversationSummaryPrompt } from '/js/services/messages-ai-prompts.js';
25
+ import { attachKind } from './helpers.js';
26
+
27
+ /** Reply-with-AI props for the whole open conversation (ReplyWithAiPopover: build(mode) β†’ prompt). */
28
+ export function buildConversationReplyProps({ activeConv, thread, peerName, peerDisplayName }) {
29
+ const src = { peerGhii: activeConv.peerGhii, subject: activeConv.subject, conversationId: activeConv.conversationId, thread, peerName };
30
+ return { title: `${t('inbox.ai.replyTo')} ${peerDisplayName}`, build: (mode) => buildConversationReplyPrompt(src, mode) };
31
+ }
32
+
33
+ /** Reply-with-AI props scoped to one message the user pointed at. */
34
+ export function buildMessageReplyProps({ activeConv, msg, peerName }) {
35
+ const src = { peerGhii: activeConv.peerGhii, subject: activeConv.subject, conversationId: activeConv.conversationId, message: msg, peerName };
36
+ return { title: t('inbox.ai.replyToMessage'), build: (mode) => buildMessageReplyPrompt(src, mode) };
37
+ }
38
+
39
+ /** Every image attachment across the loaded thread, resolved to a viewable url (urlMap is keyed
40
+ * `${messageId}::${attachmentId}`). Used both for the vision summary call and the notebook embeds. */
41
+ export function collectThreadImages(msgs, urls) {
42
+ const out = [];
43
+ for (const m of (msgs || [])) {
44
+ for (const a of (m.attachments || [])) {
45
+ if (attachKind(a) !== 'image' || a.expired) continue;
46
+ const url = urls[`${m.id}::${a.id}`];
47
+ if (url) out.push({ messageId: m.id, id: a.id, name: a.name || a.storageKey || 'image', url });
48
+ }
49
+ }
50
+ return out;
51
+ }
52
+
53
+ /**
54
+ * Build the ConversationToNotebookPopover config for the open thread: the summary prompt, plus the
55
+ * server-summary and park callbacks (the popover picks the mode and calls back).
56
+ * @param {object} args
57
+ * @param {{ conversationId?:string, peerGhii?:string, subject?:string }} args.activeConv
58
+ * @param {Array} args.thread
59
+ * @param {Record<string,string>} args.urlMap
60
+ * @param {string} [args.peerName]
61
+ * @param {string} args.title
62
+ */
63
+ export function buildConversationNotebookProps({ activeConv, thread, urlMap, peerName, title }) {
64
+ const src = { peerGhii: activeConv.peerGhii, subject: activeConv.subject, thread, peerName };
65
+ const images = collectThreadImages(thread, urlMap);
66
+ const promptText = buildConversationSummaryPrompt(src);
67
+ // Server-side summary on the owner's own OpenRouter key. Text-only on purpose: the thread's image
68
+ // attachments are JWT-presigned `/v1/download/…` urls that OpenRouter's servers can't fetch (β†’ 502),
69
+ // so we never send them to the model. The images are still captured into the notebook entry below
70
+ // (transcript embeds + source.attachments) for the owner to view; the durable value is the text.
71
+ const runServerSummary = async () => {
72
+ const resp = await api('/v1/ai/complete', {
73
+ method: 'POST',
74
+ body: JSON.stringify({ prompt: promptText }),
75
+ timeoutMs: 1_800_000,
76
+ retries: 0,
77
+ });
78
+ if (resp?.ok === false) throw new Error(resp.error?.message || t('inbox.failed'));
79
+ return resp?.data?.content || '';
80
+ };
81
+ const parkConversation = ({ summary }) => parkConversationToNotebook({
82
+ conv: { conversationId: activeConv.conversationId, peerGhii: activeConv.peerGhii, subject: activeConv.subject },
83
+ thread, peerName, summary, images,
84
+ });
85
+ return { title, promptText, runServerSummary, parkConversation };
86
+ }
@@ -6,6 +6,10 @@
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).
11
+ * v1.8.0 β€” 2026-07-21 β€” MessageBubble renders link-preview cards under the body (MessageLinkPreviews),
12
+ * gated by the `showLinkPreviews` prop (the persisted thread-head toggle).
9
13
  * v1.0.0 β€” 2026-07-13 β€” Extracted from inbox-tab.js (max-file-lines)
10
14
  * v1.1.0 β€” 2026-07-14 β€” Composer: pasted/dropped images route to the file-attachment path (upload +
11
15
  * shown as an image) instead of Toast UI base64-inlining them into the body (which blew the 50k
@@ -22,14 +26,20 @@
22
26
  * v1.5.0 β€” 2026-07-18 β€” Mobile composer is a plain auto-growing textarea (`mode:'simple'`, no Toast UI
23
27
  * toolbar/Write-Preview/WYSIWYG β€” a phone keyboard + heavy WYSIWYG is miserable); ≀760px opens straight
24
28
  * into it so Toast UI never even loads there. Desktop keeps the rich editor.
29
+ * v1.6.0 β€” 2026-07-19 β€” Composer gets an expand toggle (β€’/‑): enlarges the editor to ~60% of the
30
+ * viewport so long/formatted drafts are fully visible. Rich mode resizes via Toast UI `setHeight`;
31
+ * the markdown fallback + simple textarea grow via the `.inbox-composer--tall` class / lifted cap.
32
+ * v1.7.0 β€” 2026-07-19 β€” ConversationToNotebookPopover: capture a whole thread (with images) into the
33
+ * Notebook via three modes β€” server-side AI summary (owner's key), copy-prompt (own chat), or raw.
25
34
  */
26
35
  import { h } from 'preact';
27
36
  import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
28
37
  import htm from 'htm';
29
38
  const html = htm.bind(h);
30
39
  import { t } from '/js/i18n.js';
31
- import { escHtml } from '/js/utils.js';
40
+ import { escHtml, copyToClipboard } from '/js/utils.js';
32
41
  import { Markdown } from '/components/Markdown.js';
42
+ import { MessageLinkPreviews } from '/components/LinkPreview.js';
33
43
  import { minidenticon } from '/lib/minidenticons.min.js';
34
44
  import * as schedules from '/js/services/schedules.js';
35
45
  import { MODES } from '/js/services/messages-ai-prompts.js';
@@ -243,7 +253,18 @@ export function PollBuilder({ questions, setQuestions }) {
243
253
  </div>`;
244
254
  }
245
255
 
246
- export function MessageBubble({ msg, mine, urlMap, starred, onStar, onTrack, onPark, onReplyAi, onQuote, quoted, quotedName, onJumpTo, domId, tracked, onOpenMarkdown, answeredWith, onAnswer, submitting }) {
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
+ };
247
268
  const nonInline = (msg.attachments || []).filter(a => !a.inline);
248
269
  const expiredIds = new Set((msg.attachments || []).filter(a => a.expired).map(a => a.id));
249
270
  // urlMap is keyed by `${messageId}::${attachmentId}` because per-message attachment ids (at0, at1…)
@@ -262,6 +283,9 @@ export function MessageBubble({ msg, mine, urlMap, starred, onStar, onTrack, onP
262
283
  <div class="inbox-bubble-actions">
263
284
  ${onQuote ? html`<button class="inbox-bubble-act" title=${t('inbox.quoteReply')}
264
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>
265
289
  <button class=${`inbox-bubble-act${starred ? ' inbox-bubble-act--on' : ''}`} title=${t('inbox.markImportant')}
266
290
  onClick=${() => onStar?.(msg)}>${starred ? '⭐' : 'β˜†'}</button>
267
291
  <button class=${`inbox-bubble-act${tracked ? ' inbox-bubble-act--on' : ''}`}
@@ -277,6 +301,7 @@ export function MessageBubble({ msg, mine, urlMap, starred, onStar, onTrack, onP
277
301
  <span class="inbox-quote-text">${escHtml(quoteSnippet(quoted.body))}</span>
278
302
  </button>` : null}
279
303
  <div class="inbox-bubble-body"><${Markdown} text=${prepareBody(msg.body, urls, expiredIds)} /></div>
304
+ ${showLinkPreviews ? html`<${MessageLinkPreviews} msg=${msg} />` : null}
280
305
  ${msg.interactive?.role === 'questions' ? (
281
306
  answeredWith
282
307
  ? html`<${InteractiveAnswered} spec=${msg.interactive} answers=${answeredWith.answers || {}} />`
@@ -310,6 +335,8 @@ export function Composer({ recipient, sendLabel, sending, onSend, initialText =
310
335
  const isNarrow = typeof window !== 'undefined' && window.matchMedia?.('(max-width: 760px)').matches;
311
336
  const [mode, setMode] = useState(isNarrow ? 'simple' : 'rich');
312
337
  const [md, setMd] = useState(seeded);
338
+ // Temporarily enlarge the editor (~60% of the viewport) so long/formatted drafts are fully visible.
339
+ const [expanded, setExpanded] = useState(false);
313
340
  const [files, setFiles] = useState([]);
314
341
  const containerRef = useRef(null);
315
342
  const editorRef = useRef(null);
@@ -419,10 +446,26 @@ export function Composer({ recipient, sendLabel, sending, onSend, initialText =
419
446
  // eslint-disable-next-line react-hooks/exhaustive-deps
420
447
  }, [focusNonce]);
421
448
 
422
- // Auto-grow the simple (mobile) textarea to fit its content, capped so it never eats the thread.
423
- const autoGrow = (ta) => { if (!ta) return; ta.style.height = 'auto'; ta.style.height = Math.min(ta.scrollHeight, 132) + 'px'; };
424
- // Size the simple textarea to any seeded draft on mount (and keep it 1 row when empty).
425
- useEffect(() => { if (mode === 'simple') autoGrow(taRef.current); }, [mode]);
449
+ // Resize the Toast UI editor when the expand toggle flips (rich mode sets its own inline height via
450
+ // JS, so a CSS class can't reach it β€” the fallback/simple textareas are sized by `.inbox-composer--tall`
451
+ // in CSS instead). `160px` matches the construction default.
452
+ useEffect(() => {
453
+ if (mode !== 'rich' || !editorRef.current?.setHeight) return;
454
+ const tall = typeof window !== 'undefined' ? Math.round(window.innerHeight * 0.6) : 400;
455
+ try { editorRef.current.setHeight(expanded ? tall + 'px' : '160px'); } catch { /* noop */ }
456
+ }, [expanded, mode]);
457
+
458
+ // Auto-grow the simple (mobile) textarea to fit its content, capped so it never eats the thread. When
459
+ // expanded, the cap lifts to ~60vh so a long draft is fully visible.
460
+ const autoGrow = (ta) => {
461
+ if (!ta) return;
462
+ const cap = expanded && typeof window !== 'undefined' ? Math.round(window.innerHeight * 0.6) : 132;
463
+ ta.style.height = 'auto'; ta.style.height = Math.min(ta.scrollHeight, cap) + 'px';
464
+ };
465
+ // Size the simple textarea to any seeded draft on mount (and keep it 1 row when empty); re-fit when the
466
+ // expand cap changes.
467
+ // eslint-disable-next-line react-hooks/exhaustive-deps
468
+ useEffect(() => { if (mode === 'simple') autoGrow(taRef.current); }, [mode, expanded]);
426
469
 
427
470
  const getText = () => (mode === 'rich' && editorRef.current) ? editorRef.current.getMarkdown() : md;
428
471
  const reset = () => {
@@ -441,7 +484,7 @@ export function Composer({ recipient, sendLabel, sending, onSend, initialText =
441
484
  });
442
485
 
443
486
  return html`
444
- <div class="inbox-composer">
487
+ <div class="inbox-composer ${expanded ? 'inbox-composer--tall' : ''}">
445
488
  ${files.length > 0 ? html`<div class="inbox-file-chips">
446
489
  ${files.map((f, i) => html`<span class="inbox-file-chip" key=${f.name + i}>πŸ“Ž ${escHtml(f.name)}
447
490
  <button class="inbox-bc-chip-x" title=${t('inbox.attachmentRemove')} onClick=${() => removeFile(i)}>βœ•</button></span>`)}
@@ -459,9 +502,13 @@ export function Composer({ recipient, sendLabel, sending, onSend, initialText =
459
502
  <div class="inbox-md-preview"><${Markdown} text=${md} /></div>
460
503
  </div>`}
461
504
  <div class="inbox-composer-bar">
462
- <label class="inbox-attach-btn" title=${t('inbox.attach')}>
463
- πŸ“Ž<input ref=${fileRef} type="file" multiple hidden onChange=${(e) => setFiles(Array.from(e.target.files || []))} />
464
- </label>
505
+ <div class="inbox-bar-left">
506
+ <label class="inbox-attach-btn" title=${t('inbox.attach')}>
507
+ πŸ“Ž<input ref=${fileRef} type="file" multiple hidden onChange=${(e) => setFiles(Array.from(e.target.files || []))} />
508
+ </label>
509
+ <button type="button" class="inbox-attach-btn" title=${expanded ? t('inbox.collapse') : t('inbox.expand')}
510
+ aria-pressed=${expanded} onClick=${() => setExpanded((v) => !v)}>${expanded ? '‑' : '‒'}</button>
511
+ </div>
465
512
  <button class="btn-primary btn-sm" disabled=${sending || !recipient} onClick=${submit}>
466
513
  ${sending ? t('inbox.sending') : sendLabel}
467
514
  </button>
@@ -590,3 +637,87 @@ export function ReplyWithAiPopover({ title, build, onClose, showToast }) {
590
637
  </div>
591
638
  </div>`;
592
639
  }
640
+
641
+ /* ── Conversation β†’ Notebook β€” capture a WHOLE thread (with its images) into the notebook for later
642
+ * filing/enrichment into a workspace. Three modes, all landing in parkConversationToNotebook:
643
+ * ✨ ai β€” summarize server-side with the owner's own OpenRouter key (runServerSummary), edit, park.
644
+ * πŸ“‹ copy β€” copy the summary prompt into the owner's own AI chat, paste the result back, park.
645
+ * πŸ“₯ raw β€” park the whole chain (text + images) as-is; enrich it later in the Notebook.
646
+ * The parent (InboxTab) owns the async work (AI call + park + toasts) via the passed callbacks. ── */
647
+ export function ConversationToNotebookPopover({ title, promptText, runServerSummary, parkConversation, onClose, showToast }) {
648
+ const [mode, setMode] = useState('ai'); // 'ai' | 'copy' | 'raw'
649
+ const [copied, setCopied] = useState(false);
650
+ const [aiSummary, setAiSummary] = useState('');
651
+ const [pasted, setPasted] = useState('');
652
+ const [running, setRunning] = useState(false);
653
+ const [parking, setParking] = useState(false);
654
+
655
+ const copy = async () => {
656
+ try {
657
+ if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(promptText);
658
+ else { const ta = document.createElement('textarea'); ta.value = promptText; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); }
659
+ setCopied(true); setTimeout(() => setCopied(false), 1800);
660
+ showToast?.(t('inbox.ai.copied'));
661
+ } catch { showToast?.(t('inbox.failed'), true); }
662
+ };
663
+
664
+ const genSummary = async () => {
665
+ setRunning(true);
666
+ try {
667
+ const s = await runServerSummary();
668
+ if (s && s.trim()) setAiSummary(s.trim());
669
+ else showToast?.(t('inbox.notebook.summaryEmpty'), true);
670
+ } catch (e) { showToast?.(e?.message || t('inbox.failed'), true); }
671
+ finally { setRunning(false); }
672
+ };
673
+
674
+ const doPark = async (summary) => {
675
+ setParking(true);
676
+ try { await parkConversation({ summary: summary || '' }); showToast?.(t('inbox.notebook.parked')); onClose(); }
677
+ catch (e) { showToast?.(e?.message || t('inbox.failed'), true); setParking(false); }
678
+ };
679
+
680
+ return html`
681
+ <div class="inbox-ai-overlay" onClick=${onClose}>
682
+ <div class="inbox-ai-modal" onClick=${(e) => e.stopPropagation()}>
683
+ <div class="inbox-ai-head">
684
+ <span class="inbox-ai-title">πŸ““ ${title}</span>
685
+ <button class="btn-ghost btn-sm" onClick=${onClose} title=${t('inbox.close')}>βœ•</button>
686
+ </div>
687
+ <div class="inbox-ai-modes">
688
+ <button class=${`inbox-ai-mode${mode === 'ai' ? ' inbox-ai-mode--on' : ''}`} onClick=${() => setMode('ai')}>✨ ${t('inbox.notebook.modeAi')}</button>
689
+ <button class=${`inbox-ai-mode${mode === 'copy' ? ' inbox-ai-mode--on' : ''}`} onClick=${() => setMode('copy')}>πŸ“‹ ${t('inbox.notebook.modeCopy')}</button>
690
+ <button class=${`inbox-ai-mode${mode === 'raw' ? ' inbox-ai-mode--on' : ''}`} onClick=${() => setMode('raw')}>πŸ“₯ ${t('inbox.notebook.modeRaw')}</button>
691
+ </div>
692
+ ${mode === 'ai' ? html`
693
+ <div class="inbox-ai-hint">${t('inbox.notebook.hintAi')}</div>
694
+ ${!aiSummary ? html`
695
+ <div class="inbox-ai-actions">
696
+ <button class="btn-primary btn-sm" disabled=${running} onClick=${genSummary}>${running ? '… ' + t('inbox.notebook.summarizing') : '✨ ' + t('inbox.notebook.genSummary')}</button>
697
+ </div>`
698
+ : html`
699
+ <textarea class="inbox-ai-text" rows="12" value=${aiSummary} onInput=${(e) => setAiSummary(e.target.value)}></textarea>
700
+ <div class="inbox-ai-actions">
701
+ <button class="btn-ghost btn-sm" disabled=${running} onClick=${genSummary}>${running ? '…' : '↻ ' + t('inbox.notebook.regen')}</button>
702
+ <button class="btn-primary btn-sm" disabled=${parking} onClick=${() => doPark(aiSummary)}>${parking ? '…' : 'πŸ““ ' + t('inbox.notebook.park')}</button>
703
+ </div>`}
704
+ ` : mode === 'copy' ? html`
705
+ <div class="inbox-ai-hint">${t('inbox.notebook.hintCopy')}</div>
706
+ <textarea class="inbox-ai-text" readOnly rows="8" value=${promptText}></textarea>
707
+ <div class="inbox-ai-actions">
708
+ <button class="btn-primary btn-sm" onClick=${copy}>${copied ? 'βœ“ ' + t('inbox.ai.copied') : 'πŸ“‹ ' + t('inbox.ai.copy')}</button>
709
+ </div>
710
+ <div class="inbox-ai-hint">${t('inbox.notebook.pasteHint')}</div>
711
+ <textarea class="inbox-ai-text" rows="8" placeholder=${t('inbox.notebook.pastePh')} value=${pasted} onInput=${(e) => setPasted(e.target.value)}></textarea>
712
+ <div class="inbox-ai-actions">
713
+ <button class="btn-primary btn-sm" disabled=${parking || !pasted.trim()} onClick=${() => doPark(pasted)}>${parking ? '…' : 'πŸ““ ' + t('inbox.notebook.park')}</button>
714
+ </div>
715
+ ` : html`
716
+ <div class="inbox-ai-hint">${t('inbox.notebook.hintRaw')}</div>
717
+ <div class="inbox-ai-actions">
718
+ <button class="btn-primary btn-sm" disabled=${parking} onClick=${() => doPark('')}>${parking ? '…' : 'πŸ“₯ ' + t('inbox.notebook.parkRaw')}</button>
719
+ </div>
720
+ `}
721
+ </div>
722
+ </div>`;
723
+ }
@@ -5,11 +5,37 @@
5
5
  * pixel defense), tracked-state labels, attachment classification, the interactive-answer summary +
6
6
  * poll tally, and the lazy Toast UI editor loader. Extracted from inbox-tab.js to satisfy max-file-lines.
7
7
  * @version-history
8
+ * v1.2.0 β€” 2026-07-21 β€” resolveThreadAttachmentUrls(): resolve non-inline attachment URLs for a loaded
9
+ * thread (reusing the previous conversation's cache), extracted from inbox-tab loadThread.
8
10
  * v1.1.0 β€” 2026-07-17 β€” quoteSnippet(): one-line plain-text excerpt of a message body for reply-quotes.
9
11
  * v1.0.0 β€” 2026-07-13 β€” Extracted from inbox-tab.js (max-file-lines)
10
12
  */
11
13
  import { t, getLocale } from '/js/i18n.js';
12
14
 
15
+ /**
16
+ * Resolve presigned URLs for a thread's non-inline attachments, reusing already-resolved URLs from the
17
+ * SAME conversation's previous cache (a refresh/new message must not re-download every existing image).
18
+ * Keyed by `${messageId}::${attachmentId}` (per-message ids repeat across messages). Inbound resolves the
19
+ * recipient's duplicated local copy; outbound resolves the original. `resolveUrl` = messages.attachmentUrl.
20
+ * Returns { convId, map } to store as the new cache.
21
+ */
22
+ export async function resolveThreadAttachmentUrls(msgs, conversationId, prevCache, resolveUrl) {
23
+ const prev = prevCache?.convId === conversationId ? (prevCache.map || {}) : {};
24
+ const map = {};
25
+ await Promise.all(msgs.flatMap(m => (m.attachments || [])
26
+ .filter(a => !a.inline)
27
+ .map(async a => {
28
+ const uk = `${m.id}::${a.id}`;
29
+ if (prev[uk]) { map[uk] = prev[uk]; return; }
30
+ const key = (a.mode === 'duplicate' && a.localKey) ? a.localKey
31
+ : (m.direction === 'outbound' && a.storageKey) ? a.storageKey : null;
32
+ if (!key) return;
33
+ const u = await resolveUrl(key).catch(() => null);
34
+ if (u) map[uk] = u;
35
+ })));
36
+ return { convId: conversationId, map };
37
+ }
38
+
13
39
  /* Lazy-load the vendored Toast UI Editor (MIT, /lib/toastui/) β€” the same editor the workspace
14
40
  * document space uses, so composing a message feels like editing a document (Markdown⇄WYSIWYG).
15
41
  * ~520KB, so it stays out of the main bundle and loads only when the Inbox composer mounts. */
@@ -6,6 +6,11 @@
6
6
  * (broadcast/poll results). Each is a presentational component driven entirely by props from InboxTab;
7
7
  * the stateful container keeps all hooks. Extracted from inbox-tab.js to satisfy max-file-lines.
8
8
  * @version-history
9
+ * v1.4.0 β€” 2026-07-21 β€” ThreadPanel head: "Show all messages / Last 50" toggle (threadAll/
10
+ * toggleThreadAll), shown once a thread has β‰₯50 messages. Threads default to the full history;
11
+ * the toggle collapses to the newest 50.
12
+ * v1.3.0 β€” 2026-07-21 β€” ThreadPanel: link-preview toggle button in the head (showLinkPreviews /
13
+ * toggleLinkPreviews) + passes the flag down to each MessageBubble.
9
14
  * v1.2.0 β€” 2026-07-18 β€” Clicking ↩ Reply on a bubble now focuses the composer (via `onQuoteReply` +
10
15
  * `composerFocus` bump) so the cursor lands in the input; the βœ• cancel still uses the raw setter.
11
16
  * v1.1.0 β€” 2026-07-17 β€” Reply-to with quote: ThreadPanel resolves each message's `replyToId` to the
@@ -99,8 +104,9 @@ export function ThreadPanel({
99
104
  activeConv, thread, urlMap, important, trackedByMsg, awaitingForConv, awaitingDrafts,
100
105
  schedOpen, setSchedOpen, cmdFill, agentCommands, sending, draftPrefill, prefillNonce, msgsRef,
101
106
  peerDisplay, showToast, toggleImportant, onTrackMsg, onParkMsg, openMessageAi, submitInteractiveAnswers,
102
- setMdViewer, openConversationAi, insertCommand, setCmdFill, cancelTracked, openRecord, startSuggestedReply, doSend,
103
- replyQuote, setReplyQuote, onQuoteReply, composerFocus,
107
+ setMdViewer, openConversationAi, openConversationNotebook, insertCommand, setCmdFill, cancelTracked, openRecord, startSuggestedReply, doSend,
108
+ replyQuote, setReplyQuote, onQuoteReply, composerFocus, showLinkPreviews, toggleLinkPreviews,
109
+ threadAll, toggleThreadAll,
104
110
  }) {
105
111
  let lastDay = '';
106
112
  // Reply-to quotes: resolve a message's `replyToId` to the original within the loaded page (a parent
@@ -142,6 +148,15 @@ export function ThreadPanel({
142
148
  <div class="inbox-sub">${escHtml(activeConv.peerGhii)}</div>
143
149
  </div>
144
150
  ${!viaAgentName ? html`<button class="btn-ghost btn-sm inbox-ai-btn" onClick=${openConversationAi} title=${t('inbox.ai.replyWithAi')}>✨ <span class="inbox-ai-btn-label">${t('inbox.ai.replyWithAi')}</span></button>` : null}
151
+ ${!viaAgentName ? html`<button class="btn-ghost btn-sm inbox-ai-btn" onClick=${openConversationNotebook} title=${t('inbox.notebook.toNotebook')}>πŸ““ <span class="inbox-ai-btn-label">${t('inbox.notebook.toNotebookShort')}</span></button>` : null}
152
+ <button class=${`btn-ghost btn-sm inbox-linkprev-toggle${showLinkPreviews ? ' inbox-linkprev-toggle--on' : ''}`}
153
+ aria-pressed=${!!showLinkPreviews} onClick=${toggleLinkPreviews}
154
+ title=${showLinkPreviews ? t('inbox.linkPreview.hideAll') : t('inbox.linkPreview.showAll')}>
155
+ <span class="inbox-ai-btn-label">${t('inbox.linkPreview.label')}</span></button>
156
+ ${(thread.length >= 50) ? html`<button class=${`btn-ghost btn-sm inbox-linkprev-toggle${threadAll ? ' inbox-linkprev-toggle--on' : ''}`}
157
+ aria-pressed=${!!threadAll} onClick=${toggleThreadAll}
158
+ title=${threadAll ? t('inbox.thread.showRecent') : t('inbox.thread.showAll')}>
159
+ <span class="inbox-ai-btn-label">${threadAll ? t('inbox.thread.showRecent') : t('inbox.thread.showAll')}</span></button>` : null}
145
160
  ${peerIsMyAgent && !viaAgentName ? html`<button class=${`btn-ghost btn-sm inbox-sched-btn${schedOpen ? ' inbox-sched-btn--on' : ''}`}
146
161
  onClick=${() => setSchedOpen(o => !o)} title=${t('inbox.schedTitle')}>πŸ“…</button>` : null}
147
162
  </div>
@@ -159,7 +174,7 @@ export function ThreadPanel({
159
174
  onQuote=${(onQuoteReply && !activeConv.viaAgent) ? onQuoteReply : null}
160
175
  starred=${important.has(m.id)} onStar=${toggleImportant} onTrack=${onTrackMsg} onPark=${onParkMsg} onReplyAi=${openMessageAi} tracked=${trackedByMsg[m.id]}
161
176
  answeredWith=${m.interactive?.role === 'questions' ? answersByQ[m.id] : null}
162
- onAnswer=${submitInteractiveAnswers} submitting=${sending}
177
+ onAnswer=${submitInteractiveAnswers} submitting=${sending} showLinkPreviews=${showLinkPreviews}
163
178
  onOpenMarkdown=${(url, name) => setMdViewer({ url, name })} />`;
164
179
  })}
165
180
  </div>