@agent-native/core 0.92.10 → 0.92.12

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 (354) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +29 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/production-agent.ts +214 -17
  5. package/corpus/core/src/agent/run-manager.ts +72 -14
  6. package/corpus/core/src/agent/run-store.ts +152 -27
  7. package/corpus/core/src/cli/design-connect.ts +433 -151
  8. package/corpus/core/src/cli/skills.ts +14 -0
  9. package/corpus/core/src/client/AssistantChat.tsx +25 -0
  10. package/corpus/core/src/client/MultiTabAssistantChat.tsx +40 -6
  11. package/corpus/core/src/client/agent-chat-adapter.ts +56 -12
  12. package/corpus/core/src/client/agent-chat.ts +165 -1
  13. package/corpus/core/src/client/chat/index.ts +9 -1
  14. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
  15. package/corpus/core/src/client/index.ts +5 -0
  16. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
  17. package/corpus/core/src/collab/awareness-store.ts +23 -12
  18. package/corpus/core/src/collab/client.ts +16 -5
  19. package/corpus/core/src/collab/index.ts +4 -0
  20. package/corpus/core/src/collab/recent-edits.ts +65 -2
  21. package/corpus/core/src/index.browser.ts +1 -0
  22. package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
  23. package/corpus/core/src/server/builder-design-systems.ts +30 -4
  24. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
  25. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
  26. package/corpus/templates/clips/AGENTS.md +4 -0
  27. package/corpus/templates/clips/actions/create-recording.ts +2 -0
  28. package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
  29. package/corpus/templates/clips/actions/request-transcript.ts +102 -33
  30. package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
  31. package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
  32. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +75 -9
  33. package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
  34. package/corpus/templates/clips/app/hooks/use-player-shortcuts.ts +1 -0
  35. package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
  36. package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
  37. package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
  38. package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
  39. package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
  40. package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
  41. package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
  42. package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
  43. package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
  44. package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
  45. package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
  46. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
  47. package/corpus/templates/clips/app/routes/record.tsx +17 -4
  48. package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
  49. package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
  50. package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
  51. package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
  52. package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
  53. package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
  54. package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
  55. package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
  56. package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
  57. package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
  58. package/corpus/templates/clips/changelog/2026-07-10-fixed-copying-agent-responses-and-transcript-text-from-recor.md +6 -0
  59. package/corpus/templates/clips/desktop/src/app.tsx +12 -2
  60. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
  61. package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
  62. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
  63. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
  64. package/corpus/templates/clips/desktop/src/styles.css +6 -3
  65. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
  66. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
  67. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
  68. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
  69. package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
  70. package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
  71. package/corpus/templates/clips/shared/recording-core.ts +12 -0
  72. package/corpus/templates/content/AGENTS.md +7 -6
  73. package/corpus/templates/content/actions/_builder-cms-read-client.ts +82 -7
  74. package/corpus/templates/content/actions/_database-source-utils.ts +149 -30
  75. package/corpus/templates/content/actions/_document-flush.ts +132 -17
  76. package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
  77. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +4 -7
  78. package/corpus/templates/content/actions/attach-content-database-source.ts +41 -17
  79. package/corpus/templates/content/actions/change-content-database-source-role.ts +46 -8
  80. package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
  81. package/corpus/templates/content/actions/link-notion-page.ts +2 -0
  82. package/corpus/templates/content/actions/pull-document.ts +5 -7
  83. package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
  84. package/corpus/templates/content/actions/push-notion-page.ts +10 -0
  85. package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
  86. package/corpus/templates/content/actions/suggest-source-join-key.ts +8 -1
  87. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
  88. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
  89. package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
  90. package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
  91. package/corpus/templates/content/app/i18n-data.ts +18 -0
  92. package/corpus/templates/content/changelog/2026-07-09-builder-source-refreshes-now-keep-mapped-fields-such-as-topi.md +6 -0
  93. package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
  94. package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
  95. package/corpus/templates/content/shared/api.ts +1 -0
  96. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
  97. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
  98. package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
  99. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
  100. package/corpus/templates/design/AGENTS.md +45 -10
  101. package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
  102. package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
  103. package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
  104. package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
  105. package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
  106. package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
  107. package/corpus/templates/design/actions/generate-design.ts +79 -12
  108. package/corpus/templates/design/actions/generate-screens.ts +57 -12
  109. package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
  110. package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
  111. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
  112. package/corpus/templates/design/actions/import-design-source.ts +4 -31
  113. package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
  114. package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
  115. package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
  116. package/corpus/templates/design/actions/list-design-components.ts +104 -0
  117. package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
  118. package/corpus/templates/design/actions/open-component-source.ts +2 -4
  119. package/corpus/templates/design/actions/present-design-variants.ts +412 -16
  120. package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
  121. package/corpus/templates/design/actions/run-design-audit.ts +25 -3
  122. package/corpus/templates/design/actions/show-design-questions.ts +10 -0
  123. package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
  124. package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
  125. package/corpus/templates/design/actions/write-local-file.ts +25 -1
  126. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
  127. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
  128. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
  129. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
  130. package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
  131. package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
  132. package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
  133. package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
  134. package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
  135. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
  136. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
  137. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
  138. package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
  139. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
  140. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
  141. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
  142. package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
  143. package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
  144. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
  145. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
  146. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
  147. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
  148. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
  149. package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
  150. package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
  151. package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
  152. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
  153. package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
  154. package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
  155. package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
  156. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
  157. package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
  158. package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
  159. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
  160. package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
  161. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
  162. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
  163. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
  164. package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
  165. package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
  166. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
  167. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
  168. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
  169. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
  170. package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
  171. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
  172. package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
  173. package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
  174. package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
  175. package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
  176. package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
  177. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
  178. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
  179. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
  180. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
  181. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
  182. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
  183. package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
  184. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
  185. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
  186. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
  187. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
  188. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
  189. package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
  190. package/corpus/templates/design/app/components/design/types.ts +33 -0
  191. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
  192. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
  193. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
  194. package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
  195. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
  196. package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
  197. package/corpus/templates/design/app/i18n-data.ts +1217 -10
  198. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
  199. package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
  200. package/corpus/templates/design/app/lib/design-import.ts +24 -0
  201. package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
  202. package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
  203. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
  204. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
  205. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
  206. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
  207. package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
  208. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
  209. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
  210. package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
  211. package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
  212. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
  213. package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
  228. package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
  229. package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
  230. package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
  231. package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
  232. package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
  233. package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
  234. package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
  235. package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
  236. package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
  237. package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
  238. package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
  239. package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
  240. package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
  241. package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
  242. package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
  243. package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
  244. package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
  245. package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
  246. package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
  247. package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
  248. package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
  249. package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
  250. package/corpus/templates/design/e2e/global-setup.ts +3 -6
  251. package/corpus/templates/design/e2e/helpers.ts +27 -6
  252. package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
  253. package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
  254. package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
  255. package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
  256. package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
  257. package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
  258. package/corpus/templates/design/server/plugins/db.ts +41 -0
  259. package/corpus/templates/design/server/source-workspace.ts +64 -0
  260. package/corpus/templates/design/shared/board-file.ts +13 -2
  261. package/corpus/templates/design/shared/canvas-math.ts +231 -33
  262. package/corpus/templates/design/shared/code-layer.ts +122 -8
  263. package/corpus/templates/design/shared/component-library.ts +161 -0
  264. package/corpus/templates/design/shared/db-conflict.ts +27 -0
  265. package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
  266. package/corpus/templates/design/shared/figma-url.ts +149 -0
  267. package/corpus/templates/design/shared/pen-path.ts +16 -7
  268. package/corpus/templates/design/shared/source-mode.ts +1 -0
  269. package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
  270. package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
  271. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
  272. package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
  273. package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
  274. package/dist/agent/production-agent.d.ts +82 -7
  275. package/dist/agent/production-agent.d.ts.map +1 -1
  276. package/dist/agent/production-agent.js +180 -17
  277. package/dist/agent/production-agent.js.map +1 -1
  278. package/dist/agent/run-manager.d.ts.map +1 -1
  279. package/dist/agent/run-manager.js +63 -14
  280. package/dist/agent/run-manager.js.map +1 -1
  281. package/dist/agent/run-store.d.ts +46 -0
  282. package/dist/agent/run-store.d.ts.map +1 -1
  283. package/dist/agent/run-store.js +129 -22
  284. package/dist/agent/run-store.js.map +1 -1
  285. package/dist/cli/design-connect.d.ts +6 -0
  286. package/dist/cli/design-connect.d.ts.map +1 -1
  287. package/dist/cli/design-connect.js +336 -139
  288. package/dist/cli/design-connect.js.map +1 -1
  289. package/dist/cli/skills.d.ts.map +1 -1
  290. package/dist/cli/skills.js +14 -0
  291. package/dist/cli/skills.js.map +1 -1
  292. package/dist/client/AssistantChat.d.ts +2 -0
  293. package/dist/client/AssistantChat.d.ts.map +1 -1
  294. package/dist/client/AssistantChat.js +19 -3
  295. package/dist/client/AssistantChat.js.map +1 -1
  296. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  297. package/dist/client/MultiTabAssistantChat.js +38 -18
  298. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  299. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  300. package/dist/client/agent-chat-adapter.js +48 -12
  301. package/dist/client/agent-chat-adapter.js.map +1 -1
  302. package/dist/client/agent-chat.d.ts +60 -0
  303. package/dist/client/agent-chat.d.ts.map +1 -1
  304. package/dist/client/agent-chat.js +122 -1
  305. package/dist/client/agent-chat.js.map +1 -1
  306. package/dist/client/chat/index.d.ts +1 -1
  307. package/dist/client/chat/index.d.ts.map +1 -1
  308. package/dist/client/chat/index.js +1 -1
  309. package/dist/client/chat/index.js.map +1 -1
  310. package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
  311. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  312. package/dist/client/extensions/EmbeddedExtension.js +36 -2
  313. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  314. package/dist/client/index.d.ts +1 -1
  315. package/dist/client/index.d.ts.map +1 -1
  316. package/dist/client/index.js +1 -1
  317. package/dist/client/index.js.map +1 -1
  318. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  319. package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
  320. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  321. package/dist/collab/awareness-store.d.ts +5 -0
  322. package/dist/collab/awareness-store.d.ts.map +1 -1
  323. package/dist/collab/awareness-store.js +19 -12
  324. package/dist/collab/awareness-store.js.map +1 -1
  325. package/dist/collab/awareness.d.ts +2 -2
  326. package/dist/collab/awareness.d.ts.map +1 -1
  327. package/dist/collab/client.d.ts.map +1 -1
  328. package/dist/collab/client.js +13 -5
  329. package/dist/collab/client.js.map +1 -1
  330. package/dist/collab/index.d.ts +1 -0
  331. package/dist/collab/index.d.ts.map +1 -1
  332. package/dist/collab/index.js +1 -0
  333. package/dist/collab/index.js.map +1 -1
  334. package/dist/collab/recent-edits.d.ts +3 -1
  335. package/dist/collab/recent-edits.d.ts.map +1 -1
  336. package/dist/collab/recent-edits.js +57 -2
  337. package/dist/collab/recent-edits.js.map +1 -1
  338. package/dist/collab/struct-routes.d.ts +1 -1
  339. package/dist/index.browser.d.ts +1 -1
  340. package/dist/index.browser.d.ts.map +1 -1
  341. package/dist/index.browser.js +1 -1
  342. package/dist/index.browser.js.map +1 -1
  343. package/dist/observability/routes.d.ts +5 -5
  344. package/dist/progress/routes.d.ts +1 -1
  345. package/dist/resources/handlers.d.ts +3 -3
  346. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  347. package/dist/server/agent-chat-plugin.js +87 -10
  348. package/dist/server/agent-chat-plugin.js.map +1 -1
  349. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  350. package/dist/server/builder-design-systems.d.ts +15 -0
  351. package/dist/server/builder-design-systems.d.ts.map +1 -1
  352. package/dist/server/builder-design-systems.js +9 -4
  353. package/dist/server/builder-design-systems.js.map +1 -1
  354. package/package.json +1 -1
@@ -40,6 +40,7 @@ export function usePlayerShortcuts(opts: UsePlayerShortcutsOpts) {
40
40
  if (!enabled) return;
41
41
 
42
42
  function onKey(e: KeyboardEvent) {
43
+ if (e.metaKey || e.ctrlKey || e.altKey) return;
43
44
  if (shouldIgnore(e.target)) return;
44
45
  const player = playerRef.current;
45
46
  if (!player) return;
@@ -379,6 +379,7 @@ const messages = {
379
379
  searchPlaceholder: "نص البحث",
380
380
  copyTranscript: "نسخ النص",
381
381
  downloadSrt: "تحميل .srt",
382
+ regenerate: "إعادة إنشاء النص",
382
383
  cleanupRunning: "تنظيف النص في الخلفية.",
383
384
  noMatches: "لا توجد مباريات.",
384
385
  noTranscript: "لا يوجد نسخة بعد.",
@@ -388,6 +388,7 @@ const messages = {
388
388
  searchPlaceholder: "Transkript durchsuchen",
389
389
  copyTranscript: "Transkript kopieren",
390
390
  downloadSrt: "Laden Sie .srt herunter",
391
+ regenerate: "Transkript neu erstellen",
391
392
  cleanupRunning: "Bereinigen des Transkripts im Hintergrund.",
392
393
  noMatches: "Keine Übereinstimmungen.",
393
394
  noTranscript: "Noch kein Transkript.",
@@ -373,6 +373,7 @@ const messages = {
373
373
  searchPlaceholder: "Search transcript",
374
374
  copyTranscript: "Copy transcript",
375
375
  downloadSrt: "Download .srt",
376
+ regenerate: "Regenerate transcript",
376
377
  cleanupRunning: "Cleaning up transcript in the background.",
377
378
  noMatches: "No matches.",
378
379
  noTranscript: "No transcript yet.",
@@ -386,6 +386,7 @@ const messages = {
386
386
  searchPlaceholder: "Transcripción de búsqueda",
387
387
  copyTranscript: "Copiar transcripción",
388
388
  downloadSrt: "Descargar .srt",
389
+ regenerate: "Regenerar transcripción",
389
390
  cleanupRunning: "Limpiando la transcripción en segundo plano.",
390
391
  noMatches: "Sin coincidencias.",
391
392
  noTranscript: "Aún no hay transcripción.",
@@ -386,6 +386,7 @@ const messages = {
386
386
  searchPlaceholder: "Rechercher la transcription",
387
387
  copyTranscript: "Copier la transcription",
388
388
  downloadSrt: "Télécharger .srt",
389
+ regenerate: "Régénérer la transcription",
389
390
  cleanupRunning: "Nettoyage de la transcription en arrière-plan.",
390
391
  noMatches: "Aucun match.",
391
392
  noTranscript: "Pas encore de transcription.",
@@ -371,6 +371,7 @@ const messages = {
371
371
  searchPlaceholder: "प्रतिलेख खोजें",
372
372
  copyTranscript: "प्रतिलेख कॉपी करें",
373
373
  downloadSrt: "डाउनलोड .srt",
374
+ regenerate: "प्रतिलेख फिर से बनाएँ",
374
375
  cleanupRunning: "पृष्ठभूमि में प्रतिलेख साफ़ करना.",
375
376
  noMatches: "कोई मेल नहीं।",
376
377
  noTranscript: "अभी तक कोई प्रतिलेख नहीं.",
@@ -381,6 +381,7 @@ const messages = {
381
381
  searchPlaceholder: "トランスクリプトの検索",
382
382
  copyTranscript: "トランスクリプトをコピーする",
383
383
  downloadSrt: ".srtをダウンロード",
384
+ regenerate: "トランスクリプトを再生成",
384
385
  cleanupRunning:
385
386
  "バックグラウンドでトランスクリプトをクリーンアップしています。",
386
387
  noMatches: "一致はありません。",
@@ -376,6 +376,7 @@ const messages = {
376
376
  searchPlaceholder: "성적표 검색",
377
377
  copyTranscript: "성적표 복사",
378
378
  downloadSrt: ".srt 다운로드",
379
+ regenerate: "스크립트 다시 생성",
379
380
  cleanupRunning: "백그라운드에서 기록을 정리합니다.",
380
381
  noMatches: "일치하는 항목이 없습니다.",
381
382
  noTranscript: "아직 성적표가 없습니다.",
@@ -383,6 +383,7 @@ const messages = {
383
383
  searchPlaceholder: "Transcrição da pesquisa",
384
384
  copyTranscript: "Copiar transcrição",
385
385
  downloadSrt: "Baixe .srt",
386
+ regenerate: "Gerar transcrição novamente",
386
387
  cleanupRunning: "Limpando a transcrição em segundo plano.",
387
388
  noMatches: "Nenhuma correspondência.",
388
389
  noTranscript: "Nenhuma transcrição ainda.",
@@ -361,6 +361,7 @@ const messages = {
361
361
  searchPlaceholder: "搜索成绩单",
362
362
  copyTranscript: "复制成绩单",
363
363
  downloadSrt: "下载.srt",
364
+ regenerate: "重新生成转录文本",
364
365
  cleanupRunning: "在后台清理成绩单。",
365
366
  noMatches: "没有匹配项。",
366
367
  noTranscript: "还没有文字记录。",
@@ -361,6 +361,7 @@ const messages = {
361
361
  searchPlaceholder: "搜尋逐字稿",
362
362
  copyTranscript: "複製逐字稿",
363
363
  downloadSrt: "下載 .srt",
364
+ regenerate: "重新產生逐字稿",
364
365
  cleanupRunning: "在背景清理逐字稿。",
365
366
  noMatches: "沒有符合項目。",
366
367
  noTranscript: "還沒有逐字稿。",
@@ -59,7 +59,6 @@ import { Badge } from "@/components/ui/badge";
59
59
  import { Button } from "@/components/ui/button";
60
60
  import {
61
61
  DropdownMenu,
62
- DropdownMenuCheckboxItem,
63
62
  DropdownMenuContent,
64
63
  DropdownMenuItem,
65
64
  DropdownMenuLabel,
@@ -67,6 +66,7 @@ import {
67
66
  DropdownMenuTrigger,
68
67
  } from "@/components/ui/dropdown-menu";
69
68
  import { Spinner } from "@/components/ui/spinner";
69
+ import { Switch } from "@/components/ui/switch";
70
70
  import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
71
71
  import {
72
72
  Tooltip,
@@ -499,6 +499,15 @@ export default function RecordingPage() {
499
499
  const firstCta = ctas[0] ?? null;
500
500
  const handleAiError = (err: Error) =>
501
501
  toast.error(err?.message ?? t("recordingPage.aiRequestFailed"));
502
+ const requestTranscript = useActionMutation("request-transcript" as any, {
503
+ onSuccess: () => void playerDataQ.refetch(),
504
+ onError: (err: Error) =>
505
+ toast.error(
506
+ t("recordingPage.retryFailed", {
507
+ message: err?.message ?? t("recordingPage.networkError"),
508
+ }),
509
+ ),
510
+ });
502
511
  const regenerateTitle = useActionMutation("regenerate-title" as any, {
503
512
  onSuccess: (result: any) => {
504
513
  if (result?.updated) {
@@ -913,36 +922,34 @@ export default function RecordingPage() {
913
922
  durationMs={recording.durationMs}
914
923
  currentMs={currentMs}
915
924
  onSeek={(ms) => playerRef.current?.seek(ms)}
916
- status={transcriptStatus}
925
+ status={
926
+ requestTranscript.isPending && transcriptStatus === "failed"
927
+ ? "pending"
928
+ : transcriptStatus
929
+ }
917
930
  failureReason={transcriptFailureReason}
918
931
  cleanup={transcriptCleanup}
919
932
  recordingTitle={recording.title}
920
- onRetry={() => {
921
- // Force a fresh transcript job, then let polling swap the panel
922
- // back to the pending state while it runs.
923
- fetch(
924
- agentNativePath("/_agent-native/actions/request-transcript"),
925
- {
926
- method: "POST",
927
- headers: { "Content-Type": "application/json" },
928
- body: JSON.stringify({
929
- recordingId: recording.id,
930
- force: true,
931
- }),
932
- },
933
- )
934
- .then((res) => {
935
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
936
- })
937
- .catch((err) =>
938
- toast.error(
939
- t("recordingPage.retryFailed", {
940
- message: err?.message ?? t("recordingPage.networkError"),
941
- }),
942
- ),
943
- )
944
- .finally(() => playerDataQ.refetch());
945
- }}
933
+ onRetry={
934
+ canEdit
935
+ ? () =>
936
+ requestTranscript.mutate({
937
+ recordingId: recording.id,
938
+ force: true,
939
+ } as any)
940
+ : undefined
941
+ }
942
+ onRegenerate={
943
+ canEdit && transcriptStatus === "ready"
944
+ ? () =>
945
+ requestTranscript.mutate({
946
+ recordingId: recording.id,
947
+ force: true,
948
+ regenerate: true,
949
+ } as any)
950
+ : undefined
951
+ }
952
+ isRegenerating={requestTranscript.isPending}
946
953
  />
947
954
  </TabsContent>
948
955
  <TabsContent
@@ -1061,16 +1068,21 @@ export default function RecordingPage() {
1061
1068
  {t("recordingPage.enhanceRecording")}
1062
1069
  </DropdownMenuLabel>
1063
1070
  <DropdownMenuSeparator />
1064
- <DropdownMenuCheckboxItem
1065
- checked={includeFullVideoInAi}
1066
- disabled={aiPrefsQ.isLoading || updateAiPrefs.isPending}
1067
- onCheckedChange={handleIncludeFullVideoChange}
1068
- onSelect={(event) => event.preventDefault()}
1069
- title={t("recordingPage.includeFullVideoDescription")}
1071
+ <DropdownMenuItem
1072
+ disabled={requestTranscript.isPending}
1073
+ onSelect={() =>
1074
+ requestTranscript.mutate({
1075
+ recordingId: recording.id,
1076
+ force: true,
1077
+ regenerate: true,
1078
+ } as any)
1079
+ }
1070
1080
  >
1071
- {t("recordingPage.includeFullVideo")}
1072
- </DropdownMenuCheckboxItem>
1073
- <DropdownMenuSeparator />
1081
+ {requestTranscript.isPending ? (
1082
+ <Spinner className="size-4" />
1083
+ ) : null}
1084
+ {t("transcriptPanel.regenerate")}
1085
+ </DropdownMenuItem>
1074
1086
  <DropdownMenuItem
1075
1087
  disabled={regenerateTitle.isPending}
1076
1088
  onSelect={() =>
@@ -1161,6 +1173,25 @@ export default function RecordingPage() {
1161
1173
  </Tooltip>
1162
1174
  );
1163
1175
  })}
1176
+ <DropdownMenuSeparator />
1177
+ <DropdownMenuItem
1178
+ disabled={aiPrefsQ.isLoading || updateAiPrefs.isPending}
1179
+ onSelect={(event) => {
1180
+ event.preventDefault();
1181
+ handleIncludeFullVideoChange(!includeFullVideoInAi);
1182
+ }}
1183
+ title={t("recordingPage.includeFullVideoDescription")}
1184
+ className="justify-between gap-3"
1185
+ >
1186
+ <span>{t("recordingPage.includeFullVideo")}</span>
1187
+ <Switch
1188
+ checked={includeFullVideoInAi}
1189
+ disabled={aiPrefsQ.isLoading || updateAiPrefs.isPending}
1190
+ tabIndex={-1}
1191
+ aria-hidden="true"
1192
+ className="pointer-events-none"
1193
+ />
1194
+ </DropdownMenuItem>
1164
1195
  </DropdownMenuContent>
1165
1196
  </DropdownMenu>
1166
1197
  ) : null}
@@ -1168,6 +1199,8 @@ export default function RecordingPage() {
1168
1199
  <ShareRecordingPopover
1169
1200
  recordingId={recording.id}
1170
1201
  recordingTitle={recording.title}
1202
+ initialVisibility={recording.visibility}
1203
+ initialRole={role}
1171
1204
  videoUrl={recording.videoUrl}
1172
1205
  animatedThumbnailUrl={recording.animatedThumbnailUrl}
1173
1206
  isLoomRecording={isLoomEmbedBacked}
@@ -12,6 +12,7 @@ import {
12
12
  waitForReadyRecordingAfterFinalizeError,
13
13
  } from "@shared/finalize-recovery";
14
14
  import {
15
+ chunkUploadParallelism,
15
16
  chunkUploadUrl,
16
17
  pickMimeType,
17
18
  type UploadMode,
@@ -1576,11 +1577,11 @@ export default function RecordRoute() {
1576
1577
  hasAudio: true,
1577
1578
  width: meta.width,
1578
1579
  height: meta.height,
1579
- visibility: reportContext ? "org" : undefined,
1580
+ visibility: reportContext ? "org" : "public",
1580
1581
  spaceIds: spaceIdFromUrl ? [spaceIdFromUrl] : undefined,
1581
1582
  folderId: folderIdFromUrl ?? undefined,
1582
1583
  mimeType: uploadMimeType,
1583
- requestStreaming: false,
1584
+ requestStreaming: true,
1584
1585
  }),
1585
1586
  },
1586
1587
  );
@@ -1596,10 +1597,16 @@ export default function RecordRoute() {
1596
1597
  );
1597
1598
  }
1598
1599
  const created = (await res.json()) as {
1599
- result?: { id: string; uploadChunkUrl: string; abortUrl?: string };
1600
+ result?: {
1601
+ id: string;
1602
+ uploadChunkUrl: string;
1603
+ abortUrl?: string;
1604
+ uploadMode?: UploadMode;
1605
+ };
1600
1606
  id?: string;
1601
1607
  uploadChunkUrl?: string;
1602
1608
  abortUrl?: string;
1609
+ uploadMode?: UploadMode;
1603
1610
  };
1604
1611
  const info =
1605
1612
  created.result ??
@@ -1607,6 +1614,7 @@ export default function RecordRoute() {
1607
1614
  id: string;
1608
1615
  uploadChunkUrl: string;
1609
1616
  abortUrl?: string;
1617
+ uploadMode?: UploadMode;
1610
1618
  });
1611
1619
  if (!info?.id) {
1612
1620
  throw new Error("create-recording did not return an id");
@@ -1707,7 +1715,12 @@ export default function RecordRoute() {
1707
1715
 
1708
1716
  await Promise.all(
1709
1717
  Array.from(
1710
- { length: Math.min(UPLOAD_PARALLELISM, parallelChunks.length) },
1718
+ {
1719
+ length: Math.min(
1720
+ chunkUploadParallelism(info.uploadMode, UPLOAD_PARALLELISM),
1721
+ parallelChunks.length,
1722
+ ),
1723
+ },
1711
1724
  worker,
1712
1725
  ),
1713
1726
  );
@@ -903,6 +903,8 @@ export default function ShareRoute() {
903
903
  <ShareRecordingPopover
904
904
  recordingId={recording.id}
905
905
  recordingTitle={recording.title}
906
+ initialVisibility={recording.visibility}
907
+ initialRole={viewerIsOwner ? "owner" : undefined}
906
908
  videoUrl={recording.videoUrl}
907
909
  animatedThumbnailUrl={recording.animatedThumbnailUrl}
908
910
  isLoomRecording={isLoomEmbedBacked}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ The Clips desktop popover now sits closer to its menu-bar icon.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Desktop recording optimization progress stays visible from Stop until the finished clip opens.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Fixed long desktop recordings and large video file uploads failing without a resumable upload session.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ New video uploads are public by default, and owners can change sharing visibility as soon as they open the Share dialog.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Long recordings now get enough time to download their media before transcription starts.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Meeting Notes no longer lowers your microphone volume for other people in Zoom, Meet, or Teams.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ On mobile, tapping a playing clip reveals playback controls without interrupting the video.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Regenerate any clip transcript from its saved recording, or retry one that failed.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-09
4
+ ---
5
+
6
+ Slack previews now show the clip length alongside its description.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-10
4
+ ---
5
+
6
+ Fixed copying agent responses and transcript text from recording pages.
@@ -1527,6 +1527,10 @@ export function App() {
1527
1527
  // from THAT render and stops the camera stream even though recording is
1528
1528
  // still in flight.
1529
1529
  const recordingFlowGateRef = useRef(false);
1530
+ // Stop detaches the recorder state before optimization/upload finishes so a
1531
+ // fresh camera session can recover immediately. Keep that post-stop phase
1532
+ // separate so React cleanup does not close the finalizing progress window.
1533
+ const recordingStopFinalizingRef = useRef(false);
1530
1534
  useEffect(() => {
1531
1535
  recordingFlowGateRef.current = isRecording || recordingFlowActive;
1532
1536
  }, [isRecording, recordingFlowActive]);
@@ -1565,7 +1569,9 @@ export function App() {
1565
1569
  // Hide them from here instead. Guard on !recordingInFlight so
1566
1570
  // we don't rip the toolbar out from under an active recording.
1567
1571
  if (!recordingFlowGateRef.current) {
1568
- invoke("hide_overlays").catch(() => {});
1572
+ invoke("hide_overlays", {
1573
+ preserveFinalizing: recordingStopFinalizingRef.current,
1574
+ }).catch(() => {});
1569
1575
  }
1570
1576
  };
1571
1577
  }, [toolbarActive]);
@@ -1721,7 +1727,9 @@ export function App() {
1721
1727
  // source changed (e.g. cameraId flip re-runs this effect): hiding
1722
1728
  // would race the re-run's show_bubble and close the window out from under it.
1723
1729
  if (!recordingInFlight && !bubbleActiveRef.current) {
1724
- invoke("hide_overlays").catch(() => {});
1730
+ invoke("hide_overlays", {
1731
+ preserveFinalizing: recordingStopFinalizingRef.current,
1732
+ }).catch(() => {});
1725
1733
  }
1726
1734
  };
1727
1735
  }, [bubbleActive, cameraId, bubbleSessionEpoch]);
@@ -2351,6 +2359,7 @@ export function App() {
2351
2359
  // finalize; keeping `recorder` set through the whole upload made
2352
2360
  // reopen show a blank preview and made Start a silent no-op.
2353
2361
  const handle = recorder;
2362
+ recordingStopFinalizingRef.current = true;
2354
2363
  bubbleStreamTransferredToRecorder.current = false;
2355
2364
  bubbleStreamRef.current = null;
2356
2365
  recordingFlowGateRef.current = false;
@@ -2381,6 +2390,7 @@ export function App() {
2381
2390
  setRecError(err instanceof Error ? err.message : String(err));
2382
2391
  await loadPendingUploads();
2383
2392
  } finally {
2393
+ recordingStopFinalizingRef.current = false;
2384
2394
  invoke("set_recording_state", { active: false }).catch(() => {});
2385
2395
  if (stopFailed || stopResult?.localOnly) {
2386
2396
  invoke("show_popover").catch(() => {});
@@ -377,7 +377,9 @@ export function useMeetingTranscription({
377
377
  };
378
378
 
379
379
  // Resume the engine that initial start settled on (no fallback here —
380
- // the engine choice was already made below).
380
+ // the engine choice was already made below). Never add a second
381
+ // VoiceProcessingIO stack beside the meeting app: it can alter the
382
+ // microphone level that remote participants receive.
381
383
  const startAudio = async () => {
382
384
  await restartTranscriptionEngine(
383
385
  session.engine,
@@ -386,6 +388,7 @@ export function useMeetingTranscription({
386
388
  label: selectedMicLabel,
387
389
  },
388
390
  true,
391
+ false,
389
392
  );
390
393
  };
391
394
 
@@ -556,6 +559,10 @@ export function useMeetingTranscription({
556
559
 
557
560
  session.engine = await startTranscriptionEngine({
558
561
  mic: { deviceId: selectedMicId, label: selectedMicLabel },
562
+ // macOS 15+ uses ScreenCaptureKit's independent microphone output.
563
+ // The legacy fallback must also remain a raw tap so Zoom/Meet/Teams
564
+ // stay in sole control of their live-call voice processing.
565
+ voiceProcessing: false,
559
566
  });
560
567
 
561
568
  await invoke("silence_detector_start", {
@@ -2232,11 +2232,14 @@ async function startNativeFullscreenRecording(
2232
2232
  );
2233
2233
  }
2234
2234
 
2235
- const chromeCmd = wantsCamera
2236
- ? "hide_recording_chrome"
2237
- : "hide_overlays";
2238
- await invoke(chromeCmd).catch((err) =>
2239
- console.error(`[clips-recorder] ${chromeCmd} failed:`, err),
2235
+ // The finalizing window owns the whole stop -> optimized upload ->
2236
+ // browser-open gap. Only tear down recording chrome here; the outer
2237
+ // finally closes finalizing after the clip has opened or failed.
2238
+ await invoke("hide_recording_chrome").catch((err) =>
2239
+ console.error(
2240
+ "[clips-recorder] hide_recording_chrome failed:",
2241
+ err,
2242
+ ),
2240
2243
  );
2241
2244
  await invoke("native_fullscreen_capture_thumbnail", {
2242
2245
  serverUrl: params.serverUrl,
@@ -119,7 +119,7 @@ export async function restartTranscriptionEngine(
119
119
  engine: TranscriptionEngine,
120
120
  mic?: MicSelection,
121
121
  captureSystem: boolean = true,
122
- voiceProcessing: boolean = true,
122
+ voiceProcessing: boolean = false,
123
123
  ): Promise<void> {
124
124
  if (engine === "whisper") {
125
125
  await invoke("audio_transcription_start", {
@@ -151,14 +151,14 @@ export async function startTranscriptionEngine(opts: {
151
151
  /** Capture + transcribe system audio (whisper). Default true. */
152
152
  captureSystem?: boolean;
153
153
  /**
154
- * Enable Apple's voice-processing input mode for the Whisper mic tap. Native
155
- * recordings disable this so the transcription tap does not reconfigure the
156
- * shared microphone before ScreenCaptureKit opens it.
154
+ * Enable Apple's voice-processing input mode for the Whisper mic tap.
155
+ * Meeting and recording capture leave this off so Clips never adds a second
156
+ * VoIP processor beside Zoom, Meet, or Teams and changes their mic uplink.
157
157
  */
158
158
  voiceProcessing?: boolean;
159
159
  }): Promise<TranscriptionEngine> {
160
160
  const captureSystem = opts.captureSystem ?? true;
161
- const voiceProcessing = opts.voiceProcessing ?? true;
161
+ const voiceProcessing = opts.voiceProcessing ?? false;
162
162
  try {
163
163
  await restartTranscriptionEngine(
164
164
  "whisper",
@@ -1254,6 +1254,9 @@ export function installDesktopVoiceDictation(
1254
1254
  micDeviceId: concreteMediaDeviceId(micDeviceId) || null,
1255
1255
  micDeviceLabel: micDeviceLabel || null,
1256
1256
  captureSystem: false,
1257
+ // Short, standalone dictation sessions benefit from Apple's AEC/AGC.
1258
+ // Meeting and recording capture explicitly keep this disabled.
1259
+ voiceProcessing: true,
1257
1260
  owner: "dictation",
1258
1261
  });
1259
1262
  console.log("[voice-dictation] audio_transcription_start ok");
@@ -25,9 +25,11 @@
25
25
  --radius: 12px;
26
26
  --radius-sm: 8px;
27
27
  --radius-pill: 999px;
28
- /* Must cover `--shadow-md` blur (24px in dark mode) or the transparent
29
- Tauri window clips the drop shadow on every edge. */
28
+ /* Keep the side and bottom shadow clear of the transparent Tauri window.
29
+ The top is intentionally tighter: the popover should feel attached to
30
+ its menu-bar icon, where a clipped shadow is not visible anyway. */
30
31
  --popover-shadow-gutter: 24px;
32
+ --popover-shadow-gutter-top: 6px;
31
33
  --overlay-shadow-gutter: 18px;
32
34
 
33
35
  --shadow-sm: 0 1px 2px rgba(23, 23, 23, 0.06);
@@ -106,7 +108,8 @@ button {
106
108
 
107
109
  body[data-clips-route="popover"] #root {
108
110
  min-height: 100vh;
109
- padding: var(--popover-shadow-gutter);
111
+ padding: var(--popover-shadow-gutter-top) var(--popover-shadow-gutter)
112
+ var(--popover-shadow-gutter);
110
113
  }
111
114
 
112
115
  body[data-clips-route]:not([data-clips-route="popover"]) #root {
@@ -46,6 +46,15 @@ const REGION_GUIDES_LABEL: &str = "region-guides";
46
46
  const REGION_GUIDE_EDITOR_LABEL: &str = "region-guide-editor";
47
47
  const REGION_RECORD_BORDER_LABEL: &str = "region-record-border";
48
48
  const ONBOARDING_LABEL: &str = "onboarding";
49
+ const OVERLAY_LABELS: &[&str] = &[
50
+ COUNTDOWN_LABEL,
51
+ TOOLBAR_LABEL,
52
+ BUBBLE_LABEL,
53
+ FINALIZING_LABEL,
54
+ FLOW_BAR_LABEL,
55
+ REGION_GUIDES_LABEL,
56
+ REGION_RECORD_BORDER_LABEL,
57
+ ];
49
58
  const ONBOARDING_WIDTH_LOGICAL: f64 = 560.0;
50
59
  const ONBOARDING_HEIGHT_LOGICAL: f64 = 640.0;
51
60
 
@@ -952,19 +961,21 @@ pub async fn set_bubble_capture_excluded(app: AppHandle, excluded: bool) -> Resu
952
961
  Ok(())
953
962
  }
954
963
 
964
+ fn overlay_labels_to_hide(preserve_finalizing: bool) -> impl Iterator<Item = &'static str> {
965
+ OVERLAY_LABELS
966
+ .iter()
967
+ .copied()
968
+ .filter(move |label| !preserve_finalizing || *label != FINALIZING_LABEL)
969
+ }
970
+
955
971
  #[tauri::command]
956
- pub async fn hide_overlays(app: AppHandle) -> Result<(), String> {
972
+ pub async fn hide_overlays(
973
+ app: AppHandle,
974
+ preserve_finalizing: Option<bool>,
975
+ ) -> Result<(), String> {
957
976
  stop_countdown_control_tracking();
958
977
  let _ = app.emit("clips:countdown-shortcuts-active", false);
959
- for label in [
960
- COUNTDOWN_LABEL,
961
- TOOLBAR_LABEL,
962
- BUBBLE_LABEL,
963
- FINALIZING_LABEL,
964
- FLOW_BAR_LABEL,
965
- REGION_GUIDES_LABEL,
966
- REGION_RECORD_BORDER_LABEL,
967
- ] {
978
+ for label in overlay_labels_to_hide(preserve_finalizing.unwrap_or(false)) {
968
979
  if let Some(w) = app.get_webview_window(label) {
969
980
  let _ = w.close();
970
981
  }
@@ -1524,9 +1535,16 @@ fn remembered_voice_target_bundle(app: &AppHandle) -> Option<String> {
1524
1535
  #[cfg(test)]
1525
1536
  mod tests {
1526
1537
  use super::{
1527
- strip_trailing_period_for_messaging, text_insertion_strategy, TextInsertionStrategy,
1538
+ overlay_labels_to_hide, strip_trailing_period_for_messaging, text_insertion_strategy,
1539
+ TextInsertionStrategy, FINALIZING_LABEL,
1528
1540
  };
1529
1541
 
1542
+ #[test]
1543
+ fn overlay_cleanup_can_preserve_finalizing_progress() {
1544
+ assert!(!overlay_labels_to_hide(true).any(|label| label == FINALIZING_LABEL));
1545
+ assert!(overlay_labels_to_hide(false).any(|label| label == FINALIZING_LABEL));
1546
+ }
1547
+
1530
1548
  #[test]
1531
1549
  fn uses_clipboard_paste_for_chrome() {
1532
1550
  assert!(matches!(