@agent-native/core 0.121.1 → 0.122.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 (465) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +145 -0
  3. package/corpus/core/docs/content/actions.mdx +2 -2
  4. package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
  5. package/corpus/core/docs/content/authentication.mdx +2 -0
  6. package/corpus/core/docs/content/deployment.mdx +36 -0
  7. package/corpus/core/docs/content/getting-started.mdx +477 -115
  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/agent/engine/builder-engine.ts +35 -4
  13. package/corpus/core/src/agent/run-manager.ts +20 -1
  14. package/corpus/core/src/agent/run-store.ts +4 -1
  15. package/corpus/core/src/agent/types.ts +28 -8
  16. package/corpus/core/src/chat-threads/store.ts +45 -0
  17. package/corpus/core/src/checkpoints/index.ts +2 -0
  18. package/corpus/core/src/checkpoints/route-match.ts +13 -0
  19. package/corpus/core/src/cli/create.ts +105 -17
  20. package/corpus/core/src/cli/index.ts +20 -0
  21. package/corpus/core/src/cli/template-baseline.ts +410 -0
  22. package/corpus/core/src/cli/template-sync.ts +1004 -0
  23. package/corpus/core/src/cli/templates-meta.ts +1 -0
  24. package/corpus/core/src/client/AssistantChat.tsx +38 -12
  25. package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
  26. package/corpus/core/src/client/chat/message-components.tsx +127 -66
  27. package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
  28. package/corpus/core/src/client/error-format.ts +18 -0
  29. package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
  30. package/corpus/core/src/client/org/TeamPage.tsx +7 -6
  31. package/corpus/core/src/client/sse-event-processor.ts +3 -0
  32. package/corpus/core/src/data-widgets/index.ts +41 -0
  33. package/corpus/core/src/deploy/build.ts +11 -9
  34. package/corpus/core/src/integrations/webhook-handler.ts +63 -9
  35. package/corpus/core/src/org/auto-join-domain.ts +4 -3
  36. package/corpus/core/src/org/context.ts +108 -39
  37. package/corpus/core/src/org/index.ts +5 -0
  38. package/corpus/core/src/org/service-identity.ts +60 -0
  39. package/corpus/core/src/provider-api/index.ts +22 -1
  40. package/corpus/core/src/scripts/docs/search.ts +12 -1
  41. package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
  42. package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
  43. package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
  44. package/corpus/core/src/server/agents-bundle.ts +84 -5
  45. package/corpus/core/src/server/auth.ts +4 -3
  46. package/corpus/core/src/server/builder-browser.ts +47 -19
  47. package/corpus/core/src/server/core-routes-plugin.ts +2 -2
  48. package/corpus/core/src/server/credential-provider.ts +209 -68
  49. package/corpus/core/src/server/index.ts +3 -0
  50. package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
  51. package/corpus/core/src/server/prompts/framework-core.ts +9 -21
  52. package/corpus/core/src/server/prompts/index.ts +0 -1
  53. package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
  54. package/corpus/core/src/server/ssr-handler.ts +13 -2
  55. package/corpus/core/src/settings/user-settings.ts +13 -1
  56. package/corpus/core/src/shared/cache-control.ts +141 -0
  57. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  58. package/corpus/core/src/templates/chat/_gitignore +1 -0
  59. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  60. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  61. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  62. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  63. package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  64. package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
  65. package/corpus/core/src/vite/client.ts +5 -0
  66. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
  67. package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
  68. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
  69. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
  70. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
  71. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
  72. package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
  73. package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
  74. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  75. package/corpus/templates/analytics/AGENTS.md +91 -563
  76. package/corpus/templates/analytics/_gitignore +1 -0
  77. package/corpus/templates/analytics/actions/bigquery.ts +12 -4
  78. package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
  79. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
  80. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
  81. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
  82. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
  83. package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
  85. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
  86. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
  87. package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
  88. package/corpus/templates/analytics/server/lib/notion.ts +15 -4
  89. package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
  90. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  91. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  92. package/corpus/templates/brain/_gitignore +1 -0
  93. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  94. package/corpus/templates/calendar/_gitignore +1 -0
  95. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  96. package/corpus/templates/chat/_gitignore +1 -0
  97. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  98. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
  99. package/corpus/templates/clips/AGENTS.md +5 -4
  100. package/corpus/templates/clips/_gitignore +1 -0
  101. package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
  102. package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
  103. package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
  104. package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
  105. package/corpus/templates/clips/actions/list-recordings.ts +69 -19
  106. package/corpus/templates/clips/actions/list-viewers.ts +5 -2
  107. package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
  108. package/corpus/templates/clips/actions/request-transcript.ts +28 -1
  109. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
  110. package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
  111. package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
  112. package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
  113. package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
  114. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
  115. package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
  116. package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
  117. package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
  118. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
  119. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +46 -15
  120. package/corpus/templates/clips/app/routes/record.tsx +77 -31
  121. package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
  122. package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
  123. package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
  124. package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
  125. package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
  126. package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
  127. package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
  128. package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
  129. package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
  130. package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
  131. package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
  132. package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
  133. package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
  134. 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
  135. package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
  136. package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
  137. package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
  138. package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
  139. package/corpus/templates/clips/desktop/package.json +2 -0
  140. package/corpus/templates/clips/desktop/src/app.tsx +89 -0
  141. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
  142. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
  143. package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
  144. package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
  145. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
  146. package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
  147. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
  148. package/corpus/templates/clips/desktop/src/styles.css +127 -78
  149. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
  150. package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
  151. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
  152. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
  153. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
  154. package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
  155. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
  156. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
  157. package/corpus/templates/clips/server/db/schema.ts +25 -0
  158. package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
  159. package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
  160. package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
  161. package/corpus/templates/clips/server/lib/recordings.ts +51 -3
  162. package/corpus/templates/clips/server/plugins/db.ts +23 -0
  163. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
  164. package/corpus/templates/clips/shared/recording-link.ts +43 -0
  165. package/corpus/templates/clips/shared/share-attribution.ts +4 -0
  166. package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
  167. package/corpus/templates/clips/shared/view-analytics.ts +26 -0
  168. package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
  169. package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
  170. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
  171. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
  172. package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
  173. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  174. package/corpus/templates/content/AGENTS.md +62 -583
  175. package/corpus/templates/content/_gitignore +1 -0
  176. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
  177. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
  178. package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
  179. package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
  180. package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
  181. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
  182. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  183. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
  184. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
  185. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
  186. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
  187. package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
  188. package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
  189. package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
  190. package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
  191. package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
  192. package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
  193. package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
  194. package/corpus/templates/design/AGENTS.md +88 -503
  195. package/corpus/templates/design/_gitignore +1 -0
  196. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  197. package/corpus/templates/dispatch/_gitignore +1 -0
  198. package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
  199. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  200. package/corpus/templates/forms/_gitignore +1 -0
  201. package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
  202. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  203. package/corpus/templates/macros/_gitignore +1 -0
  204. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  205. package/corpus/templates/mail/_gitignore +1 -0
  206. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  207. package/corpus/templates/plan/_gitignore +1 -0
  208. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  209. package/corpus/templates/slides/_gitignore +1 -0
  210. package/corpus/templates/slides/server/plugins/db.ts +4 -0
  211. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  212. package/corpus/templates/tasks/AGENTS.md +1 -1
  213. package/corpus/templates/tasks/_gitignore +1 -0
  214. package/dist/a2a/activity.d.ts +4 -1
  215. package/dist/a2a/activity.d.ts.map +1 -1
  216. package/dist/a2a/activity.js +27 -16
  217. package/dist/a2a/activity.js.map +1 -1
  218. package/dist/agent/engine/builder-engine.d.ts +1 -0
  219. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  220. package/dist/agent/engine/builder-engine.js +31 -4
  221. package/dist/agent/engine/builder-engine.js.map +1 -1
  222. package/dist/agent/run-manager.d.ts.map +1 -1
  223. package/dist/agent/run-manager.js +18 -1
  224. package/dist/agent/run-manager.js.map +1 -1
  225. package/dist/agent/run-store.d.ts +1 -0
  226. package/dist/agent/run-store.d.ts.map +1 -1
  227. package/dist/agent/run-store.js +2 -1
  228. package/dist/agent/run-store.js.map +1 -1
  229. package/dist/agent/types.d.ts +12 -1
  230. package/dist/agent/types.d.ts.map +1 -1
  231. package/dist/agent/types.js +21 -1
  232. package/dist/agent/types.js.map +1 -1
  233. package/dist/chat-threads/store.d.ts +10 -0
  234. package/dist/chat-threads/store.d.ts.map +1 -1
  235. package/dist/chat-threads/store.js +41 -0
  236. package/dist/chat-threads/store.js.map +1 -1
  237. package/dist/checkpoints/index.d.ts +1 -0
  238. package/dist/checkpoints/index.d.ts.map +1 -1
  239. package/dist/checkpoints/index.js +1 -0
  240. package/dist/checkpoints/index.js.map +1 -1
  241. package/dist/checkpoints/route-match.d.ts +8 -0
  242. package/dist/checkpoints/route-match.d.ts.map +1 -0
  243. package/dist/checkpoints/route-match.js +13 -0
  244. package/dist/checkpoints/route-match.js.map +1 -0
  245. package/dist/cli/create.d.ts +35 -4
  246. package/dist/cli/create.d.ts.map +1 -1
  247. package/dist/cli/create.js +69 -19
  248. package/dist/cli/create.js.map +1 -1
  249. package/dist/cli/index.js +19 -0
  250. package/dist/cli/index.js.map +1 -1
  251. package/dist/cli/template-baseline.d.ts +54 -0
  252. package/dist/cli/template-baseline.d.ts.map +1 -0
  253. package/dist/cli/template-baseline.js +334 -0
  254. package/dist/cli/template-baseline.js.map +1 -0
  255. package/dist/cli/template-sync.d.ts +57 -0
  256. package/dist/cli/template-sync.d.ts.map +1 -0
  257. package/dist/cli/template-sync.js +787 -0
  258. package/dist/cli/template-sync.js.map +1 -0
  259. package/dist/cli/templates-meta.d.ts.map +1 -1
  260. package/dist/cli/templates-meta.js +1 -0
  261. package/dist/cli/templates-meta.js.map +1 -1
  262. package/dist/client/AssistantChat.d.ts +2 -1
  263. package/dist/client/AssistantChat.d.ts.map +1 -1
  264. package/dist/client/AssistantChat.js +38 -10
  265. package/dist/client/AssistantChat.js.map +1 -1
  266. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  267. package/dist/client/NewWorkspaceAppFlow.js +32 -2
  268. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  269. package/dist/client/chat/message-components.d.ts +20 -0
  270. package/dist/client/chat/message-components.d.ts.map +1 -1
  271. package/dist/client/chat/message-components.js +81 -46
  272. package/dist/client/chat/message-components.js.map +1 -1
  273. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  274. package/dist/client/chat/tool-call-display.js +14 -6
  275. package/dist/client/chat/tool-call-display.js.map +1 -1
  276. package/dist/client/error-format.d.ts.map +1 -1
  277. package/dist/client/error-format.js +13 -0
  278. package/dist/client/error-format.js.map +1 -1
  279. package/dist/client/org/OrgSwitcher.d.ts +8 -1
  280. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  281. package/dist/client/org/OrgSwitcher.js +3 -2
  282. package/dist/client/org/OrgSwitcher.js.map +1 -1
  283. package/dist/client/org/TeamPage.d.ts.map +1 -1
  284. package/dist/client/org/TeamPage.js +1 -1
  285. package/dist/client/org/TeamPage.js.map +1 -1
  286. package/dist/client/sse-event-processor.d.ts.map +1 -1
  287. package/dist/client/sse-event-processor.js +3 -0
  288. package/dist/client/sse-event-processor.js.map +1 -1
  289. package/dist/collab/awareness.d.ts +2 -2
  290. package/dist/collab/awareness.d.ts.map +1 -1
  291. package/dist/data-widgets/index.d.ts +3 -0
  292. package/dist/data-widgets/index.d.ts.map +1 -1
  293. package/dist/data-widgets/index.js +33 -0
  294. package/dist/data-widgets/index.js.map +1 -1
  295. package/dist/deploy/build.d.ts.map +1 -1
  296. package/dist/deploy/build.js +11 -7
  297. package/dist/deploy/build.js.map +1 -1
  298. package/dist/eject/provider-api-definitions.d.ts +1 -0
  299. package/dist/eject/provider-api-definitions.d.ts.map +1 -1
  300. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  301. package/dist/integrations/webhook-handler.js +46 -9
  302. package/dist/integrations/webhook-handler.js.map +1 -1
  303. package/dist/notifications/routes.d.ts +3 -3
  304. package/dist/observability/routes.d.ts +3 -3
  305. package/dist/org/auto-join-domain.d.ts +3 -2
  306. package/dist/org/auto-join-domain.d.ts.map +1 -1
  307. package/dist/org/auto-join-domain.js +1 -1
  308. package/dist/org/auto-join-domain.js.map +1 -1
  309. package/dist/org/context.d.ts.map +1 -1
  310. package/dist/org/context.js +84 -28
  311. package/dist/org/context.js.map +1 -1
  312. package/dist/org/index.d.ts +1 -0
  313. package/dist/org/index.d.ts.map +1 -1
  314. package/dist/org/index.js +1 -0
  315. package/dist/org/index.js.map +1 -1
  316. package/dist/org/service-identity.d.ts +43 -0
  317. package/dist/org/service-identity.d.ts.map +1 -0
  318. package/dist/org/service-identity.js +34 -0
  319. package/dist/org/service-identity.js.map +1 -0
  320. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  321. package/dist/provider-api/actions/provider-api.d.ts +13 -11
  322. package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
  323. package/dist/provider-api/index.d.ts +4 -0
  324. package/dist/provider-api/index.d.ts.map +1 -1
  325. package/dist/provider-api/index.js +17 -1
  326. package/dist/provider-api/index.js.map +1 -1
  327. package/dist/resources/handlers.d.ts +1 -1
  328. package/dist/scripts/docs/search.d.ts.map +1 -1
  329. package/dist/scripts/docs/search.js +12 -1
  330. package/dist/scripts/docs/search.js.map +1 -1
  331. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  332. package/dist/server/agent-chat/context-tools.js +3 -3
  333. package/dist/server/agent-chat/context-tools.js.map +1 -1
  334. package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
  335. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  336. package/dist/server/agent-chat/framework-prompts.js +33 -62
  337. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  338. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  339. package/dist/server/agent-chat-plugin.js +16 -10
  340. package/dist/server/agent-chat-plugin.js.map +1 -1
  341. package/dist/server/agents-bundle.d.ts +18 -0
  342. package/dist/server/agents-bundle.d.ts.map +1 -1
  343. package/dist/server/agents-bundle.js +70 -4
  344. package/dist/server/agents-bundle.js.map +1 -1
  345. package/dist/server/auth.d.ts.map +1 -1
  346. package/dist/server/auth.js +4 -3
  347. package/dist/server/auth.js.map +1 -1
  348. package/dist/server/builder-browser.d.ts.map +1 -1
  349. package/dist/server/builder-browser.js +43 -19
  350. package/dist/server/builder-browser.js.map +1 -1
  351. package/dist/server/core-routes-plugin.js +2 -2
  352. package/dist/server/core-routes-plugin.js.map +1 -1
  353. package/dist/server/credential-provider.d.ts +38 -2
  354. package/dist/server/credential-provider.d.ts.map +1 -1
  355. package/dist/server/credential-provider.js +142 -64
  356. package/dist/server/credential-provider.js.map +1 -1
  357. package/dist/server/index.d.ts +1 -1
  358. package/dist/server/index.d.ts.map +1 -1
  359. package/dist/server/index.js +1 -1
  360. package/dist/server/index.js.map +1 -1
  361. package/dist/server/prompts/framework-core-compact.d.ts +1 -1
  362. package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
  363. package/dist/server/prompts/framework-core-compact.js +7 -13
  364. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  365. package/dist/server/prompts/framework-core.d.ts +1 -1
  366. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  367. package/dist/server/prompts/framework-core.js +10 -21
  368. package/dist/server/prompts/framework-core.js.map +1 -1
  369. package/dist/server/prompts/index.d.ts +1 -1
  370. package/dist/server/prompts/index.d.ts.map +1 -1
  371. package/dist/server/prompts/index.js +1 -1
  372. package/dist/server/prompts/index.js.map +1 -1
  373. package/dist/server/prompts/shared-rules.d.ts +16 -10
  374. package/dist/server/prompts/shared-rules.d.ts.map +1 -1
  375. package/dist/server/prompts/shared-rules.js +19 -10
  376. package/dist/server/prompts/shared-rules.js.map +1 -1
  377. package/dist/server/ssr-handler.d.ts +1 -1
  378. package/dist/server/ssr-handler.d.ts.map +1 -1
  379. package/dist/server/ssr-handler.js +10 -3
  380. package/dist/server/ssr-handler.js.map +1 -1
  381. package/dist/server/transcribe-voice.d.ts +1 -1
  382. package/dist/settings/user-settings.d.ts.map +1 -1
  383. package/dist/settings/user-settings.js +13 -1
  384. package/dist/settings/user-settings.js.map +1 -1
  385. package/dist/shared/cache-control.d.ts +52 -0
  386. package/dist/shared/cache-control.d.ts.map +1 -1
  387. package/dist/shared/cache-control.js +107 -0
  388. package/dist/shared/cache-control.js.map +1 -1
  389. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  390. package/dist/templates/chat/_gitignore +1 -0
  391. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  392. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  393. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  394. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  395. package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  396. package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
  397. package/dist/vite/agents-bundle-plugin.js +8 -7
  398. package/dist/vite/agents-bundle-plugin.js.map +1 -1
  399. package/dist/vite/client.d.ts.map +1 -1
  400. package/dist/vite/client.js +2 -0
  401. package/dist/vite/client.js.map +1 -1
  402. package/docs/content/actions.mdx +2 -2
  403. package/docs/content/agent-surfaces.mdx +1 -1
  404. package/docs/content/authentication.mdx +2 -0
  405. package/docs/content/deployment.mdx +36 -0
  406. package/docs/content/getting-started.mdx +477 -115
  407. package/docs/content/http-api.mdx +266 -0
  408. package/docs/content/syncing-template-changes.mdx +159 -0
  409. package/package.json +4 -3
  410. package/src/a2a/activity.ts +38 -27
  411. package/src/agent/engine/builder-engine.ts +35 -4
  412. package/src/agent/run-manager.ts +20 -1
  413. package/src/agent/run-store.ts +4 -1
  414. package/src/agent/types.ts +28 -8
  415. package/src/chat-threads/store.ts +45 -0
  416. package/src/checkpoints/index.ts +2 -0
  417. package/src/checkpoints/route-match.ts +13 -0
  418. package/src/cli/create.ts +105 -17
  419. package/src/cli/index.ts +20 -0
  420. package/src/cli/template-baseline.ts +410 -0
  421. package/src/cli/template-sync.ts +1004 -0
  422. package/src/cli/templates-meta.ts +1 -0
  423. package/src/client/AssistantChat.tsx +38 -12
  424. package/src/client/NewWorkspaceAppFlow.tsx +75 -10
  425. package/src/client/chat/message-components.tsx +127 -66
  426. package/src/client/chat/tool-call-display.tsx +29 -5
  427. package/src/client/error-format.ts +18 -0
  428. package/src/client/org/OrgSwitcher.tsx +30 -8
  429. package/src/client/org/TeamPage.tsx +7 -6
  430. package/src/client/sse-event-processor.ts +3 -0
  431. package/src/data-widgets/index.ts +41 -0
  432. package/src/deploy/build.ts +11 -9
  433. package/src/integrations/webhook-handler.ts +63 -9
  434. package/src/org/auto-join-domain.ts +4 -3
  435. package/src/org/context.ts +108 -39
  436. package/src/org/index.ts +5 -0
  437. package/src/org/service-identity.ts +60 -0
  438. package/src/provider-api/index.ts +22 -1
  439. package/src/scripts/docs/search.ts +12 -1
  440. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
  441. package/src/server/agent-chat/context-tools.ts +9 -4
  442. package/src/server/agent-chat/framework-prompts.ts +38 -66
  443. package/src/server/agent-chat-plugin.ts +17 -10
  444. package/src/server/agents-bundle.ts +84 -5
  445. package/src/server/auth.ts +4 -3
  446. package/src/server/builder-browser.ts +47 -19
  447. package/src/server/core-routes-plugin.ts +2 -2
  448. package/src/server/credential-provider.ts +209 -68
  449. package/src/server/index.ts +3 -0
  450. package/src/server/prompts/framework-core-compact.ts +6 -13
  451. package/src/server/prompts/framework-core.ts +9 -21
  452. package/src/server/prompts/index.ts +0 -1
  453. package/src/server/prompts/shared-rules.ts +19 -11
  454. package/src/server/ssr-handler.ts +13 -2
  455. package/src/settings/user-settings.ts +13 -1
  456. package/src/shared/cache-control.ts +141 -0
  457. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  458. package/src/templates/chat/_gitignore +1 -0
  459. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  460. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  461. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  462. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  463. package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  464. package/src/vite/agents-bundle-plugin.ts +7 -6
  465. package/src/vite/client.ts +5 -0
@@ -32,7 +32,13 @@ import {
32
32
  type LoaderFunctionArgs,
33
33
  type MetaFunction,
34
34
  } from "react-router";
35
- import { Link, useLoaderData, useNavigate, useParams } from "react-router";
35
+ import {
36
+ Link,
37
+ useLoaderData,
38
+ useNavigate,
39
+ useParams,
40
+ useSearchParams,
41
+ } from "react-router";
36
42
  import { toast } from "sonner";
37
43
 
38
44
  import { CaptureInstallButton } from "@/components/capture-install-options";
@@ -41,6 +47,7 @@ import { CommentsPanel } from "@/components/player/comments-panel";
41
47
  import { RecordingOptionsMenu } from "@/components/player/delete-recording-menu";
42
48
  import { InsightsPanel } from "@/components/player/insights-panel";
43
49
  import { ReactionsTray } from "@/components/player/reactions-tray";
50
+ import { RecordingViewsBadge } from "@/components/player/recording-views-badge";
44
51
  import { ShareRecordingPopover } from "@/components/player/share-dialog";
45
52
  import { SignInPromptDialog } from "@/components/player/sign-in-prompt-dialog";
46
53
  import { TranscriptPanel } from "@/components/player/transcript-panel";
@@ -82,6 +89,7 @@ import {
82
89
  buildSignupAttributionQuery,
83
90
  readShareAttribution,
84
91
  } from "../../shared/share-attribution";
92
+ import { resolveDashboardRedirect } from "../../shared/share-dashboard-redirect";
85
93
  import { privateShareLoaderData } from "../../shared/share-loader-response";
86
94
  import {
87
95
  buildClipsShareMeta,
@@ -344,6 +352,7 @@ export default function ShareRoute() {
344
352
  const loaderData = useLoaderData<typeof loader>() as SharePageLoaderData;
345
353
  const { shareId } = useParams<{ shareId: string }>();
346
354
  const navigate = useNavigate();
355
+ const [searchParams] = useSearchParams();
347
356
 
348
357
  // Viral attribution: read the `ref`/`via` the visitor arrived on (the tagged
349
358
  // share link) so we can fire funnel events and forward attribution into the
@@ -415,6 +424,7 @@ export default function ShareRoute() {
415
424
  null,
416
425
  );
417
426
  const [processingTimeout, setProcessingTimeout] = useState(false);
427
+ const [panel, setPanel] = useState("comments");
418
428
  const requireSignIn = useCallback(
419
429
  (intent: "comment" | "react") => setSignInIntent(intent),
420
430
  [],
@@ -499,6 +509,10 @@ export default function ShareRoute() {
499
509
  viewerRole === "admin" ||
500
510
  viewerRole === "editor";
501
511
  const viewerIsOwner = Boolean(dataQ.data?.data?.viewer?.isOwner);
512
+ const viewerCanOpenDashboard = Boolean(
513
+ dataQ.data?.data?.viewer?.canOpenDashboard,
514
+ );
515
+ const viewCount = Number(dataQ.data?.data?.viewCount ?? 0);
502
516
  const showTitleSkeleton = recording
503
517
  ? shouldShowGeneratedTitleSkeleton(recording, transcriptStatus)
504
518
  : false;
@@ -522,6 +536,21 @@ export default function ShareRoute() {
522
536
  document.title = clipsSharePageTitle(recording.title);
523
537
  }, [recording?.title]);
524
538
 
539
+ // /share/:id and /r/:id render the same clip, so anyone who can open the
540
+ // authenticated page goes straight there rather than through a redundant
541
+ // "open dashboard" button. `canOpenDashboard` is the server's own
542
+ // `canOpenDirectRecordingPage` verdict; deriving it from the display role
543
+ // instead would bounce viewers between the two routes forever, since /r
544
+ // sends anyone it rejects back here.
545
+ useEffect(() => {
546
+ const target = resolveDashboardRedirect({
547
+ recordingId: recording?.id,
548
+ canOpenDashboard: viewerCanOpenDashboard,
549
+ search: searchParams.toString(),
550
+ });
551
+ if (target) navigate(target, { replace: true });
552
+ }, [viewerCanOpenDashboard, recording?.id, searchParams, navigate]);
553
+
525
554
  // The /share/* shell skips DbSyncSetup (and thus useNavigationState), so the
526
555
  // agent mounted in the side panel has no navigation context. Write it
527
556
  // explicitly for signed-in viewers so view-screen grounds the chat to this
@@ -809,12 +838,6 @@ export default function ShareRoute() {
809
838
  {t("sharePage.signInIfYours")}
810
839
  </a>
811
840
  </Button>
812
- ) : canManageStorage && isFailure ? (
813
- <Button asChild size="sm">
814
- <a href={appPath(`/r/${recording.id}`)}>
815
- {t("sharePage.openDashboard")}
816
- </a>
817
- </Button>
818
841
  ) : null}
819
842
  <Button
820
843
  onClick={() => {
@@ -866,19 +889,13 @@ export default function ShareRoute() {
866
889
  </div>
867
890
 
868
891
  <div className="flex w-full min-w-0 flex-wrap items-center justify-between gap-2 sm:w-auto sm:justify-end">
869
- {viewerCanEdit ? (
870
- <Button variant="outline" size="sm" asChild>
871
- <a
872
- href={appPath(`/r/${recording.id}`)}
873
- className="min-w-0 gap-1.5"
874
- >
875
- <span className="truncate">
876
- {t("sharePage.openDashboard")}
877
- </span>
878
- <IconExternalLink className="h-3.5 w-3.5 shrink-0" />
879
- </a>
880
- </Button>
881
- ) : session ? null : (
892
+ <RecordingViewsBadge
893
+ recordingId={recording.id}
894
+ viewCount={viewCount}
895
+ canViewDetails={viewerCanEdit}
896
+ onOpenInsights={() => setPanel("insights")}
897
+ />
898
+ {session ? null : (
882
899
  <Button variant="ghost" size="sm" asChild>
883
900
  <a
884
901
  href={appPath("/")}
@@ -984,16 +1001,6 @@ export default function ShareRoute() {
984
1001
 
985
1002
  <div className="flex shrink-0 flex-col gap-3 px-4 pb-4 sm:flex-row sm:items-start sm:px-0 sm:pb-0">
986
1003
  <div className="min-w-0 flex-1">
987
- {showTitleSkeleton ? (
988
- <Skeleton
989
- aria-label={t("sharePage.generatingTitle")}
990
- className="h-5 w-72 max-w-full"
991
- />
992
- ) : (
993
- <h2 className="break-words text-base font-semibold leading-tight">
994
- {visibleTitle}
995
- </h2>
996
- )}
997
1004
  {recording.description ? (
998
1005
  <p className="whitespace-pre-wrap break-words text-sm text-muted-foreground">
999
1006
  {recording.description}
@@ -1058,7 +1065,11 @@ export default function ShareRoute() {
1058
1065
  </div>
1059
1066
 
1060
1067
  <aside className="flex min-h-[420px] w-full min-w-0 shrink-0 flex-col border-t border-border bg-background lg:min-h-0 lg:w-[380px] lg:border-s lg:border-t-0">
1061
- <Tabs defaultValue="comments" className="flex h-full flex-col">
1068
+ <Tabs
1069
+ value={panel}
1070
+ onValueChange={setPanel}
1071
+ className="flex h-full flex-col"
1072
+ >
1062
1073
  <TabsList className="mx-3 mt-3 grid w-auto grid-cols-4">
1063
1074
  <TabsTrigger value="comments" className="text-xs gap-1">
1064
1075
  {t("recordingPage.activity")}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Clip pages now show a view count with viewer avatars next to the title, and owners can click through to see who watched and how far they got.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Clip summaries read like a description you'd write yourself instead of narrating "the speaker", and the share page no longer repeats the title under the player
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Clip view counts now separate human views from agent views, showing which AI agents (Claude, ChatGPT, Perplexity) read a clip through its agent APIs
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Clips actions can now be called by org service tokens, so external systems like a support desk can import recordings automatically.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Clips no longer briefly shows a Dock icon while launching
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Fixed owner and editor share links redirecting to the recording dashboard
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Meeting and note recordings now start as a compact pill on the right edge with a live waveform that moves with the room, and the transcript view is grayscale with an Ask anything bar built in.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ New clips now copy a shareable link instead of the owner-only link, so the link auto-copied by the web recorder, desktop app, and Chrome extension works for everyone you paste it to
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Opening a share link as the clip's owner now goes straight to the full clip page instead of showing a near-identical page with an "Open dashboard" button.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Permissions and Rewind controls now use compact, consistent hover states
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Quitting the desktop app no longer shows a false macOS crash report
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Screen recording permission errors now name the exact app to allow in macOS System Settings, instead of pointing at an entry Clips never appears under
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ The desktop app now copies a new clip's public share link to your clipboard the moment a recording finishes and shows a notification confirming it, so it's ready to paste straight into Slack
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ The recording toolbar now stays above other apps, including on fullscreen and other Spaces
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Transcript captions now use real speech timings instead of an estimated even spread
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Video playback no longer stutters and replays the last moment during a clip
@@ -1,3 +1,5 @@
1
+ import { buildRecordingShareUrl } from "@shared/recording-link";
2
+
1
3
  import {
2
4
  restartUploadModeFromResponse,
3
5
  restartUploadResetBody,
@@ -1080,12 +1082,26 @@ function sendOffscreenMessage<T>(message: Record<string, unknown>): Promise<T> {
1080
1082
  });
1081
1083
  }
1082
1084
 
1085
+ // The author's own dashboard. Fine to OPEN for the person who just recorded;
1086
+ // never the thing to hand someone else — see recordingShareUrl below.
1083
1087
  function recordingUrl(
1084
1088
  recording: Pick<NativeRecording, "clipsBaseUrl" | "recordingId">,
1085
1089
  ): string {
1086
1090
  return `${recording.clipsBaseUrl}/r/${encodeURIComponent(recording.recordingId)}`;
1087
1091
  }
1088
1092
 
1093
+ // The extension only stores the signed-in user's token and email; email is PII
1094
+ // and must never become the `via` attribution param, so share URLs go out
1095
+ // without an owner id.
1096
+ function recordingShareUrl(
1097
+ recording: Pick<NativeRecording, "clipsBaseUrl" | "recordingId">,
1098
+ ): string {
1099
+ return buildRecordingShareUrl({
1100
+ recordingId: recording.recordingId,
1101
+ origin: recording.clipsBaseUrl,
1102
+ });
1103
+ }
1104
+
1089
1105
  async function copyRecordingUrlToClipboard(
1090
1106
  recording: NativeRecording,
1091
1107
  ): Promise<void> {
@@ -1093,7 +1109,7 @@ async function copyRecordingUrlToClipboard(
1093
1109
  await ensureOffscreenDocument();
1094
1110
  await sendOffscreenMessage({
1095
1111
  type: "CLIPS_OFFSCREEN_COPY_TEXT",
1096
- text: recording.recordingUrl,
1112
+ text: recordingShareUrl(recording),
1097
1113
  });
1098
1114
  } catch (err) {
1099
1115
  console.warn("[clips-bg] could not copy recording URL", err);
@@ -23,7 +23,9 @@
23
23
  "@sentry/browser": "10.62.0",
24
24
  "@tabler/icons-react": "catalog:",
25
25
  "@tauri-apps/api": "^2.11.0",
26
+ "@tauri-apps/plugin-clipboard-manager": "^2.3.2",
26
27
  "@tauri-apps/plugin-fs": "2.5.1",
28
+ "@tauri-apps/plugin-notification": "^2.3.3",
27
29
  "@tauri-apps/plugin-process": "^2.3.1",
28
30
  "@tauri-apps/plugin-shell": "^2.3.5",
29
31
  "@tauri-apps/plugin-updater": "^2.10.1",
@@ -63,6 +63,7 @@ import {
63
63
  getCameraStreamWithFallback,
64
64
  isMediaConstraintFailure,
65
65
  } from "./lib/media-capture-constraints";
66
+ import { sendNativeNotification } from "./lib/native-notification";
66
67
  import { openMeetingJoinUrl } from "./lib/open-meeting-join-url";
67
68
  import {
68
69
  DESKTOP_CAPTURE_PERMISSION_MESSAGE,
@@ -88,6 +89,10 @@ import {
88
89
  type RecorderHandle,
89
90
  type RecorderStopResult,
90
91
  } from "./lib/recorder";
92
+ import {
93
+ copyRecordingShareLink,
94
+ recordingShareUrl,
95
+ } from "./lib/recording-link";
91
96
  import { REWIND_AGENT_PROMPT } from "./lib/rewind-agent-prompt";
92
97
  import { getRewindStatusPresentation } from "./lib/rewind-status";
93
98
  import {
@@ -208,6 +213,13 @@ interface LocalRecordingNotice {
208
213
  files: LocalExportedFile[];
209
214
  }
210
215
 
216
+ interface ShareLinkNotice {
217
+ recordingId: string;
218
+ origin: string;
219
+ url: string;
220
+ copied: boolean;
221
+ }
222
+
211
223
  interface ScreenMemoryExportResult {
212
224
  folderPath: string;
213
225
  files: Array<{
@@ -907,6 +919,8 @@ export function App() {
907
919
  );
908
920
  const [localRecordingNotice, setLocalRecordingNotice] =
909
921
  useState<LocalRecordingNotice | null>(null);
922
+ const [shareLinkNotice, setShareLinkNotice] =
923
+ useState<ShareLinkNotice | null>(null);
910
924
  const [popoverView, setPopoverView] = useState<PopoverView>("recorder");
911
925
  const [rewindSettingsReturnView, setRewindSettingsReturnView] = useState<
912
926
  "recorder" | "settings"
@@ -2565,6 +2579,32 @@ export function App() {
2565
2579
  });
2566
2580
  }
2567
2581
 
2582
+ // Never rejects: a clipboard failure must not be mistaken for a failed
2583
+ // recording by the stop/retry callers that await this inside their try block.
2584
+ async function copyShareLink(
2585
+ recordingId: string,
2586
+ origin = serverUrl,
2587
+ { notify = true }: { notify?: boolean } = {},
2588
+ ) {
2589
+ try {
2590
+ const url = recordingShareUrl(recordingId, origin);
2591
+ const copied = await copyRecordingShareLink(recordingId, origin);
2592
+ setShareLinkNotice({ recordingId, origin, url, copied });
2593
+ // The popover hides right after an automatic copy, so the banner below is
2594
+ // only seen on the next open — the OS notification is the live signal.
2595
+ if (copied && notify) {
2596
+ await sendNativeNotification({
2597
+ title: "Link copied",
2598
+ body: "Your clip link is ready to paste.",
2599
+ });
2600
+ }
2601
+ return copied;
2602
+ } catch (err) {
2603
+ console.error("[clips-tray] copy share link failed:", err);
2604
+ return false;
2605
+ }
2606
+ }
2607
+
2568
2608
  async function retryPendingUpload(upload: PendingDesktopUpload) {
2569
2609
  if (retryingUploadId || exportingUploadId || dismissingUploadId) return;
2570
2610
  const targetServerUrl = serverUrlForPendingUpload(upload, serverUrl);
@@ -2598,6 +2638,7 @@ export function App() {
2598
2638
  });
2599
2639
  }
2600
2640
  await loadPendingUploads();
2641
+ await copyShareLink(upload.recordingId, targetServerUrl);
2601
2642
  await openExternal(`${targetServerUrl}/r/${upload.recordingId}`);
2602
2643
  getCurrentWindow()
2603
2644
  .hide()
@@ -2737,6 +2778,7 @@ export function App() {
2737
2778
  }
2738
2779
  setRecError(null);
2739
2780
  setLocalRecordingNotice(null);
2781
+ setShareLinkNotice(null);
2740
2782
  console.log("[clips-popover] handleStartRecording clicked", {
2741
2783
  serverUrl,
2742
2784
  mode,
@@ -3101,6 +3143,10 @@ export function App() {
3101
3143
  });
3102
3144
  } else {
3103
3145
  setLastRecordingId(stopResult.recordingId);
3146
+ // The browser opens `/r/<id>` (the author's dashboard); what lands
3147
+ // on the clipboard must be the public `/share/<id>` link, which is
3148
+ // the one a recipient can actually open.
3149
+ await copyShareLink(stopResult.recordingId);
3104
3150
  }
3105
3151
  } catch (err) {
3106
3152
  stopFailed = true;
@@ -3639,6 +3685,20 @@ export function App() {
3639
3685
  />
3640
3686
  ) : null}
3641
3687
 
3688
+ {shareLinkNotice ? (
3689
+ <ShareLinkBanner
3690
+ notice={shareLinkNotice}
3691
+ onCopy={() => {
3692
+ void copyShareLink(
3693
+ shareLinkNotice.recordingId,
3694
+ shareLinkNotice.origin,
3695
+ { notify: false },
3696
+ );
3697
+ }}
3698
+ onDismiss={() => setShareLinkNotice(null)}
3699
+ />
3700
+ ) : null}
3701
+
3642
3702
  <div className="panel">
3643
3703
  {showSourceRow ? (
3644
3704
  <SourceRow
@@ -4233,6 +4293,35 @@ function LocalRecordingSavedBanner({
4233
4293
  );
4234
4294
  }
4235
4295
 
4296
+ function ShareLinkBanner({
4297
+ notice,
4298
+ onCopy,
4299
+ onDismiss,
4300
+ }: {
4301
+ notice: ShareLinkNotice;
4302
+ onCopy: () => void;
4303
+ onDismiss: () => void;
4304
+ }) {
4305
+ return (
4306
+ <div className="share-link-banner">
4307
+ <div className="local-save-copy">
4308
+ <div className="local-save-title">
4309
+ {notice.copied ? "Share link copied" : "Share link ready"}
4310
+ </div>
4311
+ <div className="local-save-sub">{notice.url}</div>
4312
+ </div>
4313
+ {notice.copied ? null : (
4314
+ <button type="button" onClick={onCopy}>
4315
+ Copy
4316
+ </button>
4317
+ )}
4318
+ <button type="button" className="local-save-dismiss" onClick={onDismiss}>
4319
+ Dismiss
4320
+ </button>
4321
+ </div>
4322
+ );
4323
+ }
4324
+
4236
4325
  function Header({
4237
4326
  mode,
4238
4327
  onModeChange,
@@ -830,13 +830,19 @@ export function useMeetingTranscription({
830
830
  );
831
831
 
832
832
  unlistens.push(
833
- listen<{ meetingId: string; openChat?: boolean }>(
833
+ listen<{ meetingId: string; openChat?: boolean; prompt?: string }>(
834
834
  "clips:open-meeting",
835
835
  (ev) => {
836
836
  if (!ev.payload?.meetingId) return;
837
- const query = ev.payload.openChat ? "?chat=1" : "";
837
+ const params = new URLSearchParams();
838
+ if (ev.payload.openChat) params.set("chat", "1");
839
+ const prompt = ev.payload.prompt?.trim();
840
+ if (prompt) params.set("ask", prompt);
841
+ const query = params.toString();
838
842
  openExternal(
839
- `${normalizedServerUrl}/meetings/${ev.payload.meetingId}${query}`,
843
+ `${normalizedServerUrl}/meetings/${ev.payload.meetingId}${
844
+ query ? `?${query}` : ""
845
+ }`,
840
846
  ).catch((err) =>
841
847
  console.warn("[clips-popover] open meeting in web failed:", err),
842
848
  );
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Level math for the Granola-style waveform meter on the recording pill.
3
+ *
4
+ * Kept separate from the React overlay so the "bars must track how loud people
5
+ * are talking" behaviour is unit-testable without a DOM.
6
+ */
7
+
8
+ /** Per-bar scale. The middle bar swings widest, like Granola's meter. */
9
+ export const METER_BAR_GAINS = [0.72, 1, 0.84];
10
+ export const METER_BAR_COUNT = METER_BAR_GAINS.length;
11
+ /** Height (0-1) each bar keeps at silence, so the meter idles as three dots. */
12
+ export const METER_IDLE_HEIGHT = 0.14;
13
+ /** Multiplier applied on every sample tick when no louder audio arrives. */
14
+ export const METER_LEVEL_DECAY = 0.82;
15
+ /** Floor a new sample must clear, so the meter falls smoothly instead of snapping. */
16
+ export const METER_ATTACK_DECAY = 0.55;
17
+ export const METER_SAMPLE_MS = 50;
18
+
19
+ /** Fold an incoming 0-1 audio level into the current level. */
20
+ export function nextMeterLevel(current: number, incoming: number): number {
21
+ if (!Number.isFinite(incoming)) return current;
22
+ const clamped = Math.max(0, Math.min(1, incoming));
23
+ return Math.max(current * METER_ATTACK_DECAY, clamped);
24
+ }
25
+
26
+ /** One decay tick. Snaps to silence below a threshold so bars settle at rest. */
27
+ export function decayMeterLevel(current: number): number {
28
+ const decayed = current * METER_LEVEL_DECAY;
29
+ return decayed < 0.01 ? 0 : decayed;
30
+ }
31
+
32
+ /**
33
+ * Push the newest sample onto the front of the meter's history. Bar 0 shows
34
+ * the newest level and older levels travel outward, so the bars ripple against
35
+ * each other instead of moving as one block.
36
+ */
37
+ export function advanceMeterLevels(levels: number[], sample: number): number[] {
38
+ return [sample, ...levels.slice(0, METER_BAR_COUNT - 1)];
39
+ }
40
+
41
+ /**
42
+ * Bar height as a percentage of the meter's box. Peak levels from speech taps
43
+ * are often quiet even when speech is clear, so a gentle curve keeps the meter
44
+ * responsive without turning background noise into a full-height signal.
45
+ */
46
+ export function meterBarHeight(level: number, barIndex: number): number {
47
+ const gain = METER_BAR_GAINS[barIndex] ?? 1;
48
+ const safe = Number.isFinite(level) ? Math.max(0, Math.min(1, level)) : 0;
49
+ const shaped = safe > 0 ? Math.min(1, Math.pow(safe, 0.52) * 1.08) : 0;
50
+ return (METER_IDLE_HEIGHT + shaped * gain * (1 - METER_IDLE_HEIGHT)) * 100;
51
+ }
@@ -0,0 +1,44 @@
1
+ import {
2
+ isPermissionGranted,
3
+ requestPermission,
4
+ sendNotification,
5
+ } from "@tauri-apps/plugin-notification";
6
+
7
+ export interface NativeNotification {
8
+ title: string;
9
+ body?: string;
10
+ }
11
+
12
+ export interface NativeNotificationDeps {
13
+ isPermissionGranted: () => Promise<boolean>;
14
+ requestPermission: () => Promise<NotificationPermission>;
15
+ sendNotification: (notification: NativeNotification) => void;
16
+ }
17
+
18
+ const tauriNotificationDeps: NativeNotificationDeps = {
19
+ isPermissionGranted,
20
+ requestPermission,
21
+ sendNotification,
22
+ };
23
+
24
+ /**
25
+ * Post an OS notification, requesting permission first when the user has not
26
+ * answered yet. Never rejects: callers await this inside recording stop/retry
27
+ * try blocks, where a throw would be reported as a failed recording.
28
+ */
29
+ export async function sendNativeNotification(
30
+ notification: NativeNotification,
31
+ deps: NativeNotificationDeps = tauriNotificationDeps,
32
+ ): Promise<boolean> {
33
+ try {
34
+ const granted =
35
+ (await deps.isPermissionGranted()) ||
36
+ (await deps.requestPermission()) === "granted";
37
+ if (!granted) return false;
38
+ deps.sendNotification(notification);
39
+ return true;
40
+ } catch (err) {
41
+ console.warn("[clips-tray] native notification failed:", err);
42
+ return false;
43
+ }
44
+ }
@@ -0,0 +1,67 @@
1
+ import { writeText } from "@tauri-apps/plugin-clipboard-manager";
2
+
3
+ import { buildRecordingShareUrl } from "../../../shared/recording-link";
4
+ import { normalizeServerUrl } from "./url";
5
+
6
+ /**
7
+ * Absolute, paste-ready `/share/<id>` URL. Never `/r/<id>` — that is the owner
8
+ * dashboard and renders a sign-in prompt for anyone the link is sent to.
9
+ */
10
+ export function recordingShareUrl(
11
+ recordingId: string,
12
+ serverUrl: string,
13
+ ): string {
14
+ return buildRecordingShareUrl({
15
+ recordingId,
16
+ origin: normalizeServerUrl(serverUrl),
17
+ });
18
+ }
19
+
20
+ async function writeClipboardText(text: string): Promise<boolean> {
21
+ // Rust-side write first: at recording-stop time the popover webview is
22
+ // usually not focused, and `navigator.clipboard.writeText` rejects with
23
+ // `NotAllowedError: Document is not focused` in exactly that case.
24
+ try {
25
+ await writeText(text);
26
+ return true;
27
+ } catch (err) {
28
+ console.warn("[clips-tray] native clipboard write failed:", err);
29
+ }
30
+
31
+ try {
32
+ await navigator.clipboard.writeText(text);
33
+ return true;
34
+ } catch (err) {
35
+ console.warn("[clips-tray] navigator clipboard write failed:", err);
36
+ }
37
+
38
+ try {
39
+ const textarea = document.createElement("textarea");
40
+ textarea.value = text;
41
+ textarea.setAttribute("readonly", "");
42
+ textarea.style.position = "fixed";
43
+ textarea.style.opacity = "0";
44
+ textarea.style.pointerEvents = "none";
45
+ document.body.appendChild(textarea);
46
+ textarea.select();
47
+ textarea.setSelectionRange(0, text.length);
48
+ const copied = document.execCommand("copy");
49
+ document.body.removeChild(textarea);
50
+ return copied;
51
+ } catch (err) {
52
+ console.warn("[clips-tray] execCommand clipboard write failed:", err);
53
+ return false;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Copy a recording's public share URL. Resolves to whether the clipboard
59
+ * actually took the text so callers never claim a copy that did not happen.
60
+ */
61
+ export async function copyRecordingShareLink(
62
+ recordingId: string,
63
+ serverUrl: string,
64
+ ): Promise<boolean> {
65
+ if (!recordingId.trim() || !normalizeServerUrl(serverUrl)) return false;
66
+ return writeClipboardText(recordingShareUrl(recordingId, serverUrl));
67
+ }