@agent-native/core 0.141.7 → 0.144.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 (328) hide show
  1. package/agent-native.eject.json +9 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
  4. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
  5. package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  6. package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
  7. package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  8. package/corpus/templates/analytics/AGENTS.md +35 -38
  9. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
  10. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
  11. package/corpus/templates/analytics/actions/navigate.ts +4 -5
  12. package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
  13. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
  14. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
  15. package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
  16. package/corpus/templates/analytics/app/i18n-data.ts +680 -0
  17. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
  18. package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
  19. package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
  20. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
  21. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
  22. package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
  23. package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
  25. package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
  26. package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
  27. package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
  28. package/corpus/templates/analytics/netlify.toml +7 -0
  29. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
  30. package/corpus/templates/analytics/server/db/index.ts +27 -0
  31. package/corpus/templates/analytics/server/db/schema.ts +10 -0
  32. package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
  33. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +133 -44
  34. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
  35. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  36. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
  37. package/corpus/templates/analytics/server/plugins/db.ts +52 -18
  38. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +28 -2
  39. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
  40. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
  41. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  42. package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
  43. package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  44. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
  45. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  46. package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
  47. package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  48. package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
  49. package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
  50. package/corpus/templates/brain/app/routes/sources.tsx +15 -7
  51. package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
  52. package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
  53. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
  54. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
  55. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  56. package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
  57. package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  58. package/corpus/templates/calendar/AGENTS.md +11 -32
  59. package/corpus/templates/calendar/actions/update-event.ts +107 -1
  60. package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
  61. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
  62. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
  63. package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
  64. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  65. package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  66. package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
  67. package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
  68. package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
  69. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  70. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  71. package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  72. package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  73. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
  74. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  75. package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
  76. package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  77. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
  78. package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
  79. package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
  80. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
  81. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
  82. package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
  83. package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
  84. package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
  86. package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
  87. package/corpus/templates/clips/desktop/src/app.tsx +48 -20
  88. package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
  89. package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
  90. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
  91. package/corpus/templates/clips/server/plugins/db.ts +214 -26
  92. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
  93. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  94. package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
  95. package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  96. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
  97. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  98. package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
  99. package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  100. package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
  101. package/corpus/templates/crm/server/plugins/db.ts +11 -8
  102. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
  103. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
  104. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  105. package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
  106. package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  107. package/corpus/templates/design/actions/import-from-url.ts +1 -1
  108. package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
  109. package/corpus/templates/design/app/pages/Index.tsx +6 -2
  110. package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
  111. package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
  112. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  113. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
  114. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  115. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
  116. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  117. package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
  118. package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
  119. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
  120. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  121. package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
  122. package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  123. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
  124. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  125. package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
  126. package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  127. package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  128. package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
  129. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
  130. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  131. package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
  132. package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  133. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
  134. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  135. package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
  136. package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  137. package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  138. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  139. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
  140. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  141. package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
  142. package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  143. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
  144. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
  145. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
  146. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
  147. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
  148. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
  149. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  150. package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
  151. package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  152. package/corpus/templates/slides/AGENTS.md +7 -9
  153. package/corpus/templates/slides/_gitignore +1 -0
  154. package/corpus/templates/slides/actions/export-pptx.ts +402 -36
  155. package/corpus/templates/slides/actions/import-file.ts +46 -85
  156. package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
  157. package/corpus/templates/slides/actions/import-pptx.ts +85 -60
  158. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
  159. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
  160. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
  161. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
  162. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
  163. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
  164. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +173 -0
  165. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
  166. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
  167. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
  168. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
  169. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
  170. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +4 -0
  171. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
  172. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  173. package/corpus/templates/slides/app/lib/create-deck-generation.ts +1 -1
  174. package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
  175. package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
  176. package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
  177. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
  178. package/corpus/templates/slides/app/pages/Index.tsx +91 -1
  179. package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
  180. package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
  181. package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
  182. package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
  183. package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
  184. package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
  185. package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
  186. package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
  187. package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
  188. package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
  189. package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
  190. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
  191. package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
  192. package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
  193. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
  194. package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
  195. package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
  196. package/corpus/templates/slides/server/lib/emails.ts +7 -2
  197. package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
  198. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
  199. package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
  200. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  201. package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
  202. package/corpus/templates/slides/shared/upload-types.ts +3 -0
  203. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
  204. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  205. package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
  206. package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  207. package/dist/agent/production-agent.d.ts +17 -0
  208. package/dist/agent/production-agent.js +72 -1
  209. package/dist/cli/agent-plugin.d.ts +112 -0
  210. package/dist/cli/agent-plugin.js +1081 -0
  211. package/dist/cli/app-skill.js +39 -1
  212. package/dist/cli/code-agent-executor.d.ts +3 -0
  213. package/dist/cli/code-agent-executor.js +51 -13
  214. package/dist/cli/index.js +13 -0
  215. package/dist/cli/templates-meta.js +1 -1
  216. package/dist/client/AgentPanel.d.ts +3 -1
  217. package/dist/client/AgentPanel.js +9 -2
  218. package/dist/client/AssistantChat.d.ts +8 -0
  219. package/dist/client/AssistantChat.js +23 -8
  220. package/dist/client/NewWorkspaceAppFlow.js +1 -0
  221. package/dist/client/agent-chat-adapter.js +123 -4
  222. package/dist/client/assistant-ui-recovery.d.ts +2 -1
  223. package/dist/client/assistant-ui-recovery.js +7 -3
  224. package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
  225. package/dist/client/org/TeamPage.js +1 -1
  226. package/dist/client/require-session.js +1 -1
  227. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  228. package/dist/client/resources/McpConnectionSuggestion.js +27 -10
  229. package/dist/client/resources/McpIntegrationDialog.js +77 -45
  230. package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
  231. package/dist/client/resources/mcp-integration-catalog.js +255 -2
  232. package/dist/client/resources/mcp-integration-logos.js +18 -2
  233. package/dist/client/settings/AccountSettingsCard.js +2 -1
  234. package/dist/collab/routes.d.ts +1 -1
  235. package/dist/collab/struct-routes.d.ts +1 -1
  236. package/dist/db/client.d.ts +9 -0
  237. package/dist/db/client.js +51 -16
  238. package/dist/db/create-get-db.js +2 -2
  239. package/dist/db/ddl-guard.d.ts +11 -10
  240. package/dist/db/ddl-guard.js +40 -12
  241. package/dist/deploy/build.d.ts +2 -0
  242. package/dist/deploy/build.js +97 -4
  243. package/dist/deploy/workspace-deploy.js +0 -2
  244. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  245. package/dist/guards/no-env-credentials.js +9 -0
  246. package/dist/ingestion/index.d.ts +1 -1
  247. package/dist/ingestion/pptx.d.ts +68 -0
  248. package/dist/ingestion/pptx.js +660 -213
  249. package/dist/integrations/plugin.js +9 -6
  250. package/dist/localization/default-messages.d.ts +54 -0
  251. package/dist/localization/default-messages.js +57 -2
  252. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  253. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  254. package/dist/mcp-client/oauth-routes.js +73 -6
  255. package/dist/notifications/routes.d.ts +1 -1
  256. package/dist/observability/routes.d.ts +3 -3
  257. package/dist/onboarding/app-profile.js +11 -0
  258. package/dist/resources/handlers.d.ts +1 -1
  259. package/dist/resources/store.js +15 -1
  260. package/dist/scripts/call-agent.js +34 -4
  261. package/dist/secrets/routes.d.ts +9 -9
  262. package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
  263. package/dist/server/agent-chat/action-filters-a2a.js +36 -1
  264. package/dist/server/agent-chat-plugin.js +29 -8
  265. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  266. package/dist/server/auth.js +47 -11
  267. package/dist/server/better-auth-instance.js +5 -3
  268. package/dist/server/core-routes-plugin.d.ts +8 -1
  269. package/dist/server/core-routes-plugin.js +28 -3
  270. package/dist/server/credential-provider.d.ts +3 -3
  271. package/dist/server/credential-provider.js +90 -4
  272. package/dist/server/onboarding-html.d.ts +2 -0
  273. package/dist/server/onboarding-html.js +115 -29
  274. package/dist/server/self-dispatch.d.ts +5 -4
  275. package/dist/server/self-dispatch.js +25 -14
  276. package/dist/server/ssr-handler.d.ts +1 -1
  277. package/dist/server/ssr-handler.js +1 -1
  278. package/dist/server/transcribe-voice.d.ts +1 -1
  279. package/dist/shared/cache-control.d.ts +26 -2
  280. package/dist/shared/cache-control.js +43 -2
  281. package/dist/shared/password-policy.d.ts +3 -0
  282. package/dist/shared/password-policy.js +3 -0
  283. package/dist/sharing/actions/set-resource-visibility.js +16 -4
  284. package/dist/sharing/registry.d.ts +14 -0
  285. package/dist/styles/agent-native.css +6 -0
  286. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  287. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  288. package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  289. package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  290. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  291. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  292. package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  293. package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  294. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  295. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  296. package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  297. package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  298. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  299. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  300. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  301. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  302. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  303. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  304. package/dist/templates/workspace-root/AGENTS.md +7 -0
  305. package/dist/user-profile/actions/change-password.js +8 -3
  306. package/dist/user-profile/actions/set-password.js +5 -1
  307. package/dist/vite/action-types-plugin.js +59 -0
  308. package/docs/content/skills-guide.mdx +13 -0
  309. package/package.json +6 -2
  310. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  311. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  312. package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  313. package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  314. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  315. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  316. package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  317. package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  318. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  319. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  320. package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  321. package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  322. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  323. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  324. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  325. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  326. package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  327. package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  328. package/src/templates/workspace-root/AGENTS.md +7 -0
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { getLocaleInitScript } from "../localization/server.js";
10
10
  import { DEFAULT_LOCALE, LOCALE_METADATA, LOCALE_STORAGE_KEY, SUPPORTED_LOCALES, } from "../localization/shared.js";
11
+ import { PASSWORD_MIN_LENGTH } from "../shared/password-policy.js";
11
12
  import { signInJourneyInlineScript } from "../shared/sign-in-journey.js";
12
13
  import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, withAgentNativeSocialImageCacheBuster, } from "../shared/social-meta.js";
13
14
  import { normalizeAppBasePath } from "./app-base-path.js";
@@ -69,7 +70,7 @@ const EN_AUTH_COPY = {
69
70
  email: "Email",
70
71
  password: "Password",
71
72
  confirmPassword: "Confirm password",
72
- passwordMinPlaceholder: "At least 8 characters",
73
+ passwordMinPlaceholder: `At least ${PASSWORD_MIN_LENGTH} characters`,
73
74
  confirmPasswordPlaceholder: "Confirm password",
74
75
  enterPasswordPlaceholder: "Enter password",
75
76
  magicLinkTitle: "Welcome",
@@ -165,7 +166,7 @@ const AUTH_LOCALE_COPY = {
165
166
  email: "电子邮箱",
166
167
  password: "密码",
167
168
  confirmPassword: "确认密码",
168
- passwordMinPlaceholder: "至少 8 个字符",
169
+ passwordMinPlaceholder: `至少 ${PASSWORD_MIN_LENGTH} 个字符`,
169
170
  confirmPasswordPlaceholder: "确认密码",
170
171
  enterPasswordPlaceholder: "输入密码",
171
172
  magicLinkTitle: "欢迎",
@@ -259,7 +260,7 @@ const AUTH_LOCALE_COPY = {
259
260
  email: "電子郵件",
260
261
  password: "密碼",
261
262
  confirmPassword: "確認密碼",
262
- passwordMinPlaceholder: "至少 8 個字元",
263
+ passwordMinPlaceholder: `至少 ${PASSWORD_MIN_LENGTH} 個字元`,
263
264
  confirmPasswordPlaceholder: "確認密碼",
264
265
  enterPasswordPlaceholder: "輸入密碼",
265
266
  magicLinkTitle: "歡迎",
@@ -353,7 +354,7 @@ const AUTH_LOCALE_COPY = {
353
354
  email: "Email",
354
355
  password: "Contraseña",
355
356
  confirmPassword: "Confirmar contraseña",
356
- passwordMinPlaceholder: "Al menos 8 caracteres",
357
+ passwordMinPlaceholder: `Al menos ${PASSWORD_MIN_LENGTH} caracteres`,
357
358
  confirmPasswordPlaceholder: "Confirmar contraseña",
358
359
  enterPasswordPlaceholder: "Introduce la contraseña",
359
360
  magicLinkTitle: "Bienvenido",
@@ -447,7 +448,7 @@ const AUTH_LOCALE_COPY = {
447
448
  email: "E-mail",
448
449
  password: "Mot de passe",
449
450
  confirmPassword: "Confirmer le mot de passe",
450
- passwordMinPlaceholder: "Au moins 8 caractères",
451
+ passwordMinPlaceholder: `Au moins ${PASSWORD_MIN_LENGTH} caractères`,
451
452
  confirmPasswordPlaceholder: "Confirmer le mot de passe",
452
453
  enterPasswordPlaceholder: "Saisir le mot de passe",
453
454
  magicLinkTitle: "Bienvenue",
@@ -541,7 +542,7 @@ const AUTH_LOCALE_COPY = {
541
542
  email: "E-Mail",
542
543
  password: "Passwort",
543
544
  confirmPassword: "Passwort bestätigen",
544
- passwordMinPlaceholder: "Mindestens 8 Zeichen",
545
+ passwordMinPlaceholder: `Mindestens ${PASSWORD_MIN_LENGTH} Zeichen`,
545
546
  confirmPasswordPlaceholder: "Passwort bestätigen",
546
547
  enterPasswordPlaceholder: "Passwort eingeben",
547
548
  magicLinkTitle: "Willkommen",
@@ -635,7 +636,7 @@ const AUTH_LOCALE_COPY = {
635
636
  email: "メール",
636
637
  password: "パスワード",
637
638
  confirmPassword: "パスワードを確認",
638
- passwordMinPlaceholder: "8 文字以上",
639
+ passwordMinPlaceholder: `${PASSWORD_MIN_LENGTH} 文字以上`,
639
640
  confirmPasswordPlaceholder: "パスワードを確認",
640
641
  enterPasswordPlaceholder: "パスワードを入力",
641
642
  magicLinkTitle: "ようこそ",
@@ -729,7 +730,7 @@ const AUTH_LOCALE_COPY = {
729
730
  email: "이메일",
730
731
  password: "비밀번호",
731
732
  confirmPassword: "비밀번호 확인",
732
- passwordMinPlaceholder: "8자 이상",
733
+ passwordMinPlaceholder: `${PASSWORD_MIN_LENGTH}자 이상`,
733
734
  confirmPasswordPlaceholder: "비밀번호 확인",
734
735
  enterPasswordPlaceholder: "비밀번호 입력",
735
736
  magicLinkTitle: "환영합니다",
@@ -823,7 +824,7 @@ const AUTH_LOCALE_COPY = {
823
824
  email: "Email",
824
825
  password: "Senha",
825
826
  confirmPassword: "Confirmar senha",
826
- passwordMinPlaceholder: "Pelo menos 8 caracteres",
827
+ passwordMinPlaceholder: `Pelo menos ${PASSWORD_MIN_LENGTH} caracteres`,
827
828
  confirmPasswordPlaceholder: "Confirmar senha",
828
829
  enterPasswordPlaceholder: "Digite a senha",
829
830
  magicLinkTitle: "Bem-vindo",
@@ -917,7 +918,7 @@ const AUTH_LOCALE_COPY = {
917
918
  email: "ईमेल",
918
919
  password: "पासवर्ड",
919
920
  confirmPassword: "पासवर्ड की पुष्टि करें",
920
- passwordMinPlaceholder: "कम से कम 8 अक्षर",
921
+ passwordMinPlaceholder: `कम से कम ${PASSWORD_MIN_LENGTH} अक्षर`,
921
922
  confirmPasswordPlaceholder: "पासवर्ड की पुष्टि करें",
922
923
  enterPasswordPlaceholder: "पासवर्ड दर्ज करें",
923
924
  magicLinkTitle: "स्वागत है",
@@ -1011,7 +1012,7 @@ const AUTH_LOCALE_COPY = {
1011
1012
  email: "البريد الإلكتروني",
1012
1013
  password: "كلمة المرور",
1013
1014
  confirmPassword: "تأكيد كلمة المرور",
1014
- passwordMinPlaceholder: "8 أحرف على الأقل",
1015
+ passwordMinPlaceholder: `${PASSWORD_MIN_LENGTH} أحرف على الأقل`,
1015
1016
  confirmPasswordPlaceholder: "تأكيد كلمة المرور",
1016
1017
  enterPasswordPlaceholder: "أدخل كلمة المرور",
1017
1018
  magicLinkTitle: "مرحبًا",
@@ -1216,6 +1217,7 @@ export function getOnboardingHtml(opts = {}) {
1216
1217
  const googleOnly = !!opts.googleOnly;
1217
1218
  const authMode = opts.authMode ?? "password";
1218
1219
  const magicLinkMode = authMode === "magic-link";
1220
+ const simplifiedAuth = opts.initialPrompt === true;
1219
1221
  // In a Google-only app, Google is the sole sign-in method, so always render
1220
1222
  // a working button — never gate it on env vars detected at render time. The
1221
1223
  // login page is a public, CDN-cacheable shell served to everyone (per-user
@@ -1234,7 +1236,7 @@ export function getOnboardingHtml(opts = {}) {
1234
1236
  requestHost: opts.requestHost,
1235
1237
  requestPath: opts.requestPath,
1236
1238
  });
1237
- const hasMarketing = !!marketing;
1239
+ const hasMarketing = !!marketing && !simplifiedAuth;
1238
1240
  const marketingSlug = resolveBuiltInMarketingSlug(marketing);
1239
1241
  const defaultMarketingCopy = marketing
1240
1242
  ? {
@@ -1313,6 +1315,13 @@ ${localeMenuItemsHtml}
1313
1315
  const signupLegalNoteHtml = signupLegalNotice
1314
1316
  ? ` <p class="legal-note">${localizedValue(signupLegalNotice.prefix, "legalPrefix")} <a href="${esc(signupLegalNotice.termsUrl)}" target="_blank" rel="noreferrer"${localizedAnchorLabel(signupLegalNotice.termsLabel, "legalTerms")}</a> ${localizedValue(signupLegalNotice.connector, "legalConnector")} <a href="${esc(signupLegalNotice.privacyUrl)}" target="_blank" rel="noreferrer"${localizedAnchorLabel(signupLegalNotice.privacyLabel, "legalPrivacy")}</a>${localizedValue(signupLegalNotice.suffix, "legalSuffix")}</p>`
1315
1317
  : "";
1318
+ const magicLinkSuccessHtml = magicLinkMode
1319
+ ? ` <div class="magic-link-success" id="magic-link-success" aria-live="polite" hidden>
1320
+ <p class="magic-link-success-copy"><span${i18nAttr("magicLinkSentCopy")}>${esc(t("magicLinkSentCopy"))}</span> <strong id="magic-link-success-email"></strong>.</p>
1321
+ <button type="button" class="link-button magic-link-back" id="magic-link-back"${i18nAttr("back")}>${esc(t("back"))}</button>
1322
+ </div>
1323
+ `
1324
+ : "";
1316
1325
  const signupLocalModeNoteHtml = signupLocalModeNote
1317
1326
  ? ` <div class="signup-local-mode-note" id="signup-local-mode-note" data-command="${esc(signupLocalModeNote.command)}">
1318
1327
  <p>${esc(signupLocalModeNote.text)}</p>
@@ -1371,6 +1380,9 @@ ${googleNoticeRunLocalPanelHtml}
1371
1380
  </div>`
1372
1381
  : "";
1373
1382
  const identitySsoHtml = identitySsoLoginButtonHtml();
1383
+ const identitySsoMagicLinkSelector = identitySsoHtml
1384
+ ? " .card.magic-link-complete #identity-sso-btn,\n"
1385
+ : "";
1374
1386
  const identitySsoScript = identitySsoHtml
1375
1387
  ? `
1376
1388
  function __anIdentitySsoUrl() {
@@ -1982,11 +1994,12 @@ ${hasMarketing
1982
1994
  }
1983
1995
  .btn-secondary:hover { color: #bbb; border-color: rgba(255,255,255,0.2); }
1984
1996
  .legal-note {
1985
- margin-top: 0.625rem;
1997
+ margin-top: 0.375rem;
1998
+ margin-bottom: 0.875rem;
1986
1999
  color: #666;
1987
2000
  font-size: 0.6875rem;
1988
2001
  line-height: 1.45;
1989
- text-align: center;
2002
+ text-align: start;
1990
2003
  }
1991
2004
  .legal-note a {
1992
2005
  color: #777;
@@ -2130,6 +2143,40 @@ ${hasMarketing
2130
2143
  .link-button:disabled { cursor: wait; opacity: 0.5; }
2131
2144
  .magic-link-submit { display: none; }
2132
2145
  .magic-link-submit.is-visible { display: block; }
2146
+ .magic-link-success { display: none; }
2147
+ .magic-link-success.is-visible { display: block; }
2148
+ .magic-link-success-copy {
2149
+ margin: 0;
2150
+ color: rgba(255,255,255,0.62); /* guard:allow-raw-color - standalone auth HTML has no app theme token layer */
2151
+ font-size: 0.875rem;
2152
+ line-height: 1.5;
2153
+ }
2154
+ .magic-link-success-copy strong {
2155
+ color: inherit;
2156
+ font-weight: 600;
2157
+ overflow-wrap: anywhere;
2158
+ }
2159
+ .magic-link-back {
2160
+ margin-top: 1.5rem;
2161
+ text-decoration: none;
2162
+ }
2163
+ .btn-google.magic-link-secondary {
2164
+ background: transparent;
2165
+ color: inherit;
2166
+ border: 1px solid rgba(255,255,255,0.16); /* guard:allow-raw-color - standalone auth HTML has no app theme token layer */
2167
+ }
2168
+ .btn-google.magic-link-secondary:hover {
2169
+ background: rgba(255,255,255,0.05); /* guard:allow-raw-color - standalone auth HTML has no app theme token layer */
2170
+ }
2171
+ .card.magic-link-complete .subtitle,
2172
+ .card.magic-link-complete #google-signin,
2173
+ ${identitySsoMagicLinkSelector}
2174
+ .card.magic-link-complete #auth-divider,
2175
+ .card.magic-link-complete #auth-tabs,
2176
+ .card.magic-link-complete #upgrade-note,
2177
+ .card.magic-link-complete .form {
2178
+ display: none;
2179
+ }
2133
2180
  .divider {
2134
2181
  display: flex;
2135
2182
  align-items: center;
@@ -2327,14 +2374,18 @@ ${hasMarketing
2327
2374
  .local-note a { color: #888; text-decoration: none; }
2328
2375
  .local-note a:hover { color: #bbb; }
2329
2376
  ${marketingStyles}
2377
+ /* guard:allow-raw-color - standalone auth HTML has no app theme token layer */
2378
+ body.simplified-auth { background: #141414; }
2379
+ body.simplified-auth .card { border-color: transparent; box-shadow: none; }
2380
+ body.simplified-auth .local-note { display: none !important; }
2330
2381
  </style>
2331
2382
  </head>
2332
- <body${hasMarketing ? ' class="has-marketing"' : ""}>
2383
+ <body${simplifiedAuth ? ' class="simplified-auth"' : hasMarketing ? ' class="has-marketing"' : ""}>
2333
2384
  ${localePickerHtml}
2334
2385
  ${marketingPanelHtml}
2335
2386
  <div class="card">
2336
- <h1 id="heading"${i18nAttr(googleOnly ? "signInTitle" : magicLinkMode ? "magicLinkTitle" : "welcomeTitle")}>${esc(t(googleOnly ? "signInTitle" : magicLinkMode ? "magicLinkTitle" : "welcomeTitle"))}</h1>
2337
- <p class="subtitle" id="subtitle"${i18nAttr(googleOnly ? "googleOnlySubtitle" : magicLinkMode ? "magicLinkSubtitle" : "createAccountSubtitle")}>${esc(t(googleOnly ? "googleOnlySubtitle" : magicLinkMode ? "magicLinkSubtitle" : "createAccountSubtitle"))}</p>
2387
+ <h1 id="heading"${i18nAttr(googleOnly ? "signInTitle" : "welcomeTitle")}>${esc(t(googleOnly ? "signInTitle" : "welcomeTitle"))}</h1>
2388
+ <p class="subtitle" id="subtitle"${i18nAttr(googleOnly ? "googleOnlySubtitle" : "createAccountSubtitle")}>${esc(t(googleOnly ? "googleOnlySubtitle" : "createAccountSubtitle"))}</p>
2338
2389
  <p
2339
2390
  class="upgrade-note"
2340
2391
  id="upgrade-note"
@@ -2358,7 +2409,7 @@ ${googleOnly ? "" : `\n <div class="divider" id="auth-divider"${i18nAttr("divid
2358
2409
  : ""}
2359
2410
  ${googleOnly
2360
2411
  ? ""
2361
- : `${magicLinkMode ? '\n <form id="magic-link-form" class="form">\n <label for="m-email"' + i18nAttr("email") + ">" + esc(t("email")) + '</label>\n <input id="m-email" type="email" autocomplete="email" autofocus placeholder="you@example.com" required />\n <button type="submit" id="magic-link-submit" class="magic-link-submit"' + i18nAttr("sendMagicLink") + ">" + esc(t("sendMagicLink")) + '</button>\n <p class="msg" id="m-msg"></p>\n' + signupLegalNoteHtml + '\n <p style="margin-top:0.75rem;font-size:0.75rem;text-align:center">\n <a href="#" id="use-password-link" class="link-button auth-mode-link"' + i18nAttr("usePasswordInstead") + ">" + esc(t("usePasswordInstead")) + "</a>\n </p>\n </form>\n" : ""} <div class="tabs" id="auth-tabs"${magicLinkMode ? " hidden" : ""}>
2412
+ : `${magicLinkMode ? '\n <form id="magic-link-form" class="form">\n <label for="m-email"' + i18nAttr("email") + ">" + esc(t("email")) + '</label>\n <input id="m-email" type="email" autocomplete="email" autofocus placeholder="you@example.com" required />\n <button type="submit" id="magic-link-submit" class="magic-link-submit"' + i18nAttr("sendMagicLink") + ">" + esc(t("sendMagicLink")) + '</button>\n <p class="msg" id="m-msg"></p>\n' + signupLegalNoteHtml + '\n <p style="margin-top:0.75rem;font-size:0.75rem;text-align:start">\n <a href="#" id="use-password-link" class="link-button auth-mode-link"' + i18nAttr("usePasswordInstead") + ">" + esc(t("usePasswordInstead")) + "</a>\n </p>\n </form>\n" : ""}${magicLinkSuccessHtml} <div class="tabs" id="auth-tabs">
2362
2413
  <button class="tab" data-tab="signup"${i18nAttr("createAccount")}>${esc(t("createAccount"))}</button>
2363
2414
  <button class="tab" data-tab="login"${i18nAttr("signIn")}>${esc(t("signIn"))}</button>
2364
2415
  </div>
@@ -2367,9 +2418,9 @@ ${googleOnly
2367
2418
  <label for="s-email"${i18nAttr("email")}>${esc(t("email"))}</label>
2368
2419
  <input id="s-email" type="email" autocomplete="email" autofocus placeholder="you@example.com" required />
2369
2420
  <label for="s-pass"${i18nAttr("password")}>${esc(t("password"))}</label>
2370
- <input id="s-pass" type="password" autocomplete="new-password" placeholder="${esc(t("passwordMinPlaceholder"))}"${i18nPlaceholderAttr("passwordMinPlaceholder")} required minlength="8" />
2421
+ <input id="s-pass" type="password" autocomplete="new-password" placeholder="${esc(t("passwordMinPlaceholder"))}"${i18nPlaceholderAttr("passwordMinPlaceholder")} required minlength="${PASSWORD_MIN_LENGTH}" />
2371
2422
  <label for="s-pass2"${i18nAttr("confirmPassword")}>${esc(t("confirmPassword"))}</label>
2372
- <input id="s-pass2" type="password" autocomplete="new-password" placeholder="${esc(t("confirmPasswordPlaceholder"))}"${i18nPlaceholderAttr("confirmPasswordPlaceholder")} required minlength="8" />
2423
+ <input id="s-pass2" type="password" autocomplete="new-password" placeholder="${esc(t("confirmPasswordPlaceholder"))}"${i18nPlaceholderAttr("confirmPasswordPlaceholder")} required minlength="${PASSWORD_MIN_LENGTH}" />
2373
2424
  <button type="submit"${i18nAttr("createAccount")}>${esc(t("createAccount"))}</button>
2374
2425
  ${signupLegalNoteHtml}
2375
2426
  ${signupLocalModeNoteHtml}
@@ -2457,7 +2508,7 @@ ${signInJourneyInlineScript()}
2457
2508
  var __anAuthLocale = __AN_AUTH_DEFAULT_LOCALE;
2458
2509
  var __anAuthLocalePreference = 'system';
2459
2510
  var __AN_AUTH_MODE = ${JSON.stringify(authMode)};
2460
- var __anAuthView = ${JSON.stringify(googleOnly ? "googleOnly" : magicLinkMode ? "magicLink" : "signup")};
2511
+ var __anAuthView = ${JSON.stringify(googleOnly ? "googleOnly" : "signup")};
2461
2512
  function __anAuthLocaleIsSupported(value) {
2462
2513
  return __AN_AUTH_SUPPORTED_LOCALES.indexOf(value) !== -1;
2463
2514
  }
@@ -2525,6 +2576,7 @@ ${signInJourneyInlineScript()}
2525
2576
  if (view === 'forgot') return { heading: 'resetPasswordTitle', subtitle: 'resetPasswordSubtitle' };
2526
2577
  if (view === 'verification') return { heading: 'checkEmailTitle', subtitle: 'finishAccountSubtitle' };
2527
2578
  if (view === 'googleOnly') return { heading: 'signInTitle', subtitle: 'googleOnlySubtitle' };
2579
+ if (view === 'magicLinkSent') return { heading: 'magicLinkSent', subtitle: 'magicLinkSentCopy' };
2528
2580
  if (view === 'magicLink') return { heading: 'magicLinkTitle', subtitle: 'magicLinkSubtitle' };
2529
2581
  return { heading: 'welcomeTitle', subtitle: 'createAccountSubtitle' };
2530
2582
  }
@@ -3146,9 +3198,34 @@ ${googleOnly
3146
3198
  function clearRememberedPendingSignupEmail() {
3147
3199
  rememberPendingSignupEmail('');
3148
3200
  }
3201
+ function hideMagicLinkSuccess() {
3202
+ var card = document.querySelector('.card');
3203
+ if (card) card.classList.remove('magic-link-complete');
3204
+ var success = document.getElementById('magic-link-success');
3205
+ if (success) {
3206
+ success.classList.remove('is-visible');
3207
+ success.setAttribute('hidden', '');
3208
+ }
3209
+ }
3210
+ function showMagicLinkSuccess(email) {
3211
+ var card = document.querySelector('.card');
3212
+ if (card) card.classList.add('magic-link-complete');
3213
+ var success = document.getElementById('magic-link-success');
3214
+ var successEmail = document.getElementById('magic-link-success-email');
3215
+ if (successEmail && typeof email === 'string') successEmail.textContent = email;
3216
+ if (success) {
3217
+ success.removeAttribute('hidden');
3218
+ success.classList.add('is-visible');
3219
+ }
3220
+ forms.forEach(function(x) { x.classList.remove('active'); });
3221
+ var authTabs = document.getElementById('auth-tabs');
3222
+ if (authTabs) authTabs.hidden = true;
3223
+ __anSetAuthView('magicLinkSent');
3224
+ }
3149
3225
  function showMagicLinkForm() {
3150
3226
  var form = document.getElementById('magic-link-form');
3151
3227
  if (!form) return;
3228
+ hideMagicLinkSuccess();
3152
3229
  forms.forEach(function(x) { x.classList.remove('active'); });
3153
3230
  form.classList.add('active');
3154
3231
  var authTabs = document.getElementById('auth-tabs');
@@ -3163,6 +3240,8 @@ ${googleOnly
3163
3240
  var isValid = __anIsValidAuthEmail(emailInput.value);
3164
3241
  button.classList.toggle('is-visible', isValid);
3165
3242
  button.setAttribute('aria-hidden', isValid ? 'false' : 'true');
3243
+ var googleButton = document.getElementById('google-btn');
3244
+ if (googleButton) googleButton.classList.toggle('magic-link-secondary', isValid);
3166
3245
  }
3167
3246
  function setActiveTab(name, opts) {
3168
3247
  if (name !== 'signup' && name !== 'login') return;
@@ -3419,7 +3498,7 @@ ${googleOnly
3419
3498
  }
3420
3499
  }
3421
3500
  (function initActiveTab() {
3422
- var initial = __AN_AUTH_MODE === 'magic-link' ? 'magicLink' : 'signup';
3501
+ var initial = 'signup';
3423
3502
  try {
3424
3503
  var params = new URLSearchParams(location.search);
3425
3504
  var qp = params.get('tab');
@@ -3438,8 +3517,7 @@ ${googleOnly
3438
3517
  if (stored === 'login' || stored === 'signup') initial = stored;
3439
3518
  }
3440
3519
  } catch (e) {}
3441
- if (initial === 'magicLink') showMagicLinkForm();
3442
- else setActiveTab(initial, { persist: false });
3520
+ setActiveTab(initial, { persist: false });
3443
3521
  try {
3444
3522
  if (__anIsVerifiedRedirectSuccess()) {
3445
3523
  var rememberedEmail = readRememberedPendingSignupEmail();
@@ -3472,6 +3550,14 @@ ${googleOnly
3472
3550
  e.preventDefault();
3473
3551
  showMagicLinkForm();
3474
3552
  });
3553
+ var magicLinkBack = document.getElementById('magic-link-back');
3554
+ if (magicLinkBack) magicLinkBack.addEventListener('click', function(e) {
3555
+ e.preventDefault();
3556
+ var magicLinkEmailInput = document.getElementById('m-email');
3557
+ if (magicLinkEmailInput) magicLinkEmailInput.value = '';
3558
+ showMagicLinkForm();
3559
+ if (magicLinkEmailInput) magicLinkEmailInput.focus();
3560
+ });
3475
3561
 
3476
3562
  var magicLinkForm = document.getElementById('magic-link-form');
3477
3563
  var magicLinkEmail = document.getElementById('m-email');
@@ -3505,9 +3591,9 @@ ${googleOnly
3505
3591
  return null;
3506
3592
  });
3507
3593
  if (res.ok) {
3508
- msg.textContent = __anT('magicLinkSent') + '. ' + __anT('magicLinkSentCopy') + ' ' + email + '.';
3509
- msg.classList.add('show', 'success');
3510
- btn.textContent = __anT('sent');
3594
+ btn.disabled = false;
3595
+ btn.textContent = originalLabel;
3596
+ showMagicLinkSuccess(email);
3511
3597
  return;
3512
3598
  }
3513
3599
  msg.textContent = (data && (data.error || data.message)) || __anT('magicLinkFailed');
@@ -3918,9 +4004,9 @@ export function getResetPasswordHtml() {
3918
4004
  <p class="subtitle">Set a new password for your account.</p>
3919
4005
  <form id="reset-form">
3920
4006
  <label for="p1">New password</label>
3921
- <input id="p1" type="password" autocomplete="new-password" autofocus placeholder="At least 8 characters" required minlength="8" />
4007
+ <input id="p1" type="password" autocomplete="new-password" autofocus placeholder="At least ${PASSWORD_MIN_LENGTH} characters" required minlength="${PASSWORD_MIN_LENGTH}" />
3922
4008
  <label for="p2">Confirm password</label>
3923
- <input id="p2" type="password" autocomplete="new-password" placeholder="Confirm password" required minlength="8" />
4009
+ <input id="p2" type="password" autocomplete="new-password" placeholder="Confirm password" required minlength="${PASSWORD_MIN_LENGTH}" />
3924
4010
  <button type="submit">Save new password</button>
3925
4011
  <p class="msg" id="msg"></p>
3926
4012
  </form>
@@ -7,10 +7,11 @@
7
7
  */
8
8
  export declare const DEFAULT_DISPATCH_SETTLE_MS = 250;
9
9
  /**
10
- * Resolve the base URL to fire a self-dispatch request at. Prefers explicit env
11
- * vars (most reliable on serverless, where inbound host headers can be the
12
- * platform's internal hostname), falling back to the inbound request headers
13
- * and finally localhost in dev.
10
+ * Resolve the base URL to fire a self-dispatch request at. Prefer the URL for
11
+ * this exact deploy before stable app URLs: a preview or in-flight deploy must
12
+ * not send a token minted by its function fleet to a different deploy that
13
+ * happens to serve the same public hostname. Fall back to the inbound request
14
+ * headers and finally localhost in dev.
14
15
  *
15
16
  * Throws in production / shared deployments when no env var is set — a silent
16
17
  * fallback to a bad host there would drop background work invisibly.
@@ -47,23 +47,26 @@ function readHeader(event, name) {
47
47
  }
48
48
  }
49
49
  /**
50
- * Resolve the base URL to fire a self-dispatch request at. Prefers explicit env
51
- * vars (most reliable on serverless, where inbound host headers can be the
52
- * platform's internal hostname), falling back to the inbound request headers
53
- * and finally localhost in dev.
50
+ * Resolve the base URL to fire a self-dispatch request at. Prefer the URL for
51
+ * this exact deploy before stable app URLs: a preview or in-flight deploy must
52
+ * not send a token minted by its function fleet to a different deploy that
53
+ * happens to serve the same public hostname. Fall back to the inbound request
54
+ * headers and finally localhost in dev.
54
55
  *
55
56
  * Throws in production / shared deployments when no env var is set — a silent
56
57
  * fallback to a bad host there would drop background work invisibly.
57
58
  */
58
59
  export function resolveSelfDispatchBaseUrl(event) {
59
- const fromEnv = process.env.APP_URL ||
60
- process.env.URL ||
60
+ const fromEnv = process.env.DEPLOY_PRIME_URL ||
61
61
  process.env.DEPLOY_URL ||
62
+ process.env.URL ||
63
+ process.env.APP_URL ||
62
64
  process.env.BETTER_AUTH_URL;
63
65
  if (fromEnv)
64
66
  return withConfiguredAppBasePath(String(fromEnv));
65
67
  if (process.env.NODE_ENV === "production" || !isLocalDatabase()) {
66
- throw new Error("Self-dispatch requires APP_URL, URL, DEPLOY_URL, or BETTER_AUTH_URL in " +
68
+ throw new Error("Self-dispatch requires DEPLOY_PRIME_URL, DEPLOY_URL, URL, APP_URL, or " +
69
+ "BETTER_AUTH_URL in " +
67
70
  "production/shared deployments so background work can reach this " +
68
71
  "deployment's own URL.");
69
72
  }
@@ -88,9 +91,10 @@ async function dispatchResponseError(path, res) {
88
91
  * may take minutes); it is only raced against a short settle timer so the
89
92
  * request reliably leaves a serverless box before it freezes.
90
93
  *
91
- * When `A2A_SECRET` is unset (local dev), the request is sent unsigned — the
92
- * processor accepts unsigned dispatches in dev and relies on the SQL atomic
93
- * claim for double-processing protection, mirroring the A2A/webhook flow.
94
+ * When `A2A_SECRET` is unset in local SQLite development, the request is sent
95
+ * unsigned — the processor accepts unsigned dispatches in dev and relies on
96
+ * the SQL atomic claim for double-processing protection. Shared and production
97
+ * dispatches fail before sending an unauthenticated request.
94
98
  */
95
99
  /**
96
100
  * For host-root dispatch targets (`/.netlify/functions/*`), strip the configured
@@ -127,10 +131,17 @@ export async function fireInternalDispatch(options) {
127
131
  headers["Authorization"] = `Bearer ${signInternalToken(options.taskId)}`;
128
132
  }
129
133
  catch (err) {
130
- // Distinguish the documented "no A2A_SECRET in dev" path from a real
131
- // signing failure, so a malformed secret doesn't fail invisibly.
132
- if (err instanceof Error && !/A2A_SECRET/i.test(err.message)) {
133
- console.error(`[self-dispatch] signInternalToken failed unexpectedly for ${options.taskId}:`, err);
134
+ const detail = err instanceof Error ? err.message : String(err);
135
+ // Only local SQLite development has the loopback/unsigned exception. A
136
+ // shared database or production deployment must never turn a signing
137
+ // failure into an unauthenticated processor request.
138
+ if (process.env.NODE_ENV !== "production" &&
139
+ isLocalDatabase() &&
140
+ /A2A_SECRET/i.test(detail)) {
141
+ // The processor applies the matching trusted-local policy.
142
+ }
143
+ else {
144
+ throw new Error(`[self-dispatch] Cannot sign processor handoff for ${options.taskId}: ${detail}`, { cause: err });
134
145
  }
135
146
  }
136
147
  const awaitResponse = options.awaitResponse === true;
@@ -1,4 +1,4 @@
1
- export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
1
+ export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
2
2
  /**
3
3
  * Create an h3 catch-all that hands page routes to React Router and
4
4
  * returns 404 for framework / asset paths that React Router doesn't own.
@@ -25,7 +25,7 @@ import { captureError } from "./capture-error.js";
25
25
  import { getPostHogClientConfigScript } from "./posthog-config.js";
26
26
  import { runWithRequestContext } from "./request-context.js";
27
27
  import { getRealtimeClientConfigScript, getSentryClientConfigScript, } from "./sentry-config.js";
28
- export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
28
+ export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
29
29
  function getAppBasePath() {
30
30
  return getAppBasePathFromViteEnv();
31
31
  }
@@ -20,6 +20,6 @@ export declare function createTranscribeVoiceHandler(): import("h3").EventHandle
20
20
  error: string;
21
21
  text?: undefined;
22
22
  } | {
23
- text: string;
24
23
  error?: undefined;
24
+ text: string;
25
25
  }>>;
@@ -1,11 +1,11 @@
1
1
  export declare const DEFAULT_PUBLIC_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
2
2
  export declare const DEFAULT_SSR_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
3
3
  export declare const DEFAULT_SSR_CDN_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
4
- export declare const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
4
+ export declare const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, durable, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
5
5
  export declare const DEFAULT_SSR_CACHE_HEADERS: {
6
6
  readonly "cache-control": "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
7
7
  readonly "cdn-cache-control": "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
8
- readonly "netlify-cdn-cache-control": "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
8
+ readonly "netlify-cdn-cache-control": "public, durable, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
9
9
  };
10
10
  /**
11
11
  * Deployment-wide override for the SSR shell cache policy.
@@ -58,6 +58,30 @@ export declare function ssrCacheHeadersForPolicy(policy: SsrCachePolicy): SsrCac
58
58
  * response — copy it before mutating.
59
59
  */
60
60
  export declare function resolveSsrCacheHeaders(env?: Record<string, string | undefined>): Readonly<SsrCacheHeaders>;
61
+ /**
62
+ * Provider-specific cache-KEY headers, emitted only on the provider that
63
+ * understands them.
64
+ *
65
+ * Netlify keys its durable cache on the FULL query string by default, so every
66
+ * `?fbclid=`, `?gclid=` and `?utm_source=` mints a separate entry. On a
67
+ * marketing URL that fan-out is unbounded: measured on www.agent-native.com,
68
+ * every ad or social click was a guaranteed cold render (~4.5s) that could
69
+ * never be reused. `netlify-vary` narrows the key to the params that actually
70
+ * change the response.
71
+ *
72
+ * `_routes` is react-router's partial-payload param and DOES change the body —
73
+ * `.data` is ~45KB while `.data?_routes=root` is ~108 bytes — so it must stay
74
+ * in the key. (Remix v2's `_data` is inert here; naming it instead collapses
75
+ * those two into one entry and serves the wrong payload.)
76
+ *
77
+ * This lives in core, gated by runtime, for two reasons. It was written once
78
+ * before — `DEFAULT_SSR_NETLIFY_VARY`, added 2026-07-11 in PR #2026 and deleted
79
+ * 2h09m later in PR #2031 — and then independently re-derived inside an app,
80
+ * where the next person cannot find it. And a header no other provider
81
+ * understands should not be on every response everywhere: on anything but
82
+ * Netlify this returns {}.
83
+ */
84
+ export declare function resolveSsrCacheKeyHeaders(env?: Record<string, string | undefined>): Readonly<Record<string, string>>;
61
85
  export declare function isSsrCacheEnabled(env?: Record<string, string | undefined>): boolean;
62
86
  export declare const DEFAULT_SPECULATION_RULES_PATH = "/_agent-native/speculation-rules.json";
63
87
  export declare const DEFAULT_SPECULATION_RULES_HEADER = "\"/_agent-native/speculation-rules.json\"";
@@ -1,7 +1,7 @@
1
1
  export const DEFAULT_PUBLIC_CACHE_CONTROL = "public, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
2
2
  export const DEFAULT_SSR_CACHE_CONTROL = DEFAULT_PUBLIC_CACHE_CONTROL;
3
3
  export const DEFAULT_SSR_CDN_CACHE_CONTROL = DEFAULT_SSR_CACHE_CONTROL;
4
- export const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = DEFAULT_PUBLIC_CACHE_CONTROL;
4
+ export const DEFAULT_SSR_NETLIFY_CDN_CACHE_CONTROL = "public, durable, max-age=600, stale-while-revalidate=604800, stale-if-error=3600";
5
5
  export const DEFAULT_SSR_CACHE_HEADERS = {
6
6
  "cache-control": DEFAULT_SSR_CACHE_CONTROL,
7
7
  "cdn-cache-control": DEFAULT_SSR_CDN_CACHE_CONTROL,
@@ -85,10 +85,12 @@ export function ssrCacheHeadersForPolicy(policy) {
85
85
  // the 7-day default SWR here would hand back the staleness they opted out of.
86
86
  const control = `public, max-age=${policy.seconds}, ` +
87
87
  `stale-while-revalidate=${policy.seconds}, stale-if-error=3600`;
88
+ const netlifyControl = `public, durable, max-age=${policy.seconds}, ` +
89
+ `stale-while-revalidate=${policy.seconds}, stale-if-error=3600`;
88
90
  return {
89
91
  "cache-control": control,
90
92
  "cdn-cache-control": control,
91
- "netlify-cdn-cache-control": control,
93
+ "netlify-cdn-cache-control": netlifyControl,
92
94
  };
93
95
  }
94
96
  let memoizedRaw;
@@ -109,6 +111,45 @@ export function resolveSsrCacheHeaders(env = typeof process === "undefined"
109
111
  memoizedHeaders = Object.freeze(ssrCacheHeadersForPolicy(parseSsrCacheSetting(raw)));
110
112
  return memoizedHeaders;
111
113
  }
114
+ /**
115
+ * Provider-specific cache-KEY headers, emitted only on the provider that
116
+ * understands them.
117
+ *
118
+ * Netlify keys its durable cache on the FULL query string by default, so every
119
+ * `?fbclid=`, `?gclid=` and `?utm_source=` mints a separate entry. On a
120
+ * marketing URL that fan-out is unbounded: measured on www.agent-native.com,
121
+ * every ad or social click was a guaranteed cold render (~4.5s) that could
122
+ * never be reused. `netlify-vary` narrows the key to the params that actually
123
+ * change the response.
124
+ *
125
+ * `_routes` is react-router's partial-payload param and DOES change the body —
126
+ * `.data` is ~45KB while `.data?_routes=root` is ~108 bytes — so it must stay
127
+ * in the key. (Remix v2's `_data` is inert here; naming it instead collapses
128
+ * those two into one entry and serves the wrong payload.)
129
+ *
130
+ * This lives in core, gated by runtime, for two reasons. It was written once
131
+ * before — `DEFAULT_SSR_NETLIFY_VARY`, added 2026-07-11 in PR #2026 and deleted
132
+ * 2h09m later in PR #2031 — and then independently re-derived inside an app,
133
+ * where the next person cannot find it. And a header no other provider
134
+ * understands should not be on every response everywhere: on anything but
135
+ * Netlify this returns {}.
136
+ */
137
+ export function resolveSsrCacheKeyHeaders(env = typeof process === "undefined"
138
+ ? {}
139
+ : process.env) {
140
+ // NETLIFY is the build-time marker; deployed functions expose SITE_ID at
141
+ // runtime. An explicit "false"/local override means we are not really hosted.
142
+ const explicitlyNotNetlify = env.NETLIFY_LOCAL === "true" || env.NETLIFY === "false";
143
+ const onNetlify = !explicitlyNotNetlify && (Boolean(env.NETLIFY) || Boolean(env.SITE_ID)); // guard:allow-env-credential -- Netlify's public runtime host marker, not a credential.
144
+ const none = Object.freeze({});
145
+ if (!onNetlify)
146
+ return none;
147
+ // This NARROWS the cache key rather than splitting it per user: it removes
148
+ // utm/fbclid/gclid so one entry serves everyone. The shapes the guard exists
149
+ // to stop are `private`, `no-store` and `Vary: Cookie`, none of which this is.
150
+ // guard:allow-ssr-shell-exception — narrows the shared key, never splits it
151
+ return Object.freeze({ "netlify-vary": "query=_routes|index" });
152
+ }
112
153
  export function isSsrCacheEnabled(env = typeof process === "undefined"
113
154
  ? {}
114
155
  : process.env) {
@@ -0,0 +1,3 @@
1
+ export declare const PASSWORD_MIN_LENGTH = 12;
2
+ export declare const PASSWORD_MAX_LENGTH = 128;
3
+ export declare const PASSWORD_MIN_LENGTH_MESSAGE = "Password must be at least 12 characters";
@@ -0,0 +1,3 @@
1
+ export const PASSWORD_MIN_LENGTH = 12;
2
+ export const PASSWORD_MAX_LENGTH = 128;
3
+ export const PASSWORD_MIN_LENGTH_MESSAGE = `Password must be at least ${PASSWORD_MIN_LENGTH} characters`;
@@ -52,10 +52,22 @@ export default defineAction({
52
52
  }
53
53
  }
54
54
  const beforeExtensionTargets = await getExtensionShareChangeTargets(args.resourceType, args.resourceId);
55
- await db
56
- .update(reg.resourceTable)
57
- .set(update)
58
- .where(eq(reg.resourceTable.id, args.resourceId));
55
+ if (reg.persistVisibilityChange) {
56
+ await reg.persistVisibilityChange({
57
+ resource: access.resource,
58
+ resourceId: args.resourceId,
59
+ visibility: args.visibility,
60
+ update,
61
+ userEmail: rawAccess.userEmail,
62
+ orgId: currentOrgId,
63
+ });
64
+ }
65
+ else {
66
+ await db
67
+ .update(reg.resourceTable)
68
+ .set(update)
69
+ .where(eq(reg.resourceTable.id, args.resourceId));
70
+ }
59
71
  invalidateCollabAccessCache(args.resourceType, args.resourceId);
60
72
  await notifyExtensionShareChanged(args.resourceType, args.resourceId, beforeExtensionTargets);
61
73
  return { ok: true, visibility: args.visibility };