@agent-native/core 0.80.8 → 0.80.9

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 (281) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +6 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +8 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +10 -2
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +10 -2
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +7 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +7 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +7 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +9 -2
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +6 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +6 -0
  13. package/corpus/core/docs/content/template-design.mdx +9 -2
  14. package/corpus/core/package.json +1 -1
  15. package/corpus/core/src/cli/mcp.ts +10 -0
  16. package/corpus/core/src/cli/skills.ts +58 -12
  17. package/corpus/core/src/client/error-format.ts +25 -0
  18. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +13 -11
  19. package/corpus/core/src/client/guided-questions.tsx +32 -4
  20. package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +33 -1
  21. package/corpus/core/src/client/resources/BuiltinCapabilityDetail.tsx +8 -0
  22. package/corpus/core/src/client/resources/use-builtin-capabilities.ts +4 -2
  23. package/corpus/core/src/client/session-replay.ts +34 -0
  24. package/corpus/core/src/client/sharing/ShareButton.tsx +106 -21
  25. package/corpus/core/src/coding-tools/index.ts +1 -1
  26. package/corpus/core/src/mcp/index.ts +2 -0
  27. package/corpus/core/src/mcp/screen-memory-stdio.ts +290 -0
  28. package/corpus/core/src/mcp-client/builtin-capabilities.ts +13 -1
  29. package/corpus/core/src/mcp-client/index.ts +9 -0
  30. package/corpus/core/src/mcp-client/screen-memory-local.ts +461 -0
  31. package/corpus/core/src/onboarding/types.ts +7 -0
  32. package/corpus/core/src/server/agent-chat-plugin.ts +25 -0
  33. package/corpus/core/src/server/agents-bundle.ts +35 -7
  34. package/corpus/core/src/styles/agent-native.css +5 -0
  35. package/corpus/core/src/templates/default/app/global.css +35 -35
  36. package/corpus/templates/analytics/AGENTS.md +6 -0
  37. package/corpus/templates/analytics/actions/github-repo-files.ts +9 -0
  38. package/corpus/templates/analytics/app/components/layout/Layout.tsx +4 -4
  39. package/corpus/templates/analytics/app/global.css +144 -40
  40. package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +1 -1
  41. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +1 -1
  42. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
  43. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +4 -4
  44. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +9 -9
  45. package/corpus/templates/analytics/changelog/2026-06-29-agents-can-search-and-read-connected-github-repositories-whe.md +6 -0
  46. package/corpus/templates/analytics/changelog/2026-06-29-sessions-and-explorer-layouts-adapt-when-the-agent-sidebar-is.md +6 -0
  47. package/corpus/templates/assets/app/components/layout/Layout.tsx +3 -1
  48. package/corpus/templates/assets/app/components/library/LibraryPresetGrid.tsx +1 -1
  49. package/corpus/templates/assets/app/global.css +99 -35
  50. package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -2
  51. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +4 -4
  52. package/corpus/templates/assets/app/routes/library.tsx +4 -4
  53. package/corpus/templates/assets/changelog/2026-06-29-asset-library-and-detail-layouts-adapt-when-the-agent-sidebar.md +6 -0
  54. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
  55. package/corpus/templates/brain/app/global.css +63 -35
  56. package/corpus/templates/brain/app/routes/search.tsx +1 -1
  57. package/corpus/templates/brain/app/routes/settings.tsx +1 -1
  58. package/corpus/templates/brain/app/routes/sources.tsx +2 -2
  59. package/corpus/templates/brain/changelog/2026-06-29-search-settings-and-source-layouts-adapt-when-the-agent-sidebar.md +6 -0
  60. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +4 -4
  61. package/corpus/templates/calendar/app/components/calendar/FindTimePanel.tsx +3 -2
  62. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +4 -2
  63. package/corpus/templates/calendar/app/global.css +69 -35
  64. package/corpus/templates/calendar/changelog/2026-06-29-event-and-find-time-layouts-adapt-when-the-agent-sidebar-is.md +6 -0
  65. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  66. package/corpus/templates/chat/app/global.css +35 -35
  67. package/corpus/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  68. package/corpus/templates/clips/AGENTS.md +13 -0
  69. package/corpus/templates/clips/actions/get-screen-memory-status.ts +12 -0
  70. package/corpus/templates/clips/actions/query-screen-memory-context.ts +29 -0
  71. package/corpus/templates/clips/actions/view-screen.ts +2 -2
  72. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  73. package/corpus/templates/clips/app/global.css +47 -35
  74. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +3 -3
  75. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +45 -18
  76. package/corpus/templates/clips/changelog/2026-06-29-meeting-detail-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  77. package/corpus/templates/clips/changelog/2026-06-29-screen-memory-keeps-a-local-rolling-screen-buffer-for-agent-context.md +5 -0
  78. package/corpus/templates/clips/changelog/2026-06-29-video-chat-is-easier-to-find-on-recording-pages-and-s3-setup.md +6 -0
  79. package/corpus/templates/clips/chrome-extension/src/styles.css +39 -39
  80. package/corpus/templates/clips/desktop/src/app.tsx +290 -1
  81. package/corpus/templates/clips/desktop/src/shared/config.ts +83 -0
  82. package/corpus/templates/clips/desktop/src/styles.css +67 -52
  83. package/corpus/templates/clips/desktop/src-tauri/src/config.rs +50 -0
  84. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +17 -0
  85. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +13 -13
  86. package/corpus/templates/clips/desktop/src-tauri/src/screen_memory.rs +990 -0
  87. package/corpus/templates/clips/server/plugins/onboarding.ts +2 -0
  88. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +3 -3
  89. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
  90. package/corpus/templates/content/app/global.css +29 -15
  91. package/corpus/templates/content/changelog/2026-06-29-database-gallery-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  92. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +25 -20
  93. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -0
  94. package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +8 -0
  95. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +13 -0
  96. package/corpus/templates/design/AGENTS.md +20 -12
  97. package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1054 -0
  98. package/corpus/templates/design/actions/apply-visual-edit.ts +24 -4
  99. package/corpus/templates/design/actions/export-coding-handoff.ts +12 -4
  100. package/corpus/templates/design/actions/generate-design.ts +6 -21
  101. package/corpus/templates/design/actions/generate-screens.ts +43 -2
  102. package/corpus/templates/design/actions/get-design.ts +1 -0
  103. package/corpus/templates/design/actions/present-design-variants.ts +355 -30
  104. package/corpus/templates/design/actions/view-screen.ts +75 -31
  105. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +329 -69
  106. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +1 -1
  107. package/corpus/templates/design/app/components/design/EditPanel.tsx +479 -77
  108. package/corpus/templates/design/app/components/design/LayersPanel.tsx +380 -216
  109. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1050 -196
  110. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +83 -206
  111. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +1 -1
  112. package/corpus/templates/design/app/components/design/index.ts +0 -1
  113. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +225 -133
  114. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +122 -11
  115. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +24 -5
  116. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +57 -1
  117. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +37 -12
  118. package/corpus/templates/design/app/components/design/inspector/index.ts +1 -0
  119. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +12 -5
  120. package/corpus/templates/design/app/components/design/types.ts +9 -0
  121. package/corpus/templates/design/app/components/layout/Layout.tsx +23 -5
  122. package/corpus/templates/design/app/global.css +77 -49
  123. package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
  124. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +8 -1
  125. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  126. package/corpus/templates/design/app/i18n-data.ts +45 -3
  127. package/corpus/templates/design/app/pages/DesignEditor.tsx +2602 -657
  128. package/corpus/templates/design/app/root.tsx +1 -1
  129. package/corpus/templates/design/changelog/2026-06-29-containers-no-longer-block-selecting-nested-elements-and-nor.md +6 -0
  130. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-generate-and-refine-variants-from-stronger.md +6 -0
  131. package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +6 -0
  132. package/corpus/templates/design/changelog/2026-06-29-design-questions-now-appear-as-a-cleaner-canvas-intake-with-.md +6 -0
  133. package/corpus/templates/design/changelog/2026-06-29-design-variant-directions-now-appear-as-board-screens-with-chat-buttons.md +5 -0
  134. package/corpus/templates/design/changelog/2026-06-29-element-selection-no-longer-snaps-back-to-the-previous-layer.md +6 -0
  135. package/corpus/templates/design/changelog/2026-06-29-frame-resize-measurements-now-stay-beside-the-cursor-while-d.md +6 -0
  136. package/corpus/templates/design/changelog/2026-06-29-inspector-number-fields-have-cleaner-tooltips-and-draggable-.md +6 -0
  137. package/corpus/templates/design/changelog/2026-06-29-layer-locking-layer-nesting-generated-question-intake-and-im.md +6 -0
  138. package/corpus/templates/design/changelog/2026-06-29-layer-names-in-the-sidebar-can-scroll-horizontally-instead-o.md +6 -0
  139. package/corpus/templates/design/changelog/2026-06-29-layer-nesting-in-the-sidebar-now-uses-tighter-spacing-so-nam.md +6 -0
  140. package/corpus/templates/design/changelog/2026-06-29-layers-no-longer-repeat-document-wrapper-rows-when-a-screen-.md +6 -0
  141. package/corpus/templates/design/changelog/2026-06-29-overview-previews-now-keep-element-hover-and-selection-tied-.md +6 -0
  142. package/corpus/templates/design/changelog/2026-06-29-pressing-escape-now-cancels-a-stuck-screen-drag-in-the-overv.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +6 -0
  144. package/corpus/templates/design/changelog/2026-06-29-screen-overview-only-highlights-screens-when-the-frame-or-ti.md +6 -0
  145. package/corpus/templates/design/changelog/2026-06-29-screen-overview-previews-now-resize-to-match-the-selected-de.md +6 -0
  146. package/corpus/templates/design/changelog/2026-06-29-screen-overview-selection-now-uses-a-pointer-cursor-instead-.md +6 -0
  147. package/corpus/templates/design/changelog/2026-06-29-screen-overview-selection-outlines-now-stay-locked-to-the-se.md +6 -0
  148. package/corpus/templates/design/changelog/2026-06-29-screen-overview-zoom-now-reports-real-screen-scale-separatel.md +6 -0
  149. package/corpus/templates/design/changelog/2026-06-29-screen-overview-zooming-feels-smoother-and-selection-outline.md +6 -0
  150. package/corpus/templates/design/changelog/2026-06-29-screen-overview-zooming-now-stays-on-the-overview-canvas-ins.md +6 -0
  151. package/corpus/templates/design/changelog/2026-06-29-selecting-a-nested-layer-from-all-screens-now-keeps-you-in-a.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-29-share-now-groups-link-sharing-exports-and-agent-handoff.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-29-the-design-editor-loading-skeleton-now-uses-a-softer-charcoa.md +6 -0
  154. package/corpus/templates/design/changelog/2026-06-29-the-device-preview-menu-now-sits-next-to-the-preview-button-.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-29-the-inspector-stays-read-only-while-an-empty-design-is-still.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-29-the-missing-design-view-now-matches-the-rest-of-the-editor-c.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-icon-and-tool-option-menus-better-match-the-edi.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-29-typography-controls-now-keep-the-font-name-visible-and-move-.md +6 -0
  159. package/corpus/templates/design/e2e/README.md +3 -3
  160. package/corpus/templates/design/e2e/global-setup.ts +11 -22
  161. package/corpus/templates/design/e2e/helpers.ts +122 -11
  162. package/corpus/templates/design/playwright.config.ts +9 -3
  163. package/corpus/templates/design/server/lib/coding-handoff.ts +126 -2
  164. package/corpus/templates/design/server/plugins/core-routes.ts +1 -2
  165. package/corpus/templates/design/server/routes/api/design-handoff/[id].zip.get.ts +86 -0
  166. package/corpus/templates/design/shared/code-layer.ts +125 -22
  167. package/corpus/templates/design/shared/generation-session.ts +41 -0
  168. package/corpus/templates/dispatch/app/global.css +79 -35
  169. package/corpus/templates/dispatch/app/routes/integrations.tsx +8 -7
  170. package/corpus/templates/dispatch/changelog/2026-06-29-integration-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  171. package/corpus/templates/forms/app/components/layout/Layout.tsx +6 -2
  172. package/corpus/templates/forms/app/global.css +64 -35
  173. package/corpus/templates/forms/app/pages/FormsListPage.tsx +2 -2
  174. package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +3 -3
  175. package/corpus/templates/forms/changelog/2026-06-29-form-list-and-insight-layouts-adapt-when-the-agent-sidebar.md +6 -0
  176. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +3 -1
  177. package/corpus/templates/macros/app/global.css +25 -9
  178. package/corpus/templates/macros/changelog/2026-06-29-macro-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  179. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -2
  180. package/corpus/templates/mail/app/global.css +42 -36
  181. package/corpus/templates/mail/app/pages/InboxPage.tsx +1 -1
  182. package/corpus/templates/mail/changelog/2026-06-29-the-contact-panel-now-adapts-to-the-available-mail-pane-width.md +6 -0
  183. package/corpus/templates/plan/app/components/layout/Layout.tsx +3 -1
  184. package/corpus/templates/plan/app/components/plan/DocumentArea.tsx +6 -7
  185. package/corpus/templates/plan/app/global.css +74 -42
  186. package/corpus/templates/plan/changelog/2026-06-29-plan-document-blocks-adapt-to-the-available-document-width.md +6 -0
  187. package/corpus/templates/plan/changelog/2026-06-29-plan-titles-and-summaries-can-be-edited-inline-without-focus.md +6 -0
  188. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -1
  189. package/corpus/templates/slides/app/global.css +49 -33
  190. package/corpus/templates/slides/changelog/2026-06-29-slide-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  191. package/corpus/templates/videos/app/components/layout/Layout.tsx +3 -1
  192. package/corpus/templates/videos/app/global.css +35 -35
  193. package/corpus/templates/videos/changelog/2026-06-29-video-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  194. package/dist/cli/mcp.d.ts.map +1 -1
  195. package/dist/cli/mcp.js +10 -0
  196. package/dist/cli/mcp.js.map +1 -1
  197. package/dist/cli/skills.d.ts.map +1 -1
  198. package/dist/cli/skills.js +58 -12
  199. package/dist/cli/skills.js.map +1 -1
  200. package/dist/client/error-format.d.ts.map +1 -1
  201. package/dist/client/error-format.js +17 -0
  202. package/dist/client/error-format.js.map +1 -1
  203. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  204. package/dist/client/extensions/ExtensionViewer.js +3 -4
  205. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  206. package/dist/client/guided-questions.d.ts +4 -0
  207. package/dist/client/guided-questions.d.ts.map +1 -1
  208. package/dist/client/guided-questions.js +16 -7
  209. package/dist/client/guided-questions.js.map +1 -1
  210. package/dist/client/onboarding/OnboardingPanel.js +26 -1
  211. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  212. package/dist/client/resources/BuiltinCapabilityDetail.d.ts.map +1 -1
  213. package/dist/client/resources/BuiltinCapabilityDetail.js +1 -1
  214. package/dist/client/resources/BuiltinCapabilityDetail.js.map +1 -1
  215. package/dist/client/resources/use-builtin-capabilities.d.ts +1 -1
  216. package/dist/client/resources/use-builtin-capabilities.d.ts.map +1 -1
  217. package/dist/client/resources/use-builtin-capabilities.js +2 -1
  218. package/dist/client/resources/use-builtin-capabilities.js.map +1 -1
  219. package/dist/client/session-replay.d.ts.map +1 -1
  220. package/dist/client/session-replay.js +31 -0
  221. package/dist/client/session-replay.js.map +1 -1
  222. package/dist/client/sharing/ShareButton.d.ts +14 -0
  223. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  224. package/dist/client/sharing/ShareButton.js +36 -7
  225. package/dist/client/sharing/ShareButton.js.map +1 -1
  226. package/dist/coding-tools/index.js +1 -1
  227. package/dist/coding-tools/index.js.map +1 -1
  228. package/dist/collab/routes.d.ts +1 -1
  229. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  230. package/dist/mcp/index.d.ts +2 -0
  231. package/dist/mcp/index.d.ts.map +1 -1
  232. package/dist/mcp/index.js +1 -0
  233. package/dist/mcp/index.js.map +1 -1
  234. package/dist/mcp/screen-memory-stdio.d.ts +6 -0
  235. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -0
  236. package/dist/mcp/screen-memory-stdio.js +213 -0
  237. package/dist/mcp/screen-memory-stdio.js.map +1 -0
  238. package/dist/mcp-client/builtin-capabilities.d.ts +1 -1
  239. package/dist/mcp-client/builtin-capabilities.d.ts.map +1 -1
  240. package/dist/mcp-client/builtin-capabilities.js +10 -0
  241. package/dist/mcp-client/builtin-capabilities.js.map +1 -1
  242. package/dist/mcp-client/index.d.ts +1 -0
  243. package/dist/mcp-client/index.d.ts.map +1 -1
  244. package/dist/mcp-client/index.js +1 -0
  245. package/dist/mcp-client/index.js.map +1 -1
  246. package/dist/mcp-client/screen-memory-local.d.ts +61 -0
  247. package/dist/mcp-client/screen-memory-local.d.ts.map +1 -0
  248. package/dist/mcp-client/screen-memory-local.js +336 -0
  249. package/dist/mcp-client/screen-memory-local.js.map +1 -0
  250. package/dist/notifications/routes.d.ts +2 -2
  251. package/dist/observability/routes.d.ts +8 -8
  252. package/dist/onboarding/types.d.ts +7 -0
  253. package/dist/onboarding/types.d.ts.map +1 -1
  254. package/dist/onboarding/types.js.map +1 -1
  255. package/dist/resources/handlers.d.ts +2 -2
  256. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  257. package/dist/server/agent-chat-plugin.js +26 -0
  258. package/dist/server/agent-chat-plugin.js.map +1 -1
  259. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  260. package/dist/server/agents-bundle.d.ts.map +1 -1
  261. package/dist/server/agents-bundle.js +22 -7
  262. package/dist/server/agents-bundle.js.map +1 -1
  263. package/dist/server/transcribe-voice.d.ts +1 -1
  264. package/dist/styles/agent-native.css +5 -0
  265. package/dist/templates/default/app/global.css +35 -35
  266. package/docs/content/locales/ar-SA/template-design.mdx +6 -0
  267. package/docs/content/locales/de-DE/template-design.mdx +8 -0
  268. package/docs/content/locales/es-ES/template-design.mdx +10 -2
  269. package/docs/content/locales/fr-FR/template-design.mdx +10 -2
  270. package/docs/content/locales/hi-IN/template-design.mdx +7 -0
  271. package/docs/content/locales/ja-JP/template-design.mdx +7 -0
  272. package/docs/content/locales/ko-KR/template-design.mdx +7 -0
  273. package/docs/content/locales/pt-BR/template-design.mdx +9 -2
  274. package/docs/content/locales/zh-CN/template-design.mdx +6 -0
  275. package/docs/content/locales/zh-TW/template-design.mdx +6 -0
  276. package/docs/content/template-design.mdx +9 -2
  277. package/package.json +1 -1
  278. package/src/templates/default/app/global.css +35 -35
  279. package/corpus/templates/design/app/components/design/VariantGrid.tsx +0 -189
  280. package/corpus/templates/design/app/components/design/VariantHandoffCard.tsx +0 -115
  281. package/corpus/templates/design/app/hooks/use-variant-flow.ts +0 -342
@@ -4,20 +4,20 @@
4
4
  color-scheme: light dark;
5
5
 
6
6
  /* Clips brand */
7
- --brand: #18181b;
8
- --brand-hover: #27272a;
9
- --brand-ring: rgba(24, 24, 27, 0.28);
7
+ --brand: #1a1a1a;
8
+ --brand-hover: #2e2e2e;
9
+ --brand-ring: rgba(26, 26, 26, 0.28);
10
10
 
11
11
  /* Light palette */
12
12
  --bg: #ffffff;
13
- --surface: #f5f6f9;
14
- --surface-hover: #eef0f5;
15
- --surface-strong: #e8ebf2;
16
- --fg: #0f172a;
17
- --fg-muted: #64748b;
18
- --fg-subtle: #94a3b8;
19
- --border: #e2e6ef;
20
- --border-strong: #d4d9e4;
13
+ --surface: #f7f7f7;
14
+ --surface-hover: #f0f0f0;
15
+ --surface-strong: #ebebeb;
16
+ --fg: #171717;
17
+ --fg-muted: #737373;
18
+ --fg-subtle: #a3a3a3;
19
+ --border: #e5e5e5;
20
+ --border-strong: #d9d9d9;
21
21
 
22
22
  --status-ok: #22c55e;
23
23
  --status-warn: #f97316;
@@ -28,9 +28,9 @@
28
28
  --popover-shadow-gutter: 12px;
29
29
  --overlay-shadow-gutter: 18px;
30
30
 
31
- --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
31
+ --shadow-sm: 0 1px 2px rgba(23, 23, 23, 0.06);
32
32
  --shadow-md:
33
- 0 4px 16px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
33
+ 0 4px 16px rgba(23, 23, 23, 0.08), 0 2px 4px rgba(23, 23, 23, 0.04);
34
34
 
35
35
  font-family:
36
36
  -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
@@ -40,21 +40,21 @@
40
40
 
41
41
  @media (prefers-color-scheme: dark) {
42
42
  :root {
43
- --bg: #0f1115;
44
- --surface: #181b23;
45
- --surface-hover: #1e2230;
46
- --surface-strong: #252938;
47
- --fg: #f1f5f9;
48
- --fg-muted: #94a3b8;
49
- --fg-subtle: #64748b;
50
- --border: #252938;
51
- --border-strong: #323747;
43
+ --bg: #212121;
44
+ --surface: #262626;
45
+ --surface-hover: #2e2e2e;
46
+ --surface-strong: #3d3d3d;
47
+ --fg: #f5f5f5;
48
+ --fg-muted: #a3a3a3;
49
+ --fg-subtle: #737373;
50
+ --border: #3d3d3d;
51
+ --border-strong: #4d4d4d;
52
52
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
53
53
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
54
54
  /* Invert brand on dark bg: zinc-900 would disappear, use zinc-100. */
55
- --brand: #f4f4f5;
56
- --brand-hover: #e4e4e7;
57
- --brand-ring: rgba(244, 244, 245, 0.28);
55
+ --brand: #f5f5f5;
56
+ --brand-hover: #e5e5e5;
57
+ --brand-ring: rgba(245, 245, 245, 0.28);
58
58
  }
59
59
  }
60
60
 
@@ -1611,6 +1611,21 @@ body[data-clips-route="recording-pill"] #root {
1611
1611
  background-repeat: no-repeat;
1612
1612
  }
1613
1613
 
1614
+ .setup-grid {
1615
+ display: grid;
1616
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1617
+ gap: 8px;
1618
+ }
1619
+
1620
+ .setup-mini-field {
1621
+ display: grid;
1622
+ gap: 5px;
1623
+ min-width: 0;
1624
+ color: var(--fg-muted);
1625
+ font-size: 11px;
1626
+ font-weight: 600;
1627
+ }
1628
+
1614
1629
  .setup-textarea {
1615
1630
  min-height: 86px;
1616
1631
  resize: vertical;
@@ -1625,7 +1640,7 @@ body[data-clips-route="recording-pill"] #root {
1625
1640
 
1626
1641
  .setup-button-row {
1627
1642
  display: grid;
1628
- grid-template-columns: repeat(2, minmax(0, 1fr));
1643
+ grid-template-columns: repeat(auto-fit, minmax(94px, 1fr));
1629
1644
  gap: 8px;
1630
1645
  }
1631
1646
 
@@ -1801,7 +1816,7 @@ body[data-clips-route="recording-pill"] #root {
1801
1816
  padding: 0;
1802
1817
  border: 0;
1803
1818
  background: transparent;
1804
- color: #64748b;
1819
+ color: #737373;
1805
1820
  cursor: help;
1806
1821
  font-size: 11px;
1807
1822
  line-height: 1.2;
@@ -2080,7 +2095,7 @@ body[data-clips-route="recording-pill"] #root {
2080
2095
  }
2081
2096
 
2082
2097
  .pending-upload-why {
2083
- color: #94a3b8;
2098
+ color: #a3a3a3;
2084
2099
  }
2085
2100
 
2086
2101
  .pending-upload-why:hover,
@@ -2090,19 +2105,19 @@ body[data-clips-route="recording-pill"] #root {
2090
2105
 
2091
2106
  .pending-upload-connect,
2092
2107
  .pending-upload-retry {
2093
- background: rgba(15, 23, 42, 0.7);
2108
+ background: rgba(23, 23, 23, 0.7);
2094
2109
  border-color: rgba(96, 165, 250, 0.38);
2095
2110
  color: #dbeafe;
2096
2111
  }
2097
2112
 
2098
2113
  .pending-upload-discard {
2099
- background: rgba(15, 23, 42, 0.58);
2114
+ background: rgba(23, 23, 23, 0.58);
2100
2115
  border-color: rgba(96, 165, 250, 0.38);
2101
2116
  color: #bfdbfe;
2102
2117
  }
2103
2118
 
2104
2119
  .pending-upload-folder {
2105
- background: rgba(15, 23, 42, 0.58);
2120
+ background: rgba(23, 23, 23, 0.58);
2106
2121
  border-color: rgba(96, 165, 250, 0.38);
2107
2122
  color: #dbeafe;
2108
2123
  }
@@ -3313,8 +3328,8 @@ body[data-clips-route="recording-pill"] #root {
3313
3328
  display: flex;
3314
3329
  align-items: center;
3315
3330
  justify-content: center;
3316
- background: #0f1115;
3317
- color: #f1f5f9;
3331
+ background: #212121;
3332
+ color: #f5f5f5;
3318
3333
  }
3319
3334
 
3320
3335
  .onboarding-card {
@@ -3337,7 +3352,7 @@ body[data-clips-route="recording-pill"] #root {
3337
3352
 
3338
3353
  .onboarding-subtitle {
3339
3354
  font-size: 14px;
3340
- color: #94a3b8;
3355
+ color: #a3a3a3;
3341
3356
  margin: -8px 0 0;
3342
3357
  }
3343
3358
 
@@ -3387,7 +3402,7 @@ body[data-clips-route="recording-pill"] #root {
3387
3402
 
3388
3403
  .onboarding-feature-desc {
3389
3404
  font-size: 12px;
3390
- color: #94a3b8;
3405
+ color: #a3a3a3;
3391
3406
  line-height: 1.4;
3392
3407
  }
3393
3408
 
@@ -3396,8 +3411,8 @@ body[data-clips-route="recording-pill"] #root {
3396
3411
  border: none;
3397
3412
  border-radius: 12px;
3398
3413
  padding: 12px 16px;
3399
- background: #f4f4f5;
3400
- color: #0f1115;
3414
+ background: #f5f5f5;
3415
+ color: #212121;
3401
3416
  font-size: 14px;
3402
3417
  font-weight: 600;
3403
3418
  cursor: pointer;
@@ -3409,7 +3424,7 @@ body[data-clips-route="recording-pill"] #root {
3409
3424
  }
3410
3425
 
3411
3426
  .onboarding-cta:hover {
3412
- background: #e4e4e7;
3427
+ background: #e5e5e5;
3413
3428
  }
3414
3429
 
3415
3430
  .onboarding-cta:active {
@@ -3469,7 +3484,7 @@ body[data-clips-route="recording-pill"] #root {
3469
3484
 
3470
3485
  .meeting-notification-bar-adhoc {
3471
3486
  background: transparent;
3472
- border-left: 3px dashed #94a3b8;
3487
+ border-left: 3px dashed #a3a3a3;
3473
3488
  width: 3px;
3474
3489
  }
3475
3490
 
@@ -3855,7 +3870,7 @@ body[data-clips-route="recording-pill"] #root {
3855
3870
  outline: none;
3856
3871
  border-color: rgba(255, 255, 255, 0.98);
3857
3872
  box-shadow:
3858
- 0 0 0 2px rgba(15, 23, 42, 0.5),
3873
+ 0 0 0 2px rgba(23, 23, 23, 0.5),
3859
3874
  0 0 150px 50px rgba(0, 0, 0, 0.12),
3860
3875
  inset 0 0 36px rgba(0, 0, 0, 0.08);
3861
3876
  }
@@ -3871,7 +3886,7 @@ body[data-clips-route="recording-pill"] #root {
3871
3886
  z-index: 2;
3872
3887
  width: 12px;
3873
3888
  height: 12px;
3874
- border: 1px solid rgba(15, 23, 42, 0.38);
3889
+ border: 1px solid rgba(23, 23, 23, 0.38);
3875
3890
  border-radius: 4px;
3876
3891
  background: rgba(255, 255, 255, 0.96);
3877
3892
  box-shadow:
@@ -4119,7 +4134,7 @@ body[data-clips-route="recording-pill"] #root {
4119
4134
  height: 100%;
4120
4135
  width: 100%;
4121
4136
  border-radius: 16px;
4122
- background: rgba(24, 24, 27, 0.95);
4137
+ background: rgba(26, 26, 26, 0.95);
4123
4138
  color: white;
4124
4139
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
4125
4140
  backdrop-filter: blur(12px);
@@ -4355,7 +4370,7 @@ body[data-clips-route="recording-pill"] #root {
4355
4370
  align-items: center;
4356
4371
  justify-content: center;
4357
4372
  border-radius: 50%;
4358
- color: #e4e4e7;
4373
+ color: #e5e5e5;
4359
4374
  border: none;
4360
4375
  background: transparent;
4361
4376
  transition: background 120ms;
@@ -4538,7 +4553,7 @@ body[data-clips-route="recording-pill"] #root {
4538
4553
  font-weight: 600;
4539
4554
  letter-spacing: 0.06em;
4540
4555
  text-transform: uppercase;
4541
- color: rgba(244, 244, 245, 0.4);
4556
+ color: rgba(245, 245, 245, 0.4);
4542
4557
  }
4543
4558
 
4544
4559
  .pill-pane-label-row {
@@ -4556,7 +4571,7 @@ body[data-clips-route="recording-pill"] #root {
4556
4571
  border: none;
4557
4572
  border-radius: 5px;
4558
4573
  background: transparent;
4559
- color: rgba(244, 244, 245, 0.5);
4574
+ color: rgba(245, 245, 245, 0.5);
4560
4575
  cursor: pointer;
4561
4576
  transition:
4562
4577
  background 120ms,
@@ -4565,7 +4580,7 @@ body[data-clips-route="recording-pill"] #root {
4565
4580
 
4566
4581
  .pill-copy-btn:hover:not(:disabled) {
4567
4582
  background: rgba(255, 255, 255, 0.1);
4568
- color: #f4f4f5;
4583
+ color: #f5f5f5;
4569
4584
  }
4570
4585
 
4571
4586
  .pill-copy-btn:disabled {
@@ -4593,7 +4608,7 @@ body[data-clips-route="recording-pill"] #root {
4593
4608
  border: none;
4594
4609
  outline: none;
4595
4610
  resize: none;
4596
- color: #f4f4f5;
4611
+ color: #f5f5f5;
4597
4612
  font-size: 12px;
4598
4613
  line-height: 1.5;
4599
4614
  font-family: inherit;
@@ -4613,7 +4628,7 @@ body[data-clips-route="recording-pill"] #root {
4613
4628
  padding: 2px 12px 8px;
4614
4629
  font-size: 10px;
4615
4630
  font-variant-numeric: tabular-nums;
4616
- color: rgba(244, 244, 245, 0.4);
4631
+ color: rgba(245, 245, 245, 0.4);
4617
4632
  }
4618
4633
 
4619
4634
  .pill-saved-status {
@@ -4628,7 +4643,7 @@ body[data-clips-route="recording-pill"] #root {
4628
4643
  border: none;
4629
4644
  border-radius: 6px;
4630
4645
  background: transparent;
4631
- color: rgba(244, 244, 245, 0.6);
4646
+ color: rgba(245, 245, 245, 0.6);
4632
4647
  font-size: 10px;
4633
4648
  font-weight: 500;
4634
4649
  cursor: pointer;
@@ -4639,7 +4654,7 @@ body[data-clips-route="recording-pill"] #root {
4639
4654
 
4640
4655
  .pill-open-web-btn:hover {
4641
4656
  background: rgba(255, 255, 255, 0.1);
4642
- color: #f4f4f5;
4657
+ color: #f5f5f5;
4643
4658
  }
4644
4659
 
4645
4660
  .lt-chat {
@@ -4653,7 +4668,7 @@ body[data-clips-route="recording-pill"] #root {
4653
4668
  padding: 8px 12px;
4654
4669
  font-size: 12px;
4655
4670
  line-height: 1.35;
4656
- color: #f4f4f5;
4671
+ color: #f5f5f5;
4657
4672
  }
4658
4673
 
4659
4674
  .lt-empty {
@@ -4732,7 +4747,7 @@ body[data-clips-route="recording-pill"] #root {
4732
4747
  justify-content: center;
4733
4748
  border-radius: 50%;
4734
4749
  background: rgba(255, 255, 255, 0.1);
4735
- color: #e4e4e7;
4750
+ color: #e5e5e5;
4736
4751
  border: none;
4737
4752
  transition: background 120ms;
4738
4753
  }
@@ -34,6 +34,36 @@ impl Default for RegionGuidesConfig {
34
34
  }
35
35
  }
36
36
 
37
+ #[derive(Debug, Clone, Serialize, Deserialize)]
38
+ #[serde(rename_all = "camelCase")]
39
+ pub struct ScreenMemoryConfig {
40
+ #[serde(default)]
41
+ pub enabled: bool,
42
+ #[serde(default)]
43
+ pub paused: bool,
44
+ #[serde(default = "default_screen_memory_retention_hours")]
45
+ pub retention_hours: u32,
46
+ #[serde(default = "default_screen_memory_max_bytes")]
47
+ pub max_bytes: u64,
48
+ #[serde(default = "default_screen_memory_segment_seconds")]
49
+ pub segment_seconds: u64,
50
+ #[serde(default = "default_screen_memory_sample_interval_seconds")]
51
+ pub sample_interval_seconds: u64,
52
+ }
53
+
54
+ impl Default for ScreenMemoryConfig {
55
+ fn default() -> Self {
56
+ Self {
57
+ enabled: false,
58
+ paused: false,
59
+ retention_hours: default_screen_memory_retention_hours(),
60
+ max_bytes: default_screen_memory_max_bytes(),
61
+ segment_seconds: default_screen_memory_segment_seconds(),
62
+ sample_interval_seconds: default_screen_memory_sample_interval_seconds(),
63
+ }
64
+ }
65
+ }
66
+
37
67
  #[derive(Debug, Clone, Serialize, Deserialize)]
38
68
  #[serde(rename_all = "camelCase")]
39
69
  pub struct FeatureConfig {
@@ -59,6 +89,8 @@ pub struct FeatureConfig {
59
89
  pub show_in_screen_capture: bool,
60
90
  #[serde(default)]
61
91
  pub region_guides: RegionGuidesConfig,
92
+ #[serde(default)]
93
+ pub screen_memory: ScreenMemoryConfig,
62
94
  pub onboarding_complete: bool,
63
95
  #[serde(default = "default_whisper_model_enabled")]
64
96
  pub whisper_model_enabled: bool,
@@ -97,6 +129,22 @@ fn default_whisper_model_enabled() -> bool {
97
129
  true
98
130
  }
99
131
 
132
+ fn default_screen_memory_retention_hours() -> u32 {
133
+ 24
134
+ }
135
+
136
+ fn default_screen_memory_max_bytes() -> u64 {
137
+ 20 * 1024 * 1024 * 1024
138
+ }
139
+
140
+ fn default_screen_memory_segment_seconds() -> u64 {
141
+ 5 * 60
142
+ }
143
+
144
+ fn default_screen_memory_sample_interval_seconds() -> u64 {
145
+ 10
146
+ }
147
+
100
148
  impl Default for FeatureConfig {
101
149
  fn default() -> Self {
102
150
  Self {
@@ -110,6 +158,7 @@ impl Default for FeatureConfig {
110
158
  show_meeting_widget_enabled: default_show_meeting_widget_enabled(),
111
159
  show_in_screen_capture: false,
112
160
  region_guides: RegionGuidesConfig::default(),
161
+ screen_memory: ScreenMemoryConfig::default(),
113
162
  onboarding_complete: false,
114
163
  whisper_model_enabled: default_whisper_model_enabled(),
115
164
  }
@@ -243,6 +292,7 @@ pub async fn set_feature_config(app: AppHandle, config: FeatureConfig) -> Result
243
292
  serde_json::json!({ "enabled": config.whisper_model_enabled }),
244
293
  );
245
294
  }
295
+ crate::screen_memory::sync_from_config(&app, &config);
246
296
  let _ = app.emit("app:feature-config-changed", config);
247
297
  Ok(())
248
298
  }
@@ -16,6 +16,7 @@ mod native_speech;
16
16
  mod notifications;
17
17
  mod permission_status;
18
18
  mod recording_indicator;
19
+ mod screen_memory;
19
20
  mod sentry_report;
20
21
  mod shortcuts;
21
22
  mod silence_detector;
@@ -100,6 +101,14 @@ pub fn run() {
100
101
  // config commands
101
102
  config::get_feature_config,
102
103
  config::set_feature_config,
104
+ // local-only Screen Memory backend
105
+ screen_memory::screen_memory_status,
106
+ screen_memory::screen_memory_configure,
107
+ screen_memory::screen_memory_start,
108
+ screen_memory::screen_memory_pause,
109
+ screen_memory::screen_memory_stop,
110
+ screen_memory::screen_memory_delete,
111
+ screen_memory::screen_memory_recent_segments,
103
112
  // native macOS speech recognition (no-op stubs on other OSes)
104
113
  native_speech::native_speech_start,
105
114
  native_speech::native_speech_stop,
@@ -120,6 +129,11 @@ pub fn run() {
120
129
  native_screen::native_fullscreen_pending_uploads,
121
130
  native_screen::native_fullscreen_recording_retry_upload,
122
131
  native_screen::native_fullscreen_recording_discard_upload,
132
+ // local-only always-on screen memory compatibility helpers
133
+ screen_memory::screen_memory_query,
134
+ screen_memory::screen_memory_delete_all,
135
+ screen_memory::screen_memory_export_recent,
136
+ screen_memory::screen_memory_open_folder,
123
137
  // recording indicator pill
124
138
  recording_indicator::recording_pill_show,
125
139
  recording_indicator::recording_pill_expand,
@@ -187,6 +201,7 @@ pub fn run() {
187
201
  .manage(VoiceTargetBundle::default())
188
202
  .manage(LastTranscript::default())
189
203
  .manage(native_screen::NativeFullscreenRecordingState::default())
204
+ .manage(screen_memory::ScreenMemoryState::default())
190
205
  .manage(meetings_watcher::MeetingsWatcherState::default())
191
206
  .manage(notifications::MeetingNotificationState::default())
192
207
  .manage(silence_detector::DetectorState::default())
@@ -213,6 +228,8 @@ pub fn run() {
213
228
 
214
229
  tray::build_tray(app)?;
215
230
  config::sync_launch_at_login(app.handle());
231
+ let feature_config = config::feature_config(app.handle());
232
+ screen_memory::sync_from_config(app.handle(), &feature_config);
216
233
  // Re-show always-on region guides after relaunch/reboot when the
217
234
  // setting is on (no-op if a recording owns the window or the
218
235
  // toggle is off).
@@ -28,8 +28,8 @@ use screencapturekit::stream::{
28
28
  };
29
29
  use std::sync::atomic::{AtomicBool, Ordering};
30
30
 
31
- const QUICKTIME_RECORDING_MIME_TYPE: &str = "video/quicktime";
32
- const MP4_RECORDING_MIME_TYPE: &str = "video/mp4";
31
+ pub(crate) const QUICKTIME_RECORDING_MIME_TYPE: &str = "video/quicktime";
32
+ pub(crate) const MP4_RECORDING_MIME_TYPE: &str = "video/mp4";
33
33
  // Keep native chunks comfortably under serverless request/event limits.
34
34
  const UPLOAD_CHUNK_BYTES: usize = 3 * 1024 * 1024;
35
35
  // Master switch for native transcoding/compression.
@@ -85,7 +85,7 @@ const THUMBNAIL_MAX_BYTES: u64 = 2 * 1024 * 1024;
85
85
  const THUMBNAIL_WIDTH: &str = "1280";
86
86
  const SIPS_PATH: &str = "/usr/bin/sips";
87
87
  // Minimum free space required to start recording; below this we hard-block.
88
- const DISK_SPACE_BLOCK_BYTES: u64 = 500 * 1024 * 1024;
88
+ pub(crate) const DISK_SPACE_BLOCK_BYTES: u64 = 500 * 1024 * 1024;
89
89
  // Free space below this at start time is logged as a warning but not blocked.
90
90
  const DISK_SPACE_WARN_BYTES: u64 = 2 * 1024 * 1024 * 1024;
91
91
  // Mid-recording warning threshold (emits clips:disk-space-warning).
@@ -168,7 +168,7 @@ struct RestartInfo {
168
168
  capture_region: Option<NativeCaptureRegion>,
169
169
  }
170
170
 
171
- enum NativeFullscreenBackend {
171
+ pub(crate) enum NativeFullscreenBackend {
172
172
  Screencapture {
173
173
  child: Child,
174
174
  },
@@ -195,7 +195,7 @@ enum NativeFullscreenBackend {
195
195
  /// stop path block on that callback (bounded by a timeout) before the file
196
196
  /// is moved.
197
197
  #[cfg(target_os = "macos")]
198
- struct RecordingFinish {
198
+ pub(crate) struct RecordingFinish {
199
199
  /// `None` while recording; `Some(Ok)` finished; `Some(Err)` failed.
200
200
  state: Mutex<Option<Result<(), String>>>,
201
201
  cv: Condvar,
@@ -261,13 +261,13 @@ struct PreparedRecordingFile {
261
261
  temporary: bool,
262
262
  }
263
263
 
264
- fn format_mb(bytes: u64) -> String {
264
+ pub(crate) fn format_mb(bytes: u64) -> String {
265
265
  format!("{:.1} MB", bytes as f64 / (1024.0 * 1024.0))
266
266
  }
267
267
 
268
268
  /// Returns free bytes on the volume containing `path`, or `None` on error.
269
269
  #[cfg(target_os = "macos")]
270
- fn free_disk_bytes(path: &Path) -> Option<u64> {
270
+ pub(crate) fn free_disk_bytes(path: &Path) -> Option<u64> {
271
271
  use std::ffi::CString;
272
272
  let c_path = CString::new(path.to_str()?).ok()?;
273
273
  let mut stat: libc::statvfs = unsafe { std::mem::zeroed() };
@@ -1445,7 +1445,7 @@ fn start_segment_backend(
1445
1445
  /// Configure and start a fresh ScreenCaptureKit capture writing into
1446
1446
  /// `output_path`. Shared by the initial start and the resume path.
1447
1447
  #[cfg(target_os = "macos")]
1448
- fn start_screencapturekit_backend_at(
1448
+ pub(crate) fn start_screencapturekit_backend_at(
1449
1449
  output_path: &Path,
1450
1450
  include_audio: bool,
1451
1451
  capture_system_audio: bool,
@@ -1576,7 +1576,7 @@ fn start_screencapturekit_backend_at(
1576
1576
  /// Spawn the macOS `screencapture` fallback writing into `output_path`.
1577
1577
  /// Shared by the initial start and the resume path.
1578
1578
  #[cfg(target_os = "macos")]
1579
- fn start_screencapture_backend_at(
1579
+ pub(crate) fn start_screencapture_backend_at(
1580
1580
  app: &AppHandle,
1581
1581
  output_path: &Path,
1582
1582
  include_audio: bool,
@@ -2253,7 +2253,7 @@ fn persist_saved_recording_error(app: &AppHandle, saved: &mut SavedNativeRecordi
2253
2253
  /// Returns `None` when the tray anchor hasn't been set yet or any lookup
2254
2254
  /// fails — callers fall back to the first available display.
2255
2255
  #[cfg(target_os = "macos")]
2256
- fn tray_display_id(app: &AppHandle) -> Option<u32> {
2256
+ pub(crate) fn tray_display_id(app: &AppHandle) -> Option<u32> {
2257
2257
  let tray_rect = app
2258
2258
  .try_state::<crate::state::TrayAnchor>()
2259
2259
  .and_then(|a| a.0.lock().ok().and_then(|g| *g))?;
@@ -2458,7 +2458,7 @@ fn new_fullscreen_session(
2458
2458
  }
2459
2459
  }
2460
2460
 
2461
- fn primary_monitor_size(app: &AppHandle) -> (Option<u32>, Option<u32>) {
2461
+ pub(crate) fn primary_monitor_size(app: &AppHandle) -> (Option<u32>, Option<u32>) {
2462
2462
  let monitor_size = app
2463
2463
  .primary_monitor()
2464
2464
  .ok()
@@ -2544,7 +2544,7 @@ const SCK_FINALIZE_TIMEOUT: Duration = Duration::from_secs(10);
2544
2544
  /// signals the recording finished, so the caller never moves a half-written
2545
2545
  /// MP4. Cancel passes `false` (the file is discarded immediately, so there's
2546
2546
  /// nothing to wait for and no reason to delay teardown).
2547
- fn stop_native_recording(
2547
+ pub(crate) fn stop_native_recording(
2548
2548
  backend: &mut NativeFullscreenBackend,
2549
2549
  wait_for_finalize: bool,
2550
2550
  ) -> Result<(), String> {
@@ -3074,7 +3074,7 @@ fn is_moov_corrupt_error(err: &str) -> bool {
3074
3074
  /// finding one (file is unplayable), or `None` when the file could not be
3075
3075
  /// read (transient I/O error — callers must not treat this as permanent
3076
3076
  /// corruption).
3077
- fn mp4_has_moov(path: &Path) -> Option<bool> {
3077
+ pub(crate) fn mp4_has_moov(path: &Path) -> Option<bool> {
3078
3078
  use std::io::{ErrorKind, Read, Seek, SeekFrom};
3079
3079
  let mut f = match std::fs::File::open(path) {
3080
3080
  Ok(f) => f,