@agent-native/core 0.98.17 → 0.99.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 (583) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +25 -0
  3. package/corpus/core/docs/content/actions.mdx +1 -1
  4. package/corpus/core/docs/content/authentication.mdx +1 -1
  5. package/corpus/core/docs/content/dispatch.mdx +3 -3
  6. package/corpus/core/docs/content/external-agents.mdx +30 -19
  7. package/corpus/core/docs/content/locales/ar-SA/actions.mdx +1 -1
  8. package/corpus/core/docs/content/locales/ar-SA/authentication.mdx +1 -1
  9. package/corpus/core/docs/content/locales/ar-SA/dispatch.mdx +3 -3
  10. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +23 -19
  11. package/corpus/core/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
  12. package/corpus/core/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
  13. package/corpus/core/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
  14. package/corpus/core/docs/content/locales/ar-SA/server.mdx +2 -2
  15. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
  16. package/corpus/core/docs/content/locales/ar-SA/template-assets.mdx +1 -1
  17. package/corpus/core/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
  18. package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +3 -3
  19. package/corpus/core/docs/content/locales/de-DE/actions.mdx +1 -1
  20. package/corpus/core/docs/content/locales/de-DE/authentication.mdx +1 -1
  21. package/corpus/core/docs/content/locales/de-DE/dispatch.mdx +3 -3
  22. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +23 -19
  23. package/corpus/core/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
  24. package/corpus/core/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
  25. package/corpus/core/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
  26. package/corpus/core/docs/content/locales/de-DE/server.mdx +2 -2
  27. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +1 -1
  28. package/corpus/core/docs/content/locales/de-DE/template-assets.mdx +1 -1
  29. package/corpus/core/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
  30. package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +3 -3
  31. package/corpus/core/docs/content/locales/es-ES/actions.mdx +1 -1
  32. package/corpus/core/docs/content/locales/es-ES/authentication.mdx +1 -1
  33. package/corpus/core/docs/content/locales/es-ES/dispatch.mdx +3 -3
  34. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +32 -19
  35. package/corpus/core/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
  36. package/corpus/core/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
  37. package/corpus/core/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
  38. package/corpus/core/docs/content/locales/es-ES/server.mdx +2 -2
  39. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +1 -1
  40. package/corpus/core/docs/content/locales/es-ES/template-assets.mdx +1 -1
  41. package/corpus/core/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
  42. package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +3 -3
  43. package/corpus/core/docs/content/locales/fr-FR/actions.mdx +1 -1
  44. package/corpus/core/docs/content/locales/fr-FR/authentication.mdx +1 -1
  45. package/corpus/core/docs/content/locales/fr-FR/dispatch.mdx +3 -3
  46. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +23 -19
  47. package/corpus/core/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
  48. package/corpus/core/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
  49. package/corpus/core/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
  50. package/corpus/core/docs/content/locales/fr-FR/server.mdx +2 -2
  51. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
  52. package/corpus/core/docs/content/locales/fr-FR/template-assets.mdx +1 -1
  53. package/corpus/core/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
  54. package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +3 -3
  55. package/corpus/core/docs/content/locales/hi-IN/actions.mdx +1 -1
  56. package/corpus/core/docs/content/locales/hi-IN/authentication.mdx +1 -1
  57. package/corpus/core/docs/content/locales/hi-IN/dispatch.mdx +3 -3
  58. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +31 -19
  59. package/corpus/core/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
  60. package/corpus/core/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
  61. package/corpus/core/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
  62. package/corpus/core/docs/content/locales/hi-IN/server.mdx +2 -2
  63. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
  64. package/corpus/core/docs/content/locales/hi-IN/template-assets.mdx +1 -1
  65. package/corpus/core/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
  66. package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +3 -3
  67. package/corpus/core/docs/content/locales/ja-JP/actions.mdx +1 -1
  68. package/corpus/core/docs/content/locales/ja-JP/authentication.mdx +1 -1
  69. package/corpus/core/docs/content/locales/ja-JP/dispatch.mdx +3 -3
  70. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +23 -19
  71. package/corpus/core/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
  72. package/corpus/core/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
  73. package/corpus/core/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
  74. package/corpus/core/docs/content/locales/ja-JP/server.mdx +2 -2
  75. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
  76. package/corpus/core/docs/content/locales/ja-JP/template-assets.mdx +1 -1
  77. package/corpus/core/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
  78. package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +3 -3
  79. package/corpus/core/docs/content/locales/ko-KR/actions.mdx +1 -1
  80. package/corpus/core/docs/content/locales/ko-KR/authentication.mdx +1 -1
  81. package/corpus/core/docs/content/locales/ko-KR/dispatch.mdx +3 -3
  82. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +30 -19
  83. package/corpus/core/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
  84. package/corpus/core/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
  85. package/corpus/core/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
  86. package/corpus/core/docs/content/locales/ko-KR/server.mdx +2 -2
  87. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
  88. package/corpus/core/docs/content/locales/ko-KR/template-assets.mdx +1 -1
  89. package/corpus/core/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
  90. package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +3 -3
  91. package/corpus/core/docs/content/locales/pt-BR/actions.mdx +1 -1
  92. package/corpus/core/docs/content/locales/pt-BR/authentication.mdx +1 -1
  93. package/corpus/core/docs/content/locales/pt-BR/dispatch.mdx +3 -3
  94. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +32 -19
  95. package/corpus/core/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
  96. package/corpus/core/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
  97. package/corpus/core/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
  98. package/corpus/core/docs/content/locales/pt-BR/server.mdx +2 -2
  99. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
  100. package/corpus/core/docs/content/locales/pt-BR/template-assets.mdx +1 -1
  101. package/corpus/core/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
  102. package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +3 -3
  103. package/corpus/core/docs/content/locales/zh-CN/actions.mdx +1 -1
  104. package/corpus/core/docs/content/locales/zh-CN/authentication.mdx +1 -1
  105. package/corpus/core/docs/content/locales/zh-CN/dispatch.mdx +3 -3
  106. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +23 -19
  107. package/corpus/core/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
  108. package/corpus/core/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
  109. package/corpus/core/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
  110. package/corpus/core/docs/content/locales/zh-CN/server.mdx +2 -2
  111. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
  112. package/corpus/core/docs/content/locales/zh-CN/template-assets.mdx +1 -1
  113. package/corpus/core/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
  114. package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +3 -3
  115. package/corpus/core/docs/content/locales/zh-TW/actions.mdx +1 -1
  116. package/corpus/core/docs/content/locales/zh-TW/authentication.mdx +1 -1
  117. package/corpus/core/docs/content/locales/zh-TW/dispatch.mdx +3 -3
  118. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +23 -19
  119. package/corpus/core/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
  120. package/corpus/core/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
  121. package/corpus/core/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
  122. package/corpus/core/docs/content/locales/zh-TW/server.mdx +2 -2
  123. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
  124. package/corpus/core/docs/content/locales/zh-TW/template-assets.mdx +1 -1
  125. package/corpus/core/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
  126. package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +3 -3
  127. package/corpus/core/docs/content/mcp-clients.mdx +31 -4
  128. package/corpus/core/docs/content/mcp-protocol.mdx +35 -15
  129. package/corpus/core/docs/content/plan-plugin.mdx +3 -3
  130. package/corpus/core/docs/content/server.mdx +2 -2
  131. package/corpus/core/docs/content/skills-guide.mdx +1 -1
  132. package/corpus/core/docs/content/template-assets.mdx +1 -1
  133. package/corpus/core/docs/content/template-dispatch.mdx +2 -2
  134. package/corpus/core/docs/content/template-plan.mdx +3 -3
  135. package/corpus/core/package.json +1 -1
  136. package/corpus/core/src/a2a/client.ts +3 -0
  137. package/corpus/core/src/a2a/handlers.ts +95 -7
  138. package/corpus/core/src/agent/production-agent.ts +21 -0
  139. package/corpus/core/src/cli/connect.ts +50 -24
  140. package/corpus/core/src/cli/mcp-config-writers.ts +10 -0
  141. package/corpus/core/src/cli/mcp.ts +5 -5
  142. package/corpus/core/src/cli/pr-visual-recap-workflow.ts +1 -1
  143. package/corpus/core/src/cli/skills-content/assets-skill.ts +1 -1
  144. package/corpus/core/src/cli/skills-content/design-exploration-skill.ts +1 -1
  145. package/corpus/core/src/cli/skills-content/help.ts +1 -1
  146. package/corpus/core/src/cli/skills-content/plan-setup-auth.ts +1 -1
  147. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +1 -1
  148. package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +2 -2
  149. package/corpus/core/src/cli/skills.ts +23 -12
  150. package/corpus/core/src/client/analytics.ts +13 -0
  151. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +5 -0
  152. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +17 -0
  153. package/corpus/core/src/embedding/agent.ts +8 -6
  154. package/corpus/core/src/localization/default-messages.ts +7 -0
  155. package/corpus/core/src/mcp/ask-app-inline-tasks.ts +125 -0
  156. package/corpus/core/src/mcp/build-server.ts +65 -3
  157. package/corpus/core/src/mcp/builtin-tools.ts +186 -22
  158. package/corpus/core/src/mcp/connect-route.ts +17 -14
  159. package/corpus/core/src/mcp/oauth-route.ts +38 -13
  160. package/corpus/core/src/mcp/route-paths.ts +34 -0
  161. package/corpus/core/src/mcp/server.ts +21 -10
  162. package/corpus/core/src/mcp/stdio.ts +34 -16
  163. package/corpus/core/src/mcp/workspace-resolve.ts +2 -1
  164. package/corpus/core/src/mcp-client/manager.ts +5 -3
  165. package/corpus/core/src/mcp-client/remote-store.ts +10 -10
  166. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +13 -0
  167. package/corpus/core/src/server/agent-chat-plugin.ts +42 -9
  168. package/corpus/core/src/server/agent-teams.ts +17 -0
  169. package/corpus/core/src/server/auth.ts +22 -6
  170. package/corpus/core/src/server/core-routes-plugin.ts +30 -24
  171. package/corpus/core/src/server/csrf.ts +17 -0
  172. package/corpus/core/src/server/framework-request-handler.ts +8 -2
  173. package/corpus/core/src/server/google-oauth.ts +12 -2
  174. package/corpus/core/src/server/http-response-telemetry.ts +6 -1
  175. package/corpus/core/src/server/recap-image-route.ts +3 -3
  176. package/corpus/core/src/server/security-headers.ts +7 -1
  177. package/corpus/core/src/server/ssr-handler.ts +2 -0
  178. package/corpus/core/src/shared/cache-control.ts +6 -4
  179. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +10 -0
  180. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  181. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  182. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  183. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
  184. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +10 -0
  185. package/corpus/templates/analytics/app/assets/replay-cursor.svg +17 -0
  186. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +4 -3
  187. package/corpus/templates/analytics/app/global.css +71 -4
  188. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +32 -4
  189. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +1 -1
  190. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +49 -11
  191. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -6
  192. package/corpus/templates/analytics/changelog/2026-07-13-all-time-dashboard-filters-no-longer-send-invalid-dates-to-b.md +6 -0
  193. package/corpus/templates/analytics/changelog/2026-07-13-daily-dashboard-emails-recover-more-reliably-from-serverless.md +6 -0
  194. package/corpus/templates/analytics/changelog/2026-07-13-error-issue-titles-wrap-instead-of-overflowing.md +6 -0
  195. package/corpus/templates/analytics/changelog/2026-07-13-saving-a-new-dashboard-view-no-longer-fails-with-a-server-er.md +6 -0
  196. package/corpus/templates/analytics/changelog/2026-07-13-session-replay-cursors-stay-hidden-until-their-first-recorde.md +6 -0
  197. package/corpus/templates/analytics/changelog/2026-07-13-session-replay-links-now-support-cmd-click-and-middle-click-.md +6 -0
  198. package/corpus/templates/analytics/changelog/2026-07-13-session-replays-keep-a-visible-mac-style-cursor-over-the-vis.md +6 -0
  199. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +21 -2
  200. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +57 -1
  201. package/corpus/templates/analytics/server/lib/dashboard-report.ts +266 -28
  202. package/corpus/templates/analytics/server/lib/dashboards-store.ts +43 -4
  203. package/corpus/templates/analytics/server/lib/error-capture.ts +24 -5
  204. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  205. package/corpus/templates/analytics/server/routes/[...page].get.ts +0 -2
  206. package/corpus/templates/assets/.agents/skills/security/SKILL.md +10 -0
  207. package/corpus/templates/assets/agent-native.app-skill.json +1 -1
  208. package/corpus/templates/brain/.agents/skills/security/SKILL.md +10 -0
  209. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +10 -0
  210. package/corpus/templates/calendar/AGENTS.md +2 -1
  211. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -19
  212. package/corpus/templates/calendar/app/lib/attendee-local-time.ts +14 -5
  213. package/corpus/templates/calendar/changelog/2026-07-13-your-local-time-now-follows-your-browser-timezone-and-event-.md +6 -0
  214. package/corpus/templates/chat/.agents/skills/security/SKILL.md +10 -0
  215. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +7 -2
  216. package/corpus/templates/clips/.agents/skills/security/SKILL.md +10 -0
  217. package/corpus/templates/clips/AGENTS.md +7 -0
  218. package/corpus/templates/clips/actions/list-meetings.ts +19 -4
  219. package/corpus/templates/clips/actions/start-meeting-recording.ts +7 -1
  220. package/corpus/templates/clips/app/components/library/recording-card.tsx +27 -26
  221. package/corpus/templates/clips/app/components/library/space-card.tsx +4 -6
  222. package/corpus/templates/clips/app/components/meetings/transcript-bubbles.tsx +75 -78
  223. package/corpus/templates/clips/app/components/recorder/confetti-canvas.tsx +18 -1
  224. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +6 -12
  225. package/corpus/templates/clips/app/components/recorder/recording-toolbar.tsx +19 -2
  226. package/corpus/templates/clips/app/lib/camera-composite.ts +70 -10
  227. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -1
  228. package/corpus/templates/clips/app/routes/record.tsx +5 -25
  229. package/corpus/templates/clips/changelog/2026-07-13-clips-desktop-now-requires-macos-13-for-native-capture.md +6 -0
  230. package/corpus/templates/clips/changelog/2026-07-13-clips-hide-solo-meeting-reminders.md +6 -0
  231. package/corpus/templates/clips/changelog/2026-07-13-clips-now-removes-duplicate-mic-and-system-transcript-turns-.md +6 -0
  232. package/corpus/templates/clips/changelog/2026-07-13-desktop-recordings-run-cooler-and-quieter-live-transcription.md +6 -0
  233. package/corpus/templates/clips/changelog/2026-07-13-meeting-recordings-now-stop-after-a-calendar-meeting-ends-an.md +6 -0
  234. package/corpus/templates/clips/changelog/2026-07-13-meeting-transcripts-now-use-a-clean-agent-chat-style-reading.md +6 -0
  235. package/corpus/templates/clips/changelog/2026-07-13-screen-recordings-use-less-processing-power-during-longer-ca.md +6 -0
  236. package/corpus/templates/clips/chrome-extension/src/background.ts +5 -3
  237. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +17 -14
  238. package/corpus/templates/clips/chrome-extension/src/overlay.ts +8 -2
  239. package/corpus/templates/clips/desktop/README.md +3 -0
  240. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -0
  241. package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -2
  242. package/corpus/templates/clips/desktop/src/lib/silence-events.ts +1 -0
  243. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +5 -0
  244. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +134 -5
  245. package/corpus/templates/clips/desktop/src/lib/upload-video-stream.ts +28 -0
  246. package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +10 -3
  247. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +42 -9
  248. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -2
  249. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +6 -1
  250. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +77 -1
  251. package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +104 -25
  252. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +4 -0
  253. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +287 -32
  254. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
  255. package/corpus/templates/clips/server/lib/calendar-event-classification.ts +28 -0
  256. package/corpus/templates/clips/server/routes/[...page].get.ts +1 -59
  257. package/corpus/templates/clips/shared/recording-capture.ts +37 -0
  258. package/corpus/templates/content/.agents/skills/security/SKILL.md +10 -0
  259. package/corpus/templates/content/agent-native.app-skill.json +1 -1
  260. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +18 -16
  261. package/corpus/templates/content/server/routes/[...page].get.ts +1 -15
  262. package/corpus/templates/design/.agents/skills/security/SKILL.md +10 -0
  263. package/corpus/templates/design/actions/connect-assets-mcp.ts +1 -1
  264. package/corpus/templates/design/agent-native.app-skill.json +1 -1
  265. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +88 -12
  266. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1 -0
  267. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4 -1
  268. package/corpus/templates/design/changelog/2026-07-13-adding-shapes-preserves-canvas-background.md +6 -0
  269. package/corpus/templates/design/changelog/2026-07-13-clicking-quickly-between-overlapping-elements-no-longer-bounc.md +6 -0
  270. package/corpus/templates/design/server/plugins/assets-mcp.ts +1 -1
  271. package/corpus/templates/design/server/routes/[...page].get.ts +0 -2
  272. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +10 -0
  273. package/corpus/templates/forms/.agents/skills/security/SKILL.md +10 -0
  274. package/corpus/templates/macros/.agents/skills/security/SKILL.md +10 -0
  275. package/corpus/templates/mail/.agents/skills/security/SKILL.md +10 -0
  276. package/corpus/templates/plan/.agents/skills/security/SKILL.md +10 -0
  277. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +1 -1
  278. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +2 -2
  279. package/corpus/templates/plan/agent-native.app-skill.json +1 -1
  280. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +6 -1
  281. package/corpus/templates/plan/app/pages/PlansPage.tsx +15 -6
  282. package/corpus/templates/plan/changelog/2026-07-13-fixed-local-plan-previews-continuously-flickering-while-revi.md +6 -0
  283. package/corpus/templates/plan/server/routes/[...page].get.ts +0 -2
  284. package/corpus/templates/slides/.agents/skills/security/SKILL.md +10 -0
  285. package/dist/a2a/client.d.ts +2 -0
  286. package/dist/a2a/client.d.ts.map +1 -1
  287. package/dist/a2a/client.js +2 -0
  288. package/dist/a2a/client.js.map +1 -1
  289. package/dist/a2a/handlers.d.ts.map +1 -1
  290. package/dist/a2a/handlers.js +84 -7
  291. package/dist/a2a/handlers.js.map +1 -1
  292. package/dist/agent/production-agent.d.ts +9 -0
  293. package/dist/agent/production-agent.d.ts.map +1 -1
  294. package/dist/agent/production-agent.js +12 -0
  295. package/dist/agent/production-agent.js.map +1 -1
  296. package/dist/cli/connect.d.ts +2 -2
  297. package/dist/cli/connect.d.ts.map +1 -1
  298. package/dist/cli/connect.js +45 -23
  299. package/dist/cli/connect.js.map +1 -1
  300. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  301. package/dist/cli/mcp-config-writers.js +7 -0
  302. package/dist/cli/mcp-config-writers.js.map +1 -1
  303. package/dist/cli/mcp.js +5 -3
  304. package/dist/cli/mcp.js.map +1 -1
  305. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  306. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  307. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  308. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  309. package/dist/cli/skills-content/assets-skill.d.ts +1 -1
  310. package/dist/cli/skills-content/assets-skill.d.ts.map +1 -1
  311. package/dist/cli/skills-content/assets-skill.js +1 -1
  312. package/dist/cli/skills-content/assets-skill.js.map +1 -1
  313. package/dist/cli/skills-content/design-exploration-skill.d.ts +1 -1
  314. package/dist/cli/skills-content/design-exploration-skill.d.ts.map +1 -1
  315. package/dist/cli/skills-content/design-exploration-skill.js +1 -1
  316. package/dist/cli/skills-content/design-exploration-skill.js.map +1 -1
  317. package/dist/cli/skills-content/help.d.ts +1 -1
  318. package/dist/cli/skills-content/help.d.ts.map +1 -1
  319. package/dist/cli/skills-content/help.js +1 -1
  320. package/dist/cli/skills-content/help.js.map +1 -1
  321. package/dist/cli/skills-content/plan-setup-auth.d.ts +1 -1
  322. package/dist/cli/skills-content/plan-setup-auth.d.ts.map +1 -1
  323. package/dist/cli/skills-content/plan-setup-auth.js +1 -1
  324. package/dist/cli/skills-content/plan-setup-auth.js.map +1 -1
  325. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  326. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  327. package/dist/cli/skills-content/visual-plan-skill.js +1 -1
  328. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  329. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  330. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
  331. package/dist/cli/skills-content/visual-recap-skill.js +2 -2
  332. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
  333. package/dist/cli/skills.d.ts.map +1 -1
  334. package/dist/cli/skills.js +16 -12
  335. package/dist/cli/skills.js.map +1 -1
  336. package/dist/client/analytics.d.ts.map +1 -1
  337. package/dist/client/analytics.js +11 -0
  338. package/dist/client/analytics.js.map +1 -1
  339. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  340. package/dist/client/resources/McpIntegrationDialog.js +1 -1
  341. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  342. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  343. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  344. package/dist/client/resources/mcp-integration-catalog.js +14 -0
  345. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  346. package/dist/collab/awareness.d.ts +2 -2
  347. package/dist/collab/awareness.d.ts.map +1 -1
  348. package/dist/collab/routes.d.ts +1 -1
  349. package/dist/collab/struct-routes.d.ts +1 -1
  350. package/dist/embedding/agent.d.ts.map +1 -1
  351. package/dist/embedding/agent.js +6 -7
  352. package/dist/embedding/agent.js.map +1 -1
  353. package/dist/localization/default-messages.d.ts +5 -0
  354. package/dist/localization/default-messages.d.ts.map +1 -1
  355. package/dist/localization/default-messages.js +5 -0
  356. package/dist/localization/default-messages.js.map +1 -1
  357. package/dist/mcp/ask-app-inline-tasks.d.ts +47 -0
  358. package/dist/mcp/ask-app-inline-tasks.d.ts.map +1 -0
  359. package/dist/mcp/ask-app-inline-tasks.js +87 -0
  360. package/dist/mcp/ask-app-inline-tasks.js.map +1 -0
  361. package/dist/mcp/build-server.d.ts.map +1 -1
  362. package/dist/mcp/build-server.js +56 -3
  363. package/dist/mcp/build-server.js.map +1 -1
  364. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  365. package/dist/mcp/builtin-tools.js +141 -21
  366. package/dist/mcp/builtin-tools.js.map +1 -1
  367. package/dist/mcp/connect-route.d.ts +12 -10
  368. package/dist/mcp/connect-route.d.ts.map +1 -1
  369. package/dist/mcp/connect-route.js +17 -14
  370. package/dist/mcp/connect-route.js.map +1 -1
  371. package/dist/mcp/oauth-route.d.ts +1 -1
  372. package/dist/mcp/oauth-route.d.ts.map +1 -1
  373. package/dist/mcp/oauth-route.js +30 -13
  374. package/dist/mcp/oauth-route.js.map +1 -1
  375. package/dist/mcp/route-paths.d.ts +13 -0
  376. package/dist/mcp/route-paths.d.ts.map +1 -0
  377. package/dist/mcp/route-paths.js +27 -0
  378. package/dist/mcp/route-paths.js.map +1 -0
  379. package/dist/mcp/server.d.ts +2 -1
  380. package/dist/mcp/server.d.ts.map +1 -1
  381. package/dist/mcp/server.js +14 -6
  382. package/dist/mcp/server.js.map +1 -1
  383. package/dist/mcp/stdio.d.ts +7 -6
  384. package/dist/mcp/stdio.d.ts.map +1 -1
  385. package/dist/mcp/stdio.js +27 -15
  386. package/dist/mcp/stdio.js.map +1 -1
  387. package/dist/mcp/workspace-resolve.d.ts +2 -1
  388. package/dist/mcp/workspace-resolve.d.ts.map +1 -1
  389. package/dist/mcp/workspace-resolve.js +2 -1
  390. package/dist/mcp/workspace-resolve.js.map +1 -1
  391. package/dist/mcp-client/manager.js +6 -3
  392. package/dist/mcp-client/manager.js.map +1 -1
  393. package/dist/mcp-client/remote-store.js +5 -7
  394. package/dist/mcp-client/remote-store.js.map +1 -1
  395. package/dist/notifications/routes.d.ts +3 -3
  396. package/dist/progress/routes.d.ts +1 -1
  397. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  398. package/dist/resources/handlers.d.ts +2 -2
  399. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  400. package/dist/server/agent-chat/action-filters-a2a.js +11 -1
  401. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  402. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  403. package/dist/server/agent-chat-plugin.js +43 -11
  404. package/dist/server/agent-chat-plugin.js.map +1 -1
  405. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  406. package/dist/server/agent-teams.d.ts.map +1 -1
  407. package/dist/server/agent-teams.js +15 -1
  408. package/dist/server/agent-teams.js.map +1 -1
  409. package/dist/server/auth.d.ts.map +1 -1
  410. package/dist/server/auth.js +16 -6
  411. package/dist/server/auth.js.map +1 -1
  412. package/dist/server/core-routes-plugin.d.ts +4 -3
  413. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  414. package/dist/server/core-routes-plugin.js +20 -15
  415. package/dist/server/core-routes-plugin.js.map +1 -1
  416. package/dist/server/csrf.d.ts.map +1 -1
  417. package/dist/server/csrf.js +11 -0
  418. package/dist/server/csrf.js.map +1 -1
  419. package/dist/server/framework-request-handler.d.ts.map +1 -1
  420. package/dist/server/framework-request-handler.js +8 -2
  421. package/dist/server/framework-request-handler.js.map +1 -1
  422. package/dist/server/google-oauth.d.ts +2 -0
  423. package/dist/server/google-oauth.d.ts.map +1 -1
  424. package/dist/server/google-oauth.js +11 -2
  425. package/dist/server/google-oauth.js.map +1 -1
  426. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  427. package/dist/server/http-response-telemetry.js +4 -1
  428. package/dist/server/http-response-telemetry.js.map +1 -1
  429. package/dist/server/recap-image-route.js +3 -3
  430. package/dist/server/recap-image-route.js.map +1 -1
  431. package/dist/server/security-headers.d.ts.map +1 -1
  432. package/dist/server/security-headers.js +4 -1
  433. package/dist/server/security-headers.js.map +1 -1
  434. package/dist/server/ssr-handler.d.ts.map +1 -1
  435. package/dist/server/ssr-handler.js +3 -1
  436. package/dist/server/ssr-handler.js.map +1 -1
  437. package/dist/shared/cache-control.d.ts +7 -6
  438. package/dist/shared/cache-control.d.ts.map +1 -1
  439. package/dist/shared/cache-control.js +4 -3
  440. package/dist/shared/cache-control.js.map +1 -1
  441. package/dist/templates/default/.agents/skills/security/SKILL.md +10 -0
  442. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  443. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  444. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  445. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
  446. package/docs/content/actions.mdx +1 -1
  447. package/docs/content/authentication.mdx +1 -1
  448. package/docs/content/dispatch.mdx +3 -3
  449. package/docs/content/external-agents.mdx +30 -19
  450. package/docs/content/locales/ar-SA/actions.mdx +1 -1
  451. package/docs/content/locales/ar-SA/authentication.mdx +1 -1
  452. package/docs/content/locales/ar-SA/dispatch.mdx +3 -3
  453. package/docs/content/locales/ar-SA/external-agents.mdx +23 -19
  454. package/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
  455. package/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
  456. package/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
  457. package/docs/content/locales/ar-SA/server.mdx +2 -2
  458. package/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
  459. package/docs/content/locales/ar-SA/template-assets.mdx +1 -1
  460. package/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
  461. package/docs/content/locales/ar-SA/template-plan.mdx +3 -3
  462. package/docs/content/locales/de-DE/actions.mdx +1 -1
  463. package/docs/content/locales/de-DE/authentication.mdx +1 -1
  464. package/docs/content/locales/de-DE/dispatch.mdx +3 -3
  465. package/docs/content/locales/de-DE/external-agents.mdx +23 -19
  466. package/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
  467. package/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
  468. package/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
  469. package/docs/content/locales/de-DE/server.mdx +2 -2
  470. package/docs/content/locales/de-DE/skills-guide.mdx +1 -1
  471. package/docs/content/locales/de-DE/template-assets.mdx +1 -1
  472. package/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
  473. package/docs/content/locales/de-DE/template-plan.mdx +3 -3
  474. package/docs/content/locales/es-ES/actions.mdx +1 -1
  475. package/docs/content/locales/es-ES/authentication.mdx +1 -1
  476. package/docs/content/locales/es-ES/dispatch.mdx +3 -3
  477. package/docs/content/locales/es-ES/external-agents.mdx +32 -19
  478. package/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
  479. package/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
  480. package/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
  481. package/docs/content/locales/es-ES/server.mdx +2 -2
  482. package/docs/content/locales/es-ES/skills-guide.mdx +1 -1
  483. package/docs/content/locales/es-ES/template-assets.mdx +1 -1
  484. package/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
  485. package/docs/content/locales/es-ES/template-plan.mdx +3 -3
  486. package/docs/content/locales/fr-FR/actions.mdx +1 -1
  487. package/docs/content/locales/fr-FR/authentication.mdx +1 -1
  488. package/docs/content/locales/fr-FR/dispatch.mdx +3 -3
  489. package/docs/content/locales/fr-FR/external-agents.mdx +23 -19
  490. package/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
  491. package/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
  492. package/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
  493. package/docs/content/locales/fr-FR/server.mdx +2 -2
  494. package/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
  495. package/docs/content/locales/fr-FR/template-assets.mdx +1 -1
  496. package/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
  497. package/docs/content/locales/fr-FR/template-plan.mdx +3 -3
  498. package/docs/content/locales/hi-IN/actions.mdx +1 -1
  499. package/docs/content/locales/hi-IN/authentication.mdx +1 -1
  500. package/docs/content/locales/hi-IN/dispatch.mdx +3 -3
  501. package/docs/content/locales/hi-IN/external-agents.mdx +31 -19
  502. package/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
  503. package/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
  504. package/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
  505. package/docs/content/locales/hi-IN/server.mdx +2 -2
  506. package/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
  507. package/docs/content/locales/hi-IN/template-assets.mdx +1 -1
  508. package/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
  509. package/docs/content/locales/hi-IN/template-plan.mdx +3 -3
  510. package/docs/content/locales/ja-JP/actions.mdx +1 -1
  511. package/docs/content/locales/ja-JP/authentication.mdx +1 -1
  512. package/docs/content/locales/ja-JP/dispatch.mdx +3 -3
  513. package/docs/content/locales/ja-JP/external-agents.mdx +23 -19
  514. package/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
  515. package/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
  516. package/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
  517. package/docs/content/locales/ja-JP/server.mdx +2 -2
  518. package/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
  519. package/docs/content/locales/ja-JP/template-assets.mdx +1 -1
  520. package/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
  521. package/docs/content/locales/ja-JP/template-plan.mdx +3 -3
  522. package/docs/content/locales/ko-KR/actions.mdx +1 -1
  523. package/docs/content/locales/ko-KR/authentication.mdx +1 -1
  524. package/docs/content/locales/ko-KR/dispatch.mdx +3 -3
  525. package/docs/content/locales/ko-KR/external-agents.mdx +30 -19
  526. package/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
  527. package/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
  528. package/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
  529. package/docs/content/locales/ko-KR/server.mdx +2 -2
  530. package/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
  531. package/docs/content/locales/ko-KR/template-assets.mdx +1 -1
  532. package/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
  533. package/docs/content/locales/ko-KR/template-plan.mdx +3 -3
  534. package/docs/content/locales/pt-BR/actions.mdx +1 -1
  535. package/docs/content/locales/pt-BR/authentication.mdx +1 -1
  536. package/docs/content/locales/pt-BR/dispatch.mdx +3 -3
  537. package/docs/content/locales/pt-BR/external-agents.mdx +32 -19
  538. package/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
  539. package/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
  540. package/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
  541. package/docs/content/locales/pt-BR/server.mdx +2 -2
  542. package/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
  543. package/docs/content/locales/pt-BR/template-assets.mdx +1 -1
  544. package/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
  545. package/docs/content/locales/pt-BR/template-plan.mdx +3 -3
  546. package/docs/content/locales/zh-CN/actions.mdx +1 -1
  547. package/docs/content/locales/zh-CN/authentication.mdx +1 -1
  548. package/docs/content/locales/zh-CN/dispatch.mdx +3 -3
  549. package/docs/content/locales/zh-CN/external-agents.mdx +23 -19
  550. package/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
  551. package/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
  552. package/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
  553. package/docs/content/locales/zh-CN/server.mdx +2 -2
  554. package/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
  555. package/docs/content/locales/zh-CN/template-assets.mdx +1 -1
  556. package/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
  557. package/docs/content/locales/zh-CN/template-plan.mdx +3 -3
  558. package/docs/content/locales/zh-TW/actions.mdx +1 -1
  559. package/docs/content/locales/zh-TW/authentication.mdx +1 -1
  560. package/docs/content/locales/zh-TW/dispatch.mdx +3 -3
  561. package/docs/content/locales/zh-TW/external-agents.mdx +23 -19
  562. package/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
  563. package/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
  564. package/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
  565. package/docs/content/locales/zh-TW/server.mdx +2 -2
  566. package/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
  567. package/docs/content/locales/zh-TW/template-assets.mdx +1 -1
  568. package/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
  569. package/docs/content/locales/zh-TW/template-plan.mdx +3 -3
  570. package/docs/content/mcp-clients.mdx +31 -4
  571. package/docs/content/mcp-protocol.mdx +35 -15
  572. package/docs/content/plan-plugin.mdx +3 -3
  573. package/docs/content/server.mdx +2 -2
  574. package/docs/content/skills-guide.mdx +1 -1
  575. package/docs/content/template-assets.mdx +1 -1
  576. package/docs/content/template-dispatch.mdx +2 -2
  577. package/docs/content/template-plan.mdx +3 -3
  578. package/package.json +2 -2
  579. package/src/templates/default/.agents/skills/security/SKILL.md +10 -0
  580. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  581. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  582. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  583. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
@@ -161,9 +161,7 @@ export default defineEventHandler(async (event) => {
161
161
  const headers = new Headers(response.headers);
162
162
  headers.delete("content-length");
163
163
  if (discovery.privateResponse) {
164
- headers.set("Cache-Control", "private, max-age=0, no-store");
165
164
  headers.set("Referrer-Policy", "no-referrer");
166
- setResponseHeader(event, "Cache-Control", "private, max-age=0, no-store");
167
165
  setResponseHeader(event, "Referrer-Policy", "no-referrer");
168
166
  }
169
167
 
@@ -147,6 +147,16 @@ export default defineEventHandler(async (event) => {
147
147
 
148
148
  - Never create unprotected routes that modify data.
149
149
 
150
+ **Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
151
+ The rule above is for routes that read or mutate user data. The SSR page
152
+ render and React Router `.data` route are different: they serve one
153
+ impersonal, public-cacheable shell to every visitor by design, and loaders on
154
+ that path render no user data. Do not "fix" this by adding `getSession`,
155
+ `private`, or `no-store` to it — that regresses the CDN cache contract for the
156
+ whole site. Data scoping lives in actions and API routes; the client gates
157
+ private UI after the shell loads. See the `authentication` skill and
158
+ `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
159
+
150
160
  ## Human-in-the-Loop Approval for High-Consequence Actions
151
161
 
152
162
  For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
@@ -5,7 +5,7 @@
5
5
  "description": "Create, search, select, and export brand image and video assets from the Assets app.",
6
6
  "hosted": {
7
7
  "url": "https://assets.agent-native.com",
8
- "mcpUrl": "https://assets.agent-native.com/_agent-native/mcp"
8
+ "mcpUrl": "https://assets.agent-native.com/mcp"
9
9
  },
10
10
  "mcp": {
11
11
  "serverName": "agent-native-assets"
@@ -147,6 +147,16 @@ export default defineEventHandler(async (event) => {
147
147
 
148
148
  - Never create unprotected routes that modify data.
149
149
 
150
+ **Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
151
+ The rule above is for routes that read or mutate user data. The SSR page
152
+ render and React Router `.data` route are different: they serve one
153
+ impersonal, public-cacheable shell to every visitor by design, and loaders on
154
+ that path render no user data. Do not "fix" this by adding `getSession`,
155
+ `private`, or `no-store` to it — that regresses the CDN cache contract for the
156
+ whole site. Data scoping lives in actions and API routes; the client gates
157
+ private UI after the shell loads. See the `authentication` skill and
158
+ `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
159
+
150
160
  ## Human-in-the-Loop Approval for High-Consequence Actions
151
161
 
152
162
  For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
@@ -147,6 +147,16 @@ export default defineEventHandler(async (event) => {
147
147
 
148
148
  - Never create unprotected routes that modify data.
149
149
 
150
+ **Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
151
+ The rule above is for routes that read or mutate user data. The SSR page
152
+ render and React Router `.data` route are different: they serve one
153
+ impersonal, public-cacheable shell to every visitor by design, and loaders on
154
+ that path render no user data. Do not "fix" this by adding `getSession`,
155
+ `private`, or `no-store` to it — that regresses the CDN cache contract for the
156
+ whole site. Data scoping lives in actions and API routes; the client gates
157
+ private UI after the shell loads. See the `authentication` skill and
158
+ `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
159
+
150
160
  ## Human-in-the-Loop Approval for High-Consequence Actions
151
161
 
152
162
  For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
@@ -67,7 +67,8 @@ Detailed event, availability, booking, storage, and UI rules live in
67
67
  - Use `get-attendee-timezones` / `set-attendee-timezone` to read or save
68
68
  per-guest IANA timezone overrides (`attendee-timezones` user setting). The UI
69
69
  shows each guest's local event-start time when a timezone is known (self from
70
- the event/browser zone; others from `attendee.timeZone` or the override map).
70
+ the browser zone; others from `attendee.timeZone` or the override map, with
71
+ the event zone as a fallback for the organizer).
71
72
  - Use `rsvp-event` for invitation responses. Pass `note` when the user wants a
72
73
  visible RSVP comment on a declined or tentative response; pass an empty note to
73
74
  clear an existing RSVP comment.
@@ -11,7 +11,6 @@ import {
11
11
  IconMapPin,
12
12
  IconUser,
13
13
  IconVideo,
14
- IconGlobe,
15
14
  IconRefresh,
16
15
  IconBell,
17
16
  IconChevronRight,
@@ -86,7 +85,6 @@ import {
86
85
  dateTimeInTimezoneToIso,
87
86
  formatRecurrenceText,
88
87
  formatReminderText,
89
- formatTimezoneLabel,
90
88
  getEventEndValidationMessage,
91
89
  getLocalTimezone,
92
90
  getRecurrencePreset,
@@ -1274,17 +1272,6 @@ export function EventDetailPopover({
1274
1272
  ? t("eventForm.loadingRepeat")
1275
1273
  : formatRecurrenceText(recurrenceRules) ||
1276
1274
  (isRecurringEvent ? t("eventForm.repeats") : null);
1277
- // Show the browser's local timezone offset (this is what the user sees times in)
1278
- const localOffsetMinutes = -new Date().getTimezoneOffset();
1279
- const localOffsetSign = localOffsetMinutes >= 0 ? "+" : "-";
1280
- const localOffsetH = Math.floor(Math.abs(localOffsetMinutes) / 60);
1281
- const localOffsetM = Math.abs(localOffsetMinutes) % 60;
1282
- const tzLabel = event.startTimeZone
1283
- ? formatTimezoneLabel(event.startTimeZone)
1284
- : localOffsetM
1285
- ? `GMT${localOffsetSign}${localOffsetH}:${String(localOffsetM).padStart(2, "0")}`
1286
- : `GMT${localOffsetSign}${localOffsetH}`;
1287
-
1288
1275
  const handleOpenChange = useCallback(
1289
1276
  (newOpen: boolean) => {
1290
1277
  if (!newOpen && open) {
@@ -1726,12 +1713,6 @@ export function EventDetailPopover({
1726
1713
  />
1727
1714
  )}
1728
1715
 
1729
- {/* Timezone */}
1730
- <div className="flex items-center gap-3 py-1.5">
1731
- <IconGlobe className="h-4 w-4 shrink-0 text-muted-foreground" />
1732
- <span className="text-sm text-muted-foreground">{tzLabel}</span>
1733
- </div>
1734
-
1735
1716
  {/* Recurrence */}
1736
1717
  {editingField === "recurrence" ? (
1737
1718
  <div className="flex items-start gap-3 py-1.5">
@@ -3,9 +3,12 @@
3
3
  *
4
4
  * Resolution priority for an attendee's IANA timezone:
5
5
  * 1. Self attendee (`attendee.self` or email matches accountEmail) →
6
- * event.startTimeZone, else the browser timezone
6
+ * the browser timezone, so an event owner's timezone is never shown as
7
+ * the signed-in user's local time
7
8
  * 2. Optional `attendee.timeZone` on the attendee object
8
9
  * 3. User-stored override from the `attendee-timezones` setting map
10
+ * 4. The event start timezone for the organizer when no more specific zone is
11
+ * available
9
12
  *
10
13
  * When no timezone is known, returns null — never invent a zone.
11
14
  */
@@ -13,6 +16,7 @@
13
16
  export type AttendeeTimezoneSource = {
14
17
  email: string;
15
18
  self?: boolean;
19
+ organizer?: boolean;
16
20
  timeZone?: string;
17
21
  };
18
22
 
@@ -61,15 +65,16 @@ export function resolveAttendeeTimeZone(
61
65
  } = input;
62
66
 
63
67
  if (isSelfAttendee(attendee, accountEmail)) {
64
- if (isValidIanaTimeZone(eventStartTimeZone)) {
65
- return eventStartTimeZone!.trim();
66
- }
67
68
  const browser =
68
69
  browserTimeZone?.trim() ||
69
70
  (typeof Intl !== "undefined"
70
71
  ? Intl.DateTimeFormat().resolvedOptions().timeZone
71
72
  : undefined);
72
- return isValidIanaTimeZone(browser) ? browser!.trim() : null;
73
+ if (isValidIanaTimeZone(browser)) return browser!.trim();
74
+
75
+ return isValidIanaTimeZone(eventStartTimeZone)
76
+ ? eventStartTimeZone!.trim()
77
+ : null;
73
78
  }
74
79
 
75
80
  if (isValidIanaTimeZone(attendee.timeZone)) {
@@ -82,6 +87,10 @@ export function resolveAttendeeTimeZone(
82
87
  return override!.trim();
83
88
  }
84
89
 
90
+ if (attendee.organizer && isValidIanaTimeZone(eventStartTimeZone)) {
91
+ return eventStartTimeZone!.trim();
92
+ }
93
+
85
94
  return null;
86
95
  }
87
96
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Your local time now follows your browser timezone, and event details no longer show a redundant timezone row.
@@ -147,6 +147,16 @@ export default defineEventHandler(async (event) => {
147
147
 
148
148
  - Never create unprotected routes that modify data.
149
149
 
150
+ **Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
151
+ The rule above is for routes that read or mutate user data. The SSR page
152
+ render and React Router `.data` route are different: they serve one
153
+ impersonal, public-cacheable shell to every visitor by design, and loaders on
154
+ that path render no user data. Do not "fix" this by adding `getSession`,
155
+ `private`, or `no-store` to it — that regresses the CDN cache contract for the
156
+ whole site. Data scoping lives in actions and API routes; the client gates
157
+ private UI after the shell loads. See the `authentication` skill and
158
+ `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
159
+
150
160
  ## Human-in-the-Loop Approval for High-Consequence Actions
151
161
 
152
162
  For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
@@ -44,7 +44,7 @@ Raw `MediaRecorder` files are not friendly to progressive HTTP playback, which
44
44
  shows up as "clip takes minutes to load" and "re-buffers every time I seek"
45
45
  even though the file downloads fine:
46
46
 
47
- - **MP4** is written with the `moov` metadata atom *after* `mdat`, so a player
47
+ - **MP4** is written with the `moov` metadata atom _after_ `mdat`, so a player
48
48
  must fetch the whole file before it can start or seek.
49
49
  - **WebM** is a live stream with no Cues (seek index) and an unknown Segment
50
50
  duration, so Chrome won't honor `currentTime = X` and has to scan/download.
@@ -116,7 +116,12 @@ different listing.
116
116
 
117
117
  ## Camera bubble
118
118
 
119
- When mode is `screen+camera`, we composite a circular camera feed in the corner. Render the bubble in a separate `<video>` element and record it into a second `MediaRecorder`; the server side stitches them with ffmpeg.wasm during `processing`. Do **not** try to pre-composite in the browser — that burns GPU and drops frames.
119
+ When mode is `screen+camera`, "the bubble" is two different things:
120
+
121
+ - **On-screen self-view.** `CameraBubble` renders a plain, unrecorded `<video>` element the user drags around to frame themselves during countdown/recording. It is never captured — it's just local framing UI.
122
+ - **Recorded composite.** Display capture can't include that DOM element once the user records another window/app, so the saved video has to bake the camera circle in before `MediaRecorder` ever sees a frame. `createCameraCompositeStream` (`app/lib/camera-composite.ts`) draws the display video plus a clipped, mirrored camera circle onto an offscreen `<canvas>` and feeds `canvas.captureStream()` into a single `MediaRecorder`. There is **no** second `MediaRecorder` and **no** server-side ffmpeg stitching — the composite happens client-side, live, before upload.
123
+
124
+ Because that draw loop runs continuously for the whole recording, keep its CPU/GPU cost bounded: a Worker-based timer drives the draw loop at the capture frame rate (`SCREEN_CAPTURE_FRAME_RATE`, 24fps — falling back to `requestAnimationFrame` only if Worker creation fails, e.g. under a strict CSP), the canvas is hard-capped to 1080p-class dimensions (1920px on its longest edge) even if the source display track is Retina/4K, and the bubble's drop shadow is pre-rendered into a small cached sprite (keyed by bubble size) instead of re-blurring with `shadowBlur` every frame.
120
125
 
121
126
  ## Error recovery
122
127
 
@@ -147,6 +147,16 @@ export default defineEventHandler(async (event) => {
147
147
 
148
148
  - Never create unprotected routes that modify data.
149
149
 
150
+ **Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
151
+ The rule above is for routes that read or mutate user data. The SSR page
152
+ render and React Router `.data` route are different: they serve one
153
+ impersonal, public-cacheable shell to every visitor by design, and loaders on
154
+ that path render no user data. Do not "fix" this by adding `getSession`,
155
+ `private`, or `no-store` to it — that regresses the CDN cache contract for the
156
+ whole site. Data scoping lives in actions and API routes; the client gates
157
+ private UI after the shell loads. See the `authentication` skill and
158
+ `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
159
+
150
160
  ## Human-in-the-Loop Approval for High-Consequence Actions
151
161
 
152
162
  For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
@@ -36,6 +36,9 @@ Detailed media, meeting, dictation, editing, and sharing rules live in
36
36
  generation run in the durable post-finalize path; do not hide a usable native
37
37
  transcript behind failed metadata work, and keep heuristic titles replaceable
38
38
  until the agent refinement lands.
39
+ - Desktop native transcripts merge microphone and system-audio streams while
40
+ removing overlapping duplicate speech and low-speech Whisper hallucinations;
41
+ keep system audio enabled when the meeting audio comes from another app.
39
42
  - Use `request-transcript --recordingId=<id> --force=true` to retry a failed
40
43
  transcript. Pass `--regenerate=true` to replace an existing ready transcript
41
44
  from the stored recording media; if regeneration fails, keep the prior ready
@@ -95,6 +98,10 @@ Detailed media, meeting, dictation, editing, and sharing rules live in
95
98
  (`connect-slack`, `/api/slack/oauth/callback`) so each Slack workspace gets
96
99
  its own encrypted bot token in `app_secrets`. `SLACK_BOT_TOKEN` is only a
97
100
  legacy single-workspace fallback and must remain behind the team allowlist.
101
+ - Atlassian/Jira is available through the shared MCP integration catalog. It
102
+ uses Atlassian Rovo MCP OAuth; explain that an Atlassian organization admin
103
+ may need to allow the Clips app domain and enable the required Read, Write,
104
+ and Search permissions before the connection can complete.
98
105
  - Browser recordings can include redacted browser diagnostics captured during
99
106
  the recording session. `save-browser-diagnostics` is UI/internal and stores
100
107
  bounded console logs plus fetch/XHR method, URL path/query keys, status, and
@@ -14,6 +14,7 @@
14
14
  */
15
15
 
16
16
  import { defineAction } from "@agent-native/core";
17
+ import { getRequestUserEmail } from "@agent-native/core/server/request-context";
17
18
  import { accessFilter } from "@agent-native/core/sharing";
18
19
  import {
19
20
  and,
@@ -31,7 +32,7 @@ import {
31
32
  import { z } from "zod";
32
33
 
33
34
  import { getDb, schema } from "../server/db/index.js";
34
- import { isPersonalSoloCalendarEvent } from "../server/lib/calendar-event-classification.js";
35
+ import { isSoloCalendarEvent } from "../server/lib/calendar-event-classification.js";
35
36
  import {
36
37
  calendarEventToMeetingView,
37
38
  eventEndIso,
@@ -86,12 +87,13 @@ export default defineAction({
86
87
  excludePersonalSoloEvents: booleanParam
87
88
  .default(false)
88
89
  .describe(
89
- "Exclude obvious solo personal calendar blocks such as Gym or Dinner. Used by desktop meeting reminders.",
90
+ "Exclude calendar events with no active attendee besides the current user. Used by desktop meeting reminders.",
90
91
  ),
91
92
  }),
92
93
  http: { method: "GET" },
93
94
  run: async (args) => {
94
95
  const db = getDb();
96
+ const currentUserEmail = getRequestUserEmail();
95
97
  const now = new Date();
96
98
  const nowIso = now.toISOString();
97
99
 
@@ -188,6 +190,11 @@ export default defineAction({
188
190
  // event was emitted here — not merely because some other account returned
189
191
  // data or errored.
190
192
  const emittedLiveEventKeys = new Set<string>();
193
+ // Calendar events excluded from desktop reminders because they have no
194
+ // active attendee besides the current user. Keep the correlated
195
+ // persisted meeting ids here too, so materialized solo events cannot
196
+ // re-enter the reminder list through the fallback persisted-row merge.
197
+ const excludedLiveEventKeys = new Set<string>();
191
198
  // Map a persisted meeting's `calendarEventId` (calendar_events.id) to the
192
199
  // Google event externalId so we can match it against the emitted set.
193
200
  const calendarEventIdToExternalId = new Map<string, string>();
@@ -269,10 +276,15 @@ export default defineAction({
269
276
  for (const event of items) {
270
277
  if (!event.id || event.status === "cancelled") continue;
271
278
  if (!isTimedCalendarEvent(event)) continue;
279
+ const cached = cachedByExternalId.get(event.id);
272
280
  if (
273
281
  args.excludePersonalSoloEvents &&
274
- isPersonalSoloCalendarEvent({ account, event })
282
+ isSoloCalendarEvent({ account, event, currentUserEmail })
275
283
  ) {
284
+ excludedLiveEventKeys.add(event.id);
285
+ if (cached?.meetingId) {
286
+ excludedLiveEventKeys.add(cached.meetingId);
287
+ }
276
288
  continue;
277
289
  }
278
290
  const startIso = eventStartIso(event);
@@ -301,7 +313,6 @@ export default defineAction({
301
313
  continue;
302
314
  }
303
315
 
304
- const cached = cachedByExternalId.get(event.id);
305
316
  const persisted = cached?.meetingId
306
317
  ? persistedById.get(cached.meetingId)
307
318
  : null;
@@ -344,6 +355,10 @@ export default defineAction({
344
355
  const liveExternalId = meeting.calendarEventId
345
356
  ? calendarEventIdToExternalId.get(meeting.calendarEventId)
346
357
  : undefined;
358
+ const liveEventExcluded =
359
+ excludedLiveEventKeys.has(meeting.id) ||
360
+ (liveExternalId ? excludedLiveEventKeys.has(liveExternalId) : false);
361
+ if (liveEventExcluded) continue;
347
362
  const liveEventEmitted =
348
363
  emittedLiveEventKeys.has(meeting.id) ||
349
364
  (liveExternalId ? emittedLiveEventKeys.has(liveExternalId) : false);
@@ -71,6 +71,7 @@ export default defineAction({
71
71
  recording: existing,
72
72
  meetingId,
73
73
  created: false,
74
+ scheduledEnd: meeting.scheduledEnd,
74
75
  };
75
76
  }
76
77
  }
@@ -117,6 +118,11 @@ export default defineAction({
117
118
  .where(eq(schema.recordings.id, recordingId))
118
119
  .limit(1);
119
120
 
120
- return { recording, meetingId, created: true };
121
+ return {
122
+ recording,
123
+ meetingId,
124
+ created: true,
125
+ scheduledEnd: meeting.scheduledEnd,
126
+ };
121
127
  },
122
128
  });
@@ -13,7 +13,7 @@ import {
13
13
  IconAlertTriangle,
14
14
  } from "@tabler/icons-react";
15
15
  import { useCallback, useMemo, useState } from "react";
16
- import { useNavigate } from "react-router";
16
+ import { Link } from "react-router";
17
17
 
18
18
  import { ViewedByPopover } from "@/components/sharing/viewed-by-popover";
19
19
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
@@ -85,7 +85,6 @@ export function RecordingCard({
85
85
  onTrash,
86
86
  readOnly = false,
87
87
  }: RecordingCardProps) {
88
- const navigate = useNavigate();
89
88
  const t = useT();
90
89
  const { formatDate, formatRelativeTime } = useFormatters();
91
90
  const [hovered, setHovered] = useState(false);
@@ -141,26 +140,23 @@ export function RecordingCard({
141
140
 
142
141
  const recordingPath = `/r/${recording.id}`;
143
142
 
144
- const handleOpen = useCallback(
145
- (event: React.MouseEvent<HTMLElement>) => {
146
- const shouldOpenNewTab =
147
- event.button === 1 ||
148
- (event.button === 0 && (event.metaKey || event.ctrlKey));
149
-
150
- if (shouldOpenNewTab) {
151
- event.preventDefault();
152
- event.stopPropagation();
153
- window.open(recordingPath, "_blank", "noopener,noreferrer");
143
+ const handleLinkClick = useCallback(
144
+ (event: React.MouseEvent<HTMLAnchorElement>) => {
145
+ if (
146
+ !selectionMode ||
147
+ event.button !== 0 ||
148
+ event.metaKey ||
149
+ event.ctrlKey ||
150
+ event.shiftKey ||
151
+ event.altKey
152
+ ) {
154
153
  return;
155
154
  }
156
155
 
157
- if (selectionMode) {
158
- onToggleSelect?.(recording.id);
159
- } else {
160
- navigate(recordingPath);
161
- }
156
+ event.preventDefault();
157
+ onToggleSelect?.(recording.id);
162
158
  },
163
- [navigate, onToggleSelect, recording.id, recordingPath, selectionMode],
159
+ [onToggleSelect, recording.id, selectionMode],
164
160
  );
165
161
 
166
162
  const handleCheckbox = useCallback(
@@ -182,8 +178,6 @@ export function RecordingCard({
182
178
  return (
183
179
  <div
184
180
  role="article"
185
- onClick={handleOpen}
186
- onAuxClick={handleOpen}
187
181
  onMouseEnter={() => setHovered(true)}
188
182
  onMouseLeave={() => setHovered(false)}
189
183
  className={cn(
@@ -193,8 +187,15 @@ export function RecordingCard({
193
187
  selected && "ring-2 ring-primary border-primary",
194
188
  )}
195
189
  >
190
+ <Link
191
+ to={recordingPath}
192
+ aria-label={displayTitle}
193
+ onClick={handleLinkClick}
194
+ className="absolute inset-0 z-0 rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset"
195
+ />
196
+
196
197
  {/* Thumbnail */}
197
- <div className="relative aspect-video bg-muted overflow-hidden">
198
+ <div className="relative z-10 aspect-video overflow-hidden bg-muted pointer-events-none">
198
199
  {displayThumbnail ? (
199
200
  // eslint-disable-next-line jsx-a11y/alt-text
200
201
  <img
@@ -229,7 +230,7 @@ export function RecordingCard({
229
230
  {canSelect && (selectionMode || hovered || selected) && (
230
231
  <div
231
232
  onClick={handleCheckbox}
232
- className="absolute top-2 start-2 flex h-5 w-5 items-center justify-center rounded bg-background/90 border border-border"
233
+ className="pointer-events-auto absolute top-2 start-2 flex h-5 w-5 items-center justify-center rounded border border-border bg-background/90"
233
234
  >
234
235
  <Checkbox
235
236
  checked={selected}
@@ -285,7 +286,7 @@ export function RecordingCard({
285
286
  <button
286
287
  type="button"
287
288
  onClick={handleRemoveFailed}
288
- className="rounded border border-border px-1.5 py-0.5 text-[10px] text-foreground hover:bg-accent"
289
+ className="pointer-events-auto rounded border border-border px-1.5 py-0.5 text-[10px] text-foreground hover:bg-accent"
289
290
  >
290
291
  {t("clipsFinalRaw.remove")}
291
292
  </button>
@@ -296,7 +297,7 @@ export function RecordingCard({
296
297
  </div>
297
298
 
298
299
  {/* Body */}
299
- <div className="flex-1 p-3 space-y-2">
300
+ <div className="relative z-10 flex-1 space-y-2 p-3 pointer-events-none">
300
301
  <div className="flex items-start gap-2">
301
302
  <div className="min-w-0 flex-1">
302
303
  {hasDefaultTitle ? (
@@ -319,7 +320,7 @@ export function RecordingCard({
319
320
  {recording.viewCount > 0 && !readOnly ? (
320
321
  <ViewedByPopover
321
322
  recordingId={recording.id}
322
- className="underline-offset-2 hover:underline hover:text-foreground"
323
+ className="pointer-events-auto underline-offset-2 hover:underline hover:text-foreground"
323
324
  >
324
325
  {t("clipsFinalRaw.viewsCount", {
325
326
  count: recording.viewCount,
@@ -341,7 +342,7 @@ export function RecordingCard({
341
342
  <DropdownMenu>
342
343
  <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
343
344
  <button
344
- className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
345
+ className="pointer-events-auto rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
345
346
  aria-label={t("clipsFinalRaw.recordingMenu")}
346
347
  >
347
348
  <IconDots className="h-4 w-4" />
@@ -1,5 +1,5 @@
1
1
  import { IconUsersGroup, IconVideo } from "@tabler/icons-react";
2
- import { useNavigate } from "react-router";
2
+ import { Link } from "react-router";
3
3
 
4
4
  import { cn } from "@/lib/utils";
5
5
 
@@ -19,15 +19,13 @@ interface SpaceCardProps {
19
19
  }
20
20
 
21
21
  export function SpaceCard({ space, className }: SpaceCardProps) {
22
- const navigate = useNavigate();
23
22
  const color = space.color || "hsl(var(--primary))";
24
23
  const members = space.memberEmails ?? [];
25
24
  const initial = (space.name.trim().slice(0, 1) || "S").toUpperCase();
26
25
 
27
26
  return (
28
- <button
29
- type="button"
30
- onClick={() => navigate(`/spaces/${space.id}`)}
27
+ <Link
28
+ to={`/spaces/${space.id}`}
31
29
  className={cn(
32
30
  "group flex flex-col overflow-hidden rounded-lg border border-border bg-card text-start",
33
31
  "hover:border-primary/40",
@@ -92,6 +90,6 @@ export function SpaceCard({ space, className }: SpaceCardProps) {
92
90
  </div>
93
91
  )}
94
92
  </div>
95
- </button>
93
+ </Link>
96
94
  );
97
95
  }