@agent-native/core 0.121.2 → 0.122.1

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 (588) hide show
  1. package/README.md +4 -12
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +148 -0
  4. package/corpus/core/docs/content/actions.mdx +2 -2
  5. package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
  6. package/corpus/core/docs/content/authentication.mdx +2 -0
  7. package/corpus/core/docs/content/deployment.mdx +36 -0
  8. package/corpus/core/docs/content/http-api.mdx +266 -0
  9. package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
  10. package/corpus/core/package.json +2 -1
  11. package/corpus/core/src/a2a/activity.ts +38 -27
  12. package/corpus/core/src/a2a/client.ts +57 -4
  13. package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
  14. package/corpus/core/src/agent/run-manager.ts +20 -1
  15. package/corpus/core/src/agent/run-store.ts +4 -1
  16. package/corpus/core/src/agent/types.ts +28 -8
  17. package/corpus/core/src/chat-threads/store.ts +45 -0
  18. package/corpus/core/src/checkpoints/index.ts +2 -0
  19. package/corpus/core/src/checkpoints/route-match.ts +13 -0
  20. package/corpus/core/src/cli/create.ts +105 -17
  21. package/corpus/core/src/cli/index.ts +20 -0
  22. package/corpus/core/src/cli/template-baseline.ts +410 -0
  23. package/corpus/core/src/cli/template-sync.ts +1004 -0
  24. package/corpus/core/src/cli/templates-meta.ts +1 -0
  25. package/corpus/core/src/client/AssistantChat.tsx +38 -12
  26. package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
  27. package/corpus/core/src/client/chat/message-components.tsx +127 -66
  28. package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
  29. package/corpus/core/src/client/error-format.ts +18 -0
  30. package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
  31. package/corpus/core/src/client/org/TeamPage.tsx +7 -6
  32. package/corpus/core/src/client/settings/SettingsPanel.tsx +9 -9
  33. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +12 -2
  34. package/corpus/core/src/client/sse-event-processor.ts +3 -0
  35. package/corpus/core/src/data-widgets/index.ts +41 -0
  36. package/corpus/core/src/deploy/build.ts +11 -9
  37. package/corpus/core/src/extensions/url-safety.ts +67 -4
  38. package/corpus/core/src/integrations/webhook-handler.ts +63 -9
  39. package/corpus/core/src/org/auto-join-domain.ts +4 -3
  40. package/corpus/core/src/org/context.ts +108 -39
  41. package/corpus/core/src/org/index.ts +5 -0
  42. package/corpus/core/src/org/service-identity.ts +60 -0
  43. package/corpus/core/src/provider-api/index.ts +22 -1
  44. package/corpus/core/src/scripts/docs/search.ts +12 -1
  45. package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
  46. package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
  47. package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
  48. package/corpus/core/src/server/agents-bundle.ts +84 -5
  49. package/corpus/core/src/server/auth.ts +4 -3
  50. package/corpus/core/src/server/builder-browser.ts +47 -19
  51. package/corpus/core/src/server/core-routes-plugin.ts +2 -2
  52. package/corpus/core/src/server/credential-provider.ts +209 -68
  53. package/corpus/core/src/server/index.ts +3 -0
  54. package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
  55. package/corpus/core/src/server/prompts/framework-core.ts +9 -21
  56. package/corpus/core/src/server/prompts/index.ts +0 -1
  57. package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
  58. package/corpus/core/src/server/ssr-handler.ts +13 -2
  59. package/corpus/core/src/settings/user-settings.ts +13 -1
  60. package/corpus/core/src/shared/cache-control.ts +141 -0
  61. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  62. package/corpus/core/src/templates/chat/_gitignore +1 -0
  63. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  64. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  65. package/corpus/core/src/templates/default/app/root.tsx +1 -1
  66. package/corpus/core/src/templates/default/public/manifest.json +2 -2
  67. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  68. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  69. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  70. package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  71. package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
  72. package/corpus/core/src/vite/client.ts +69 -3
  73. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
  74. package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
  75. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
  76. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
  77. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
  78. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
  79. package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
  80. package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
  81. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  82. package/corpus/templates/analytics/AGENTS.md +91 -563
  83. package/corpus/templates/analytics/_gitignore +1 -0
  84. package/corpus/templates/analytics/actions/bigquery.ts +12 -4
  85. package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
  86. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
  87. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -23
  88. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
  89. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
  90. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
  91. package/corpus/templates/analytics/app/routes/_index.tsx +1 -1
  92. package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  96. package/corpus/templates/analytics/package.json +1 -1
  97. package/corpus/templates/analytics/public/manifest.json +1 -1
  98. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
  99. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
  100. package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
  101. package/corpus/templates/analytics/server/lib/notion.ts +15 -4
  102. package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
  103. package/corpus/templates/analytics/server/plugins/auth.ts +1 -1
  104. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  105. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +0 -2
  106. package/corpus/templates/assets/app/routes/_index.tsx +1 -1
  107. package/corpus/templates/assets/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  108. package/corpus/templates/assets/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  109. package/corpus/templates/assets/server/plugins/auth.ts +1 -1
  110. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  111. package/corpus/templates/brain/_gitignore +1 -0
  112. package/corpus/templates/brain/app/lib/brain.ts +0 -7
  113. package/corpus/templates/brain/app/routes/_index.tsx +1 -2
  114. package/corpus/templates/brain/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  115. package/corpus/templates/brain/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  116. package/corpus/templates/brain/package.json +1 -1
  117. package/corpus/templates/brain/public/manifest.json +1 -1
  118. package/corpus/templates/brain/server/plugins/auth.ts +1 -1
  119. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  120. package/corpus/templates/calendar/_gitignore +1 -0
  121. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -6
  122. package/corpus/templates/calendar/app/routes/_app._index.tsx +1 -1
  123. package/corpus/templates/calendar/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  124. package/corpus/templates/calendar/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  125. package/corpus/templates/calendar/package.json +1 -1
  126. package/corpus/templates/calendar/public/manifest.json +1 -1
  127. package/corpus/templates/calendar/server/plugins/auth.ts +1 -1
  128. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  129. package/corpus/templates/chat/_gitignore +1 -0
  130. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  131. package/corpus/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  132. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  133. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
  134. package/corpus/templates/clips/AGENTS.md +5 -4
  135. package/corpus/templates/clips/_gitignore +1 -0
  136. package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
  137. package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
  138. package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
  139. package/corpus/templates/clips/actions/import-loom-recording.ts +53 -98
  140. package/corpus/templates/clips/actions/lib/loom-import-job.ts +260 -0
  141. package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
  142. package/corpus/templates/clips/actions/list-recordings.ts +69 -19
  143. package/corpus/templates/clips/actions/list-viewers.ts +5 -2
  144. package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
  145. package/corpus/templates/clips/actions/request-transcript.ts +28 -1
  146. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
  147. package/corpus/templates/clips/app/components/library/library-layout.tsx +0 -7
  148. package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
  149. package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
  150. package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
  151. package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
  152. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
  153. package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
  154. package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
  155. package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
  156. package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
  157. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
  158. package/corpus/templates/clips/app/routes/_index.tsx +1 -1
  159. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +52 -15
  160. package/corpus/templates/clips/app/routes/record.tsx +82 -31
  161. package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
  162. package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
  163. package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
  164. package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
  165. package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
  166. package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
  167. package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
  168. package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
  169. package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
  170. package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
  171. package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
  172. package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
  173. package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
  174. package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
  175. package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
  176. package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  180. package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
  181. package/corpus/templates/clips/desktop/package.json +2 -0
  182. package/corpus/templates/clips/desktop/src/app.tsx +89 -0
  183. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
  184. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
  185. package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
  186. package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
  187. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
  188. package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
  189. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
  190. package/corpus/templates/clips/desktop/src/styles.css +127 -78
  191. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
  192. package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
  193. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
  194. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
  195. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
  196. package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
  197. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
  198. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
  199. package/corpus/templates/clips/server/db/schema.ts +27 -0
  200. package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
  201. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -1
  202. package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
  203. package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
  204. package/corpus/templates/clips/server/lib/recordings.ts +51 -3
  205. package/corpus/templates/clips/server/plugins/auth.ts +1 -1
  206. package/corpus/templates/clips/server/plugins/db.ts +31 -0
  207. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +56 -3
  208. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
  209. package/corpus/templates/clips/shared/recording-link.ts +43 -0
  210. package/corpus/templates/clips/shared/share-attribution.ts +4 -0
  211. package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
  212. package/corpus/templates/clips/shared/view-analytics.ts +26 -0
  213. package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
  214. package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
  215. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
  216. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
  217. package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
  218. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  219. package/corpus/templates/content/AGENTS.md +62 -583
  220. package/corpus/templates/content/_gitignore +1 -0
  221. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -39
  222. package/corpus/templates/content/app/routes/_app._index.tsx +1 -2
  223. package/corpus/templates/content/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  224. package/corpus/templates/content/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  225. package/corpus/templates/content/package.json +1 -1
  226. package/corpus/templates/content/public/manifest.json +1 -1
  227. package/corpus/templates/content/server/plugins/auth.ts +1 -1
  228. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
  229. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
  230. package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
  231. package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
  232. package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
  233. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
  234. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  235. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
  236. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
  237. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
  238. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
  239. package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
  240. package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
  241. package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
  242. package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
  243. package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
  244. package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
  245. package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
  246. package/corpus/templates/design/AGENTS.md +88 -503
  247. package/corpus/templates/design/_gitignore +1 -0
  248. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  249. package/corpus/templates/design/app/routes/_index.tsx +1 -1
  250. package/corpus/templates/design/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  251. package/corpus/templates/design/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  252. package/corpus/templates/design/server/plugins/auth.ts +1 -1
  253. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  254. package/corpus/templates/dispatch/_gitignore +1 -0
  255. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -10
  256. package/corpus/templates/dispatch/app/routes/overview.tsx +1 -1
  257. package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
  258. package/corpus/templates/dispatch/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  259. package/corpus/templates/dispatch/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  260. package/corpus/templates/dispatch/package.json +1 -1
  261. package/corpus/templates/dispatch/public/manifest.json +1 -1
  262. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  263. package/corpus/templates/forms/_gitignore +1 -0
  264. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +0 -35
  265. package/corpus/templates/forms/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  266. package/corpus/templates/forms/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  267. package/corpus/templates/forms/package.json +1 -1
  268. package/corpus/templates/forms/public/manifest.json +1 -1
  269. package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
  270. package/corpus/templates/forms/server/plugins/auth.ts +1 -1
  271. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  272. package/corpus/templates/macros/_gitignore +1 -0
  273. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -2
  274. package/corpus/templates/macros/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  275. package/corpus/templates/macros/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  276. package/corpus/templates/macros/package.json +1 -1
  277. package/corpus/templates/macros/server/plugins/auth.ts +2 -2
  278. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  279. package/corpus/templates/mail/_gitignore +1 -0
  280. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -39
  281. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +1 -1
  282. package/corpus/templates/mail/app/routes/$view.tsx +1 -1
  283. package/corpus/templates/mail/app/routes/_index.tsx +1 -1
  284. package/corpus/templates/mail/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  285. package/corpus/templates/mail/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  286. package/corpus/templates/mail/package.json +1 -1
  287. package/corpus/templates/mail/public/manifest.json +1 -1
  288. package/corpus/templates/mail/server/plugins/auth.ts +1 -1
  289. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  290. package/corpus/templates/plan/_gitignore +1 -0
  291. package/corpus/templates/plan/agent-native.app-skill.json +1 -1
  292. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -9
  293. package/corpus/templates/plan/app/lib/app-config.ts +1 -1
  294. package/corpus/templates/plan/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  295. package/corpus/templates/plan/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  296. package/corpus/templates/plan/package.json +1 -1
  297. package/corpus/templates/plan/public/manifest.json +1 -1
  298. package/corpus/templates/plan/server/plugins/auth.ts +1 -1
  299. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  300. package/corpus/templates/slides/_gitignore +1 -0
  301. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
  302. package/corpus/templates/slides/app/routes/_index.tsx +1 -1
  303. package/corpus/templates/slides/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  304. package/corpus/templates/slides/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  305. package/corpus/templates/slides/package.json +1 -1
  306. package/corpus/templates/slides/public/manifest.json +1 -1
  307. package/corpus/templates/slides/server/plugins/auth.ts +1 -1
  308. package/corpus/templates/slides/server/plugins/db.ts +4 -0
  309. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  310. package/corpus/templates/tasks/AGENTS.md +1 -1
  311. package/corpus/templates/tasks/_gitignore +1 -0
  312. package/dist/a2a/activity.d.ts +4 -1
  313. package/dist/a2a/activity.d.ts.map +1 -1
  314. package/dist/a2a/activity.js +27 -16
  315. package/dist/a2a/activity.js.map +1 -1
  316. package/dist/a2a/client.d.ts.map +1 -1
  317. package/dist/a2a/client.js +58 -4
  318. package/dist/a2a/client.js.map +1 -1
  319. package/dist/agent/engine/builder-engine.d.ts +1 -0
  320. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  321. package/dist/agent/engine/builder-engine.js +31 -4
  322. package/dist/agent/engine/builder-engine.js.map +1 -1
  323. package/dist/agent/run-manager.d.ts.map +1 -1
  324. package/dist/agent/run-manager.js +18 -1
  325. package/dist/agent/run-manager.js.map +1 -1
  326. package/dist/agent/run-store.d.ts +1 -0
  327. package/dist/agent/run-store.d.ts.map +1 -1
  328. package/dist/agent/run-store.js +2 -1
  329. package/dist/agent/run-store.js.map +1 -1
  330. package/dist/agent/types.d.ts +12 -1
  331. package/dist/agent/types.d.ts.map +1 -1
  332. package/dist/agent/types.js +21 -1
  333. package/dist/agent/types.js.map +1 -1
  334. package/dist/chat-threads/store.d.ts +10 -0
  335. package/dist/chat-threads/store.d.ts.map +1 -1
  336. package/dist/chat-threads/store.js +41 -0
  337. package/dist/chat-threads/store.js.map +1 -1
  338. package/dist/checkpoints/index.d.ts +1 -0
  339. package/dist/checkpoints/index.d.ts.map +1 -1
  340. package/dist/checkpoints/index.js +1 -0
  341. package/dist/checkpoints/index.js.map +1 -1
  342. package/dist/checkpoints/route-match.d.ts +8 -0
  343. package/dist/checkpoints/route-match.d.ts.map +1 -0
  344. package/dist/checkpoints/route-match.js +13 -0
  345. package/dist/checkpoints/route-match.js.map +1 -0
  346. package/dist/cli/create.d.ts +35 -4
  347. package/dist/cli/create.d.ts.map +1 -1
  348. package/dist/cli/create.js +69 -19
  349. package/dist/cli/create.js.map +1 -1
  350. package/dist/cli/index.js +19 -0
  351. package/dist/cli/index.js.map +1 -1
  352. package/dist/cli/template-baseline.d.ts +54 -0
  353. package/dist/cli/template-baseline.d.ts.map +1 -0
  354. package/dist/cli/template-baseline.js +334 -0
  355. package/dist/cli/template-baseline.js.map +1 -0
  356. package/dist/cli/template-sync.d.ts +57 -0
  357. package/dist/cli/template-sync.d.ts.map +1 -0
  358. package/dist/cli/template-sync.js +787 -0
  359. package/dist/cli/template-sync.js.map +1 -0
  360. package/dist/cli/templates-meta.d.ts.map +1 -1
  361. package/dist/cli/templates-meta.js +1 -0
  362. package/dist/cli/templates-meta.js.map +1 -1
  363. package/dist/client/AssistantChat.d.ts +2 -1
  364. package/dist/client/AssistantChat.d.ts.map +1 -1
  365. package/dist/client/AssistantChat.js +38 -10
  366. package/dist/client/AssistantChat.js.map +1 -1
  367. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  368. package/dist/client/NewWorkspaceAppFlow.js +32 -2
  369. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  370. package/dist/client/chat/message-components.d.ts +20 -0
  371. package/dist/client/chat/message-components.d.ts.map +1 -1
  372. package/dist/client/chat/message-components.js +81 -46
  373. package/dist/client/chat/message-components.js.map +1 -1
  374. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  375. package/dist/client/chat/tool-call-display.js +14 -6
  376. package/dist/client/chat/tool-call-display.js.map +1 -1
  377. package/dist/client/error-format.d.ts.map +1 -1
  378. package/dist/client/error-format.js +13 -0
  379. package/dist/client/error-format.js.map +1 -1
  380. package/dist/client/org/OrgSwitcher.d.ts +8 -1
  381. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  382. package/dist/client/org/OrgSwitcher.js +3 -2
  383. package/dist/client/org/OrgSwitcher.js.map +1 -1
  384. package/dist/client/org/TeamPage.d.ts.map +1 -1
  385. package/dist/client/org/TeamPage.js +1 -1
  386. package/dist/client/org/TeamPage.js.map +1 -1
  387. package/dist/client/settings/SettingsPanel.js +9 -9
  388. package/dist/client/settings/SettingsPanel.js.map +1 -1
  389. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  390. package/dist/client/settings/SettingsTabsPage.js +7 -4
  391. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  392. package/dist/client/sse-event-processor.d.ts.map +1 -1
  393. package/dist/client/sse-event-processor.js +3 -0
  394. package/dist/client/sse-event-processor.js.map +1 -1
  395. package/dist/collab/awareness.d.ts +2 -2
  396. package/dist/collab/awareness.d.ts.map +1 -1
  397. package/dist/collab/struct-routes.d.ts +1 -1
  398. package/dist/data-widgets/index.d.ts +3 -0
  399. package/dist/data-widgets/index.d.ts.map +1 -1
  400. package/dist/data-widgets/index.js +33 -0
  401. package/dist/data-widgets/index.js.map +1 -1
  402. package/dist/deploy/build.d.ts.map +1 -1
  403. package/dist/deploy/build.js +11 -7
  404. package/dist/deploy/build.js.map +1 -1
  405. package/dist/eject/provider-api-definitions.d.ts +1 -0
  406. package/dist/eject/provider-api-definitions.d.ts.map +1 -1
  407. package/dist/extensions/url-safety.d.ts +9 -16
  408. package/dist/extensions/url-safety.d.ts.map +1 -1
  409. package/dist/extensions/url-safety.js +48 -4
  410. package/dist/extensions/url-safety.js.map +1 -1
  411. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  412. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  413. package/dist/integrations/webhook-handler.js +46 -9
  414. package/dist/integrations/webhook-handler.js.map +1 -1
  415. package/dist/notifications/routes.d.ts +2 -2
  416. package/dist/observability/routes.d.ts +3 -3
  417. package/dist/org/auto-join-domain.d.ts +3 -2
  418. package/dist/org/auto-join-domain.d.ts.map +1 -1
  419. package/dist/org/auto-join-domain.js +1 -1
  420. package/dist/org/auto-join-domain.js.map +1 -1
  421. package/dist/org/context.d.ts.map +1 -1
  422. package/dist/org/context.js +84 -28
  423. package/dist/org/context.js.map +1 -1
  424. package/dist/org/index.d.ts +1 -0
  425. package/dist/org/index.d.ts.map +1 -1
  426. package/dist/org/index.js +1 -0
  427. package/dist/org/index.js.map +1 -1
  428. package/dist/org/service-identity.d.ts +43 -0
  429. package/dist/org/service-identity.d.ts.map +1 -0
  430. package/dist/org/service-identity.js +34 -0
  431. package/dist/org/service-identity.js.map +1 -0
  432. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  433. package/dist/provider-api/actions/provider-api.d.ts +13 -11
  434. package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
  435. package/dist/provider-api/index.d.ts +4 -0
  436. package/dist/provider-api/index.d.ts.map +1 -1
  437. package/dist/provider-api/index.js +17 -1
  438. package/dist/provider-api/index.js.map +1 -1
  439. package/dist/scripts/docs/search.d.ts.map +1 -1
  440. package/dist/scripts/docs/search.js +12 -1
  441. package/dist/scripts/docs/search.js.map +1 -1
  442. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  443. package/dist/server/agent-chat/context-tools.js +3 -3
  444. package/dist/server/agent-chat/context-tools.js.map +1 -1
  445. package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
  446. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  447. package/dist/server/agent-chat/framework-prompts.js +33 -62
  448. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  449. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  450. package/dist/server/agent-chat-plugin.js +16 -10
  451. package/dist/server/agent-chat-plugin.js.map +1 -1
  452. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  453. package/dist/server/agents-bundle.d.ts +18 -0
  454. package/dist/server/agents-bundle.d.ts.map +1 -1
  455. package/dist/server/agents-bundle.js +70 -4
  456. package/dist/server/agents-bundle.js.map +1 -1
  457. package/dist/server/auth.d.ts.map +1 -1
  458. package/dist/server/auth.js +4 -3
  459. package/dist/server/auth.js.map +1 -1
  460. package/dist/server/builder-browser.d.ts.map +1 -1
  461. package/dist/server/builder-browser.js +43 -19
  462. package/dist/server/builder-browser.js.map +1 -1
  463. package/dist/server/core-routes-plugin.js +2 -2
  464. package/dist/server/core-routes-plugin.js.map +1 -1
  465. package/dist/server/credential-provider.d.ts +38 -2
  466. package/dist/server/credential-provider.d.ts.map +1 -1
  467. package/dist/server/credential-provider.js +142 -64
  468. package/dist/server/credential-provider.js.map +1 -1
  469. package/dist/server/index.d.ts +1 -1
  470. package/dist/server/index.d.ts.map +1 -1
  471. package/dist/server/index.js +1 -1
  472. package/dist/server/index.js.map +1 -1
  473. package/dist/server/prompts/framework-core-compact.d.ts +1 -1
  474. package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
  475. package/dist/server/prompts/framework-core-compact.js +7 -13
  476. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  477. package/dist/server/prompts/framework-core.d.ts +1 -1
  478. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  479. package/dist/server/prompts/framework-core.js +10 -21
  480. package/dist/server/prompts/framework-core.js.map +1 -1
  481. package/dist/server/prompts/index.d.ts +1 -1
  482. package/dist/server/prompts/index.d.ts.map +1 -1
  483. package/dist/server/prompts/index.js +1 -1
  484. package/dist/server/prompts/index.js.map +1 -1
  485. package/dist/server/prompts/shared-rules.d.ts +16 -10
  486. package/dist/server/prompts/shared-rules.d.ts.map +1 -1
  487. package/dist/server/prompts/shared-rules.js +19 -10
  488. package/dist/server/prompts/shared-rules.js.map +1 -1
  489. package/dist/server/ssr-handler.d.ts +1 -1
  490. package/dist/server/ssr-handler.d.ts.map +1 -1
  491. package/dist/server/ssr-handler.js +10 -3
  492. package/dist/server/ssr-handler.js.map +1 -1
  493. package/dist/server/transcribe-voice.d.ts +1 -1
  494. package/dist/settings/user-settings.d.ts.map +1 -1
  495. package/dist/settings/user-settings.js +13 -1
  496. package/dist/settings/user-settings.js.map +1 -1
  497. package/dist/shared/cache-control.d.ts +52 -0
  498. package/dist/shared/cache-control.d.ts.map +1 -1
  499. package/dist/shared/cache-control.js +107 -0
  500. package/dist/shared/cache-control.js.map +1 -1
  501. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  502. package/dist/templates/chat/_gitignore +1 -0
  503. package/dist/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  504. package/dist/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  505. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  506. package/dist/templates/default/app/root.tsx +1 -1
  507. package/dist/templates/default/public/manifest.json +2 -2
  508. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  509. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  510. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  511. package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  512. package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
  513. package/dist/vite/agents-bundle-plugin.js +8 -7
  514. package/dist/vite/agents-bundle-plugin.js.map +1 -1
  515. package/dist/vite/client.d.ts.map +1 -1
  516. package/dist/vite/client.js +66 -1
  517. package/dist/vite/client.js.map +1 -1
  518. package/docs/content/actions.mdx +2 -2
  519. package/docs/content/agent-surfaces.mdx +1 -1
  520. package/docs/content/authentication.mdx +2 -0
  521. package/docs/content/deployment.mdx +36 -0
  522. package/docs/content/http-api.mdx +266 -0
  523. package/docs/content/syncing-template-changes.mdx +159 -0
  524. package/package.json +4 -3
  525. package/src/a2a/activity.ts +38 -27
  526. package/src/a2a/client.ts +57 -4
  527. package/src/agent/engine/builder-engine.ts +35 -4
  528. package/src/agent/run-manager.ts +20 -1
  529. package/src/agent/run-store.ts +4 -1
  530. package/src/agent/types.ts +28 -8
  531. package/src/chat-threads/store.ts +45 -0
  532. package/src/checkpoints/index.ts +2 -0
  533. package/src/checkpoints/route-match.ts +13 -0
  534. package/src/cli/create.ts +105 -17
  535. package/src/cli/index.ts +20 -0
  536. package/src/cli/template-baseline.ts +410 -0
  537. package/src/cli/template-sync.ts +1004 -0
  538. package/src/cli/templates-meta.ts +1 -0
  539. package/src/client/AssistantChat.tsx +38 -12
  540. package/src/client/NewWorkspaceAppFlow.tsx +75 -10
  541. package/src/client/chat/message-components.tsx +127 -66
  542. package/src/client/chat/tool-call-display.tsx +29 -5
  543. package/src/client/error-format.ts +18 -0
  544. package/src/client/org/OrgSwitcher.tsx +30 -8
  545. package/src/client/org/TeamPage.tsx +7 -6
  546. package/src/client/settings/SettingsPanel.tsx +9 -9
  547. package/src/client/settings/SettingsTabsPage.tsx +12 -2
  548. package/src/client/sse-event-processor.ts +3 -0
  549. package/src/data-widgets/index.ts +41 -0
  550. package/src/deploy/build.ts +11 -9
  551. package/src/extensions/url-safety.ts +67 -4
  552. package/src/integrations/webhook-handler.ts +63 -9
  553. package/src/org/auto-join-domain.ts +4 -3
  554. package/src/org/context.ts +108 -39
  555. package/src/org/index.ts +5 -0
  556. package/src/org/service-identity.ts +60 -0
  557. package/src/provider-api/index.ts +22 -1
  558. package/src/scripts/docs/search.ts +12 -1
  559. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
  560. package/src/server/agent-chat/context-tools.ts +9 -4
  561. package/src/server/agent-chat/framework-prompts.ts +38 -66
  562. package/src/server/agent-chat-plugin.ts +17 -10
  563. package/src/server/agents-bundle.ts +84 -5
  564. package/src/server/auth.ts +4 -3
  565. package/src/server/builder-browser.ts +47 -19
  566. package/src/server/core-routes-plugin.ts +2 -2
  567. package/src/server/credential-provider.ts +209 -68
  568. package/src/server/index.ts +3 -0
  569. package/src/server/prompts/framework-core-compact.ts +6 -13
  570. package/src/server/prompts/framework-core.ts +9 -21
  571. package/src/server/prompts/index.ts +0 -1
  572. package/src/server/prompts/shared-rules.ts +19 -11
  573. package/src/server/ssr-handler.ts +13 -2
  574. package/src/settings/user-settings.ts +13 -1
  575. package/src/shared/cache-control.ts +141 -0
  576. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  577. package/src/templates/chat/_gitignore +1 -0
  578. package/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  579. package/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  580. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  581. package/src/templates/default/app/root.tsx +1 -1
  582. package/src/templates/default/public/manifest.json +2 -2
  583. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  584. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  585. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  586. package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  587. package/src/vite/agents-bundle-plugin.ts +7 -6
  588. package/src/vite/client.ts +69 -3
@@ -3,8 +3,10 @@
3
3
  *
4
4
  * Owner-only — uses assertAccess at editor level (owners always satisfy).
5
5
  *
6
- * Returns: views, uniqueViewers, completionRate, dropOff (100 buckets),
7
- * ctaConversionRate.
6
+ * Returns: views (total counted human view sessions, so a returning viewer
7
+ * counts again), agentViews (outside agents reading the clip's agent APIs),
8
+ * uniqueViewers (distinct people behind those views), completionRate,
9
+ * dropOff (100 buckets), ctaConversionRate.
8
10
  *
9
11
  * Usage:
10
12
  * pnpm action get-recording-insights --recordingId=<id>
@@ -12,11 +14,19 @@
12
14
 
13
15
  import { defineAction } from "@agent-native/core";
14
16
  import { assertAccess } from "@agent-native/core/sharing";
15
- import { eq } from "drizzle-orm";
17
+ import { count, eq } from "drizzle-orm";
16
18
  import { z } from "zod";
17
19
 
18
20
  import { getDb, schema } from "../server/db/index.js";
19
- import { clampCompletionPct } from "../shared/view-analytics.js";
21
+ import {
22
+ countRecordingAgentViews,
23
+ listRecordingAgentViewers,
24
+ } from "../server/lib/agent-views.js";
25
+ import {
26
+ clampCompletionPct,
27
+ displayViewerName,
28
+ isCountedViewerRow,
29
+ } from "../shared/view-analytics.js";
20
30
 
21
31
  export default defineAction({
22
32
  description:
@@ -39,11 +49,31 @@ export default defineAction({
39
49
  .from(schema.recordingEvents)
40
50
  .where(eq(schema.recordingEvents.recordingId, args.recordingId));
41
51
 
42
- const views = viewerRows.filter((v) => v.countedView).length;
52
+ const [[viewLogRow], agentViews, agentViewers] = await Promise.all([
53
+ db
54
+ .select({ value: count() })
55
+ .from(schema.recordingViews)
56
+ .where(eq(schema.recordingViews.recordingId, args.recordingId)),
57
+ countRecordingAgentViews(args.recordingId),
58
+ listRecordingAgentViewers(args.recordingId),
59
+ ]);
60
+
61
+ // Same definition as `countedViewCondition`, applied to rows already in
62
+ // memory so this action keeps its single viewer-row read. One row per
63
+ // person, so this is the distinct-viewer count, not the view total.
64
+ const countedViewers = viewerRows.filter(isCountedViewerRow).length;
43
65
  const uniqueViewers = new Set(
44
- viewerRows.map((v) => v.viewerEmail ?? `anon:${v.id}`),
66
+ viewerRows
67
+ .filter(isCountedViewerRow)
68
+ .map((v) => v.viewerEmail ?? `anon:${v.id}`),
45
69
  ).size;
46
70
 
71
+ // Mirrors `countRecordingViews`: `recording_views` only exists from
72
+ // migration v46, so clips recorded before it have zero log rows. Floor the
73
+ // total at the counted-viewer count so those clips keep reporting a real
74
+ // number instead of 0, and so total can never read below uniqueViewers.
75
+ const views = Math.max(Number(viewLogRow?.value ?? 0), countedViewers);
76
+
47
77
  const completionRate =
48
78
  viewerRows.length === 0
49
79
  ? 0
@@ -75,8 +105,12 @@ export default defineAction({
75
105
  }
76
106
 
77
107
  const ctaClicks = events.filter((e) => e.kind === "cta-click").length;
108
+ // CTA conversion is per person, so the denominator is counted viewers — not
109
+ // `views`, which counts repeat sessions from the same viewer.
78
110
  const ctaConversionRate =
79
- views === 0 ? 0 : Math.min(100, (ctaClicks / views) * 100);
111
+ countedViewers === 0
112
+ ? 0
113
+ : Math.min(100, (ctaClicks / countedViewers) * 100);
80
114
 
81
115
  // Top viewers by total watch ms
82
116
  const topViewers = viewerRows
@@ -85,13 +119,15 @@ export default defineAction({
85
119
  .slice(0, 20)
86
120
  .map((v) => ({
87
121
  viewerEmail: v.viewerEmail,
88
- viewerName: v.viewerName,
122
+ viewerName: displayViewerName(v.viewerName),
89
123
  totalWatchMs: v.totalWatchMs ?? 0,
90
124
  completedPct: clampCompletionPct(v.completedPct),
91
125
  }));
92
126
 
93
127
  return {
94
128
  views,
129
+ agentViews,
130
+ agentViewers,
95
131
  uniqueViewers,
96
132
  completionRate,
97
133
  ctaConversionRate,
@@ -7,6 +7,7 @@
7
7
  * - reactions
8
8
  * - chapters (parsed from recording.chaptersJson)
9
9
  * - CTAs
10
+ * - counted-view total
10
11
  *
11
12
  * This is the read endpoint the player/:id and share/:id routes use.
12
13
  * Access is gated by assertAccess at viewer level — for public-visibility
@@ -20,23 +21,24 @@
20
21
  import { defineAction, embedApp } from "@agent-native/core";
21
22
  import { readAppState } from "@agent-native/core/application-state";
22
23
  import { buildDeepLink } from "@agent-native/core/server";
23
- import {
24
- getRequestOrgId,
25
- getRequestUserEmail,
26
- } from "@agent-native/core/server/request-context";
27
24
  import { resolveAccess, ForbiddenError } from "@agent-native/core/sharing";
28
- import { and, asc, eq, or, sql } from "drizzle-orm";
25
+ import { asc, eq } from "drizzle-orm";
29
26
  import { z } from "zod";
30
27
 
31
28
  import { getDb, schema } from "../server/db/index.js";
32
29
  import { isAgentRecordingCaller } from "../server/lib/agent-recording-access.js";
30
+ import { countRecordingAgentViews } from "../server/lib/agent-views.js";
33
31
  import { isMediaVerificationPending } from "../server/lib/media-verification-state.js";
34
32
  import { resolvePlayerVideoUrl } from "../server/lib/player-video-url.js";
35
33
  import {
36
34
  canOpenDirectRecordingPage,
37
35
  isRecordingExpired,
38
36
  } from "../server/lib/recording-page-access.js";
39
- import { parseSpaceIds } from "../server/lib/recordings.js";
37
+ import { hasExplicitRecordingShare } from "../server/lib/recording-share-grant.js";
38
+ import {
39
+ countRecordingViews,
40
+ parseSpaceIds,
41
+ } from "../server/lib/recordings.js";
40
42
  import { parseBrowserDiagnosticsRow } from "../shared/browser-diagnostics.js";
41
43
  import {
42
44
  CLIPS_BUILDER_CREDITS_STATE_KEY,
@@ -93,7 +95,7 @@ function recordingDeepLink(recordingId: string): string {
93
95
 
94
96
  export default defineAction({
95
97
  description:
96
- "Fetch everything the player page needs for a recording: metadata, transcript, comments, reactions, chapters, CTAs, and the caller's effective role. Agent calls receive a bounded transcript payload; browser player calls receive the full transcript.",
98
+ "Fetch everything the player page needs for a recording: metadata, transcript, comments, reactions, chapters, CTAs, the counted-view total, and the caller's effective role. Agent calls receive a bounded transcript payload; browser player calls receive the full transcript.",
97
99
  schema: z.object({
98
100
  recordingId: z.string().describe("Recording ID"),
99
101
  }),
@@ -121,55 +123,13 @@ export default defineAction({
121
123
  throw new ForbiddenError("Recording has expired");
122
124
  }
123
125
 
124
- let hasExplicitShare = access.role === "owner";
125
- if (
126
- rec.visibility === "public" &&
127
- access.role !== "owner" &&
128
- !rec.password &&
129
- isAgentRecordingCaller(ctx?.caller)
130
- ) {
131
- hasExplicitShare = true;
132
- }
133
- if (
134
- rec.visibility === "public" &&
135
- access.role !== "owner" &&
136
- !hasExplicitShare
137
- ) {
138
- const userEmail = getRequestUserEmail()?.trim().toLowerCase();
139
- const orgId = getRequestOrgId();
140
- const principals = [];
141
- if (userEmail) {
142
- principals.push(
143
- and(
144
- eq(schema.recordingShares.principalType, "user"),
145
- sql`lower(${schema.recordingShares.principalId}) = ${userEmail}`,
146
- ),
147
- );
148
- }
149
- if (orgId) {
150
- principals.push(
151
- and(
152
- eq(schema.recordingShares.principalType, "org"),
153
- eq(schema.recordingShares.principalId, orgId),
154
- ),
155
- );
156
- }
157
- if (principals.length > 0) {
158
- const [share] = await db
159
- .select({ id: schema.recordingShares.id })
160
- .from(schema.recordingShares)
161
- .where(
162
- and(
163
- eq(schema.recordingShares.resourceId, args.recordingId),
164
- or(...principals),
165
- ),
166
- )
167
- .limit(1);
168
- hasExplicitShare = Boolean(share);
169
- } else {
170
- hasExplicitShare = false;
171
- }
172
- }
126
+ const hasExplicitShare = await hasExplicitRecordingShare({
127
+ recordingId: args.recordingId,
128
+ role: access.role,
129
+ visibility: rec.visibility,
130
+ hasPassword: Boolean(rec.password),
131
+ isAgentCaller: isAgentRecordingCaller(ctx?.caller),
132
+ });
173
133
 
174
134
  if (
175
135
  !canOpenDirectRecordingPage({
@@ -193,20 +153,27 @@ export default defineAction({
193
153
  access.role === "owner" ||
194
154
  access.role === "admin" ||
195
155
  access.role === "editor";
196
- const [cleanupStateRaw, builderCreditsRaw, verificationPending] =
197
- await Promise.all([
198
- readAppState(`transcript-cleanup-${args.recordingId}`).catch(
199
- () => null,
200
- ),
201
- canEditRecording
202
- ? readAppState(CLIPS_BUILDER_CREDITS_STATE_KEY).catch(() => null)
203
- : Promise.resolve(null),
204
- isMediaVerificationPending({
205
- ownerEmail: rec.ownerEmail,
206
- recordingId: args.recordingId,
207
- recordingStatus: rec.status,
208
- }),
209
- ]);
156
+ // This action is on a 1-3s poll from the player, so every read here shares
157
+ // one Promise.all instead of adding serial round-trips.
158
+ const [
159
+ cleanupStateRaw,
160
+ builderCreditsRaw,
161
+ verificationPending,
162
+ viewCount,
163
+ agentViewCount,
164
+ ] = await Promise.all([
165
+ readAppState(`transcript-cleanup-${args.recordingId}`).catch(() => null),
166
+ canEditRecording
167
+ ? readAppState(CLIPS_BUILDER_CREDITS_STATE_KEY).catch(() => null)
168
+ : Promise.resolve(null),
169
+ isMediaVerificationPending({
170
+ ownerEmail: rec.ownerEmail,
171
+ recordingId: args.recordingId,
172
+ recordingStatus: rec.status,
173
+ }),
174
+ countRecordingViews(args.recordingId).catch(() => 0),
175
+ countRecordingAgentViews(args.recordingId).catch(() => 0),
176
+ ]);
210
177
  const cleanupState =
211
178
  cleanupStateRaw && typeof cleanupStateRaw === "object"
212
179
  ? (cleanupStateRaw as Record<string, unknown>)
@@ -338,6 +305,8 @@ export default defineAction({
338
305
 
339
306
  return {
340
307
  role: access.role,
308
+ viewCount,
309
+ agentViewCount,
341
310
  recording: {
342
311
  id: rec.id,
343
312
  organizationId: rec.organizationId,
@@ -1,14 +1,13 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { writeAppState } from "@agent-native/core/application-state";
3
3
  import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
4
- import { uploadFile } from "@agent-native/core/file-upload";
5
4
  import { buildDeepLink } from "@agent-native/core/server";
6
5
  import { extractLoomVideoId, normalizeLoomShareUrl } from "@shared/loom.js";
7
6
  import { and, eq } from "drizzle-orm";
8
7
  import { z } from "zod";
9
8
 
10
9
  import { getDb, schema } from "../server/db/index.js";
11
- import { queueBuilderMediaCompression } from "../server/lib/builder-media-compression.js";
10
+ import { dispatchPostFinalizeJob } from "../server/lib/post-finalize-dispatch.js";
12
11
  import {
13
12
  getCurrentOwnerEmail,
14
13
  getOrganizationDefaultVisibility,
@@ -19,11 +18,7 @@ import {
19
18
  stringifySpaceIds,
20
19
  } from "../server/lib/recordings.js";
21
20
  import { hasRequestVideoStorage } from "../server/lib/video-storage.js";
22
- import {
23
- fetchLoomTranscript,
24
- loomTranscriptUnavailableMessage,
25
- } from "./lib/loom-transcript.js";
26
- import { downloadLoomVideo } from "./lib/loom-video.js";
21
+ import { failLoomImport } from "./lib/loom-import-job.js";
27
22
 
28
23
  const LoomOembedSchema = z
29
24
  .object({
@@ -132,7 +127,7 @@ async function fetchLoomOembed(shareUrl: string) {
132
127
 
133
128
  export default defineAction({
134
129
  description:
135
- "Import a public Loom share URL into Clips as a playable recording. Downloads Loom's public MP4, reuploads it to the configured Clips storage provider, and imports Loom's public transcript when available. If storage is not connected, creates a waiting recording that can be retried after storage setup.",
130
+ "Import a public Loom share URL into Clips as a playable recording. Creates the recording immediately and downloads Loom's public MP4, reuploads it to the configured Clips storage provider, and imports Loom's public transcript in the background (Loom's CDN plus a reupload can take longer than a single request should block on). If storage is not connected, creates a waiting recording that can be retried after storage setup.",
136
131
  schema: ImportLoomRecordingSchema,
137
132
  run: async (args) => {
138
133
  const shareUrl = normalizeLoomShareUrl(args.url);
@@ -163,15 +158,17 @@ export default defineAction({
163
158
  const existingSourceUrl = normalizeLoomShareUrl(
164
159
  existingRecording.sourceWindowTitle ?? "",
165
160
  );
166
- const isWaitingStorageRetry =
167
- existingRecording.status === "uploading" &&
161
+ const isRetryableLoomImport =
168
162
  !existingRecording.videoUrl &&
169
- existingRecording.failureReason ===
170
- LOOM_STORAGE_SETUP_REQUIRED_REASON &&
171
- existingSourceUrl === shareUrl;
172
- if (!isWaitingStorageRetry) {
163
+ existingSourceUrl === shareUrl &&
164
+ (existingRecording.status === "processing" ||
165
+ existingRecording.status === "failed" ||
166
+ (existingRecording.status === "uploading" &&
167
+ existingRecording.failureReason ===
168
+ LOOM_STORAGE_SETUP_REQUIRED_REASON));
169
+ if (!isRetryableLoomImport) {
173
170
  throw new Error(
174
- "Only a waiting-storage Loom import can be retried in place.",
171
+ "Only an incomplete Loom import can be retried in place.",
175
172
  );
176
173
  }
177
174
  }
@@ -241,6 +238,8 @@ export default defineAction({
241
238
  status: "uploading",
242
239
  videoUrl: null,
243
240
  failureReason: LOOM_STORAGE_SETUP_REQUIRED_REASON,
241
+ loomImportClaimId: null,
242
+ loomImportClaimedAt: null,
244
243
  })
245
244
  .where(eq(schema.recordings.id, id));
246
245
  } else {
@@ -293,123 +292,79 @@ export default defineAction({
293
292
  );
294
293
  }
295
294
 
296
- const media = await downloadLoomVideo({ loomId, shareUrl });
297
- const upload = await uploadFile({
298
- data: media.bytes,
299
- filename: `${id}.mp4`,
300
- mimeType: media.mimeType,
301
- ownerEmail,
302
- stableUrl: true,
303
- recordAsset: false,
304
- });
305
-
306
- const recordingValues = buildRecordingValues(media.sizeBytes);
307
- if (upload === null) {
308
- return await saveWaitingForStorage(media.sizeBytes);
309
- }
310
-
311
- if (!upload?.url) {
312
- throw new Error(
313
- "File upload returned no URL. Check your storage provider configuration.",
314
- );
315
- }
316
-
317
- const videoUrl = upload.url;
295
+ // Storage is connected: create the row now and hand the slow Loom
296
+ // download + reupload + transcript off to a durable background job.
297
+ // Loom's CDN plus a reupload can outlast the platform's request timeout;
298
+ // doing it inline previously crashed the function mid-download instead of
299
+ // returning a clean error (see post-finalize-worker.post.ts's "loom-import"
300
+ // kind / runLoomImportJob).
301
+ const recordingValues = buildRecordingValues(
302
+ existingRecording?.videoSizeBytes ?? 0,
303
+ );
318
304
  if (existingRecording) {
319
305
  await db
320
306
  .update(schema.recordings)
321
307
  .set({
322
308
  ...recordingValues,
323
- videoUrl,
324
- status: "ready",
309
+ status: "processing",
310
+ videoUrl: null,
325
311
  failureReason: null,
312
+ loomImportClaimId: null,
313
+ loomImportClaimedAt: null,
326
314
  })
327
315
  .where(eq(schema.recordings.id, id));
328
316
  } else {
329
317
  await db.insert(schema.recordings).values({
330
318
  id,
331
319
  ...recordingValues,
332
- videoUrl,
333
- status: "ready",
320
+ videoUrl: null,
321
+ status: "processing",
334
322
  failureReason: null,
335
323
  ownerEmail,
336
324
  createdAt: now,
337
325
  });
338
326
  }
339
327
 
340
- void queueBuilderMediaCompression({
328
+ await writeAppState(`recording-upload-${id}`, {
341
329
  recordingId: id,
342
- ownerEmail,
343
- videoUrl,
344
- mimeType: media.mimeType,
345
- providerId: upload.provider,
346
- assetDbId: upload.id,
347
- sourceSizeBytes: media.sizeBytes,
348
- }).catch((err) => {
349
- console.warn("[clips] Loom media compression queue failed", {
350
- recordingId: id,
351
- error: err instanceof Error ? err.message : String(err),
352
- });
330
+ status: "processing",
331
+ progress: 100,
332
+ provider: "loom",
333
+ sourceUrl: shareUrl,
334
+ durationMs,
335
+ width,
336
+ height,
337
+ hasAudio: true,
338
+ hasCamera: false,
339
+ updatedAt: now,
353
340
  });
341
+ await writeAppState("refresh-signal", { ts: Date.now() });
342
+ await writeAppState("navigate", { view: "recording", recordingId: id });
354
343
 
355
- let transcript: Awaited<ReturnType<typeof fetchLoomTranscript>> = null;
356
344
  try {
357
- transcript = await fetchLoomTranscript({ shareUrl, durationMs });
358
- } catch (err) {
359
- console.warn(
360
- `[clips] Loom transcript import skipped for ${loomId}:`,
361
- (err as Error)?.message ?? String(err),
362
- );
363
- }
364
-
365
- const transcriptValues = {
366
- ownerEmail,
367
- language: transcript?.language ?? "en",
368
- segmentsJson: transcript ? JSON.stringify(transcript.segments) : "[]",
369
- fullText: transcript?.fullText ?? "",
370
- status: transcript ? ("ready" as const) : ("failed" as const),
371
- failureReason: transcript ? null : loomTranscriptUnavailableMessage(),
372
- updatedAt: now,
373
- };
374
- const [existingTranscript] = await db
375
- .select({ recordingId: schema.recordingTranscripts.recordingId })
376
- .from(schema.recordingTranscripts)
377
- .where(eq(schema.recordingTranscripts.recordingId, id));
378
- if (existingTranscript) {
379
- await db
380
- .update(schema.recordingTranscripts)
381
- .set(transcriptValues)
382
- .where(eq(schema.recordingTranscripts.recordingId, id));
383
- } else {
384
- await db.insert(schema.recordingTranscripts).values({
345
+ await dispatchPostFinalizeJob({
385
346
  recordingId: id,
386
- ...transcriptValues,
387
- createdAt: now,
347
+ kind: "loom-import",
348
+ requireAccepted: true,
388
349
  });
350
+ } catch (err) {
351
+ const failureReason = `Could not start the Loom import: ${
352
+ err instanceof Error ? err.message : String(err)
353
+ }`;
354
+ await failLoomImport(id, failureReason);
355
+ throw new Error(failureReason);
389
356
  }
390
357
 
391
- await writeAppState("refresh-signal", { ts: Date.now() });
392
- await writeAppState("navigate", { view: "recording", recordingId: id });
393
-
394
358
  return {
395
359
  recordingId: id,
396
360
  title,
397
- status: "ready" as const,
361
+ status: "processing" as const,
398
362
  provider: "loom" as const,
399
363
  sourceUrl: shareUrl,
400
- videoUrl,
401
- embedUrl: videoUrl,
402
364
  thumbnailUrl: oembed.thumbnail_url ?? null,
403
365
  durationMs,
404
- transcriptStatus: transcript
405
- ? ("ready" as const)
406
- : ("unavailable" as const),
407
366
  importMode: "reuploaded" as const,
408
- storageProvider: upload.provider,
409
- videoSizeBytes: media.sizeBytes,
410
- note: transcript
411
- ? "Imported as a Clips-hosted MP4 with Loom's public transcript."
412
- : "Imported as a Clips-hosted MP4. Loom did not expose an importable transcript; use request-transcript to transcribe the uploaded media.",
367
+ note: "Downloading and importing this Loom recording in the background.",
413
368
  };
414
369
  },
415
370
  link: ({ result }) => {