@agent-native/core 0.100.2 → 0.101.3

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 (388) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +83 -0
  3. package/corpus/core/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
  4. package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +7 -0
  5. package/corpus/core/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
  6. package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +7 -0
  7. package/corpus/core/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
  8. package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +14 -0
  9. package/corpus/core/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
  10. package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +7 -0
  11. package/corpus/core/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
  12. package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +7 -0
  13. package/corpus/core/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
  14. package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +7 -0
  15. package/corpus/core/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
  16. package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +7 -0
  17. package/corpus/core/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
  18. package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +14 -0
  19. package/corpus/core/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
  20. package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +7 -0
  21. package/corpus/core/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
  22. package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +7 -0
  23. package/corpus/core/docs/content/pr-visual-recap.mdx +50 -32
  24. package/corpus/core/docs/content/template-plan.mdx +14 -0
  25. package/corpus/core/docs/content/toolkit-comments-review.mdx +16 -2
  26. package/corpus/core/package.json +4 -1
  27. package/corpus/core/src/a2a/index.ts +2 -1
  28. package/corpus/core/src/a2a/server.ts +34 -9
  29. package/corpus/core/src/agent/production-agent.ts +56 -10
  30. package/corpus/core/src/cli/create.ts +47 -19
  31. package/corpus/core/src/cli/pr-visual-recap-workflow.ts +2 -3
  32. package/corpus/core/src/cli/recap.ts +3 -4932
  33. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +6 -4
  34. package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +7 -1
  35. package/corpus/core/src/client/AgentPanel.tsx +19 -17
  36. package/corpus/core/src/client/analytics.ts +8 -1
  37. package/corpus/core/src/client/chat/markdown-renderer.tsx +54 -8
  38. package/corpus/core/src/client/chat/message-components.tsx +8 -2
  39. package/corpus/core/src/client/clipboard.ts +28 -1
  40. package/corpus/core/src/client/guided-questions.tsx +4 -0
  41. package/corpus/core/src/client/i18n.tsx +2 -1
  42. package/corpus/core/src/client/index.ts +4 -0
  43. package/corpus/core/src/client/review/ReviewCommentComposer.tsx +108 -0
  44. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +482 -150
  45. package/corpus/core/src/client/review/index.ts +8 -0
  46. package/corpus/core/src/client/review/use-review.ts +35 -1
  47. package/corpus/core/src/client/use-agent-chat-context.ts +3 -2
  48. package/corpus/core/src/credentials/index.ts +41 -8
  49. package/corpus/core/src/extensions/fetch-tool.ts +33 -3
  50. package/corpus/core/src/notifications/channels.ts +20 -6
  51. package/corpus/core/src/review/actions/create-review-comment.ts +2 -1
  52. package/corpus/core/src/review/actions/get-review-feedback.ts +6 -11
  53. package/corpus/core/src/review/actions/list-review-comments.ts +38 -4
  54. package/corpus/core/src/review/actions/reply-review-comment.ts +33 -22
  55. package/corpus/core/src/review/actions/resolve-review-thread.ts +29 -2
  56. package/corpus/core/src/review/actions/send-review-thread-to-agent.ts +62 -0
  57. package/corpus/core/src/review/identity.ts +101 -0
  58. package/corpus/core/src/review/index.ts +14 -0
  59. package/corpus/core/src/review/store.ts +315 -8
  60. package/corpus/core/src/review/types.ts +4 -0
  61. package/corpus/core/src/secrets/crypto.ts +26 -10
  62. package/corpus/core/src/secrets/storage.ts +16 -3
  63. package/corpus/core/src/server/action-discovery.ts +4 -0
  64. package/corpus/core/src/server/action-routes.ts +125 -4
  65. package/corpus/core/src/server/agent-chat/plugin-options.ts +16 -0
  66. package/corpus/core/src/server/agent-chat-plugin.ts +61 -7
  67. package/corpus/core/src/server/derived-secret.ts +5 -1
  68. package/corpus/core/src/server/index.ts +8 -0
  69. package/corpus/core/src/vite/action-types-plugin.ts +4 -0
  70. package/corpus/templates/analytics/changelog/2026-07-14-daily-dashboard-email-captures-authenticate-with-a-sessi.md +6 -0
  71. package/corpus/templates/analytics/changelog/2026-07-14-long-running-cross-app-analyses-now-continue-reliably-in-the.md +6 -0
  72. package/corpus/templates/analytics/server/lib/dashboard-report.ts +156 -3
  73. package/corpus/templates/analytics/server/plugins/agent-chat.ts +8 -4
  74. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +402 -142
  75. package/corpus/templates/assets/app/i18n/zh-TW.ts +1 -0
  76. package/corpus/templates/assets/app/i18n-data.ts +1 -0
  77. package/corpus/templates/assets/app/routes/library.tsx +187 -48
  78. package/corpus/templates/assets/changelog/2026-07-13-merged-the-candidates-panel-into-the-library-as-a-drafts-tab.md +6 -0
  79. package/corpus/templates/chat/app/lib/agent-page.tsx +40 -0
  80. package/corpus/templates/chat/app/routes/agent.tsx +5 -3
  81. package/corpus/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  82. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +5 -0
  83. package/corpus/templates/clips/AGENTS.md +4 -0
  84. package/corpus/templates/clips/actions/get-feature-flags.ts +30 -0
  85. package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
  86. package/corpus/templates/clips/actions/request-transcript.ts +41 -1
  87. package/corpus/templates/clips/actions/view-screen.ts +5 -9
  88. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  89. package/corpus/templates/clips/app/components/player/share-dialog.tsx +44 -81
  90. package/corpus/templates/clips/app/components/player/video-player.tsx +39 -1
  91. package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +6 -12
  92. package/corpus/templates/clips/app/hooks/use-mse-video-source.ts +146 -0
  93. package/corpus/templates/clips/app/i18n/ar-SA.ts +0 -8
  94. package/corpus/templates/clips/app/i18n/de-DE.ts +0 -9
  95. package/corpus/templates/clips/app/i18n/en-US.ts +0 -8
  96. package/corpus/templates/clips/app/i18n/es-ES.ts +0 -9
  97. package/corpus/templates/clips/app/i18n/fr-FR.ts +0 -9
  98. package/corpus/templates/clips/app/i18n/hi-IN.ts +0 -8
  99. package/corpus/templates/clips/app/i18n/ja-JP.ts +0 -9
  100. package/corpus/templates/clips/app/i18n/ko-KR.ts +0 -9
  101. package/corpus/templates/clips/app/i18n/pt-BR.ts +0 -9
  102. package/corpus/templates/clips/app/i18n/zh-CN.ts +0 -7
  103. package/corpus/templates/clips/app/i18n/zh-TW.ts +0 -7
  104. package/corpus/templates/clips/app/lib/capture-install-options.ts +21 -0
  105. package/corpus/templates/clips/app/lib/fmp4.ts +271 -0
  106. package/corpus/templates/clips/app/lib/mse-video-loader.ts +585 -0
  107. package/corpus/templates/clips/app/routes/_app.dictate.tsx +0 -4
  108. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -13
  109. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +2 -37
  110. package/corpus/templates/clips/app/routes/download.tsx +3 -2
  111. package/corpus/templates/clips/changelog/2026-07-10-shared-clips-now-start-playing-instantly-instead-of-showing-.md +6 -0
  112. package/corpus/templates/clips/changelog/2026-07-14-clips-now-distinguishes-transcript-previews-from-incomplete-.md +6 -0
  113. package/corpus/templates/clips/changelog/2026-07-14-desktop-app-prompts-stay-hidden-after-you-download-the-insta.md +6 -0
  114. package/corpus/templates/clips/changelog/2026-07-14-share-dialogs-show-separate-links-for-people-and-agents.md +6 -0
  115. package/corpus/templates/clips/desktop/src/lib/recorder.ts +5 -0
  116. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -0
  117. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -0
  118. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +2518 -0
  119. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +353 -0
  120. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +558 -67
  121. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +11 -1
  122. package/corpus/templates/clips/desktop/src-tauri/src/remote_flags.rs +188 -0
  123. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +1 -1
  124. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +1 -0
  125. package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -0
  126. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +5 -1
  127. package/corpus/templates/clips/shared/feature-flags.ts +41 -0
  128. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +3 -0
  129. package/corpus/templates/design/.agents/skills/design-review-feedback/SKILL.md +42 -0
  130. package/corpus/templates/design/AGENTS.md +6 -0
  131. package/corpus/templates/design/README.md +1 -0
  132. package/corpus/templates/design/actions/navigate.ts +4 -4
  133. package/corpus/templates/design/actions/view-screen.ts +116 -2
  134. package/corpus/templates/design/agent-native.app-skill.json +5 -0
  135. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +52 -59
  136. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +13 -9
  137. package/corpus/templates/design/app/components/design/EditPanel.tsx +79 -11
  138. package/corpus/templates/design/app/components/design/LayersPanel.tsx +78 -65
  139. package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +161 -0
  140. package/corpus/templates/design/app/components/design/ReviewStatusControl.tsx +96 -0
  141. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +166 -0
  142. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
  143. package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1077 -0
  144. package/corpus/templates/design/app/components/visual-editor/index.ts +1 -0
  145. package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +42 -0
  146. package/corpus/templates/design/app/hooks/use-design-systems.ts +2 -2
  147. package/corpus/templates/design/app/hooks/use-navigation-state.ts +9 -6
  148. package/corpus/templates/design/app/hooks/use-question-flow.ts +7 -1
  149. package/corpus/templates/design/app/i18n/ar-SA.ts +56 -1
  150. package/corpus/templates/design/app/i18n/de-DE.ts +57 -1
  151. package/corpus/templates/design/app/i18n/en-US.ts +56 -1
  152. package/corpus/templates/design/app/i18n/es-ES.ts +56 -1
  153. package/corpus/templates/design/app/i18n/fr-FR.ts +57 -1
  154. package/corpus/templates/design/app/i18n/hi-IN.ts +56 -1
  155. package/corpus/templates/design/app/i18n/ja-JP.ts +56 -1
  156. package/corpus/templates/design/app/i18n/ko-KR.ts +56 -1
  157. package/corpus/templates/design/app/i18n/pt-BR.ts +57 -1
  158. package/corpus/templates/design/app/i18n/zh-CN.ts +56 -1
  159. package/corpus/templates/design/app/i18n/zh-TW.ts +51 -0
  160. package/corpus/templates/design/app/pages/Present.tsx +172 -14
  161. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +23 -0
  162. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +10 -0
  163. package/corpus/templates/design/app/pages/present-review-state.ts +18 -0
  164. package/corpus/templates/design/app/public-routes.ts +8 -0
  165. package/corpus/templates/design/app/root.tsx +7 -6
  166. package/corpus/templates/design/changelog/2026-07-13-dragged-design-assets-now-appear-at-the-visible-drop-locatio.md +6 -0
  167. package/corpus/templates/design/changelog/2026-07-13-reviewers-can-pin-comments-on-shared-designs-and-apply-verif.md +6 -0
  168. package/corpus/templates/design/server/plugins/agent-chat.ts +10 -0
  169. package/corpus/templates/design/server/plugins/auth.ts +7 -5
  170. package/corpus/templates/design/server/plugins/review.ts +9 -0
  171. package/corpus/templates/design/shared/review-anchor.ts +83 -0
  172. package/corpus/templates/design/shared/review-summary.ts +25 -0
  173. package/corpus/templates/dispatch/changelog/2026-07-14-dispatch-now-distinguishes-connected-agents-from-locally-mou.md +6 -0
  174. package/corpus/templates/forms/.agents/skills/form-publishing/SKILL.md +2 -0
  175. package/corpus/templates/forms/AGENTS.md +4 -0
  176. package/corpus/templates/forms/actions/create-form.ts +2 -1
  177. package/corpus/templates/forms/actions/update-form.ts +5 -2
  178. package/corpus/templates/forms/app/i18n/ar-SA.ts +3 -0
  179. package/corpus/templates/forms/app/i18n/de-DE.ts +3 -0
  180. package/corpus/templates/forms/app/i18n/en-US.ts +3 -0
  181. package/corpus/templates/forms/app/i18n/es-ES.ts +3 -0
  182. package/corpus/templates/forms/app/i18n/fr-FR.ts +3 -0
  183. package/corpus/templates/forms/app/i18n/hi-IN.ts +3 -0
  184. package/corpus/templates/forms/app/i18n/ja-JP.ts +3 -0
  185. package/corpus/templates/forms/app/i18n/ko-KR.ts +3 -0
  186. package/corpus/templates/forms/app/i18n/pt-BR.ts +3 -0
  187. package/corpus/templates/forms/app/i18n/zh-CN.ts +3 -0
  188. package/corpus/templates/forms/app/i18n/zh-TW.ts +3 -0
  189. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +19 -0
  190. package/corpus/templates/forms/changelog/2026-07-14-fixed-the-ask-forms-loading-input-appearing-above-the-welcom.md +6 -0
  191. package/corpus/templates/forms/changelog/2026-07-14-form-social-previews-now-show-the-form-title-description-and.md +6 -0
  192. package/corpus/templates/forms/changelog/2026-07-14-forms-can-email-the-form-owner-when-new-responses-arrive.md +6 -0
  193. package/corpus/templates/forms/server/handlers/submissions.ts +17 -0
  194. package/corpus/templates/forms/server/lib/form-og-image.ts +64 -6
  195. package/corpus/templates/forms/server/lib/public-form-ssr.ts +6 -2
  196. package/corpus/templates/forms/server/lib/response-email.ts +65 -0
  197. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
  198. package/corpus/templates/forms/server/routes/api/forms/og/[...slug]/og.png.get.ts +184 -0
  199. package/corpus/templates/forms/shared/types.ts +2 -0
  200. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +6 -4
  201. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +7 -1
  202. package/dist/a2a/index.d.ts +2 -1
  203. package/dist/a2a/index.d.ts.map +1 -1
  204. package/dist/a2a/index.js +1 -1
  205. package/dist/a2a/index.js.map +1 -1
  206. package/dist/a2a/server.d.ts +25 -0
  207. package/dist/a2a/server.d.ts.map +1 -1
  208. package/dist/a2a/server.js +30 -6
  209. package/dist/a2a/server.js.map +1 -1
  210. package/dist/agent/production-agent.d.ts +2 -0
  211. package/dist/agent/production-agent.d.ts.map +1 -1
  212. package/dist/agent/production-agent.js +37 -12
  213. package/dist/agent/production-agent.js.map +1 -1
  214. package/dist/cli/create.d.ts +5 -3
  215. package/dist/cli/create.d.ts.map +1 -1
  216. package/dist/cli/create.js +44 -19
  217. package/dist/cli/create.js.map +1 -1
  218. package/dist/cli/pr-visual-recap-workflow.d.ts +2 -2
  219. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  220. package/dist/cli/pr-visual-recap-workflow.js +2 -2
  221. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  222. package/dist/cli/recap.d.ts +3 -562
  223. package/dist/cli/recap.d.ts.map +1 -1
  224. package/dist/cli/recap.js +3 -3875
  225. package/dist/cli/recap.js.map +1 -1
  226. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  227. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  228. package/dist/cli/skills-content/visual-plan-skill.js +6 -4
  229. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  230. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  231. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
  232. package/dist/cli/skills-content/visual-recap-skill.js +7 -1
  233. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
  234. package/dist/client/AgentPanel.d.ts.map +1 -1
  235. package/dist/client/AgentPanel.js +3 -3
  236. package/dist/client/AgentPanel.js.map +1 -1
  237. package/dist/client/analytics.d.ts +5 -0
  238. package/dist/client/analytics.d.ts.map +1 -1
  239. package/dist/client/analytics.js +3 -1
  240. package/dist/client/analytics.js.map +1 -1
  241. package/dist/client/chat/markdown-renderer.d.ts +1 -0
  242. package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
  243. package/dist/client/chat/markdown-renderer.js +36 -1
  244. package/dist/client/chat/markdown-renderer.js.map +1 -1
  245. package/dist/client/chat/message-components.d.ts.map +1 -1
  246. package/dist/client/chat/message-components.js +5 -2
  247. package/dist/client/chat/message-components.js.map +1 -1
  248. package/dist/client/clipboard.d.ts +3 -1
  249. package/dist/client/clipboard.d.ts.map +1 -1
  250. package/dist/client/clipboard.js +24 -1
  251. package/dist/client/clipboard.js.map +1 -1
  252. package/dist/client/guided-questions.d.ts +3 -1
  253. package/dist/client/guided-questions.d.ts.map +1 -1
  254. package/dist/client/guided-questions.js +2 -1
  255. package/dist/client/guided-questions.js.map +1 -1
  256. package/dist/client/i18n.d.ts.map +1 -1
  257. package/dist/client/i18n.js +3 -1
  258. package/dist/client/i18n.js.map +1 -1
  259. package/dist/client/index.d.ts +1 -1
  260. package/dist/client/index.d.ts.map +1 -1
  261. package/dist/client/index.js +1 -1
  262. package/dist/client/index.js.map +1 -1
  263. package/dist/client/review/ReviewCommentComposer.d.ts +18 -0
  264. package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -0
  265. package/dist/client/review/ReviewCommentComposer.js +30 -0
  266. package/dist/client/review/ReviewCommentComposer.js.map +1 -0
  267. package/dist/client/review/ReviewThreadPanel.d.ts +28 -1
  268. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
  269. package/dist/client/review/ReviewThreadPanel.js +151 -39
  270. package/dist/client/review/ReviewThreadPanel.js.map +1 -1
  271. package/dist/client/review/index.d.ts +3 -2
  272. package/dist/client/review/index.d.ts.map +1 -1
  273. package/dist/client/review/index.js +2 -1
  274. package/dist/client/review/index.js.map +1 -1
  275. package/dist/client/review/use-review.d.ts +23 -0
  276. package/dist/client/review/use-review.d.ts.map +1 -1
  277. package/dist/client/review/use-review.js +3 -0
  278. package/dist/client/review/use-review.js.map +1 -1
  279. package/dist/client/use-agent-chat-context.d.ts +1 -1
  280. package/dist/client/use-agent-chat-context.d.ts.map +1 -1
  281. package/dist/client/use-agent-chat-context.js +4 -2
  282. package/dist/client/use-agent-chat-context.js.map +1 -1
  283. package/dist/collab/awareness.d.ts +2 -2
  284. package/dist/collab/awareness.d.ts.map +1 -1
  285. package/dist/collab/struct-routes.d.ts +1 -1
  286. package/dist/credentials/index.d.ts +12 -7
  287. package/dist/credentials/index.d.ts.map +1 -1
  288. package/dist/credentials/index.js +33 -8
  289. package/dist/credentials/index.js.map +1 -1
  290. package/dist/extensions/fetch-tool.d.ts +13 -1
  291. package/dist/extensions/fetch-tool.d.ts.map +1 -1
  292. package/dist/extensions/fetch-tool.js +9 -2
  293. package/dist/extensions/fetch-tool.js.map +1 -1
  294. package/dist/notifications/channels.js +20 -4
  295. package/dist/notifications/channels.js.map +1 -1
  296. package/dist/observability/routes.d.ts +5 -5
  297. package/dist/progress/routes.d.ts +1 -1
  298. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  299. package/dist/resources/handlers.d.ts +3 -3
  300. package/dist/review/actions/create-review-comment.js +2 -1
  301. package/dist/review/actions/create-review-comment.js.map +1 -1
  302. package/dist/review/actions/get-review-feedback.js +6 -11
  303. package/dist/review/actions/get-review-feedback.js.map +1 -1
  304. package/dist/review/actions/list-review-comments.d.ts +1 -0
  305. package/dist/review/actions/list-review-comments.js +25 -4
  306. package/dist/review/actions/list-review-comments.js.map +1 -1
  307. package/dist/review/actions/reply-review-comment.js +12 -5
  308. package/dist/review/actions/reply-review-comment.js.map +1 -1
  309. package/dist/review/actions/resolve-review-thread.d.ts +3 -0
  310. package/dist/review/actions/resolve-review-thread.js +20 -3
  311. package/dist/review/actions/resolve-review-thread.js.map +1 -1
  312. package/dist/review/actions/send-review-thread-to-agent.d.ts +17 -0
  313. package/dist/review/actions/send-review-thread-to-agent.d.ts.map +1 -0
  314. package/dist/review/actions/send-review-thread-to-agent.js +49 -0
  315. package/dist/review/actions/send-review-thread-to-agent.js.map +1 -0
  316. package/dist/review/identity.d.ts +6 -0
  317. package/dist/review/identity.d.ts.map +1 -0
  318. package/dist/review/identity.js +68 -0
  319. package/dist/review/identity.js.map +1 -0
  320. package/dist/review/index.d.ts +3 -1
  321. package/dist/review/index.d.ts.map +1 -1
  322. package/dist/review/index.js +2 -1
  323. package/dist/review/index.js.map +1 -1
  324. package/dist/review/store.d.ts +36 -0
  325. package/dist/review/store.d.ts.map +1 -1
  326. package/dist/review/store.js +223 -8
  327. package/dist/review/store.js.map +1 -1
  328. package/dist/review/types.d.ts +4 -0
  329. package/dist/review/types.d.ts.map +1 -1
  330. package/dist/review/types.js.map +1 -1
  331. package/dist/secrets/crypto.d.ts +15 -7
  332. package/dist/secrets/crypto.d.ts.map +1 -1
  333. package/dist/secrets/crypto.js +23 -10
  334. package/dist/secrets/crypto.js.map +1 -1
  335. package/dist/secrets/routes.d.ts +9 -9
  336. package/dist/secrets/storage.d.ts.map +1 -1
  337. package/dist/secrets/storage.js +16 -3
  338. package/dist/secrets/storage.js.map +1 -1
  339. package/dist/server/action-discovery.d.ts.map +1 -1
  340. package/dist/server/action-discovery.js +4 -0
  341. package/dist/server/action-discovery.js.map +1 -1
  342. package/dist/server/action-routes.d.ts +45 -0
  343. package/dist/server/action-routes.d.ts.map +1 -1
  344. package/dist/server/action-routes.js +71 -5
  345. package/dist/server/action-routes.js.map +1 -1
  346. package/dist/server/agent-chat/plugin-options.d.ts +16 -0
  347. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  348. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  349. package/dist/server/agent-chat-plugin.d.ts +20 -0
  350. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  351. package/dist/server/agent-chat-plugin.js +39 -4
  352. package/dist/server/agent-chat-plugin.js.map +1 -1
  353. package/dist/server/derived-secret.d.ts +1 -1
  354. package/dist/server/derived-secret.d.ts.map +1 -1
  355. package/dist/server/derived-secret.js.map +1 -1
  356. package/dist/server/index.d.ts +3 -1
  357. package/dist/server/index.d.ts.map +1 -1
  358. package/dist/server/index.js +2 -0
  359. package/dist/server/index.js.map +1 -1
  360. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  361. package/dist/vite/action-types-plugin.js +4 -0
  362. package/dist/vite/action-types-plugin.js.map +1 -1
  363. package/docs/content/locales/ar-SA/pr-visual-recap.mdx +48 -30
  364. package/docs/content/locales/ar-SA/template-plan.mdx +7 -0
  365. package/docs/content/locales/de-DE/pr-visual-recap.mdx +48 -30
  366. package/docs/content/locales/de-DE/template-plan.mdx +7 -0
  367. package/docs/content/locales/es-ES/pr-visual-recap.mdx +48 -30
  368. package/docs/content/locales/es-ES/template-plan.mdx +14 -0
  369. package/docs/content/locales/fr-FR/pr-visual-recap.mdx +48 -30
  370. package/docs/content/locales/fr-FR/template-plan.mdx +7 -0
  371. package/docs/content/locales/hi-IN/pr-visual-recap.mdx +48 -30
  372. package/docs/content/locales/hi-IN/template-plan.mdx +7 -0
  373. package/docs/content/locales/ja-JP/pr-visual-recap.mdx +48 -30
  374. package/docs/content/locales/ja-JP/template-plan.mdx +7 -0
  375. package/docs/content/locales/ko-KR/pr-visual-recap.mdx +48 -30
  376. package/docs/content/locales/ko-KR/template-plan.mdx +7 -0
  377. package/docs/content/locales/pt-BR/pr-visual-recap.mdx +48 -30
  378. package/docs/content/locales/pt-BR/template-plan.mdx +14 -0
  379. package/docs/content/locales/zh-CN/pr-visual-recap.mdx +48 -30
  380. package/docs/content/locales/zh-CN/template-plan.mdx +7 -0
  381. package/docs/content/locales/zh-TW/pr-visual-recap.mdx +48 -30
  382. package/docs/content/locales/zh-TW/template-plan.mdx +7 -0
  383. package/docs/content/pr-visual-recap.mdx +50 -32
  384. package/docs/content/template-plan.mdx +14 -0
  385. package/docs/content/toolkit-comments-review.mdx +16 -2
  386. package/package.json +4 -1
  387. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +0 -68
  388. package/corpus/templates/forms/server/routes/api/forms/og/[slug]/og.png.get.ts +0 -45
@@ -7,7 +7,6 @@ import {
7
7
  } from "@agent-native/core/client";
8
8
  import {
9
9
  IconCode,
10
- IconChevronDown,
11
10
  IconExternalLink,
12
11
  IconLink,
13
12
  IconMail,
@@ -33,13 +32,7 @@ import {
33
32
  type SharesResponse,
34
33
  type Visibility,
35
34
  } from "@/components/sharing/share-ui";
36
- import { SlackShareHint } from "@/components/sharing/slack-share-hint";
37
35
  import { Button } from "@/components/ui/button";
38
- import {
39
- Collapsible,
40
- CollapsibleContent,
41
- CollapsibleTrigger,
42
- } from "@/components/ui/collapsible";
43
36
  import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
44
37
  import { Input } from "@/components/ui/input";
45
38
  import { Label } from "@/components/ui/label";
@@ -317,7 +310,6 @@ function LinkTab({
317
310
  const agentLinkRequestIdRef = useRef(0);
318
311
  const [agentContextUrl, setAgentContextUrl] = useState("");
319
312
  const [agentLinkError, setAgentLinkError] = useState(false);
320
- const [agentShareOpen, setAgentShareOpen] = useState(false);
321
313
 
322
314
  useEffect(() => {
323
315
  createAgentLinkAsyncRef.current = createAgentLink.mutateAsync;
@@ -352,26 +344,22 @@ function LinkTab({
352
344
  setAgentLinkError(false);
353
345
  if (!sharesLoaded) return;
354
346
 
355
- if (!isPublic && agentShareOpen) {
347
+ if (!isPublic) {
356
348
  void loadAgentContextUrl();
357
349
  }
358
350
 
359
351
  return () => {
360
352
  agentLinkRequestIdRef.current += 1;
361
353
  };
362
- }, [
363
- agentShareOpen,
364
- isPublic,
365
- loadAgentContextUrl,
366
- recordingId,
367
- sharesLoaded,
368
- visibility,
369
- ]);
354
+ }, [isPublic, loadAgentContextUrl, recordingId, sharesLoaded, visibility]);
370
355
 
356
+ const agentLink = isPublic ? shareUrl : agentContextUrl;
371
357
  const agentShareDisabled =
372
- isPending || createAgentLink.isPending || !agentContextUrl;
373
- const agentPrompt = agentContextUrl
374
- ? t("shareDialog.agentPrompt", { agentContextUrl })
358
+ visibilityPending ||
359
+ !sharesLoaded ||
360
+ (!isPublic && (isPending || createAgentLink.isPending || !agentContextUrl));
361
+ const agentPrompt = agentLink
362
+ ? t("shareDialog.agentPrompt", { agentContextUrl: agentLink })
375
363
  : "";
376
364
 
377
365
  return (
@@ -399,67 +387,42 @@ function LinkTab({
399
387
  }
400
388
  />
401
389
 
402
- {/* Public links unfurl into a playable video in Slack; surface that here
403
- (and a connect link) instead of leaving it buried in Settings. */}
404
- {isPublic ? <SlackShareHint canManage={canManage} /> : null}
405
-
406
- {sharesLoaded && !isPublic ? (
407
- <Collapsible open={agentShareOpen} onOpenChange={setAgentShareOpen}>
408
- <CollapsibleTrigger asChild>
409
- <Button
410
- type="button"
411
- variant="ghost"
412
- className="h-auto w-full justify-between px-0 py-1 text-left hover:bg-transparent"
413
- >
414
- <span className="min-w-0">
415
- <span className="block text-xs font-medium text-foreground">
416
- {t("shareDialog.shareWithAgents")}
417
- </span>
418
- <span className="mt-0.5 block text-xs font-normal text-muted-foreground">
419
- {t("shareDialog.agentTokenDescription")}
420
- </span>
421
- </span>
422
- <IconChevronDown
423
- className={`h-4 w-4 shrink-0 text-muted-foreground transition-transform ${
424
- agentShareOpen ? "rotate-180" : ""
425
- }`}
426
- aria-hidden
427
- />
428
- </Button>
429
- </CollapsibleTrigger>
430
- <CollapsibleContent className="pt-2">
431
- <div className="space-y-3 rounded-md border border-border bg-muted/30 p-3">
432
- <CopyField
433
- label={t("shareDialog.shareWithAgents")}
434
- value={agentContextUrl}
435
- disabled={agentShareDisabled}
436
- />
437
- {agentLinkError ? (
438
- <div className="flex items-center justify-between gap-2 rounded-md border border-border bg-background px-3 py-2">
439
- <p className="text-xs text-muted-foreground">
440
- {t("shareDialog.agentLinkUnavailable")}
441
- </p>
442
- <Button
443
- type="button"
444
- variant="ghost"
445
- size="sm"
446
- className="h-7"
447
- onClick={() => void loadAgentContextUrl()}
448
- disabled={createAgentLink.isPending}
449
- >
450
- {t("shareDialog.retryAgentLink")}
451
- </Button>
452
- </div>
453
- ) : null}
454
- <CopyField
455
- label={t("shareDialog.copyAgentPrompt")}
456
- value={agentPrompt}
457
- disabled={agentShareDisabled}
458
- />
459
- </div>
460
- </CollapsibleContent>
461
- </Collapsible>
462
- ) : null}
390
+ <div className="space-y-2">
391
+ <CopyField
392
+ label={t("shareDialog.shareWithAgents")}
393
+ value={agentLink}
394
+ disabled={agentShareDisabled}
395
+ />
396
+ {sharesLoaded && !isPublic ? (
397
+ <>
398
+ <p className="text-xs text-muted-foreground">
399
+ {t("shareDialog.agentTokenDescription")}
400
+ </p>
401
+ {agentLinkError ? (
402
+ <div className="flex items-center justify-between gap-2 rounded-md border border-border bg-muted/30 px-3 py-2">
403
+ <p className="text-xs text-muted-foreground">
404
+ {t("shareDialog.agentLinkUnavailable")}
405
+ </p>
406
+ <Button
407
+ type="button"
408
+ variant="ghost"
409
+ size="sm"
410
+ className="h-7"
411
+ onClick={() => void loadAgentContextUrl()}
412
+ disabled={createAgentLink.isPending}
413
+ >
414
+ {t("shareDialog.retryAgentLink")}
415
+ </Button>
416
+ </div>
417
+ ) : null}
418
+ <CopyField
419
+ label={t("shareDialog.copyAgentPrompt")}
420
+ value={agentPrompt}
421
+ disabled={agentShareDisabled}
422
+ />
423
+ </>
424
+ ) : null}
425
+ </div>
463
426
 
464
427
  {sharesLoaded && !isPublic && canManage ? (
465
428
  <MakePublicCard
@@ -28,6 +28,7 @@ import {
28
28
  DropdownMenuTrigger,
29
29
  } from "@/components/ui/dropdown-menu";
30
30
  import { Spinner } from "@/components/ui/spinner";
31
+ import { useMseVideoSource } from "@/hooks/use-mse-video-source";
31
32
  import {
32
33
  parsePlaybackSpeed,
33
34
  readPlaybackSpeedPreference,
@@ -365,6 +366,32 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
365
366
  [resolvedVideoSrc],
366
367
  );
367
368
 
369
+ // Media Source Extensions path for raw fragmented-MP4 recordings (desktop
370
+ // live-stream uploads). Those files declare no up-front duration, so the
371
+ // native progressive pipeline scans the whole file before it can play from
372
+ // a CDN. When the asset sniffs as fragmented, `mse.mode === "mse"` and we
373
+ // hand the element a MediaSource object URL instead of the raw URL, with the
374
+ // duration supplied from the DB. Everything else (classic MP4, WebM, Loom,
375
+ // browsers without MediaSource) stays on the native `<video src>` path,
376
+ // byte-for-byte unchanged.
377
+ const mse = useMseVideoSource({
378
+ videoRef,
379
+ sourceUrl: resolvedVideoSrc,
380
+ durationMs,
381
+ videoFormat,
382
+ disabled: isLoomEmbed || unsupportedFormat,
383
+ });
384
+ const mseActive = mse.mode === "mse" && Boolean(mse.objectUrl);
385
+ // The URL actually put on the <video> element: the MediaSource object URL
386
+ // while MSE drives playback, nothing while we're still sniffing an eligible
387
+ // asset (so the browser never starts the slow native scan), otherwise the
388
+ // normal resolved/cache-busted source.
389
+ const domVideoSrc = mseActive
390
+ ? mse.objectUrl
391
+ : mse.mode === "pending"
392
+ ? undefined
393
+ : activeVideoSrc;
394
+
368
395
  useEffect(() => {
369
396
  if (!resolvedVideoSrc) {
370
397
  setActiveVideoSrc(undefined);
@@ -1164,7 +1191,7 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1164
1191
  ) : activeVideoSrc ? (
1165
1192
  <video
1166
1193
  ref={videoRef}
1167
- src={activeVideoSrc}
1194
+ src={domVideoSrc}
1168
1195
  poster={resolveLocalUrl(thumbnailUrl)}
1169
1196
  // `crossOrigin` is only needed so the owner's canvas thumbnail
1170
1197
  // capture isn't tainted. For everyone else (viewers, and the Slack
@@ -1328,6 +1355,17 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1328
1355
  playAttemptPendingRef.current = false;
1329
1356
  setIsPlayPending(false);
1330
1357
 
1358
+ // If the MSE pipeline surfaced a media error, tear it down and let
1359
+ // the native <video src> path take over the raw asset URL instead
1360
+ // of running the cache-bust retry against a MediaSource blob URL.
1361
+ if (mseActive) {
1362
+ mse.fallbackToNative();
1363
+ setIsBuffering(false);
1364
+ setIsPreparing(true);
1365
+ setCanPlay(false);
1366
+ return;
1367
+ }
1368
+
1331
1369
  // Most "format not supported" / decode errors reported here are
1332
1370
  // transient — e.g. the share page's video element started
1333
1371
  // fetching a moment before a background seekable-remux pass
@@ -1,8 +1,10 @@
1
1
  import { useCallback, useEffect, useState } from "react";
2
2
 
3
3
  import { useIsMobile } from "@/hooks/use-mobile";
4
-
5
- const DISMISSED_KEY = "clips.desktop-promo.dismissed";
4
+ import {
5
+ hasDownloadedDesktopApp,
6
+ markDesktopAppDownloaded,
7
+ } from "@/lib/capture-install-options";
6
8
 
7
9
  function detectDesktopApp(): boolean {
8
10
  if (typeof navigator === "undefined") return false;
@@ -25,20 +27,12 @@ export function useDesktopPromo() {
25
27
 
26
28
  useEffect(() => {
27
29
  setIsDesktopApp(detectDesktopApp());
28
- setDismissed(
29
- typeof window !== "undefined" &&
30
- window.localStorage?.getItem(DISMISSED_KEY) === "1",
31
- );
30
+ setDismissed(hasDownloadedDesktopApp());
32
31
  }, []);
33
32
 
34
33
  const dismiss = useCallback(() => {
35
34
  setDismissed(true);
36
- try {
37
- window.localStorage?.setItem(DISMISSED_KEY, "1");
38
- } catch {
39
- // localStorage can throw in private browsing — ignore, dismissal
40
- // still holds for the session via React state.
41
- }
35
+ markDesktopAppDownloaded();
42
36
  }, []);
43
37
 
44
38
  return {
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Decides whether a recording should play through Media Source Extensions and,
3
+ * when it should, owns the `MseVideoLoader` lifecycle.
4
+ *
5
+ * Raw fragmented-MP4 recordings (from the desktop live-streaming pipeline)
6
+ * declare no up-front duration, so the browser's progressive `<video src>`
7
+ * pipeline stalls when they're served from a CDN. This hook sniffs the asset,
8
+ * and for fragmented files hands the video element a `MediaSource` object URL
9
+ * driven by range requests with the duration supplied from the DB. Classic MP4,
10
+ * WebM, Loom, and anything the browser can't MSE fall back to the native path
11
+ * unchanged.
12
+ */
13
+
14
+ import {
15
+ type RefObject,
16
+ useCallback,
17
+ useEffect,
18
+ useRef,
19
+ useState,
20
+ } from "react";
21
+
22
+ import { sniffFragmentedMp4 } from "@/lib/fmp4";
23
+ import { MseVideoLoader, isMediaSourceSupported } from "@/lib/mse-video-loader";
24
+
25
+ export type MseSourceMode = "pending" | "native" | "mse";
26
+
27
+ export interface UseMseVideoSourceParams {
28
+ videoRef: RefObject<HTMLVideoElement | null>;
29
+ /** The resolved asset URL (proxied same-origin or provider URL). */
30
+ sourceUrl: string | undefined;
31
+ /** Authoritative duration in ms from the DB. */
32
+ durationMs: number;
33
+ /** Container format hint. WebM is never eligible for this MP4-only loader. */
34
+ videoFormat?: "webm" | "mp4" | null;
35
+ /** True for Loom embeds / formats the browser cannot decode — never MSE. */
36
+ disabled?: boolean;
37
+ }
38
+
39
+ export interface UseMseVideoSourceResult {
40
+ mode: MseSourceMode;
41
+ /** MediaSource object URL to use as `<video src>` when `mode === "mse"`. */
42
+ objectUrl: string | undefined;
43
+ /** Drop MSE and revert to the plain `<video src>` path. */
44
+ fallbackToNative: () => void;
45
+ }
46
+
47
+ export function useMseVideoSource({
48
+ videoRef,
49
+ sourceUrl,
50
+ durationMs,
51
+ videoFormat,
52
+ disabled,
53
+ }: UseMseVideoSourceParams): UseMseVideoSourceResult {
54
+ // WebM recordings use the native Infinity-duration workaround; only MP4 (and
55
+ // unknown-format, which the sniff will confirm) are candidates.
56
+ const eligible =
57
+ !disabled &&
58
+ !!sourceUrl &&
59
+ videoFormat !== "webm" &&
60
+ isMediaSourceSupported();
61
+
62
+ const [mode, setMode] = useState<MseSourceMode>(() =>
63
+ eligible ? "pending" : "native",
64
+ );
65
+ const [objectUrl, setObjectUrl] = useState<string | undefined>(undefined);
66
+ const loaderRef = useRef<MseVideoLoader | null>(null);
67
+
68
+ // Latest duration, kept in a ref so the (deliberately duration-independent)
69
+ // rebuild effect below seeds a freshly created loader with the current value
70
+ // even if it changed during the async sniff. Updating a ref in render is
71
+ // side-effect-free and safe.
72
+ const durationMsRef = useRef(durationMs);
73
+ durationMsRef.current = durationMs;
74
+
75
+ useEffect(() => {
76
+ loaderRef.current?.destroy();
77
+ loaderRef.current = null;
78
+ setObjectUrl(undefined);
79
+
80
+ if (!eligible || !sourceUrl) {
81
+ setMode("native");
82
+ return;
83
+ }
84
+
85
+ setMode("pending");
86
+ let cancelled = false;
87
+
88
+ void sniffFragmentedMp4(sourceUrl)
89
+ .then((isFragmented) => {
90
+ if (cancelled) return;
91
+ const video = videoRef.current;
92
+ if (!isFragmented || !video) {
93
+ setMode("native");
94
+ return;
95
+ }
96
+ try {
97
+ const loader = new MseVideoLoader({
98
+ url: sourceUrl,
99
+ durationMs: durationMsRef.current,
100
+ video,
101
+ onFatal: () => {
102
+ if (cancelled) return;
103
+ loaderRef.current?.destroy();
104
+ loaderRef.current = null;
105
+ setObjectUrl(undefined);
106
+ setMode("native");
107
+ },
108
+ });
109
+ loaderRef.current = loader;
110
+ setObjectUrl(loader.objectUrl);
111
+ setMode("mse");
112
+ } catch {
113
+ setMode("native");
114
+ }
115
+ })
116
+ .catch(() => {
117
+ if (!cancelled) setMode("native");
118
+ });
119
+
120
+ return () => {
121
+ cancelled = true;
122
+ loaderRef.current?.destroy();
123
+ loaderRef.current = null;
124
+ };
125
+ // videoRef is a stable ref object. `durationMs` is intentionally excluded:
126
+ // it only seeds the timeline and is pushed to the live loader by the effect
127
+ // below, so a metadata-poll update must not rebuild the loader (which would
128
+ // revoke the object URL and restart playback from byte zero).
129
+ // eslint-disable-next-line react-hooks/exhaustive-deps
130
+ }, [eligible, sourceUrl]);
131
+
132
+ // Recording metadata polling can raise the DB duration while the same
133
+ // fragmented asset is still playing; apply it to the live loader in place.
134
+ useEffect(() => {
135
+ loaderRef.current?.setDuration(durationMs);
136
+ }, [durationMs]);
137
+
138
+ const fallbackToNative = useCallback(() => {
139
+ loaderRef.current?.destroy();
140
+ loaderRef.current = null;
141
+ setObjectUrl(undefined);
142
+ setMode("native");
143
+ }, []);
144
+
145
+ return { mode, objectUrl, fallbackToNative };
146
+ }
@@ -887,14 +887,6 @@ const messages = {
887
887
  "سيفقد {{email}} الوصول إلى هذه المؤسسة. يمكنك دائمًا دعوته مرة أخرى.",
888
888
  remove: "إزالة",
889
889
  },
890
- slackShareHint: {
891
- playsInline: "يعمل داخل Slack",
892
- connectedDescription:
893
- "الصق هذا الرابط في أي مساحة عمل متصلة لتشغيله داخلها.",
894
- makeInline: "اجعله يعمل داخل Slack",
895
- connectDescription: "قم بتوصيل مساحة عمل حتى يظهر هذا الرابط كفيديو.",
896
- connect: "اتصال",
897
- },
898
890
  commentsPanel: {
899
891
  disabled: "تم تعطيل التعليقات لهذا التسجيل.",
900
892
  beFirst: "كن أول من يعلق",
@@ -911,15 +911,6 @@ Alle sichtbaren Änderungen für Clips-Nutzer werden hier dokumentiert. Du kanns
911
911
  "{{email}} verliert den Zugriff auf diese Organisation. Du kannst die Person jederzeit erneut einladen.",
912
912
  remove: "Entfernen",
913
913
  },
914
- slackShareHint: {
915
- playsInline: "Wird inline in Slack abgespielt",
916
- connectedDescription:
917
- "Füge diesen Link in einem verbundenen Workspace ein, um ihn inline abzuspielen.",
918
- makeInline: "Inline-Wiedergabe in Slack aktivieren",
919
- connectDescription:
920
- "Verbinde einen Workspace, damit dieser Link als Video angezeigt wird.",
921
- connect: "Verbinden",
922
- },
923
914
  commentsPanel: {
924
915
  disabled: "Kommentare sind für diese Aufzeichnung deaktiviert.",
925
916
  beFirst: "Schreibe den ersten Kommentar",
@@ -882,14 +882,6 @@ All notable user-facing changes to Clips are documented here. Open it any time f
882
882
  "{{email}} will lose access to this organization. You can always invite them back.",
883
883
  remove: "Remove",
884
884
  },
885
- slackShareHint: {
886
- playsInline: "Plays inline in Slack",
887
- connectedDescription:
888
- "Paste this link in any connected workspace to play it inline.",
889
- makeInline: "Make it play inline in Slack",
890
- connectDescription: "Connect a workspace so this link unfurls as a video.",
891
- connect: "Connect",
892
- },
893
885
  commentsPanel: {
894
886
  disabled: "Comments are disabled for this recording.",
895
887
  beFirst: "Be the first to comment",
@@ -904,15 +904,6 @@ Todos los cambios visibles para los usuarios de Clips se documentan aquí. Puede
904
904
  "{{email}} perderá acceso a esta organización. Siempre puedes volver a invitarlo.",
905
905
  remove: "Eliminar",
906
906
  },
907
- slackShareHint: {
908
- playsInline: "Se reproduce inline en Slack",
909
- connectedDescription:
910
- "Pega este enlace en cualquier espacio conectado para reproducirlo inline.",
911
- makeInline: "Haz que se reproduzca inline en Slack",
912
- connectDescription:
913
- "Conecta un espacio para que este enlace se despliegue como video.",
914
- connect: "Conectar",
915
- },
916
907
  commentsPanel: {
917
908
  disabled: "Los comentarios están desactivados para esta grabación.",
918
909
  beFirst: "Sé la primera persona en comentar",
@@ -906,15 +906,6 @@ Tous les changements visibles par les utilisateurs de Clips sont documentés ici
906
906
  "{{email}} perdra l’accès à cette organisation. Vous pourrez toujours l’inviter à nouveau.",
907
907
  remove: "Retirer",
908
908
  },
909
- slackShareHint: {
910
- playsInline: "Lecture inline dans Slack",
911
- connectedDescription:
912
- "Collez ce lien dans n’importe quel espace connecté pour le lire inline.",
913
- makeInline: "Le lire inline dans Slack",
914
- connectDescription:
915
- "Connectez un espace pour que ce lien se déplie en vidéo.",
916
- connect: "Connecter",
917
- },
918
909
  commentsPanel: {
919
910
  disabled: "Les commentaires sont désactivés pour cet enregistrement.",
920
911
  beFirst: "Soyez le premier à commenter",
@@ -876,14 +876,6 @@ Clips में उपयोगकर्ताओं को दिखने व
876
876
  "{{email}} इस संगठन तक पहुंच खो देगा। आप उन्हें हमेशा वापस आमंत्रित कर सकते हैं।",
877
877
  remove: "हटाएं",
878
878
  },
879
- slackShareHint: {
880
- playsInline: "Slack में इनलाइन चलता है",
881
- connectedDescription:
882
- "इसे इनलाइन चलाने के लिए यह लिंक किसी भी जुड़े हुए वर्कस्पेस में पेस्ट करें।",
883
- makeInline: "इसे Slack में इनलाइन चलाएं",
884
- connectDescription: "एक वर्कस्पेस कनेक्ट करें ताकि यह लिंक वीडियो के रूप में खुले।",
885
- connect: "कनेक्ट करें",
886
- },
887
879
  commentsPanel: {
888
880
  disabled: "इस रिकॉर्डिंग के लिए टिप्पणियां बंद हैं।",
889
881
  beFirst: "पहली टिप्पणी करें",
@@ -893,15 +893,6 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
893
893
  "{{email}} はこの組織へのアクセスを失います。いつでも再招待できます。",
894
894
  remove: "削除",
895
895
  },
896
- slackShareHint: {
897
- playsInline: "Slack 内でインライン再生",
898
- connectedDescription:
899
- "このリンクを接続済みワークスペースに貼り付けるとインライン再生されます。",
900
- makeInline: "Slack でインライン再生する",
901
- connectDescription:
902
- "ワークスペースを接続すると、このリンクが動画として展開されます。",
903
- connect: "接続",
904
- },
905
896
  commentsPanel: {
906
897
  disabled: "この録画ではコメントが無効です。",
907
898
  beFirst: "最初にコメントする",
@@ -883,15 +883,6 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
883
883
  "{{email}}은 이 조직에 대한 액세스 권한을 잃습니다. 언제든 다시 초대할 수 있습니다.",
884
884
  remove: "제거",
885
885
  },
886
- slackShareHint: {
887
- playsInline: "Slack에서 인라인 재생",
888
- connectedDescription:
889
- "이 링크를 연결된 워크스페이스에 붙여넣으면 인라인으로 재생됩니다.",
890
- makeInline: "Slack에서 인라인 재생하기",
891
- connectDescription:
892
- "워크스페이스를 연결하면 이 링크가 동영상으로 펼쳐집니다.",
893
- connect: "연결",
894
- },
895
886
  commentsPanel: {
896
887
  disabled: "이 녹화에서는 댓글이 비활성화되어 있습니다.",
897
888
  beFirst: "첫 댓글을 남겨보세요",
@@ -900,15 +900,6 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
900
900
  "{{email}} perderá acesso a esta organização. Você sempre pode convidá-lo novamente.",
901
901
  remove: "Remover",
902
902
  },
903
- slackShareHint: {
904
- playsInline: "Reproduz inline no Slack",
905
- connectedDescription:
906
- "Cole este link em qualquer workspace conectado para reproduzi-lo inline.",
907
- makeInline: "Faça reproduzir inline no Slack",
908
- connectDescription:
909
- "Conecte um workspace para que este link abra como vídeo.",
910
- connect: "Conectar",
911
- },
912
903
  commentsPanel: {
913
904
  disabled: "Os comentários estão desativados para esta gravação.",
914
905
  beFirst: "Seja a primeira pessoa a comentar",
@@ -849,13 +849,6 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
849
849
  "{{email}} 将失去对此组织的访问权限。你随时可以重新邀请他们。",
850
850
  remove: "移除",
851
851
  },
852
- slackShareHint: {
853
- playsInline: "可在 Slack 中内联播放",
854
- connectedDescription: "将此链接粘贴到任何已连接工作区即可内联播放。",
855
- makeInline: "让它在 Slack 中内联播放",
856
- connectDescription: "连接一个工作区,让此链接展开为视频。",
857
- connect: "连接",
858
- },
859
852
  commentsPanel: {
860
853
  disabled: "此录制已禁用评论。",
861
854
  beFirst: "成为第一个评论的人",
@@ -842,13 +842,6 @@ const messages = {
842
842
  "{{email}} 將失去對此組織的存取權限。你隨時可以重新邀請他們。",
843
843
  remove: "移除",
844
844
  },
845
- slackShareHint: {
846
- playsInline: "可在 Slack 中行內播放",
847
- connectedDescription: "將此連結貼上到任何已連線工作區即可行內播放。",
848
- makeInline: "讓它在 Slack 中行內播放",
849
- connectDescription: "連線一個工作區,讓此連結展開為影片。",
850
- connect: "連線",
851
- },
852
845
  commentsPanel: {
853
846
  disabled: "此錄製已停用評論。",
854
847
  beFirst: "成為第一個評論的人",
@@ -1,3 +1,24 @@
1
+ const DESKTOP_DOWNLOAD_STORAGE_KEY = "clips.desktop-promo.dismissed";
2
+
3
+ export function hasDownloadedDesktopApp(): boolean {
4
+ try {
5
+ return (
6
+ typeof window !== "undefined" &&
7
+ window.localStorage?.getItem(DESKTOP_DOWNLOAD_STORAGE_KEY) === "1"
8
+ );
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+
14
+ export function markDesktopAppDownloaded(): void {
15
+ try {
16
+ window.localStorage?.setItem(DESKTOP_DOWNLOAD_STORAGE_KEY, "1");
17
+ } catch {
18
+ // Download tracking is best-effort and must not block the installer.
19
+ }
20
+ }
21
+
1
22
  function isFalsy(value: unknown): boolean {
2
23
  if (typeof value !== "string") return false;
3
24
  return ["0", "false", "no", "off"].includes(value.trim().toLowerCase());