@agent-native/core 0.108.0 → 0.109.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +25 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/client.ts +162 -17
  5. package/corpus/core/src/a2a/correlation.ts +50 -0
  6. package/corpus/core/src/a2a/handlers.ts +200 -14
  7. package/corpus/core/src/a2a/index.ts +7 -1
  8. package/corpus/core/src/a2a/invoke.ts +77 -1
  9. package/corpus/core/src/a2a/server.ts +13 -1
  10. package/corpus/core/src/a2a/task-store.ts +146 -6
  11. package/corpus/core/src/a2a/types.ts +32 -0
  12. package/corpus/core/src/action.ts +5 -2
  13. package/corpus/core/src/agent/production-agent.ts +33 -4
  14. package/corpus/core/src/client/AssistantChat.tsx +648 -603
  15. package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
  16. package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
  17. package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
  18. package/corpus/core/src/client/analytics.ts +84 -0
  19. package/corpus/core/src/client/chat/message-components.tsx +94 -22
  20. package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
  21. package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  22. package/corpus/core/src/client/chat-thread-url.ts +11 -0
  23. package/corpus/core/src/client/error-capture.ts +12 -0
  24. package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
  25. package/corpus/core/src/client/index.ts +2 -0
  26. package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
  27. package/corpus/core/src/client/session-replay.ts +31 -0
  28. package/corpus/core/src/client/use-run-stuck-detection.ts +27 -1
  29. package/corpus/core/src/db/client.ts +55 -0
  30. package/corpus/core/src/extensions/actions.ts +2 -14
  31. package/corpus/core/src/extensions/store.ts +1 -1
  32. package/corpus/core/src/localization/default-messages.ts +3 -0
  33. package/corpus/core/src/mcp/build-server.ts +2 -2
  34. package/corpus/core/src/observability/traces.ts +172 -19
  35. package/corpus/core/src/progress/actions.ts +4 -2
  36. package/corpus/core/src/provider-api/index.ts +205 -105
  37. package/corpus/core/src/scripts/call-agent.ts +190 -19
  38. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +112 -25
  39. package/corpus/core/src/server/agent-chat-plugin.ts +136 -4
  40. package/corpus/core/src/styles/agent-conversation.css +7 -0
  41. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
  42. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
  43. package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
  44. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
  45. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
  46. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
  47. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
  48. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
  49. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
  50. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
  51. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
  53. package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  54. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  55. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  56. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  57. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
  58. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
  59. package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
  60. package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
  61. package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
  62. package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
  63. package/corpus/templates/analytics/AGENTS.md +22 -13
  64. package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
  65. package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
  66. package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
  67. package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
  68. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
  69. package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
  70. package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
  71. package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
  72. package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
  73. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  74. package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
  75. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
  76. package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
  77. package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
  78. package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
  79. package/corpus/templates/analytics/app/i18n-data.ts +134 -0
  80. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
  81. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
  82. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
  83. package/corpus/templates/analytics/changelog/2026-07-17-analytics-now-includes-a-default-alert-for-spikes-in-stuck-agent-chats.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
  85. package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
  86. package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
  87. package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
  88. package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
  89. package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
  90. package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
  91. package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
  92. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +23 -14
  93. package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
  94. package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
  95. package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
  96. package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +3 -3
  97. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
  98. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +209 -87
  99. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
  100. package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
  101. package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
  102. package/corpus/templates/analytics/server/lib/gong.ts +54 -66
  103. package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
  104. package/corpus/templates/analytics/server/lib/notion.ts +83 -8
  105. package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
  106. package/corpus/templates/analytics/server/lib/slack.ts +242 -90
  107. package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
  108. package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
  109. package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
  110. package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
  111. package/corpus/templates/clips/actions/finalize-recording.ts +541 -62
  112. package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
  113. package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
  114. package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
  115. package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
  116. package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +17 -2
  117. package/corpus/templates/clips/app/components/player/video-player.tsx +14 -2
  118. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +2 -2
  119. package/corpus/templates/clips/app/entry.client.tsx +6 -1
  120. package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
  121. package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
  122. package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
  123. package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
  124. package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
  125. package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
  126. package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
  127. package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
  128. package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
  129. package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
  130. package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
  131. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
  132. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -1
  133. package/corpus/templates/clips/app/routes/record.tsx +3 -3
  134. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -3
  135. package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
  136. package/corpus/templates/clips/changelog/2026-07-17-clips-now-retries-storage-verification-in-the-background-ins.md +6 -0
  137. package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
  138. package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
  139. package/corpus/templates/clips/changelog/2026-07-17-fixed-broken-thumbnail-icons-appearing-over-playable-clip-em.md +6 -0
  140. package/corpus/templates/clips/changelog/2026-07-17-playback-comments-stay-readable-at-faster-playback-speeds.md +6 -0
  141. package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +3 -0
  142. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +3 -3
  143. package/corpus/templates/clips/desktop/src/app.tsx +19 -7
  144. package/corpus/templates/clips/desktop/src/lib/recorder.ts +111 -13
  145. package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +16 -7
  146. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -4
  147. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +32 -15
  148. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +45 -18
  149. package/corpus/templates/clips/server/jobs/media-verification.ts +130 -0
  150. package/corpus/templates/clips/server/lib/builder-media-compression.ts +15 -0
  151. package/corpus/templates/clips/server/lib/media-verification-state.ts +38 -0
  152. package/corpus/templates/clips/server/lib/player-thumbnail-url.ts +31 -0
  153. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +10 -3
  154. package/corpus/templates/clips/server/plugins/auth.ts +5 -5
  155. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  156. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +12 -2
  157. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +6 -1
  158. package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +340 -0
  159. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +24 -7
  160. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +91 -7
  161. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +14 -0
  162. package/corpus/templates/clips/shared/finalize-recovery.ts +61 -2
  163. package/corpus/templates/clips/shared/share-meta.ts +1 -1
  164. package/corpus/templates/content/app/entry.client.tsx +6 -1
  165. package/corpus/templates/dispatch/AGENTS.md +5 -0
  166. package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
  167. package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
  168. package/corpus/templates/mail/app/entry.client.tsx +6 -1
  169. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
  170. package/corpus/templates/slides/.env.example +0 -1
  171. package/corpus/templates/slides/AGENTS.md +4 -0
  172. package/corpus/templates/slides/DEVELOPING.md +2 -2
  173. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
  174. package/corpus/templates/slides/actions/logo-config.ts +6 -7
  175. package/corpus/templates/slides/actions/search-images.ts +11 -39
  176. package/corpus/templates/slides/actions/search-logos.ts +5 -52
  177. package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
  178. package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
  179. package/corpus/templates/slides/app/entry.client.tsx +6 -1
  180. package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
  181. package/corpus/templates/slides/server/register-secrets.ts +30 -0
  182. package/dist/a2a/client.d.ts +47 -1
  183. package/dist/a2a/client.d.ts.map +1 -1
  184. package/dist/a2a/client.js +94 -12
  185. package/dist/a2a/client.js.map +1 -1
  186. package/dist/a2a/correlation.d.ts +10 -0
  187. package/dist/a2a/correlation.d.ts.map +1 -0
  188. package/dist/a2a/correlation.js +40 -0
  189. package/dist/a2a/correlation.js.map +1 -0
  190. package/dist/a2a/handlers.d.ts.map +1 -1
  191. package/dist/a2a/handlers.js +147 -15
  192. package/dist/a2a/handlers.js.map +1 -1
  193. package/dist/a2a/index.d.ts +4 -4
  194. package/dist/a2a/index.d.ts.map +1 -1
  195. package/dist/a2a/index.js +2 -2
  196. package/dist/a2a/index.js.map +1 -1
  197. package/dist/a2a/invoke.d.ts +29 -2
  198. package/dist/a2a/invoke.d.ts.map +1 -1
  199. package/dist/a2a/invoke.js +33 -1
  200. package/dist/a2a/invoke.js.map +1 -1
  201. package/dist/a2a/server.d.ts.map +1 -1
  202. package/dist/a2a/server.js +14 -1
  203. package/dist/a2a/server.js.map +1 -1
  204. package/dist/a2a/task-store.d.ts +12 -1
  205. package/dist/a2a/task-store.d.ts.map +1 -1
  206. package/dist/a2a/task-store.js +96 -6
  207. package/dist/a2a/task-store.js.map +1 -1
  208. package/dist/a2a/types.d.ts +27 -0
  209. package/dist/a2a/types.d.ts.map +1 -1
  210. package/dist/a2a/types.js.map +1 -1
  211. package/dist/action.d.ts +5 -2
  212. package/dist/action.d.ts.map +1 -1
  213. package/dist/action.js.map +1 -1
  214. package/dist/agent/production-agent.d.ts +14 -0
  215. package/dist/agent/production-agent.d.ts.map +1 -1
  216. package/dist/agent/production-agent.js +19 -3
  217. package/dist/agent/production-agent.js.map +1 -1
  218. package/dist/client/AssistantChat.d.ts +14 -1
  219. package/dist/client/AssistantChat.d.ts.map +1 -1
  220. package/dist/client/AssistantChat.js +158 -136
  221. package/dist/client/AssistantChat.js.map +1 -1
  222. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  223. package/dist/client/MultiTabAssistantChat.js +27 -4
  224. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  225. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  226. package/dist/client/agent-chat-adapter.js +21 -39
  227. package/dist/client/agent-chat-adapter.js.map +1 -1
  228. package/dist/client/agent-sidebar-state.d.ts +1 -0
  229. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  230. package/dist/client/agent-sidebar-state.js +4 -0
  231. package/dist/client/agent-sidebar-state.js.map +1 -1
  232. package/dist/client/analytics.d.ts +14 -0
  233. package/dist/client/analytics.d.ts.map +1 -1
  234. package/dist/client/analytics.js +67 -0
  235. package/dist/client/analytics.js.map +1 -1
  236. package/dist/client/chat/message-components.d.ts +8 -0
  237. package/dist/client/chat/message-components.d.ts.map +1 -1
  238. package/dist/client/chat/message-components.js +62 -19
  239. package/dist/client/chat/message-components.js.map +1 -1
  240. package/dist/client/chat/tool-call-display.d.ts +6 -0
  241. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  242. package/dist/client/chat/tool-call-display.js +83 -14
  243. package/dist/client/chat/tool-call-display.js.map +1 -1
  244. package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
  245. package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
  246. package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
  247. package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
  248. package/dist/client/chat-thread-url.d.ts +2 -0
  249. package/dist/client/chat-thread-url.d.ts.map +1 -0
  250. package/dist/client/chat-thread-url.js +12 -0
  251. package/dist/client/chat-thread-url.js.map +1 -0
  252. package/dist/client/error-capture.d.ts.map +1 -1
  253. package/dist/client/error-capture.js +7 -0
  254. package/dist/client/error-capture.js.map +1 -1
  255. package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
  256. package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
  257. package/dist/client/extensions/ExtensionSlot.js +28 -3
  258. package/dist/client/extensions/ExtensionSlot.js.map +1 -1
  259. package/dist/client/index.d.ts +1 -1
  260. package/dist/client/index.d.ts.map +1 -1
  261. package/dist/client/index.js +1 -1
  262. package/dist/client/index.js.map +1 -1
  263. package/dist/client/route-chunk-recovery.d.ts.map +1 -1
  264. package/dist/client/route-chunk-recovery.js +14 -9
  265. package/dist/client/route-chunk-recovery.js.map +1 -1
  266. package/dist/client/session-replay.d.ts +15 -0
  267. package/dist/client/session-replay.d.ts.map +1 -1
  268. package/dist/client/session-replay.js +20 -0
  269. package/dist/client/session-replay.js.map +1 -1
  270. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  271. package/dist/client/use-run-stuck-detection.js +25 -1
  272. package/dist/client/use-run-stuck-detection.js.map +1 -1
  273. package/dist/db/client.d.ts +7 -0
  274. package/dist/db/client.d.ts.map +1 -1
  275. package/dist/db/client.js +33 -0
  276. package/dist/db/client.js.map +1 -1
  277. package/dist/extensions/actions.d.ts.map +1 -1
  278. package/dist/extensions/actions.js +2 -10
  279. package/dist/extensions/actions.js.map +1 -1
  280. package/dist/extensions/store.js +1 -1
  281. package/dist/extensions/store.js.map +1 -1
  282. package/dist/localization/default-messages.d.ts +3 -0
  283. package/dist/localization/default-messages.d.ts.map +1 -1
  284. package/dist/localization/default-messages.js +3 -0
  285. package/dist/localization/default-messages.js.map +1 -1
  286. package/dist/mcp/build-server.d.ts +2 -0
  287. package/dist/mcp/build-server.d.ts.map +1 -1
  288. package/dist/mcp/build-server.js +2 -2
  289. package/dist/mcp/build-server.js.map +1 -1
  290. package/dist/notifications/routes.d.ts +2 -2
  291. package/dist/observability/routes.d.ts +5 -5
  292. package/dist/observability/traces.d.ts +9 -0
  293. package/dist/observability/traces.d.ts.map +1 -1
  294. package/dist/observability/traces.js +137 -19
  295. package/dist/observability/traces.js.map +1 -1
  296. package/dist/progress/actions.d.ts.map +1 -1
  297. package/dist/progress/actions.js +3 -2
  298. package/dist/progress/actions.js.map +1 -1
  299. package/dist/progress/routes.d.ts +1 -1
  300. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  301. package/dist/provider-api/index.d.ts.map +1 -1
  302. package/dist/provider-api/index.js +91 -8
  303. package/dist/provider-api/index.js.map +1 -1
  304. package/dist/scripts/call-agent.d.ts.map +1 -1
  305. package/dist/scripts/call-agent.js +140 -17
  306. package/dist/scripts/call-agent.js.map +1 -1
  307. package/dist/secrets/routes.d.ts +9 -9
  308. package/dist/server/agent-chat/action-filters-a2a.d.ts +24 -2
  309. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  310. package/dist/server/agent-chat/action-filters-a2a.js +62 -7
  311. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  312. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  313. package/dist/server/agent-chat-plugin.js +118 -5
  314. package/dist/server/agent-chat-plugin.js.map +1 -1
  315. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  316. package/dist/server/transcribe-voice.d.ts +1 -1
  317. package/dist/styles/agent-conversation.css +7 -0
  318. package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
  319. package/dist/templates/default/app/i18n/de-DE.ts +20 -0
  320. package/dist/templates/default/app/i18n/en-US.ts +20 -0
  321. package/dist/templates/default/app/i18n/es-ES.ts +20 -0
  322. package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
  323. package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
  324. package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
  325. package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
  326. package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
  327. package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
  328. package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
  329. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
  330. package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  331. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  332. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  333. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  334. package/package.json +1 -1
  335. package/src/templates/default/app/i18n/ar-SA.ts +20 -0
  336. package/src/templates/default/app/i18n/de-DE.ts +20 -0
  337. package/src/templates/default/app/i18n/en-US.ts +20 -0
  338. package/src/templates/default/app/i18n/es-ES.ts +20 -0
  339. package/src/templates/default/app/i18n/fr-FR.ts +21 -0
  340. package/src/templates/default/app/i18n/hi-IN.ts +19 -0
  341. package/src/templates/default/app/i18n/ja-JP.ts +20 -0
  342. package/src/templates/default/app/i18n/ko-KR.ts +19 -0
  343. package/src/templates/default/app/i18n/pt-BR.ts +20 -0
  344. package/src/templates/default/app/i18n/zh-CN.ts +19 -0
  345. package/src/templates/default/app/i18n/zh-TW.ts +19 -0
  346. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +49 -0
  347. package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
  348. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +7 -1
  349. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
  350. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  351. package/corpus/templates/analytics/server/handlers/github.ts +0 -200
  352. package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
  353. package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
  354. package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
  355. package/corpus/templates/analytics/server/lib/github.ts +0 -660
  356. package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
  357. package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
  358. package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
  359. package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
  360. package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
  361. package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
  362. package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
  363. package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
  364. package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
  365. package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
  366. package/corpus/templates/slides/actions/image-search.ts +0 -64
  367. package/corpus/templates/slides/actions/import-github.ts +0 -182
  368. package/corpus/templates/slides/actions/logo-lookup.ts +0 -113
@@ -630,6 +630,17 @@ const messages = {
630
630
  languageDescription:
631
631
  "このアカウントのインターフェイス言語を選択します。Clips はデバイス間で設定を記憶します。",
632
632
  languageLabel: "インターフェイス言語",
633
+ uploadWorkspaceTitle: "アクティブなワークスペース",
634
+ uploadWorkspaceDescription:
635
+ "デスクトップからのアップロードを含む新しい Clips 録画で使用するワークスペースを選択します。",
636
+ uploadWorkspaceLabel: "現在のワークスペース",
637
+ uploadWorkspacePlaceholder: "ワークスペースを選択",
638
+ uploadWorkspaceHint:
639
+ "変更すると、ワークスペースに関連する Clips の表示も更新されます。",
640
+ uploadWorkspaceSaving: "ワークスペースを保存中…",
641
+ uploadWorkspaceSaved: "アクティブなワークスペースを更新しました",
642
+ uploadWorkspaceSaveFailed:
643
+ "アクティブなワークスペースを更新できませんでした",
633
644
  whatsNew: "最新情報",
634
645
  changelogEmpty: "まだ更新はありません。",
635
646
  viewAllUpdates: "すべての更新を見る",
@@ -1383,7 +1394,7 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
1383
1394
  uploadFailed: "アップロードに失敗しました",
1384
1395
  connectStorageToFinish: "開いてストレージを接続し、保存を完了します。",
1385
1396
  retryFromClipsMenu:
1386
- "Clips メニューから再試行できます。録画し直す必要はありません。",
1397
+ "メニューバーからClipsを開いて、この保存済みアップロードを再試行できます。録画し直す必要はありません。",
1387
1398
  removeFailedClip: "失敗したクリップを削除します。",
1388
1399
  remove: "削除",
1389
1400
  viewsCount: "{{count}} 回表示",
@@ -623,6 +623,16 @@ const messages = {
623
623
  languageDescription:
624
624
  "이 계정의 인터페이스 언어를 선택하세요. Clips가 여러 기기에서 기억합니다.",
625
625
  languageLabel: "인터페이스 언어",
626
+ uploadWorkspaceTitle: "활성 워크스페이스",
627
+ uploadWorkspaceDescription:
628
+ "데스크톱 업로드를 포함한 새 Clips 녹화에 사용할 워크스페이스를 선택하세요.",
629
+ uploadWorkspaceLabel: "현재 워크스페이스",
630
+ uploadWorkspacePlaceholder: "워크스페이스 선택",
631
+ uploadWorkspaceHint:
632
+ "변경하면 워크스페이스와 관련된 Clips 화면도 업데이트됩니다.",
633
+ uploadWorkspaceSaving: "워크스페이스 저장 중…",
634
+ uploadWorkspaceSaved: "활성 워크스페이스가 업데이트됨",
635
+ uploadWorkspaceSaveFailed: "활성 워크스페이스를 업데이트할 수 없음",
626
636
  whatsNew: "새 소식",
627
637
  changelogEmpty: "아직 업데이트가 없습니다.",
628
638
  viewAllUpdates: "모든 업데이트 보기",
@@ -1366,7 +1376,7 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
1366
1376
  uploadFailed: "업로드 실패",
1367
1377
  connectStorageToFinish: "열어서 저장소를 연결하고 저장을 완료하세요.",
1368
1378
  retryFromClipsMenu:
1369
- "Clips 메뉴에서 다시 시도하세요. 다시 녹화할 필요는 없습니다.",
1379
+ "메뉴 막대에서 Clips 열어 저장된 업로드를 다시 시도하세요. 다시 녹화할 필요가 없습니다.",
1370
1380
  removeFailedClip: "실패한 클립 제거.",
1371
1381
  remove: "제거",
1372
1382
  viewsCount: "조회수 {{count}}회",
@@ -633,6 +633,16 @@ const messages = {
633
633
  languageDescription:
634
634
  "Escolha o idioma da interface para esta conta. O Clips lembrará em todos os seus dispositivos.",
635
635
  languageLabel: "Idioma da interface",
636
+ uploadWorkspaceTitle: "Espaço ativo",
637
+ uploadWorkspaceDescription:
638
+ "Escolha o espaço que o Clips usará para novas gravações, incluindo uploads do desktop.",
639
+ uploadWorkspaceLabel: "Espaço atual",
640
+ uploadWorkspacePlaceholder: "Escolha um espaço",
641
+ uploadWorkspaceHint:
642
+ "Isso também atualiza as telas do Clips vinculadas ao espaço.",
643
+ uploadWorkspaceSaving: "Salvando espaço…",
644
+ uploadWorkspaceSaved: "Espaço ativo atualizado",
645
+ uploadWorkspaceSaveFailed: "Não foi possível atualizar o espaço ativo",
636
646
  whatsNew: "Novidades",
637
647
  changelogEmpty: "Ainda não há atualizações.",
638
648
  viewAllUpdates: "Ver todas as atualizações",
@@ -1386,7 +1396,7 @@ Todas as mudanças visíveis para usuários do Clips são documentadas aqui. Voc
1386
1396
  connectStorageToFinish:
1387
1397
  "Abra para conectar o armazenamento e concluir o salvamento.",
1388
1398
  retryFromClipsMenu:
1389
- "Tente novamente pelo menu do Clips; não precisa gravar de novo.",
1399
+ "Abra o Clips pela barra de menus para tentar novamente este upload salvo; não é preciso gravar de novo.",
1390
1400
  removeFailedClip: "Remover este clip com falha.",
1391
1401
  remove: "Remover",
1392
1402
  viewsCount: "{{count}} visualizações",
@@ -598,6 +598,15 @@ const messages = {
598
598
  languageDescription:
599
599
  "选择此账号的界面语言。Clips 会在不同设备上记住你的选择。",
600
600
  languageLabel: "界面语言",
601
+ uploadWorkspaceTitle: "当前工作区",
602
+ uploadWorkspaceDescription:
603
+ "选择 Clips 用于新录制内容(包括桌面上传)的工作区。",
604
+ uploadWorkspaceLabel: "当前工作区",
605
+ uploadWorkspacePlaceholder: "选择工作区",
606
+ uploadWorkspaceHint: "切换后,Clips 中与工作区相关的视图也会更新。",
607
+ uploadWorkspaceSaving: "正在保存工作区…",
608
+ uploadWorkspaceSaved: "当前工作区已更新",
609
+ uploadWorkspaceSaveFailed: "无法更新当前工作区",
601
610
  whatsNew: "最新变化",
602
611
  changelogEmpty: "暂无更新。",
603
612
  viewAllUpdates: "查看所有更新",
@@ -1326,7 +1335,8 @@ Clips 中所有面向用户的重要更改都会记录在这里。你可以随
1326
1335
  savedLocally: "已保存到本地",
1327
1336
  uploadFailed: "上传失败",
1328
1337
  connectStorageToFinish: "打开以连接存储并完成保存。",
1329
- retryFromClipsMenu: "从 Clips 菜单重试;无需重新录制。",
1338
+ retryFromClipsMenu:
1339
+ "从菜单栏打开 Clips,重试这个已保存的上传;无需重新录制。",
1330
1340
  removeFailedClip: "移除此失败剪辑。",
1331
1341
  remove: "移除",
1332
1342
  viewsCount: "{{count}} 次观看",
@@ -598,6 +598,15 @@ const messages = {
598
598
  languageDescription:
599
599
  "選取此帳號的介面語言。Clips 會在不同設備上記住你的選取。",
600
600
  languageLabel: "介面語言",
601
+ uploadWorkspaceTitle: "目前工作區",
602
+ uploadWorkspaceDescription:
603
+ "選擇 Clips 用於新錄製內容(包括桌面上傳)的工作區。",
604
+ uploadWorkspaceLabel: "目前工作區",
605
+ uploadWorkspacePlaceholder: "選擇工作區",
606
+ uploadWorkspaceHint: "切換後,Clips 中與工作區相關的檢視也會更新。",
607
+ uploadWorkspaceSaving: "正在儲存工作區…",
608
+ uploadWorkspaceSaved: "目前工作區已更新",
609
+ uploadWorkspaceSaveFailed: "無法更新目前工作區",
601
610
  whatsNew: "最新變化",
602
611
  changelogEmpty: "暫無更新。",
603
612
  viewAllUpdates: "檢視所有更新",
@@ -1302,7 +1311,8 @@ const messages = {
1302
1311
  savedLocally: "已儲存到本機",
1303
1312
  uploadFailed: "上傳失敗",
1304
1313
  connectStorageToFinish: "開啟以連線儲存並完成儲存。",
1305
- retryFromClipsMenu: "從 Clips 選單重試;不需要重新錄製。",
1314
+ retryFromClipsMenu:
1315
+ "從選單列開啟 Clips 以重試這個已儲存的上傳;不需要重新錄製。",
1306
1316
  removeFailedClip: "移除此失敗剪輯。",
1307
1317
  remove: "移除",
1308
1318
  viewsCount: "{{count}} 次觀看",
@@ -12,7 +12,7 @@ import {
12
12
  useT,
13
13
  type SettingsSearchEntry,
14
14
  } from "@agent-native/core/client";
15
- import { TeamPage } from "@agent-native/core/client/org";
15
+ import { TeamPage, useOrg, useSwitchOrg } from "@agent-native/core/client/org";
16
16
  import {
17
17
  BUILDER_CREDITS_UPGRADE_URL,
18
18
  type BuilderCreditsStatus,
@@ -30,6 +30,7 @@ import {
30
30
  IconServer,
31
31
  IconTrash,
32
32
  IconUser,
33
+ IconUsersGroup,
33
34
  } from "@tabler/icons-react";
34
35
  import { useCallback, useEffect, useMemo, useState } from "react";
35
36
  import { toast } from "sonner";
@@ -394,6 +395,8 @@ export default function SettingsIndexRoute() {
394
395
  const { session } = useSession();
395
396
  const t = useT();
396
397
  const agentSettingsTabs = useAgentSettingsTabs();
398
+ const { data: org } = useOrg();
399
+ const switchOrg = useSwitchOrg();
397
400
  const email = session?.email ?? "";
398
401
  const storageStatus = useVideoStorageStatus();
399
402
  const builderStatus = useBuilderStatus();
@@ -505,6 +508,22 @@ export default function SettingsIndexRoute() {
505
508
  void refreshApiKeyStatus();
506
509
  }, [refreshApiKeyStatus]);
507
510
 
511
+ const orgs = org?.orgs ?? [];
512
+
513
+ async function handleUploadWorkspaceChange(organizationId: string) {
514
+ if (!organizationId || organizationId === org?.orgId) return;
515
+ try {
516
+ await switchOrg.mutateAsync(organizationId);
517
+ toast.success(t("settings.uploadWorkspaceSaved"));
518
+ } catch (err) {
519
+ toast.error(
520
+ err instanceof Error
521
+ ? err.message
522
+ : t("settings.uploadWorkspaceSaveFailed"),
523
+ );
524
+ }
525
+ }
526
+
508
527
  async function handleSave() {
509
528
  setSaving(true);
510
529
  try {
@@ -761,6 +780,13 @@ export default function SettingsIndexRoute() {
761
780
  keywords: "storage s3 builder bucket cloud video",
762
781
  hash: "video-storage",
763
782
  },
783
+ {
784
+ id: "clips-upload-workspace",
785
+ label: t("settings.uploadWorkspaceTitle"),
786
+ keywords:
787
+ "upload recordings desktop destination organization workspace",
788
+ hash: "upload-workspace",
789
+ },
764
790
  {
765
791
  id: "clips-slack",
766
792
  label: t("settings.slackTitle"),
@@ -835,6 +861,51 @@ export default function SettingsIndexRoute() {
835
861
  </CardContent>
836
862
  </Card>
837
863
 
864
+ {orgs.length > 0 ? (
865
+ <Card id="upload-workspace" className="scroll-mt-16">
866
+ <CardHeader>
867
+ <CardTitle className="flex items-center gap-2 text-base">
868
+ <IconUsersGroup className="size-4 text-primary" />
869
+ {t("settings.uploadWorkspaceTitle")}
870
+ </CardTitle>
871
+ <CardDescription>
872
+ {t("settings.uploadWorkspaceDescription")}
873
+ </CardDescription>
874
+ </CardHeader>
875
+ <CardContent className="max-w-md space-y-1.5">
876
+ <Label htmlFor="upload-workspace-select">
877
+ {t("settings.uploadWorkspaceLabel")}
878
+ </Label>
879
+ <Select
880
+ value={org?.orgId ?? undefined}
881
+ onValueChange={handleUploadWorkspaceChange}
882
+ disabled={switchOrg.isPending || orgs.length < 2}
883
+ >
884
+ <SelectTrigger id="upload-workspace-select">
885
+ <SelectValue
886
+ placeholder={t("settings.uploadWorkspacePlaceholder")}
887
+ />
888
+ </SelectTrigger>
889
+ <SelectContent>
890
+ {orgs.map((workspace) => (
891
+ <SelectItem
892
+ key={workspace.orgId}
893
+ value={workspace.orgId}
894
+ >
895
+ {workspace.orgName}
896
+ </SelectItem>
897
+ ))}
898
+ </SelectContent>
899
+ </Select>
900
+ <p className="text-xs text-muted-foreground">
901
+ {switchOrg.isPending
902
+ ? t("settings.uploadWorkspaceSaving")
903
+ : t("settings.uploadWorkspaceHint")}
904
+ </p>
905
+ </CardContent>
906
+ </Card>
907
+ ) : null}
908
+
838
909
  <Card id="video-storage" className="scroll-mt-16">
839
910
  <CardHeader>
840
911
  <CardTitle className="text-base flex items-center gap-2">
@@ -92,7 +92,7 @@ import { cn } from "@/lib/utils";
92
92
  import { STALE_PENDING_TRANSCRIPT_REASON } from "../../shared/transcript-status";
93
93
 
94
94
  const UPLOAD_STUCK_TIMEOUT_MS = 5 * 60 * 1000;
95
- const PROCESSING_STUCK_TIMEOUT_MS = 2 * 60 * 1000;
95
+ const PROCESSING_STUCK_TIMEOUT_MS = 12 * 60 * 1000;
96
96
  const READY_MEDIA_SETTLE_POLL_MS = 20 * 1000;
97
97
  const READY_MEDIA_SETTLE_POLL_INTERVAL_MS = 1000;
98
98
 
@@ -9,7 +9,7 @@ import { useLiveTranscription } from "@agent-native/core/client/transcription/us
9
9
  import type { BrowserDiagnosticsData } from "@shared/browser-diagnostics";
10
10
  import {
11
11
  isStoredButUnservableFinalizeError,
12
- waitForReadyRecordingAfterFinalizeError,
12
+ waitForAcceptedRecordingAfterFinalizeError,
13
13
  } from "@shared/finalize-recovery";
14
14
  import {
15
15
  chunkUploadParallelism,
@@ -1733,7 +1733,7 @@ export default function RecordRoute() {
1733
1733
  createdId &&
1734
1734
  (err as { name?: string } | null)?.name !== "AbortError"
1735
1735
  ) {
1736
- const recovered = await waitForReadyRecordingAfterFinalizeError({
1736
+ const recovered = await waitForAcceptedRecordingAfterFinalizeError({
1737
1737
  uploadUrl: uploadBase,
1738
1738
  recordingId: createdId,
1739
1739
  preferAuthenticated: true,
@@ -1764,7 +1764,7 @@ export default function RecordRoute() {
1764
1764
  chunkRes.status !== 413 &&
1765
1765
  !isUploadSizeError(error.message)
1766
1766
  ) {
1767
- const recovered = await waitForReadyRecordingAfterFinalizeError({
1767
+ const recovered = await waitForAcceptedRecordingAfterFinalizeError({
1768
1768
  uploadUrl: uploadBase,
1769
1769
  recordingId: createdId,
1770
1770
  preferAuthenticated: true,
@@ -67,6 +67,7 @@ import { parsePlaybackSpeed } from "@/lib/playback-speed";
67
67
  import { isStorageSetupFailureReason } from "@/lib/storage-failures";
68
68
 
69
69
  import { getDb, schema } from "../../server/db";
70
+ import { resolvePlayerThumbnailUrl } from "../../server/lib/player-thumbnail-url";
70
71
  import {
71
72
  buildAgentApiUrls,
72
73
  CLIPS_AGENT_ACCESS_PARAM,
@@ -226,8 +227,10 @@ export async function loader({ params, url }: LoaderFunctionArgs) {
226
227
  id: rec.id,
227
228
  title: rec.title,
228
229
  description: rec.description,
229
- thumbnailUrl: rec.thumbnailUrl,
230
- animatedThumbnailUrl: rec.animatedThumbnailUrl,
230
+ thumbnailUrl: rec.password
231
+ ? null
232
+ : resolvePlayerThumbnailUrl(rec, { appPath }),
233
+ animatedThumbnailUrl: null,
231
234
  visibility: rec.visibility,
232
235
  status: rec.status,
233
236
  archivedAt: rec.archivedAt,
@@ -286,7 +289,7 @@ const CLIPS_TEMPLATE_URL = "https://www.agent-native.com/templates/clips";
286
289
  const CLIPS_AGENT_DOCS_URL =
287
290
  "https://www.agent-native.com/docs/template-clips#agent-readable-clips";
288
291
  const UPLOAD_STUCK_TIMEOUT_MS = 5 * 60 * 1000;
289
- const PROCESSING_STUCK_TIMEOUT_MS = 2 * 60 * 1000;
292
+ const PROCESSING_STUCK_TIMEOUT_MS = 12 * 60 * 1000;
290
293
 
291
294
  type ViewerPlatform = "mac" | "windows" | "linux";
292
295
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Choose which workspace receives new Clips recordings and desktop uploads
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Clips now retries storage verification in the background instead of failing completed uploads prematurely.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Create folders directly from the move menu
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Failed desktop uploads now offer a direct way to reopen Clips and retry without re-recording.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Fixed broken thumbnail icons appearing over playable clip embeds
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-17
4
+ ---
5
+
6
+ Playback comments stay readable at faster playback speeds
@@ -2,6 +2,9 @@ export {
2
2
  authenticatedRecordingStatusUrl,
3
3
  publicRecordingStatusUrl,
4
4
  readyRecordingFromPublicPayload,
5
+ waitForAcceptedRecordingAfterFinalizeError,
5
6
  waitForReadyRecordingAfterFinalizeError,
7
+ type RecoveredFinalizeRecording,
8
+ type RecoveredProcessingRecording,
6
9
  type RecoveredReadyRecording,
7
10
  } from "@shared/finalize-recovery";
@@ -35,7 +35,7 @@ import {
35
35
  } from "@shared/recording-core";
36
36
  import { MAX_UPLOAD_BYTES } from "@shared/upload-limits";
37
37
 
38
- import { waitForReadyRecordingAfterFinalizeError } from "./finalize-recovery";
38
+ import { waitForAcceptedRecordingAfterFinalizeError } from "./finalize-recovery";
39
39
  import {
40
40
  createNativeTranscriptionCapture,
41
41
  type NativeTranscriptionCapture,
@@ -875,7 +875,7 @@ async function uploadChunk(
875
875
  if (extra.isFinal && res.status === 504) {
876
876
  triedFinalUploadRecovery = true;
877
877
  await res.text().catch(() => "");
878
- const recovered = await waitForReadyRecordingAfterFinalizeError({
878
+ const recovered = await waitForAcceptedRecordingAfterFinalizeError({
879
879
  uploadUrl: recording.uploadUrl,
880
880
  recordingId: recording.recordingId,
881
881
  authToken: recording.authToken,
@@ -1619,7 +1619,7 @@ async function finalizeStop(recording: ActiveRecording): Promise<void> {
1619
1619
  const error = err instanceof Error ? err : new Error(String(err));
1620
1620
 
1621
1621
  if (isFinalUploadRecoveryCandidate(error)) {
1622
- const recovered = await waitForReadyRecordingAfterFinalizeError({
1622
+ const recovered = await waitForAcceptedRecordingAfterFinalizeError({
1623
1623
  uploadUrl: recording.uploadUrl,
1624
1624
  recordingId: recording.recordingId,
1625
1625
  authToken: recording.authToken,
@@ -70,6 +70,7 @@ import {
70
70
  exportBrowserRecordingBackup,
71
71
  listBrowserRecordingBackups,
72
72
  retryBrowserRecordingBackup,
73
+ scheduleNativeBackupCleanupAfterProcessing,
73
74
  shouldUseNativeFullscreenRecording,
74
75
  startRecording,
75
76
  type LocalExportedFile,
@@ -1894,12 +1895,23 @@ export function App() {
1894
1895
  try {
1895
1896
  const authToken = loadDesktopAuthToken(targetServerUrl);
1896
1897
  if (upload.kind === "native") {
1897
- await invoke("native_fullscreen_recording_retry_upload", {
1898
- serverUrl: targetServerUrl,
1899
- recordingId: upload.recordingId,
1900
- authToken,
1901
- cookie: typeof document !== "undefined" ? document.cookie || "" : "",
1902
- });
1898
+ const result = await invoke<{ verificationPending?: boolean }>(
1899
+ "native_fullscreen_recording_retry_upload",
1900
+ {
1901
+ serverUrl: targetServerUrl,
1902
+ recordingId: upload.recordingId,
1903
+ authToken,
1904
+ cookie:
1905
+ typeof document !== "undefined" ? document.cookie || "" : "",
1906
+ },
1907
+ );
1908
+ if (result.verificationPending) {
1909
+ scheduleNativeBackupCleanupAfterProcessing({
1910
+ serverUrl: targetServerUrl,
1911
+ recordingId: upload.recordingId,
1912
+ authToken,
1913
+ });
1914
+ }
1903
1915
  } else {
1904
1916
  await retryBrowserRecordingBackup({
1905
1917
  recordingId: upload.recordingId,
@@ -4569,7 +4581,7 @@ function Setup({
4569
4581
  <div className="setup-section">
4570
4582
  <SettingLabel
4571
4583
  label="Clip Drafts"
4572
- hint="Clips dismissed after an upload problem stay in Movies/Clips/Drafts until you remove them in Finder."
4584
+ hint="Only clips you dismiss from the saved-upload card appear in Movies/Clips/Drafts. To retry a failed upload, return to the Clips popover and use Retry."
4573
4585
  />
4574
4586
  <button
4575
4587
  type="button"
@@ -51,7 +51,10 @@ import { invoke } from "@tauri-apps/api/core";
51
51
  import { emit, listen, type UnlistenFn } from "@tauri-apps/api/event";
52
52
  import { open as openExternal } from "@tauri-apps/plugin-shell";
53
53
 
54
- import { waitForReadyRecordingAfterFinalizeError } from "../../../shared/finalize-recovery";
54
+ import {
55
+ waitForAcceptedRecordingAfterFinalizeError,
56
+ waitForReadyRecordingAfterFinalizeError,
57
+ } from "../../../shared/finalize-recovery";
55
58
  import type { LocalRecordingMode } from "../shared/config";
56
59
  import { createAudioCue, type AudioCue } from "./audio-cue";
57
60
  import { createCameraCompositeStream } from "./camera-composite";
@@ -752,7 +755,56 @@ async function markBrowserRecordingBackupError(
752
755
  });
753
756
  }
754
757
 
755
- async function recoverReadyRecordingAfterFinalizeError({
758
+ function scheduleBrowserBackupCleanupAfterProcessing(args: {
759
+ serverUrl: string;
760
+ recordingId: string;
761
+ authToken?: string;
762
+ }): void {
763
+ void waitForReadyRecordingAfterFinalizeError({
764
+ uploadUrl: chunkUrl(args.serverUrl, args.recordingId, 0, false),
765
+ recordingId: args.recordingId,
766
+ authToken: args.authToken,
767
+ preferAuthenticated: true,
768
+ timeoutMs: 12 * 60 * 1000,
769
+ })
770
+ .then((recovered) => {
771
+ if (recovered?.status === "ready") {
772
+ return deleteBrowserRecordingBackup(args.recordingId);
773
+ }
774
+ })
775
+ .catch((err) => {
776
+ console.warn(
777
+ "[clips-recorder] background backup cleanup check failed:",
778
+ err,
779
+ );
780
+ });
781
+ }
782
+
783
+ export function scheduleNativeBackupCleanupAfterProcessing(args: {
784
+ serverUrl: string;
785
+ recordingId: string;
786
+ authToken?: string;
787
+ }): void {
788
+ void waitForReadyRecordingAfterFinalizeError({
789
+ uploadUrl: chunkUrl(args.serverUrl, args.recordingId, 0, false),
790
+ recordingId: args.recordingId,
791
+ authToken: args.authToken,
792
+ preferAuthenticated: true,
793
+ timeoutMs: 12 * 60 * 1000,
794
+ })
795
+ .then((recovered) => {
796
+ if (recovered?.status === "ready") {
797
+ return invoke("native_fullscreen_recording_dismiss_upload", {
798
+ recordingId: args.recordingId,
799
+ });
800
+ }
801
+ })
802
+ .catch((err) => {
803
+ console.warn("[clips-recorder] native backup cleanup check failed:", err);
804
+ });
805
+ }
806
+
807
+ async function recoverAcceptedRecordingAfterFinalizeError({
756
808
  serverUrl,
757
809
  recordingId,
758
810
  authToken,
@@ -760,19 +812,27 @@ async function recoverReadyRecordingAfterFinalizeError({
760
812
  serverUrl: string;
761
813
  recordingId: string;
762
814
  authToken?: string;
763
- }): Promise<boolean> {
764
- const recovered = await waitForReadyRecordingAfterFinalizeError({
815
+ }): Promise<"processing" | "ready" | null> {
816
+ const recovered = await waitForAcceptedRecordingAfterFinalizeError({
765
817
  uploadUrl: chunkUrl(serverUrl, recordingId, 0, false),
766
818
  recordingId,
767
819
  authToken,
768
820
  preferAuthenticated: true,
769
821
  });
770
- if (!recovered) return false;
822
+ if (!recovered) return null;
823
+ if (recovered.status === "processing") {
824
+ scheduleBrowserBackupCleanupAfterProcessing({
825
+ serverUrl,
826
+ recordingId,
827
+ authToken,
828
+ });
829
+ return "processing";
830
+ }
771
831
  await markBrowserRecordingBackupError(
772
832
  recordingId,
773
833
  "Upload completed, but its final receipt could not be verified. The local backup was kept.",
774
834
  ).catch(() => {});
775
- return true;
835
+ return "ready";
776
836
  }
777
837
 
778
838
  export async function listBrowserRecordingBackups(): Promise<
@@ -951,10 +1011,21 @@ export async function retryBrowserRecordingBackup(input: {
951
1011
  validatedChunks,
952
1012
  input.authToken,
953
1013
  );
954
- verifyFinalizeReceipt(receipt, meta);
1014
+ const receiptStatus = verifyFinalizeReceipt(receipt, meta);
1015
+ if (receiptStatus === "processing") {
1016
+ scheduleBrowserBackupCleanupAfterProcessing({
1017
+ serverUrl: meta.serverUrl,
1018
+ recordingId: meta.recordingId,
1019
+ authToken: input.authToken,
1020
+ });
1021
+ return {
1022
+ recordingId: meta.recordingId,
1023
+ viewUrl: `/r/${meta.recordingId}`,
1024
+ };
1025
+ }
955
1026
  } catch (err) {
956
1027
  if (
957
- await recoverReadyRecordingAfterFinalizeError({
1028
+ await recoverAcceptedRecordingAfterFinalizeError({
958
1029
  serverUrl: meta.serverUrl,
959
1030
  recordingId: meta.recordingId,
960
1031
  authToken: input.authToken,
@@ -1007,10 +1078,21 @@ export async function retryBrowserRecordingBackup(input: {
1007
1078
  new Blob([], { type: meta.mimeType }),
1008
1079
  input.authToken,
1009
1080
  );
1010
- verifyFinalizeReceipt(receipt, meta);
1081
+ const receiptStatus = verifyFinalizeReceipt(receipt, meta);
1082
+ if (receiptStatus === "processing") {
1083
+ scheduleBrowserBackupCleanupAfterProcessing({
1084
+ serverUrl: meta.serverUrl,
1085
+ recordingId: meta.recordingId,
1086
+ authToken: input.authToken,
1087
+ });
1088
+ return {
1089
+ recordingId: meta.recordingId,
1090
+ viewUrl: `/r/${meta.recordingId}`,
1091
+ };
1092
+ }
1011
1093
  } catch (err) {
1012
1094
  if (
1013
- await recoverReadyRecordingAfterFinalizeError({
1095
+ await recoverAcceptedRecordingAfterFinalizeError({
1014
1096
  serverUrl: meta.serverUrl,
1015
1097
  recordingId: meta.recordingId,
1016
1098
  authToken: input.authToken,
@@ -1143,6 +1225,7 @@ interface NativeFullscreenUploadResult {
1143
1225
  durationMs: number;
1144
1226
  width?: number;
1145
1227
  height?: number;
1228
+ verificationPending?: boolean;
1146
1229
  }
1147
1230
 
1148
1231
  interface NativeFullscreenSaveResult {
@@ -2490,7 +2573,7 @@ async function startNativeFullscreenRecording(
2490
2573
  uploadResult = await uploadPromise;
2491
2574
  } catch (err) {
2492
2575
  if (
2493
- await recoverReadyRecordingAfterFinalizeError({
2576
+ await recoverAcceptedRecordingAfterFinalizeError({
2494
2577
  serverUrl: params.serverUrl,
2495
2578
  recordingId: id,
2496
2579
  authToken: params.authToken,
@@ -2505,6 +2588,13 @@ async function startNativeFullscreenRecording(
2505
2588
  );
2506
2589
  throw err;
2507
2590
  }
2591
+ if (uploadResult.verificationPending) {
2592
+ scheduleNativeBackupCleanupAfterProcessing({
2593
+ serverUrl: params.serverUrl,
2594
+ recordingId: id,
2595
+ authToken: params.authToken,
2596
+ });
2597
+ }
2508
2598
  const transcriptSaved = await transcriptSavePromise;
2509
2599
  if (!transcriptSaved && capturedTranscript?.text.trim()) {
2510
2600
  // The first write runs in parallel with native upload. Retry once
@@ -3878,15 +3968,23 @@ async function startRecordingInner(
3878
3968
  const receipt = bodyText
3879
3969
  ? (JSON.parse(bodyText) as FinalizeReceipt)
3880
3970
  : null;
3881
- verifyFinalizeReceipt(receipt, {
3971
+ const receiptStatus = verifyFinalizeReceipt(receipt, {
3882
3972
  bytes: backupBytes,
3883
3973
  durationMs,
3884
3974
  });
3975
+ if (receiptStatus === "processing") {
3976
+ scheduleBrowserBackupCleanupAfterProcessing({
3977
+ serverUrl: params.serverUrl,
3978
+ recordingId: id,
3979
+ authToken: params.authToken,
3980
+ });
3981
+ return { recordingId: id, viewUrl };
3982
+ }
3885
3983
  } catch (err) {
3886
3984
  console.error("[clips-recorder] finalize fetch failed:", err);
3887
3985
  const error = err instanceof Error ? err : new Error(String(err));
3888
3986
  if (
3889
- await recoverReadyRecordingAfterFinalizeError({
3987
+ await recoverAcceptedRecordingAfterFinalizeError({
3890
3988
  serverUrl: params.serverUrl,
3891
3989
  recordingId: id,
3892
3990
  authToken: params.authToken,