@agent-native/core 0.169.1 → 0.171.0

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 (463) hide show
  1. package/agent-native.eject.json +4 -1
  2. package/bin/agent-native.js +23 -5
  3. package/corpus/README.md +1 -1
  4. package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
  5. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  6. package/corpus/templates/analytics/app/i18n-data.ts +28 -0
  7. package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
  8. package/corpus/templates/analytics/app/routes/$.tsx +10 -0
  9. package/corpus/templates/analytics/app/routes.ts +3 -1
  10. package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
  11. package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
  12. package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
  13. package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
  14. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
  15. package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
  16. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
  17. package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
  18. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
  20. package/corpus/templates/analytics/server/lib/slack.ts +4 -2
  21. package/corpus/templates/analytics/vitest.config.ts +6 -1
  22. package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
  23. package/corpus/templates/assets/app/routes/library.tsx +5 -3
  24. package/corpus/templates/assets/app/routes.ts +3 -1
  25. package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
  26. package/corpus/templates/assets/vitest.config.ts +6 -1
  27. package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
  28. package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
  29. package/corpus/templates/brain/app/routes/sources.tsx +8 -3
  30. package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
  31. package/corpus/templates/brain/vitest.config.ts +1 -0
  32. package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
  33. package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
  34. package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
  35. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
  36. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
  37. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
  38. package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
  39. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
  40. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
  41. package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
  42. package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
  43. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
  44. package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
  45. package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
  46. package/corpus/templates/calendar/app/routes.ts +3 -1
  47. package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
  48. package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
  49. package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
  50. package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
  51. package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
  52. package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
  53. package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
  54. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
  55. package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
  56. package/corpus/templates/calendar/server/onboarding.ts +85 -0
  57. package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
  58. package/corpus/templates/calendar/shared/api.ts +9 -1
  59. package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  60. package/corpus/templates/chat/app/routes.ts +3 -1
  61. package/corpus/templates/chat/vitest.config.ts +8 -0
  62. package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
  63. package/corpus/templates/clips/actions/get-meeting.ts +9 -4
  64. package/corpus/templates/clips/actions/list-recordings.ts +16 -3
  65. package/corpus/templates/clips/actions/search-meetings.ts +1 -0
  66. package/corpus/templates/clips/actions/view-screen.ts +8 -1
  67. package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
  68. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
  69. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
  70. package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
  71. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
  72. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
  73. package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
  74. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
  75. package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
  76. package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
  77. package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
  78. package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
  80. package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
  81. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
  82. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
  83. package/corpus/templates/clips/desktop/src/app.tsx +53 -24
  84. package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
  85. package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
  86. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
  87. package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
  88. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
  89. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
  90. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
  91. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
  92. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
  93. package/corpus/templates/clips/server/lib/emails.ts +17 -33
  94. package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
  95. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
  96. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
  97. package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
  98. package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
  99. package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
  100. package/corpus/templates/content/app/i18n-data.ts +25 -0
  101. package/corpus/templates/content/app/routes.ts +3 -1
  102. package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
  103. package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
  104. package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
  105. package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
  106. package/corpus/templates/content/vitest.config.ts +7 -1
  107. package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
  108. package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
  109. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1383 -88
  110. package/corpus/templates/design/actions/generate-design.ts +98 -47
  111. package/corpus/templates/design/actions/get-design-system.ts +6 -1
  112. package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
  113. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
  114. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
  115. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
  116. package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
  117. package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
  118. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -1
  119. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
  120. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
  121. package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
  122. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
  123. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -4
  124. package/corpus/templates/design/app/i18n-data.ts +1 -0
  125. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
  126. package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
  127. package/corpus/templates/design/app/pages/DesignEditor.tsx +77 -35
  128. package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
  129. package/corpus/templates/design/app/pages/Index.tsx +2 -0
  130. package/corpus/templates/design/app/pages/Templates.tsx +0 -10
  131. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
  132. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
  133. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
  134. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
  135. package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
  136. package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
  137. package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
  138. package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
  139. package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
  140. package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
  141. package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
  142. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
  143. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
  144. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
  145. package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
  146. package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
  147. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
  148. package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
  149. package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
  150. package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
  151. package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
  152. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
  153. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
  154. package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
  155. package/corpus/templates/design/app/routes.ts +3 -1
  156. package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
  157. package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
  158. package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
  159. package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
  160. package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
  161. package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
  162. package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
  163. package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
  164. package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
  165. package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
  166. package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
  167. package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
  168. package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
  169. package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
  170. package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
  171. package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
  172. package/corpus/templates/design/package.json +2 -0
  173. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
  174. package/corpus/templates/design/shared/canvas-math.ts +612 -206
  175. package/corpus/templates/design/shared/pen-path.ts +37 -0
  176. package/corpus/templates/design/vitest.config.ts +7 -1
  177. package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
  178. package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
  179. package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
  180. package/corpus/templates/dispatch/app/routes.ts +3 -1
  181. package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
  182. package/corpus/templates/factory/.env.example +2 -7
  183. package/corpus/templates/factory/AGENTS.md +3 -0
  184. package/corpus/templates/factory/README.md +5 -3
  185. package/corpus/templates/factory/actions/create-factory.ts +16 -3
  186. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
  187. package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
  188. package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
  189. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  190. package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
  191. package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
  192. package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
  193. package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
  194. package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
  195. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
  196. package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
  197. package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
  198. package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
  199. package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
  200. package/corpus/templates/factory/app/routes/factory.tsx +84 -11
  201. package/corpus/templates/factory/app/routes.ts +3 -1
  202. package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
  203. package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
  204. package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
  205. package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
  206. package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
  207. package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
  208. package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
  209. package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
  210. package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
  211. package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
  212. package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
  213. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
  214. package/corpus/templates/factory/vitest.config.ts +17 -2
  215. package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
  216. package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
  217. package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  218. package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
  219. package/corpus/templates/forms/vitest.config.ts +1 -0
  220. package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
  221. package/corpus/templates/macros/app/routes.ts +3 -1
  222. package/corpus/templates/macros/vitest.config.ts +6 -1
  223. package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
  224. package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
  225. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
  226. package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
  227. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
  228. package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
  229. package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
  230. package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
  231. package/corpus/templates/mail/app/routes/$.tsx +9 -0
  232. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
  233. package/corpus/templates/mail/app/routes/$view.tsx +47 -1
  234. package/corpus/templates/mail/app/routes.ts +3 -1
  235. package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
  236. package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
  237. package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
  238. package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
  239. package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
  240. package/corpus/templates/mail/server/onboarding.ts +66 -18
  241. package/corpus/templates/mail/vitest.config.ts +6 -1
  242. package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
  243. package/corpus/templates/plan/app/routes/settings.tsx +4 -1
  244. package/corpus/templates/plan/app/routes.ts +3 -1
  245. package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  246. package/corpus/templates/plan/netlify.toml +1 -1
  247. package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
  248. package/corpus/templates/slides/actions/patch-deck.ts +79 -10
  249. package/corpus/templates/slides/actions/update-slide.ts +11 -1
  250. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
  251. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
  252. package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
  253. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
  254. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
  255. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
  256. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
  257. package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
  258. package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
  259. package/corpus/templates/slides/app/routes.ts +3 -1
  260. package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
  261. package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
  262. package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
  263. package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
  264. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
  265. package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
  266. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
  267. package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
  268. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
  269. package/corpus/templates/slides/tsconfig.json +5 -0
  270. package/corpus/templates/slides/vitest.config.ts +6 -1
  271. package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
  272. package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
  273. package/corpus/templates/tasks/app/routes.ts +3 -1
  274. package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
  275. package/corpus/templates/tasks/vitest.config.ts +7 -1
  276. package/dist/action.d.ts +91 -0
  277. package/dist/action.js +50 -0
  278. package/dist/agent/abort-reasons.d.ts +38 -0
  279. package/dist/agent/abort-reasons.js +49 -0
  280. package/dist/agent/engine/ai-sdk-engine.js +8 -5
  281. package/dist/agent/engine/anthropic-engine.js +7 -5
  282. package/dist/agent/engine/first-event-timeout.d.ts +42 -17
  283. package/dist/agent/engine/first-event-timeout.js +67 -25
  284. package/dist/agent/production-agent.d.ts +23 -0
  285. package/dist/agent/production-agent.js +107 -102
  286. package/dist/agent/run-loop-with-resume.d.ts +2 -28
  287. package/dist/agent/run-loop-with-resume.js +25 -40
  288. package/dist/agent/run-manager.js +5 -4
  289. package/dist/agent/run-store.d.ts +55 -0
  290. package/dist/agent/run-store.js +124 -1
  291. package/dist/agent/tool-search.js +2 -1
  292. package/dist/agent/types.d.ts +9 -4
  293. package/dist/app-config/auth.d.ts +1 -0
  294. package/dist/app-config/auth.js +7 -0
  295. package/dist/app-config/configuration-error.d.ts +11 -0
  296. package/dist/app-config/configuration-error.js +14 -0
  297. package/dist/app-config/index.d.ts +1 -0
  298. package/dist/app-config/index.js +1 -0
  299. package/dist/app-config/integrations.d.ts +1 -0
  300. package/dist/app-config/integrations.js +10 -0
  301. package/dist/app-config/plugins.d.ts +34 -0
  302. package/dist/app-config/plugins.js +39 -0
  303. package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
  304. package/dist/app-config/run-lifecycle-invariants.js +18 -25
  305. package/dist/app-config/schema.d.ts +17 -0
  306. package/dist/app-config/schema.js +2 -0
  307. package/dist/chat-threads/schema-migrations.js +20 -0
  308. package/dist/chat-threads/store.js +21 -4
  309. package/dist/cli/native-dependencies.d.ts +4 -0
  310. package/dist/cli/native-dependencies.js +15 -0
  311. package/dist/client/EnvironmentBadge.d.ts +1 -1
  312. package/dist/client/EnvironmentBadge.js +40 -5
  313. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  314. package/dist/client/MultiTabAssistantChat.js +35 -14
  315. package/dist/client/agent-chat/index.d.ts +1 -1
  316. package/dist/client/agent-chat/index.js +1 -1
  317. package/dist/client/agent-page/use-jobs.d.ts +2 -1
  318. package/dist/client/agent-page/use-jobs.js +3 -5
  319. package/dist/client/agent-sidebar-state.js +3 -1
  320. package/dist/client/blocks/library/code-tabs.js +5 -0
  321. package/dist/client/blocks/library/code.js +1 -0
  322. package/dist/client/chat-first/apps-rail.js +2 -2
  323. package/dist/client/chat-model-groups.d.ts +12 -0
  324. package/dist/client/chat-model-groups.js +3 -2
  325. package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
  326. package/dist/client/integrations/GoogleProductLogo.js +45 -0
  327. package/dist/client/integrations/index.d.ts +2 -0
  328. package/dist/client/integrations/index.js +2 -0
  329. package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
  330. package/dist/client/integrations/workspace-provider-oauth.js +13 -0
  331. package/dist/client/resources/mcp-integration-catalog.js +0 -29
  332. package/dist/client/settings/SettingsTabsPage.js +10 -6
  333. package/dist/client/sharing/ShareButton.js +11 -2
  334. package/dist/client/use-chat-models.d.ts +6 -0
  335. package/dist/client/use-chat-models.js +10 -0
  336. package/dist/client/use-db-sync.js +27 -9
  337. package/dist/collab/routes.d.ts +1 -1
  338. package/dist/collab/struct-routes.d.ts +1 -1
  339. package/dist/connections/catalog.d.ts +111 -9
  340. package/dist/connections/catalog.js +86 -30
  341. package/dist/db/create-get-db.js +18 -0
  342. package/dist/db/ddl-guard.d.ts +0 -4
  343. package/dist/db/ddl-guard.js +46 -0
  344. package/dist/deploy/build.d.ts +19 -0
  345. package/dist/deploy/build.js +190 -16
  346. package/dist/deploy/function-bundle.d.ts +45 -0
  347. package/dist/deploy/function-bundle.js +337 -0
  348. package/dist/deploy/workspace-deploy.js +19 -1
  349. package/dist/eject/workspace-connections.js +4 -0
  350. package/dist/email-catalog/registry.d.ts +4 -0
  351. package/dist/email-catalog/registry.js +79 -14
  352. package/dist/extensions/content-patch.js +14 -2
  353. package/dist/integrations/plugin.d.ts +10 -0
  354. package/dist/integrations/plugin.js +40 -6
  355. package/dist/jobs/actions/run-automation-now.d.ts +2 -1
  356. package/dist/jobs/actions/run-automation-now.js +11 -5
  357. package/dist/jobs/frontmatter.js +53 -2
  358. package/dist/jobs/run-now.d.ts +11 -1
  359. package/dist/jobs/run-now.js +42 -7
  360. package/dist/jobs/scheduler.d.ts +1 -0
  361. package/dist/jobs/scheduler.js +2 -1
  362. package/dist/localization/core-messages/ar-SA.js +3 -0
  363. package/dist/localization/core-messages/de-DE.js +3 -0
  364. package/dist/localization/core-messages/en-US.d.ts +3 -0
  365. package/dist/localization/core-messages/en-US.js +3 -0
  366. package/dist/localization/core-messages/es-ES.js +3 -0
  367. package/dist/localization/core-messages/fr-FR.js +3 -0
  368. package/dist/localization/core-messages/hi-IN.js +3 -0
  369. package/dist/localization/core-messages/ja-JP.js +3 -0
  370. package/dist/localization/core-messages/ko-KR.js +3 -0
  371. package/dist/localization/core-messages/pt-BR.js +3 -0
  372. package/dist/localization/core-messages/zh-CN.js +3 -0
  373. package/dist/localization/core-messages/zh-TW.js +3 -0
  374. package/dist/localization/core-messages.d.ts +3 -0
  375. package/dist/localization/default-messages.d.ts +2 -5
  376. package/dist/localization/default-messages.js +2 -5
  377. package/dist/mcp/build-server.d.ts +9 -0
  378. package/dist/mcp/build-server.js +37 -8
  379. package/dist/mcp-client/oauth-client.d.ts +7 -0
  380. package/dist/mcp-client/oauth-client.js +12 -1
  381. package/dist/oauth-tokens/index.d.ts +1 -1
  382. package/dist/oauth-tokens/index.js +1 -1
  383. package/dist/oauth-tokens/lifecycle.d.ts +11 -0
  384. package/dist/oauth-tokens/lifecycle.js +17 -0
  385. package/dist/oauth-tokens/store.js +7 -0
  386. package/dist/observability/posthog-ai.d.ts +15 -1
  387. package/dist/observability/posthog-ai.js +24 -12
  388. package/dist/observability/traces.js +158 -28
  389. package/dist/onboarding/app-profile.js +2 -2
  390. package/dist/onboarding/plugin.js +10 -2
  391. package/dist/onboarding/types.d.ts +2 -0
  392. package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
  393. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  394. package/dist/provider-api/index.js +2 -0
  395. package/dist/resources/handlers.d.ts +2 -2
  396. package/dist/resources/store.js +13 -4
  397. package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
  398. package/dist/secrets/register-framework-secrets.js +1 -1
  399. package/dist/server/action-discovery.js +5 -0
  400. package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
  401. package/dist/server/agent-chat/action-filters-a2a.js +48 -9
  402. package/dist/server/agent-chat-plugin.js +36 -9
  403. package/dist/server/agent-discovery.js +43 -20
  404. package/dist/server/auth.js +18 -16
  405. package/dist/server/beta-opt-out-html.js +45 -4
  406. package/dist/server/better-auth-instance.d.ts +2 -1
  407. package/dist/server/better-auth-instance.js +37 -7
  408. package/dist/server/builder-design-systems.d.ts +4 -1
  409. package/dist/server/builder-design-systems.js +87 -6
  410. package/dist/server/builder-oauth.d.ts +1 -7
  411. package/dist/server/builder-oauth.js +80 -163
  412. package/dist/server/core-routes-plugin.d.ts +29 -0
  413. package/dist/server/core-routes-plugin.js +100 -20
  414. package/dist/server/default-plugins.d.ts +18 -0
  415. package/dist/server/default-plugins.js +22 -0
  416. package/dist/server/edge.d.ts +1 -0
  417. package/dist/server/edge.js +1 -0
  418. package/dist/server/framework-request-handler.js +31 -3
  419. package/dist/server/google-oauth.d.ts +3 -0
  420. package/dist/server/google-oauth.js +3 -0
  421. package/dist/server/index.d.ts +4 -4
  422. package/dist/server/index.js +3 -3
  423. package/dist/server/onboarding-html.js +37 -3
  424. package/dist/server/realtime-token.d.ts +1 -1
  425. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  426. package/dist/server/workspace-provider-oauth.js +72 -20
  427. package/dist/shared/agent-sidebar-url.d.ts +1 -0
  428. package/dist/shared/agent-sidebar-url.js +1 -0
  429. package/dist/shared/environment-lanes.d.ts +2 -0
  430. package/dist/shared/environment-lanes.js +3 -1
  431. package/dist/shared/index.d.ts +3 -1
  432. package/dist/shared/index.js +3 -1
  433. package/dist/shared/surface-visibility.d.ts +31 -0
  434. package/dist/shared/surface-visibility.js +57 -0
  435. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  436. package/dist/templates/chat/app/routes.ts +3 -1
  437. package/dist/templates/chat/vitest.config.ts +8 -0
  438. package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  439. package/dist/templates/default/app/routes.ts +3 -1
  440. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  441. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
  442. package/dist/tracking/registry.d.ts +11 -0
  443. package/dist/tracking/registry.js +5 -2
  444. package/dist/triggers/actions.js +10 -3
  445. package/dist/usage/store.js +23 -3
  446. package/dist/user-profile/actions/get-auth-methods.js +18 -5
  447. package/dist/vite/client.js +33 -7
  448. package/docs/content/actions-access-control.mdx +43 -4
  449. package/docs/content/actions-defining.mdx +16 -0
  450. package/docs/content/authentication.mdx +40 -21
  451. package/docs/content/environment-variables.mdx +1 -0
  452. package/docs/content/template-clips-capture-everywhere.mdx +29 -30
  453. package/docs/content/template-clips-developers.mdx +4 -4
  454. package/docs/content/template-clips.mdx +3 -1
  455. package/package.json +2 -2
  456. package/src/eject/workspace-connections.ts +4 -0
  457. package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
  458. package/src/templates/chat/app/routes.ts +3 -1
  459. package/src/templates/chat/vitest.config.ts +8 -0
  460. package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
  461. package/src/templates/default/app/routes.ts +3 -1
  462. package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
  463. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
@@ -959,6 +959,34 @@ struct CustomScreenCaptureWriterState {
959
959
  session_start_time: Option<(i64, i32)>,
960
960
  finished: bool,
961
961
  failed: Option<String>,
962
+ /// Per-track append bookkeeping, keyed by the labels in `track_labels`.
963
+ /// Only interesting when something goes wrong: `appendSampleBuffer`
964
+ /// reports a bare `false` plus an `AVErrorUnknown`, naming neither the
965
+ /// track nor the timestamp, so a mid-recording writer death is otherwise
966
+ /// undiagnosable from a user's log.
967
+ append_stats: std::collections::HashMap<&'static str, TrackAppendStats>,
968
+ }
969
+
970
+ /// Track labels used for append diagnostics. Static strings so the stats map
971
+ /// keys stay allocation-free on the realtime capture callbacks.
972
+ mod track_labels {
973
+ pub(super) const VIDEO: &str = "video";
974
+ pub(super) const SYSTEM_AUDIO: &str = "system-audio";
975
+ pub(super) const MIC_AUDIO: &str = "mic-audio";
976
+ pub(super) const MIXED_AUDIO: &str = "mixed-audio";
977
+ }
978
+
979
+ /// What we know about one writer input's append history. Enough to answer the
980
+ /// two questions a writer failure raises: which track broke, and was its
981
+ /// timeline still monotonic when it did.
982
+ #[derive(Default, Clone, Copy)]
983
+ struct TrackAppendStats {
984
+ appended: u64,
985
+ last_pts_seconds: Option<f64>,
986
+ /// Count of samples whose PTS did not advance past the previous one.
987
+ /// AVAssetWriter rejects a non-monotonic timeline, so a non-zero count
988
+ /// here beside a failure is the answer rather than a coincidence.
989
+ pts_regressions: u64,
962
990
  }
963
991
 
964
992
  // SAFETY: `Retained<AnyObject>` is `!Send`/`!Sync` by default because objc2
@@ -1558,6 +1586,7 @@ impl CustomScreenCaptureWriter {
1558
1586
  session_start_time: None,
1559
1587
  finished: false,
1560
1588
  failed: None,
1589
+ append_stats: std::collections::HashMap::new(),
1561
1590
  })),
1562
1591
  mixer: mixer.map(|m| Arc::new(Mutex::new(m))),
1563
1592
  started: Arc::new(AtomicBool::new(false)),
@@ -1675,6 +1704,35 @@ impl CustomScreenCaptureWriter {
1675
1704
  .and_then(|guard| guard.failed.clone())
1676
1705
  }
1677
1706
 
1707
+ /// One line describing what each writer input managed to append. Paired
1708
+ /// with a failure it separates "this track died" from "this track was
1709
+ /// never fed", which the failure string alone cannot say.
1710
+ fn append_stats_summary(&self) -> String {
1711
+ let Ok(guard) = self.inner.lock() else {
1712
+ return "append stats unavailable (writer lock poisoned)".to_string();
1713
+ };
1714
+ if guard.append_stats.is_empty() {
1715
+ return "no samples appended on any track".to_string();
1716
+ }
1717
+ let mut tracks: Vec<_> = guard.append_stats.iter().collect();
1718
+ tracks.sort_by_key(|(track, _)| **track);
1719
+ tracks
1720
+ .iter()
1721
+ .map(|(track, stats)| {
1722
+ format!(
1723
+ "{track}: appended={} last_pts={} regressions={}",
1724
+ stats.appended,
1725
+ stats
1726
+ .last_pts_seconds
1727
+ .map(|v| format!("{v:.6}s"))
1728
+ .unwrap_or_else(|| "none".to_string()),
1729
+ stats.pts_regressions
1730
+ )
1731
+ })
1732
+ .collect::<Vec<_>>()
1733
+ .join(" | ")
1734
+ }
1735
+
1678
1736
  /// Accumulated pause offset in seconds. Every appended sample skips this
1679
1737
  /// much wall-clock time so a pause/resume leaves no gap in the file.
1680
1738
  pub(super) fn pause_offset(&self) -> f64 {
@@ -1719,10 +1777,14 @@ impl CustomScreenCaptureWriter {
1719
1777
  if guard.finished || guard.failed.is_some() {
1720
1778
  return;
1721
1779
  }
1722
- let input = match of_type {
1723
- SCStreamOutputType::Screen => Some(guard.video_input.clone()),
1724
- SCStreamOutputType::Audio => guard.system_audio_input.clone(),
1725
- SCStreamOutputType::Microphone => guard.mic_audio_input.clone(),
1780
+ let (input, track) = match of_type {
1781
+ SCStreamOutputType::Screen => (Some(guard.video_input.clone()), track_labels::VIDEO),
1782
+ SCStreamOutputType::Audio => {
1783
+ (guard.system_audio_input.clone(), track_labels::SYSTEM_AUDIO)
1784
+ }
1785
+ SCStreamOutputType::Microphone => {
1786
+ (guard.mic_audio_input.clone(), track_labels::MIC_AUDIO)
1787
+ }
1726
1788
  };
1727
1789
  let Some(input) = input else {
1728
1790
  return;
@@ -1731,6 +1793,7 @@ impl CustomScreenCaptureWriter {
1731
1793
  Ok(timing) if timing.presentation_time_stamp.is_valid() => timing,
1732
1794
  _ => return,
1733
1795
  };
1796
+ let source_pts = timing.presentation_time_stamp.as_seconds();
1734
1797
 
1735
1798
  unsafe {
1736
1799
  if !self.ensure_session_started(&mut guard, timing.presentation_time_stamp) {
@@ -1748,15 +1811,27 @@ impl CustomScreenCaptureWriter {
1748
1811
  let pause_offset = self.pause_offset();
1749
1812
  match retimed_sample_copy(sample, &timing, base, pause_offset) {
1750
1813
  Ok(copy) => {
1751
- self.append_sample_ptr(&mut guard, &input, copy.as_ptr());
1814
+ // Report the rebased PTS, not the source one — that is
1815
+ // the timeline the writer actually validates.
1816
+ let rebased_pts = copy
1817
+ .sample_timing_info(0)
1818
+ .ok()
1819
+ .and_then(|t| t.presentation_time_stamp.as_seconds());
1820
+ self.append_sample_ptr(
1821
+ &mut guard,
1822
+ &input,
1823
+ copy.as_ptr(),
1824
+ track,
1825
+ rebased_pts,
1826
+ );
1752
1827
  }
1753
1828
  Err(err) => {
1754
1829
  drop(guard);
1755
- self.fail(format!("sample retime failed: {err}"));
1830
+ self.fail(format!("sample retime failed on {track}: {err}"));
1756
1831
  }
1757
1832
  }
1758
1833
  } else {
1759
- self.append_sample_ptr(&mut guard, &input, sample.as_ptr());
1834
+ self.append_sample_ptr(&mut guard, &input, sample.as_ptr(), track, source_pts);
1760
1835
  }
1761
1836
  }
1762
1837
  }
@@ -1822,8 +1897,18 @@ impl CustomScreenCaptureWriter {
1822
1897
  return;
1823
1898
  };
1824
1899
  for buffer in &emitted {
1900
+ let pts = buffer
1901
+ .sample_timing_info(0)
1902
+ .ok()
1903
+ .and_then(|t| t.presentation_time_stamp.as_seconds());
1825
1904
  unsafe {
1826
- self.append_sample_ptr(&mut guard, &input, buffer.as_ptr());
1905
+ self.append_sample_ptr(
1906
+ &mut guard,
1907
+ &input,
1908
+ buffer.as_ptr(),
1909
+ track_labels::MIXED_AUDIO,
1910
+ pts,
1911
+ );
1827
1912
  }
1828
1913
  if guard.failed.is_some() {
1829
1914
  break;
@@ -1936,6 +2021,8 @@ impl CustomScreenCaptureWriter {
1936
2021
  guard: &mut CustomScreenCaptureWriterState,
1937
2022
  input: &objc2::rc::Retained<objc2::runtime::AnyObject>,
1938
2023
  sample_ptr: *mut std::ffi::c_void,
2024
+ track: &'static str,
2025
+ pts_seconds: Option<f64>,
1939
2026
  ) {
1940
2027
  use objc2::msg_send;
1941
2028
 
@@ -1945,10 +2032,43 @@ impl CustomScreenCaptureWriter {
1945
2032
  // count and periodically log so sustained backpressure is visible.
1946
2033
  let dropped = self.dropped_samples.fetch_add(1, Ordering::Relaxed) + 1;
1947
2034
  if dropped == 1 || dropped % 100 == 0 {
1948
- eprintln!("[mixer] writer input not ready; dropped {dropped} sample(s) so far");
2035
+ eprintln!(
2036
+ "[mixer] writer input not ready on {track}; dropped {dropped} sample(s) so far"
2037
+ );
1949
2038
  }
1950
2039
  return;
1951
2040
  }
2041
+ // Record the timeline BEFORE the append so a failure report describes
2042
+ // the sample that was actually rejected, not the last good one.
2043
+ let stats = guard.append_stats.entry(track).or_default();
2044
+ let previous_pts = stats.last_pts_seconds;
2045
+ if let Some(pts) = pts_seconds {
2046
+ if previous_pts.is_some_and(|last| pts <= last) {
2047
+ stats.pts_regressions += 1;
2048
+ let regressions = stats.pts_regressions;
2049
+ if regressions == 1 || regressions % 100 == 0 {
2050
+ crate::logfile::diagnostic(&format!(
2051
+ "[capture-health] {track} PTS did not advance: {:.6}s after {:.6}s ({regressions} so far)",
2052
+ pts,
2053
+ previous_pts.unwrap_or(f64::NAN)
2054
+ ));
2055
+ }
2056
+ }
2057
+ stats.last_pts_seconds = Some(pts);
2058
+ }
2059
+ let appended_before = stats.appended;
2060
+ stats.appended += 1;
2061
+ let pts_report = |outcome: &str| {
2062
+ format!(
2063
+ "AVAssetWriter appendSampleBuffer {outcome} on {track} (pts={}, previous={}, appended={appended_before})",
2064
+ pts_seconds
2065
+ .map(|v| format!("{v:.6}s"))
2066
+ .unwrap_or_else(|| "unknown".to_string()),
2067
+ previous_pts
2068
+ .map(|v| format!("{v:.6}s"))
2069
+ .unwrap_or_else(|| "none".to_string()),
2070
+ )
2071
+ };
1952
2072
  // `appendSampleBuffer:` throws Objective-C exceptions on bad input
1953
2073
  // (format/timestamp/state). Those can't be caught by `catch_unwind`
1954
2074
  // and would abort the app, so contain them here.
@@ -1962,15 +2082,18 @@ impl CustomScreenCaptureWriter {
1962
2082
  Ok(false) => {
1963
2083
  self.appends_closed.store(true, Ordering::SeqCst);
1964
2084
  guard.failed = Some(format!(
1965
- "AVAssetWriter appendSampleBuffer failed{}",
2085
+ "{}{}",
2086
+ pts_report("failed"),
1966
2087
  av_writer_error_suffix(&guard.writer)
1967
2088
  ));
1968
2089
  }
1969
2090
  Err(exc) => {
1970
2091
  self.appends_closed.store(true, Ordering::SeqCst);
1971
2092
  let detail = describe_objc_exception(exc);
1972
- eprintln!("[mixer] appendSampleBuffer raised Objective-C exception: {detail}");
1973
- guard.failed = Some(format!("AVAssetWriter appendSampleBuffer raised: {detail}"));
2093
+ eprintln!(
2094
+ "[mixer] appendSampleBuffer raised Objective-C exception on {track}: {detail}"
2095
+ );
2096
+ guard.failed = Some(format!("{}: {detail}", pts_report("raised")));
1974
2097
  }
1975
2098
  }
1976
2099
  }
@@ -2012,8 +2135,18 @@ impl CustomScreenCaptureWriter {
2012
2135
  Ok(buffers) => {
2013
2136
  if let Some(input) = guard.mixed_audio_input.clone() {
2014
2137
  for buffer in &buffers {
2138
+ let pts = buffer
2139
+ .sample_timing_info(0)
2140
+ .ok()
2141
+ .and_then(|t| t.presentation_time_stamp.as_seconds());
2015
2142
  unsafe {
2016
- self.append_sample_ptr(&mut guard, &input, buffer.as_ptr());
2143
+ self.append_sample_ptr(
2144
+ &mut guard,
2145
+ &input,
2146
+ buffer.as_ptr(),
2147
+ track_labels::MIXED_AUDIO,
2148
+ pts,
2149
+ );
2017
2150
  }
2018
2151
  if guard.failed.is_some() {
2019
2152
  break;
@@ -3909,6 +4042,10 @@ fn spawn_capture_watchdog(
3909
4042
  crate::logfile::diagnostic(&format!(
3910
4043
  "[capture-health] writer closed unexpectedly; finalizing partial recording: {writer_error}"
3911
4044
  ));
4045
+ crate::logfile::diagnostic(&format!(
4046
+ "[capture-health] append stats at failure — {}",
4047
+ writer.append_stats_summary()
4048
+ ));
3912
4049
  if let Ok(guard) = stream.lock() {
3913
4050
  let _ = guard.stop_capture();
3914
4051
  }
@@ -135,8 +135,17 @@ fn build_menu_with_meetings(
135
135
  )?;
136
136
  let devtools_item =
137
137
  MenuItem::with_id(app, "devtools", "Toggle DevTools", true, Some("Cmd+Alt+I"))?;
138
+ let version_item = MenuItem::with_id(
139
+ app,
140
+ "version",
141
+ format!("Clips v{}", env!("CARGO_PKG_VERSION")),
142
+ false,
143
+ None::<&str>,
144
+ )?;
138
145
  let quit_item = MenuItem::with_id(app, "quit", "Quit Clips", true, None::<&str>)?;
139
146
  let separator = PredefinedMenuItem::separator(app)?;
147
+ let separator2 = PredefinedMenuItem::separator(app)?;
148
+ let separator3 = PredefinedMenuItem::separator(app)?;
140
149
  let menu = Menu::with_items(
141
150
  app,
142
151
  &[
@@ -147,6 +156,9 @@ fn build_menu_with_meetings(
147
156
  &paste_last_dictation_item,
148
157
  &region_guides_item,
149
158
  &devtools_item,
159
+ &separator2,
160
+ &version_item,
161
+ &separator3,
150
162
  &quit_item,
151
163
  ],
152
164
  )?;
@@ -304,6 +304,23 @@ export async function lockCalendarAccount(
304
304
  return locked.length > 0;
305
305
  }
306
306
 
307
+ /**
308
+ * The calendar could not be read. Distinct from `null` (no such event, or the
309
+ * caller cannot see it): the event may well exist and be visible, so callers
310
+ * must offer a retry rather than reporting it permanently gone.
311
+ */
312
+ export class CalendarEventUnavailableError extends Error {
313
+ constructor(message: string, options?: { cause?: unknown }) {
314
+ super(message);
315
+ this.name = "CalendarEventUnavailableError";
316
+ // Assigned rather than passed to `super`: the Error `cause` option needs
317
+ // the ES2022 lib, which this template does not target.
318
+ if (options && "cause" in options) {
319
+ (this as { cause?: unknown }).cause = options.cause;
320
+ }
321
+ }
322
+ }
323
+
307
324
  export async function fetchLiveCalendarEventFromId(virtualId: string) {
308
325
  const parsed = parseCalendarMeetingId(virtualId);
309
326
  if (!parsed) return null;
@@ -325,13 +342,18 @@ export async function fetchLiveCalendarEventFromId(virtualId: string) {
325
342
  // Transient refresh failure — record the real error (won't match
326
343
  // shouldMarkNeedsReauth) instead of a permanent needs-reauth marker.
327
344
  await recordCalendarFetchError(account, err);
328
- return null;
345
+ throw new CalendarEventUnavailableError(
346
+ "Could not reach Google Calendar to load this event.",
347
+ { cause: err },
348
+ );
329
349
  }
330
350
  if (!accessToken) {
331
351
  await recordCalendarFetchError(account, new Error("Token refresh failed"), {
332
352
  needsReauth: true,
333
353
  });
334
- return null;
354
+ throw new CalendarEventUnavailableError(
355
+ "Google Calendar needs to be reconnected before this event can load.",
356
+ );
335
357
  }
336
358
 
337
359
  try {
@@ -345,7 +367,10 @@ export async function fetchLiveCalendarEventFromId(virtualId: string) {
345
367
  return { account, event };
346
368
  } catch (err) {
347
369
  await recordCalendarFetchError(account, err);
348
- return null;
370
+ throw new CalendarEventUnavailableError(
371
+ "Could not load this event from Google Calendar.",
372
+ { cause: err },
373
+ );
349
374
  }
350
375
  }
351
376
 
@@ -9,7 +9,10 @@
9
9
  * than a copy of it.
10
10
  */
11
11
 
12
- import { defineTransactionalEmail } from "@agent-native/core/email-catalog";
12
+ import {
13
+ replaceTransactionalEmails,
14
+ type TransactionalEmailDefinition,
15
+ } from "@agent-native/core/email-catalog";
13
16
 
14
17
  import { renderClipsInviteEmail } from "../../actions/invite-member.js";
15
18
  import {
@@ -51,38 +54,13 @@ export const CLIPS_ORGANIZATION_INVITE_EMAIL_ID = "clips.organization-invite";
51
54
  const CLIPS_SENDER =
52
55
  'From is the configured EMAIL_FROM with the display name "Agent-Native Clips"; on first-party agent-native.com deployments it becomes clips@agent-native.com. Reply-to is hello@agent-native.com.';
53
56
 
54
- let registered = false;
55
- const GLOBAL_REGISTRATION_KEY =
56
- "__agentNativeClipsTransactionalEmailCatalogRegistered";
57
- const globalRegistrationState = globalThis as typeof globalThis &
58
- Record<string, boolean | undefined>;
59
-
60
- function defineClipsTransactionalEmail(
61
- definition: Parameters<typeof defineTransactionalEmail>[0],
62
- ): boolean {
63
- try {
64
- defineTransactionalEmail(definition);
65
- return true;
66
- } catch (error) {
67
- if (
68
- error instanceof Error &&
69
- error.message.startsWith('Duplicate transactional email id "clips.')
70
- ) {
71
- // The same Clips catalog can be evaluated twice by Nitro/Vite. The
72
- // first definition is canonical, so a duplicate is already registered.
73
- return false;
74
- }
75
- throw error;
76
- }
77
- }
78
-
79
- export function registerClipsEmails(): void {
80
- // Nitro/Vite can evaluate the same server module through two module
81
- // instances during dev reloads. Keep the catalog registration process-wide
82
- // so those instances cannot submit the same id twice.
83
- if (registered || globalRegistrationState[GLOBAL_REGISTRATION_KEY]) return;
84
- registered = true;
85
- globalRegistrationState[GLOBAL_REGISTRATION_KEY] = true;
57
+ function registerClipsEmailDefinitions(): void {
58
+ const definitions: TransactionalEmailDefinition[] = [];
59
+ const defineClipsTransactionalEmail = (
60
+ definition: TransactionalEmailDefinition,
61
+ ): void => {
62
+ definitions.push({ ...definition, app: "clips" });
63
+ };
86
64
 
87
65
  defineClipsTransactionalEmail({
88
66
  id: CLIPS_ACCESS_REQUEST_EMAIL_ID,
@@ -305,4 +283,10 @@ export function registerClipsEmails(): void {
305
283
  inviteUrl: "https://example.com/invite/sample-token",
306
284
  }),
307
285
  });
286
+
287
+ replaceTransactionalEmails("clips", "clips.", definitions);
288
+ }
289
+
290
+ export function registerClipsEmails(): void {
291
+ registerClipsEmailDefinitions();
308
292
  }
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
19
19
  as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
20
20
  signing secrets, OAuth refresh tokens, or private Builder/customer data.
21
21
 
22
- Secret values are supplied at runtime through deployment configuration, the
23
- encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
- `${keys.NAME}` substitution. Examples must use obvious placeholders such as
25
- `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
22
+ Provider secret values are supplied at runtime through the encrypted
23
+ `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
24
+ `${keys.NAME}` substitution. Deployment configuration is reserved for
25
+ deploy-level secrets and non-provider configuration. Examples must use obvious
26
+ placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
27
+ real-looking copied values.
28
+
29
+ Provider credentials and provider account identifiers are workspace data. Use
30
+ standard workspace connections and org/workspace vault scopes; never put them
31
+ in `.env` or deployment environment variables, and never add a provider-specific
32
+ action or startup bootstrap just to write a credential for one organization.
26
33
 
27
34
  ## Credential Modeling Preflight
28
35