@agent-native/core 0.114.15 → 0.115.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 (467) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/bin/agent-native.js +35 -14
  3. package/bin/launcher.js +34 -0
  4. package/corpus/README.md +3 -3
  5. package/corpus/core/CHANGELOG.md +35 -0
  6. package/corpus/core/agent-native.eject.json +2 -0
  7. package/corpus/core/bin/agent-native.js +35 -14
  8. package/corpus/core/bin/launcher.js +34 -0
  9. package/corpus/core/docs/content/agent-native-toolkit.mdx +16 -0
  10. package/corpus/core/docs/content/recurring-jobs.mdx +35 -6
  11. package/corpus/core/export-snapshot.json +4 -0
  12. package/corpus/core/package.json +5 -1
  13. package/corpus/core/src/action.ts +22 -1
  14. package/corpus/core/src/agent/production-agent.ts +105 -3
  15. package/corpus/core/src/cli/templates-meta.ts +12 -0
  16. package/corpus/core/src/client/AssistantChat.tsx +53 -26
  17. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +19 -0
  18. package/corpus/core/src/client/agent-page/use-jobs.ts +1 -0
  19. package/corpus/core/src/client/chat/message-components.tsx +35 -1
  20. package/corpus/core/src/client/chat/tool-call-display.tsx +38 -3
  21. package/corpus/core/src/connections/catalog.ts +20 -1
  22. package/corpus/core/src/connections/reader.ts +65 -0
  23. package/corpus/core/src/dashboard-storage/index.ts +27 -0
  24. package/corpus/core/src/dashboard-storage/panel-source.ts +168 -0
  25. package/corpus/core/src/dashboard-storage/schema.ts +62 -0
  26. package/corpus/core/src/dashboard-storage/store.ts +333 -0
  27. package/corpus/core/src/deploy/build.ts +95 -16
  28. package/corpus/core/src/eject/provider-api-definitions.ts +1 -0
  29. package/corpus/core/src/eject/workspace-connections.ts +1 -0
  30. package/corpus/core/src/extensions/actions.ts +199 -73
  31. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +2 -0
  32. package/corpus/core/src/jobs/scheduler.ts +71 -4
  33. package/corpus/core/src/jobs/tools.ts +31 -1
  34. package/corpus/core/src/localization/default-messages.ts +1 -0
  35. package/corpus/core/src/mcp-client/index.ts +6 -0
  36. package/corpus/core/src/provider-api/actions/provider-api.ts +1 -1
  37. package/corpus/core/src/provider-api/index.ts +190 -5
  38. package/corpus/core/src/secrets/register-framework-secrets.ts +8 -0
  39. package/corpus/core/src/server/agent-chat/context-tools.ts +9 -0
  40. package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
  41. package/corpus/core/src/server/agent-chat-plugin.ts +22 -2
  42. package/corpus/core/src/server/core-routes-plugin.ts +1 -0
  43. package/corpus/core/src/server/credential-provider.ts +9 -3
  44. package/corpus/core/src/server/workspace-provider-oauth.ts +181 -4
  45. package/corpus/core/src/styles/agent-native.css +45 -2
  46. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
  47. package/corpus/core/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
  48. package/corpus/core/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
  49. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
  50. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
  51. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
  53. package/corpus/core/src/triggers/actions.ts +11 -2
  54. package/corpus/core/src/triggers/dispatcher.ts +20 -1
  55. package/corpus/core/src/triggers/types.ts +5 -0
  56. package/corpus/core/src/vite/action-types-plugin.ts +9 -1
  57. package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +115 -0
  58. package/corpus/templates/analytics/AGENTS.md +11 -11
  59. package/corpus/templates/analytics/_gitignore +39 -0
  60. package/corpus/templates/analytics/actions/query-dashboard-panel.ts +30 -0
  61. package/corpus/templates/analytics/actions/update-dashboard.ts +2 -1
  62. package/corpus/templates/analytics/app/lib/sql-query.ts +11 -25
  63. package/corpus/templates/analytics/changelog/2026-07-21-fixed-extension-updates-failing-before-changes-could-be-appl.md +6 -0
  64. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +1 -0
  65. package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +51 -0
  66. package/corpus/templates/analytics/server/lib/prometheus.ts +1 -1
  67. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
  68. package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +115 -0
  69. package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +115 -0
  70. package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +115 -0
  71. package/corpus/templates/calendar/_gitignore +39 -0
  72. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
  73. package/corpus/templates/chat/AGENTS.md +1 -1
  74. package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +115 -0
  75. package/corpus/templates/clips/AGENTS.md +7 -0
  76. package/corpus/templates/clips/actions/prepare-crm-call-evidence.ts +58 -0
  77. package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +25 -8
  78. package/corpus/templates/clips/app/components/library/library-grid.tsx +118 -9
  79. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  80. package/corpus/templates/clips/app/components/library/recording-card.tsx +10 -8
  81. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +88 -11
  82. package/corpus/templates/clips/app/i18n/en-US.ts +6 -0
  83. package/corpus/templates/clips/app/routes/_app.trash.tsx +16 -1
  84. package/corpus/templates/clips/changelog/2026-07-21-crm-call-evidence-handoff.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-07-21-recording-retries-and-restarts-keep-their-upload-session-so-.md +6 -0
  86. package/corpus/templates/clips/chrome-extension/src/background.ts +20 -5
  87. package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +19 -0
  88. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -0
  89. package/corpus/templates/clips/desktop/src/app.tsx +24 -3
  90. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +9 -0
  91. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +54 -28
  92. package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
  93. package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +115 -0
  94. package/corpus/templates/content/_gitignore +39 -0
  95. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +20 -38
  96. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +40 -1
  97. package/corpus/templates/content/learnings.defaults.md +5 -0
  98. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +115 -0
  99. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
  100. package/corpus/templates/crm/.agents/skills/crm/SKILL.md +128 -0
  101. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  102. package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +169 -0
  103. package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
  104. package/corpus/templates/crm/.env.example +5 -0
  105. package/corpus/templates/crm/AGENTS.md +120 -0
  106. package/corpus/templates/crm/CHANGELOG.md +1 -0
  107. package/corpus/templates/crm/DEVELOPING.md +66 -0
  108. package/corpus/templates/crm/README.md +106 -0
  109. package/corpus/templates/crm/_gitignore +12 -0
  110. package/corpus/templates/crm/actions/_crm-action-utils.ts +87 -0
  111. package/corpus/templates/crm/actions/_crm-dashboard.ts +69 -0
  112. package/corpus/templates/crm/actions/_crm-signal-utils.ts +79 -0
  113. package/corpus/templates/crm/actions/apply-crm-proposals.ts +203 -0
  114. package/corpus/templates/crm/actions/attach-call-evidence.ts +170 -0
  115. package/corpus/templates/crm/actions/configure-crm-connection.ts +126 -0
  116. package/corpus/templates/crm/actions/configure-native-crm.ts +44 -0
  117. package/corpus/templates/crm/actions/create-crm-record.ts +148 -0
  118. package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +58 -0
  119. package/corpus/templates/crm/actions/delete-staged-dataset.ts +14 -0
  120. package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +36 -0
  121. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +33 -0
  122. package/corpus/templates/crm/actions/get-crm-dashboard.ts +14 -0
  123. package/corpus/templates/crm/actions/get-crm-overview.ts +13 -0
  124. package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +61 -0
  125. package/corpus/templates/crm/actions/get-crm-record.ts +75 -0
  126. package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +81 -0
  127. package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +15 -0
  128. package/corpus/templates/crm/actions/list-crm-dashboards.ts +15 -0
  129. package/corpus/templates/crm/actions/list-crm-proposals.ts +31 -0
  130. package/corpus/templates/crm/actions/list-crm-records.ts +79 -0
  131. package/corpus/templates/crm/actions/list-crm-saved-views.ts +15 -0
  132. package/corpus/templates/crm/actions/list-crm-signal-hits.ts +43 -0
  133. package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +32 -0
  134. package/corpus/templates/crm/actions/list-crm-tasks.ts +22 -0
  135. package/corpus/templates/crm/actions/list-staged-datasets.ts +14 -0
  136. package/corpus/templates/crm/actions/list-workspace-connections.ts +47 -0
  137. package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +87 -0
  138. package/corpus/templates/crm/actions/manage-crm-task.ts +132 -0
  139. package/corpus/templates/crm/actions/navigate.ts +63 -0
  140. package/corpus/templates/crm/actions/provider-api-catalog.ts +22 -0
  141. package/corpus/templates/crm/actions/provider-api-docs.ts +54 -0
  142. package/corpus/templates/crm/actions/provider-api-request.ts +92 -0
  143. package/corpus/templates/crm/actions/query-staged-dataset.ts +44 -0
  144. package/corpus/templates/crm/actions/record-crm-call-insight.ts +160 -0
  145. package/corpus/templates/crm/actions/record-crm-smart-signal.ts +150 -0
  146. package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +23 -0
  147. package/corpus/templates/crm/actions/review-crm-signal.ts +31 -0
  148. package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +103 -0
  149. package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +275 -0
  150. package/corpus/templates/crm/actions/run.ts +11 -0
  151. package/corpus/templates/crm/actions/save-crm-dashboard.ts +51 -0
  152. package/corpus/templates/crm/actions/save-crm-saved-view.ts +119 -0
  153. package/corpus/templates/crm/actions/sync-crm.ts +146 -0
  154. package/corpus/templates/crm/actions/update-crm-record.ts +508 -0
  155. package/corpus/templates/crm/actions/view-screen.ts +218 -0
  156. package/corpus/templates/crm/agent-native.app-skill.json +58 -0
  157. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +158 -0
  158. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +83 -0
  159. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +225 -0
  160. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +413 -0
  161. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +510 -0
  162. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +134 -0
  163. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +367 -0
  164. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +92 -0
  165. package/corpus/templates/crm/app/components/crm/Surface.tsx +96 -0
  166. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +180 -0
  167. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +106 -0
  168. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +84 -0
  169. package/corpus/templates/crm/app/entry.client.tsx +16 -0
  170. package/corpus/templates/crm/app/entry.server.tsx +10 -0
  171. package/corpus/templates/crm/app/global.css +167 -0
  172. package/corpus/templates/crm/app/hooks/use-navigation-state.ts +60 -0
  173. package/corpus/templates/crm/app/i18n/en-US.ts +89 -0
  174. package/corpus/templates/crm/app/i18n/index.ts +34 -0
  175. package/corpus/templates/crm/app/lib/dashboard.ts +13 -0
  176. package/corpus/templates/crm/app/lib/navigation.ts +54 -0
  177. package/corpus/templates/crm/app/lib/tab-id.ts +1 -0
  178. package/corpus/templates/crm/app/lib/types.ts +172 -0
  179. package/corpus/templates/crm/app/lib/utils.ts +1 -0
  180. package/corpus/templates/crm/app/root.tsx +88 -0
  181. package/corpus/templates/crm/app/routes/_index.tsx +26 -0
  182. package/corpus/templates/crm/app/routes/accounts.tsx +41 -0
  183. package/corpus/templates/crm/app/routes/agent.tsx +5 -0
  184. package/corpus/templates/crm/app/routes/ask.tsx +53 -0
  185. package/corpus/templates/crm/app/routes/dashboard.tsx +118 -0
  186. package/corpus/templates/crm/app/routes/opportunities.tsx +41 -0
  187. package/corpus/templates/crm/app/routes/people.tsx +41 -0
  188. package/corpus/templates/crm/app/routes/proposals.tsx +266 -0
  189. package/corpus/templates/crm/app/routes/records.$recordId.tsx +35 -0
  190. package/corpus/templates/crm/app/routes/settings.tsx +63 -0
  191. package/corpus/templates/crm/app/routes/setup.tsx +308 -0
  192. package/corpus/templates/crm/app/routes/tasks.tsx +252 -0
  193. package/corpus/templates/crm/app/routes/views.tsx +333 -0
  194. package/corpus/templates/crm/app/routes.ts +17 -0
  195. package/corpus/templates/crm/app/vite-env.d.ts +6 -0
  196. package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +6 -0
  197. package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +6 -0
  198. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +6 -0
  199. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +6 -0
  200. package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +6 -0
  201. package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +6 -0
  202. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +6 -0
  203. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +6 -0
  204. package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +6 -0
  205. package/corpus/templates/crm/components.json +20 -0
  206. package/corpus/templates/crm/docs/architecture/crm-contract.md +180 -0
  207. package/corpus/templates/crm/learnings.defaults.md +5 -0
  208. package/corpus/templates/crm/package.json +59 -0
  209. package/corpus/templates/crm/public/favicon.svg +1 -0
  210. package/corpus/templates/crm/public/icon-180.svg +1 -0
  211. package/corpus/templates/crm/public/manifest.json +11 -0
  212. package/corpus/templates/crm/react-router.config.ts +7 -0
  213. package/corpus/templates/crm/server/crm/adapter.ts +32 -0
  214. package/corpus/templates/crm/server/crm/crm-field-firewall.ts +64 -0
  215. package/corpus/templates/crm/server/crm/crm-mirror.ts +711 -0
  216. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +1143 -0
  217. package/corpus/templates/crm/server/crm/native-adapter.ts +1715 -0
  218. package/corpus/templates/crm/server/crm/read-through.ts +207 -0
  219. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +1255 -0
  220. package/corpus/templates/crm/server/db/crm-store.ts +1170 -0
  221. package/corpus/templates/crm/server/db/index.ts +169 -0
  222. package/corpus/templates/crm/server/db/schema.ts +441 -0
  223. package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +65 -0
  224. package/corpus/templates/crm/server/lib/intelligence/evidence.ts +105 -0
  225. package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +100 -0
  226. package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +144 -0
  227. package/corpus/templates/crm/server/lib/intelligence/summary.ts +141 -0
  228. package/corpus/templates/crm/server/lib/provider-api.ts +64 -0
  229. package/corpus/templates/crm/server/middleware/auth.ts +4 -0
  230. package/corpus/templates/crm/server/plugins/agent-chat.ts +68 -0
  231. package/corpus/templates/crm/server/plugins/auth.ts +14 -0
  232. package/corpus/templates/crm/server/plugins/core-routes.ts +17 -0
  233. package/corpus/templates/crm/server/plugins/db.ts +454 -0
  234. package/corpus/templates/crm/server/routes/[...page].get.ts +5 -0
  235. package/corpus/templates/crm/shared/crm-automation-recipes.ts +132 -0
  236. package/corpus/templates/crm/shared/crm-contract.ts +254 -0
  237. package/corpus/templates/crm/shared/crm-sales-config.ts +63 -0
  238. package/corpus/templates/crm/ssr-entry.ts +11 -0
  239. package/corpus/templates/crm/tsconfig.json +24 -0
  240. package/corpus/templates/crm/vite.config.ts +15 -0
  241. package/corpus/templates/crm/vitest.config.ts +5 -0
  242. package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +115 -0
  243. package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +115 -0
  244. package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +115 -0
  245. package/corpus/templates/forms/_gitignore +39 -0
  246. package/corpus/templates/forms/learnings.defaults.md +5 -0
  247. package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +115 -0
  248. package/corpus/templates/macros/_gitignore +39 -0
  249. package/corpus/templates/macros/learnings.defaults.md +5 -0
  250. package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +115 -0
  251. package/corpus/templates/mail/_gitignore +39 -0
  252. package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +115 -0
  253. package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +115 -0
  254. package/corpus/templates/slides/_gitignore +39 -0
  255. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +27 -0
  256. package/corpus/templates/tasks/_gitignore +39 -0
  257. package/corpus/toolkit/CHANGELOG.md +12 -0
  258. package/corpus/toolkit/README.md +30 -0
  259. package/corpus/toolkit/agent-native.eject.json +33 -0
  260. package/corpus/toolkit/package.json +15 -1
  261. package/corpus/toolkit/src/dashboard/DataTable.tsx +273 -0
  262. package/corpus/toolkit/src/dashboard/DateRangePicker.tsx +57 -0
  263. package/corpus/toolkit/src/dashboard/GenericChartPanel.tsx +461 -0
  264. package/corpus/toolkit/src/dashboard/MetricCard.tsx +54 -0
  265. package/corpus/toolkit/src/dashboard/StatsCard.tsx +49 -0
  266. package/corpus/toolkit/src/dashboard/dashboard-layout.ts +329 -0
  267. package/corpus/toolkit/src/dashboard/index.ts +6 -0
  268. package/corpus/toolkit/src/index.ts +1 -0
  269. package/corpus/toolkit/src/ui/calendar.tsx +8 -8
  270. package/corpus/toolkit/src/ui/date-picker.tsx +4 -1
  271. package/dist/action.d.ts +14 -1
  272. package/dist/action.d.ts.map +1 -1
  273. package/dist/action.js.map +1 -1
  274. package/dist/agent/production-agent.d.ts +3 -1
  275. package/dist/agent/production-agent.d.ts.map +1 -1
  276. package/dist/agent/production-agent.js +83 -3
  277. package/dist/agent/production-agent.js.map +1 -1
  278. package/dist/cli/templates-meta.d.ts.map +1 -1
  279. package/dist/cli/templates-meta.js +12 -0
  280. package/dist/cli/templates-meta.js.map +1 -1
  281. package/dist/client/AssistantChat.d.ts +4 -0
  282. package/dist/client/AssistantChat.d.ts.map +1 -1
  283. package/dist/client/AssistantChat.js +30 -17
  284. package/dist/client/AssistantChat.js.map +1 -1
  285. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
  286. package/dist/client/agent-page/AgentJobsTab.js +3 -1
  287. package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
  288. package/dist/client/agent-page/use-jobs.d.ts +1 -0
  289. package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
  290. package/dist/client/agent-page/use-jobs.js.map +1 -1
  291. package/dist/client/chat/message-components.d.ts +5 -0
  292. package/dist/client/chat/message-components.d.ts.map +1 -1
  293. package/dist/client/chat/message-components.js +17 -1
  294. package/dist/client/chat/message-components.js.map +1 -1
  295. package/dist/client/chat/tool-call-display.d.ts +3 -1
  296. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  297. package/dist/client/chat/tool-call-display.js +17 -7
  298. package/dist/client/chat/tool-call-display.js.map +1 -1
  299. package/dist/collab/awareness.d.ts +2 -2
  300. package/dist/collab/awareness.d.ts.map +1 -1
  301. package/dist/collab/routes.d.ts +1 -1
  302. package/dist/collab/struct-routes.d.ts +1 -1
  303. package/dist/connections/catalog.d.ts +17 -3
  304. package/dist/connections/catalog.d.ts.map +1 -1
  305. package/dist/connections/catalog.js +16 -1
  306. package/dist/connections/catalog.js.map +1 -1
  307. package/dist/connections/reader.d.ts +18 -0
  308. package/dist/connections/reader.d.ts.map +1 -1
  309. package/dist/connections/reader.js +41 -0
  310. package/dist/connections/reader.js.map +1 -1
  311. package/dist/dashboard-storage/index.d.ts +4 -0
  312. package/dist/dashboard-storage/index.d.ts.map +1 -0
  313. package/dist/dashboard-storage/index.js +4 -0
  314. package/dist/dashboard-storage/index.js.map +1 -0
  315. package/dist/dashboard-storage/panel-source.d.ts +68 -0
  316. package/dist/dashboard-storage/panel-source.d.ts.map +1 -0
  317. package/dist/dashboard-storage/panel-source.js +76 -0
  318. package/dist/dashboard-storage/panel-source.js.map +1 -0
  319. package/dist/dashboard-storage/schema.d.ts +562 -0
  320. package/dist/dashboard-storage/schema.d.ts.map +1 -0
  321. package/dist/dashboard-storage/schema.js +32 -0
  322. package/dist/dashboard-storage/schema.js.map +1 -0
  323. package/dist/dashboard-storage/store.d.ts +62 -0
  324. package/dist/dashboard-storage/store.d.ts.map +1 -0
  325. package/dist/dashboard-storage/store.js +227 -0
  326. package/dist/dashboard-storage/store.js.map +1 -0
  327. package/dist/deploy/build.d.ts +7 -0
  328. package/dist/deploy/build.d.ts.map +1 -1
  329. package/dist/deploy/build.js +78 -14
  330. package/dist/deploy/build.js.map +1 -1
  331. package/dist/eject/provider-api-definitions.d.ts +2 -1
  332. package/dist/eject/provider-api-definitions.d.ts.map +1 -1
  333. package/dist/eject/provider-api-definitions.js +1 -0
  334. package/dist/eject/provider-api-definitions.js.map +1 -1
  335. package/dist/eject/workspace-connections.d.ts.map +1 -1
  336. package/dist/eject/workspace-connections.js +1 -0
  337. package/dist/eject/workspace-connections.js.map +1 -1
  338. package/dist/extensions/actions.d.ts.map +1 -1
  339. package/dist/extensions/actions.js +165 -67
  340. package/dist/extensions/actions.js.map +1 -1
  341. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  342. package/dist/jobs/actions/list-recurring-jobs.d.ts +1 -0
  343. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
  344. package/dist/jobs/actions/list-recurring-jobs.js +1 -0
  345. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
  346. package/dist/jobs/scheduler.d.ts +17 -2
  347. package/dist/jobs/scheduler.d.ts.map +1 -1
  348. package/dist/jobs/scheduler.js +51 -2
  349. package/dist/jobs/scheduler.js.map +1 -1
  350. package/dist/jobs/tools.d.ts.map +1 -1
  351. package/dist/jobs/tools.js +32 -2
  352. package/dist/jobs/tools.js.map +1 -1
  353. package/dist/localization/default-messages.d.ts +1 -0
  354. package/dist/localization/default-messages.d.ts.map +1 -1
  355. package/dist/localization/default-messages.js +1 -0
  356. package/dist/localization/default-messages.js.map +1 -1
  357. package/dist/mcp-client/index.d.ts +2 -0
  358. package/dist/mcp-client/index.d.ts.map +1 -1
  359. package/dist/mcp-client/index.js +5 -0
  360. package/dist/mcp-client/index.js.map +1 -1
  361. package/dist/observability/routes.d.ts +1 -1
  362. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  363. package/dist/provider-api/actions/provider-api.d.ts +8 -6
  364. package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
  365. package/dist/provider-api/actions/provider-api.js +1 -1
  366. package/dist/provider-api/actions/provider-api.js.map +1 -1
  367. package/dist/provider-api/index.d.ts +11 -7
  368. package/dist/provider-api/index.d.ts.map +1 -1
  369. package/dist/provider-api/index.js +143 -5
  370. package/dist/provider-api/index.js.map +1 -1
  371. package/dist/resources/handlers.d.ts +1 -1
  372. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  373. package/dist/secrets/register-framework-secrets.js +7 -0
  374. package/dist/secrets/register-framework-secrets.js.map +1 -1
  375. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  376. package/dist/server/agent-chat/context-tools.js +9 -0
  377. package/dist/server/agent-chat/context-tools.js.map +1 -1
  378. package/dist/server/agent-chat/framework-prompts.js +2 -2
  379. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  380. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  381. package/dist/server/agent-chat-plugin.js +18 -2
  382. package/dist/server/agent-chat-plugin.js.map +1 -1
  383. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  384. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  385. package/dist/server/core-routes-plugin.js +1 -0
  386. package/dist/server/core-routes-plugin.js.map +1 -1
  387. package/dist/server/credential-provider.d.ts +4 -3
  388. package/dist/server/credential-provider.d.ts.map +1 -1
  389. package/dist/server/credential-provider.js +9 -3
  390. package/dist/server/credential-provider.js.map +1 -1
  391. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  392. package/dist/server/workspace-provider-oauth.d.ts.map +1 -1
  393. package/dist/server/workspace-provider-oauth.js +141 -4
  394. package/dist/server/workspace-provider-oauth.js.map +1 -1
  395. package/dist/styles/agent-native.css +45 -2
  396. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
  397. package/dist/templates/chat/AGENTS.md +1 -1
  398. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
  399. package/dist/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
  400. package/dist/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
  401. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
  402. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
  403. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
  404. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
  405. package/dist/triggers/actions.d.ts.map +1 -1
  406. package/dist/triggers/actions.js +10 -2
  407. package/dist/triggers/actions.js.map +1 -1
  408. package/dist/triggers/dispatcher.d.ts.map +1 -1
  409. package/dist/triggers/dispatcher.js +15 -0
  410. package/dist/triggers/dispatcher.js.map +1 -1
  411. package/dist/triggers/types.d.ts +5 -0
  412. package/dist/triggers/types.d.ts.map +1 -1
  413. package/dist/triggers/types.js.map +1 -1
  414. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  415. package/dist/vite/action-types-plugin.js +4 -1
  416. package/dist/vite/action-types-plugin.js.map +1 -1
  417. package/docs/content/agent-native-toolkit.mdx +16 -0
  418. package/docs/content/recurring-jobs.mdx +35 -6
  419. package/package.json +6 -2
  420. package/src/action.ts +22 -1
  421. package/src/agent/production-agent.ts +105 -3
  422. package/src/cli/templates-meta.ts +12 -0
  423. package/src/client/AssistantChat.tsx +53 -26
  424. package/src/client/agent-page/AgentJobsTab.tsx +19 -0
  425. package/src/client/agent-page/use-jobs.ts +1 -0
  426. package/src/client/chat/message-components.tsx +35 -1
  427. package/src/client/chat/tool-call-display.tsx +38 -3
  428. package/src/connections/catalog.ts +20 -1
  429. package/src/connections/reader.ts +65 -0
  430. package/src/dashboard-storage/index.ts +27 -0
  431. package/src/dashboard-storage/panel-source.ts +168 -0
  432. package/src/dashboard-storage/schema.ts +62 -0
  433. package/src/dashboard-storage/store.ts +333 -0
  434. package/src/deploy/build.ts +95 -16
  435. package/src/eject/provider-api-definitions.ts +1 -0
  436. package/src/eject/workspace-connections.ts +1 -0
  437. package/src/extensions/actions.ts +199 -73
  438. package/src/jobs/actions/list-recurring-jobs.ts +2 -0
  439. package/src/jobs/scheduler.ts +71 -4
  440. package/src/jobs/tools.ts +31 -1
  441. package/src/localization/default-messages.ts +1 -0
  442. package/src/mcp-client/index.ts +6 -0
  443. package/src/provider-api/actions/provider-api.ts +1 -1
  444. package/src/provider-api/index.ts +190 -5
  445. package/src/secrets/register-framework-secrets.ts +8 -0
  446. package/src/server/agent-chat/context-tools.ts +9 -0
  447. package/src/server/agent-chat/framework-prompts.ts +2 -2
  448. package/src/server/agent-chat-plugin.ts +22 -2
  449. package/src/server/core-routes-plugin.ts +1 -0
  450. package/src/server/credential-provider.ts +9 -3
  451. package/src/server/workspace-provider-oauth.ts +181 -4
  452. package/src/styles/agent-native.css +45 -2
  453. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
  454. package/src/templates/chat/AGENTS.md +1 -1
  455. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
  456. package/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
  457. package/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
  458. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
  459. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
  460. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
  461. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
  462. package/src/triggers/actions.ts +11 -2
  463. package/src/triggers/dispatcher.ts +20 -1
  464. package/src/triggers/types.ts +5 -0
  465. package/src/vite/action-types-plugin.ts +9 -1
  466. package/corpus/templates/analytics/server/handlers/sql-query.ts +0 -36
  467. package/corpus/templates/analytics/server/routes/api/sql-query.post.ts +0 -1
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: agent-native-docs
3
+ description: >-
4
+ How to find version-matched Agent Native framework docs and source bundled in
5
+ node_modules. Use before implementing or answering questions about
6
+ @agent-native/core APIs, generated apps, workspaces, templates, or advanced
7
+ features.
8
+ scope: dev
9
+ metadata:
10
+ internal: true
11
+ ---
12
+
13
+ # Agent Native Docs Lookup
14
+
15
+ ## Rule
16
+
17
+ Before implementing or explaining non-trivial Agent Native behavior, read the
18
+ version-matched docs installed with `@agent-native/core`. When examples,
19
+ imports, or implementation details matter, inspect the packaged source corpus
20
+ too.
21
+
22
+ ## Why
23
+
24
+ Generated apps and workspaces may be on a different framework version than the
25
+ public docs or model memory. The installed package is the source that matches
26
+ the app in front of you. It also includes a source-only corpus of core and
27
+ first-party templates so agents can replicate current best-practice patterns
28
+ without needing the framework monorepo checkout.
29
+
30
+ ## How
31
+
32
+ From a generated app directory:
33
+
34
+ ```bash
35
+ pnpm action docs-search --query "<feature>"
36
+ pnpm action docs-search --slug <slug>
37
+ pnpm action docs-search --list
38
+ pnpm action source-search --query "<pattern>"
39
+ pnpm action source-search --path templates/plan/AGENTS.md
40
+ pnpm action source-search --path toolkit/src/index.ts
41
+ pnpm action source-search --list
42
+ ```
43
+
44
+ The headless `pnpm agent` loop and built-in app agent also expose a read-only
45
+ `docs-search` tool with the same `query`, `slug`, and `list` options, plus a
46
+ read-only `source-search` tool with `query`, `path`, and `list`.
47
+
48
+ If the action runner is unavailable, search the package directly:
49
+
50
+ ```bash
51
+ rg -n "actions|automations|a2a|sharing" node_modules/@agent-native/core/docs
52
+ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
53
+ ```
54
+
55
+ Then read `node_modules/@agent-native/core/docs/AGENTS.md` or the matching file
56
+ under `node_modules/@agent-native/core/docs/content/`. For source examples,
57
+ read files under `node_modules/@agent-native/core/corpus/core/` or
58
+ `node_modules/@agent-native/core/corpus/templates/`.
59
+
60
+ Toolkit source is searchable at `toolkit/` in the Core corpus and also ships as
61
+ readable TypeScript under `node_modules/@agent-native/toolkit/src/`. Read
62
+ `customizing-agent-native` before taking ownership of a shared component: inspect package
63
+ source as a read-only reference, then configure, compose, or eject the smallest
64
+ supported unit into app-owned source. Preserve public actions, application
65
+ state, auth, and agent-chat runtime contracts. Never edit `node_modules` or
66
+ deep-import its private source. Manual copying is only the fallback described by
67
+ an unknown third-party package's add-style blueprint.
68
+
69
+ ## Reuse Proven Patterns (rg + cp)
70
+
71
+ Version-matched installed source outranks web docs or memory: it is the exact
72
+ code shipping with this app. `node_modules/@agent-native/core/corpus/templates/`
73
+ holds source for every first-party template, not just the one this app started
74
+ from, so a pattern from the mail template is fair game for a tasks app. Grep
75
+ across it, then copy a whole file as a starting point instead of writing the
76
+ pattern from scratch:
77
+
78
+ ```bash
79
+ # Find how other templates solved a similar problem
80
+ rg -n "drag.*drop|reorder" node_modules/@agent-native/core/corpus/templates
81
+
82
+ # Grab a proven action file as a starting point, then adapt names/schema
83
+ cp node_modules/@agent-native/core/corpus/templates/mail/actions/archive-email.ts \
84
+ actions/archive-item.ts
85
+
86
+ # Read the full framework source behind an API, not just the corpus copy
87
+ rg -n "defineAction" node_modules/@agent-native/core/src/action.ts
88
+ ```
89
+
90
+ Copying template-level app code (actions, components, skill files) is the
91
+ expected reuse path — templates exist to be forked. This is different from
92
+ copying `core`/`toolkit` **runtime internals**: for those, follow
93
+ `customizing-agent-native`'s configure/compose/eject ladder instead of
94
+ hand-duplicating framework logic.
95
+
96
+ ## Useful Slugs
97
+
98
+ | Need | Slugs |
99
+ | ------------------------------ | ------------------------------------------------------------- |
100
+ | Actions and typed client calls | `actions`, `client` |
101
+ | SQL, auth, access, sharing | `database`, `authentication`, `security`, `sharing` |
102
+ | UI state visible to the agent | `context-awareness` |
103
+ | Headless and chat-first apps | `pure-agent-apps`, `agent-surfaces`, `using-your-agent` |
104
+ | Automations and schedules | `automations`, `recurring-jobs` |
105
+ | Cross-app and external agents | `a2a-protocol`, `external-agents`, `mcp-protocol`, `mcp-apps` |
106
+ | Skills and instructions | `skills-guide`, `writing-agent-instructions` |
107
+
108
+ ## Don't
109
+
110
+ - Do not rely on memory for framework APIs when package docs are present.
111
+ - Do not add custom REST wrappers for app data before reading `actions`.
112
+ - Do not add inline LLM calls before reading `using-your-agent` and
113
+ `agent-surfaces`.
114
+ - Do not copy framework runtime internals when a public API or narrow UI copy
115
+ will do; read `customizing-agent-native` for the supported override ladder.
@@ -21,6 +21,13 @@ ladder.
21
21
  - Never hardcode API keys, tokens, webhook URLs, signing secrets, private Builder/internal data, customer data, or credential-looking literals. Use secrets/OAuth/runtime configuration and obvious placeholders in examples.
22
22
  - Use actions for recording metadata, transcripts, cleanup, summaries, chapters,
23
23
  comments, spaces/folders, meetings, and sharing. Do not bypass access helpers.
24
+ - Use `prepare-crm-call-evidence` only for a viewer-accessible recording
25
+ explicitly identified by a user action or the exact approved CRM A2A recipe.
26
+ It returns an opaque clip ID, durable HTTPS `/r/<id>` page, and optional
27
+ capture time for CRM; it never returns the event media URL, a transcript,
28
+ temporary token, quote, or summary. A CRM recipe may install a Clips-owned
29
+ `clip.created` trigger only through an exact user-approved A2A automation
30
+ definition.
24
31
  - Organization admins can use `set-organization-branding` with
25
32
  `defaultVisibility=public|org|private` to choose the visibility applied when
26
33
  new recordings omit an explicit visibility. The default remains `public`, and
@@ -0,0 +1,58 @@
1
+ import { defineAction } from "@agent-native/core/action";
2
+ import { getRequestContext } from "@agent-native/core/server";
3
+ import { assertAccess } from "@agent-native/core/sharing";
4
+ import { z } from "zod";
5
+
6
+ import { getServerAppBasePath } from "../server/lib/public-agent-context.js";
7
+
8
+ function clipsOrigin(): string {
9
+ const raw = getRequestContext()?.requestOrigin || process.env.APP_URL;
10
+ if (!raw) {
11
+ throw new Error(
12
+ "Clips needs an HTTPS APP_URL before it can prepare CRM evidence links.",
13
+ );
14
+ }
15
+ let url: URL;
16
+ try {
17
+ url = new URL(raw);
18
+ } catch {
19
+ throw new Error(
20
+ "Clips needs a valid HTTPS APP_URL before it can prepare CRM evidence links.",
21
+ );
22
+ }
23
+ if (url.protocol !== "https:") {
24
+ throw new Error(
25
+ "Clips needs an HTTPS APP_URL before it can prepare CRM evidence links.",
26
+ );
27
+ }
28
+ return url.origin;
29
+ }
30
+
31
+ export default defineAction({
32
+ description:
33
+ "Prepare one access-gated Clips recording as bounded CRM call evidence. Returns only an opaque recording id, durable HTTPS recording page, and optional capture time; never media, a transcript, or a temporary access token.",
34
+ schema: z.object({
35
+ recordingId: z.string().trim().min(1).max(256),
36
+ }),
37
+ readOnly: true,
38
+ run: async ({ recordingId }) => {
39
+ const access = await assertAccess("recording", recordingId, "viewer");
40
+ const recording = access.resource as {
41
+ id: string;
42
+ createdAt?: string | null;
43
+ archivedAt?: string | null;
44
+ trashedAt?: string | null;
45
+ };
46
+ if (recording.archivedAt || recording.trashedAt) {
47
+ throw new Error("Archived or trashed Clips cannot be attached to CRM.");
48
+ }
49
+ const sourceUrl = `${clipsOrigin()}${getServerAppBasePath()}/r/${encodeURIComponent(recording.id)}`;
50
+ return {
51
+ sourceApp: "clips" as const,
52
+ artifactType: "call-evidence" as const,
53
+ artifactId: recording.id,
54
+ sourceUrl,
55
+ ...(recording.createdAt ? { capturedAt: recording.createdAt } : {}),
56
+ };
57
+ },
58
+ });
@@ -27,6 +27,8 @@ export interface BulkMoveTarget {
27
27
 
28
28
  interface BulkActionToolbarProps {
29
29
  count: number;
30
+ allSelected?: boolean;
31
+ onSelectAll?: () => void;
30
32
  onArchive?: () => void;
31
33
  onMove?: (folderId: string | null) => void;
32
34
  onTrash?: () => void;
@@ -38,6 +40,8 @@ interface BulkActionToolbarProps {
38
40
 
39
41
  export function BulkActionToolbar({
40
42
  count,
43
+ allSelected = false,
44
+ onSelectAll,
41
45
  onArchive,
42
46
  onMove,
43
47
  onTrash,
@@ -53,17 +57,30 @@ export function BulkActionToolbar({
53
57
  return (
54
58
  <div
55
59
  className={cn(
56
- "flex w-fit max-w-full items-center gap-1 rounded-xl border border-border bg-popover px-3 py-2 shadow-lg",
60
+ "flex w-fit max-w-full items-center gap-1 rounded-xl bg-foreground px-3 py-2 text-background shadow-2xl ring-1 ring-black/10 dark:ring-white/10",
57
61
  )}
58
62
  >
59
- <span className="pe-2 text-xs font-medium text-foreground">
63
+ <span className="pe-2 text-xs font-medium">
60
64
  {t("clipsFinalRaw.selectedCount", { count })}
61
65
  </span>
62
- <div className="h-4 w-px bg-border" />
66
+ {onSelectAll && (
67
+ <Button
68
+ variant="ghost"
69
+ size="sm"
70
+ className="h-8 gap-1.5 text-background hover:bg-background/15 hover:text-background"
71
+ onClick={onSelectAll}
72
+ disabled={isPending}
73
+ >
74
+ {allSelected
75
+ ? t("clipsFinalRaw.deselectAll")
76
+ : t("clipsFinalRaw.selectAll")}
77
+ </Button>
78
+ )}
79
+ <div className="h-4 w-px bg-background/20" />
63
80
  <Button
64
81
  variant="ghost"
65
82
  size="sm"
66
- className="h-8 gap-1.5"
83
+ className="h-8 gap-1.5 text-background hover:bg-background/15 hover:text-background"
67
84
  onClick={onArchive}
68
85
  disabled={isPending}
69
86
  >
@@ -75,7 +92,7 @@ export function BulkActionToolbar({
75
92
  <Button
76
93
  variant="ghost"
77
94
  size="sm"
78
- className="h-8 gap-1.5"
95
+ className="h-8 gap-1.5 text-background hover:bg-background/15 hover:text-background"
79
96
  disabled={isPending}
80
97
  >
81
98
  <IconFolder className="h-3.5 w-3.5" /> {t("clipsFinalRaw.move")}
@@ -121,17 +138,17 @@ export function BulkActionToolbar({
121
138
  <Button
122
139
  variant="ghost"
123
140
  size="sm"
124
- className="h-8 gap-1.5 text-destructive hover:text-destructive"
141
+ className="h-8 gap-1.5 text-red-400 hover:bg-background/15 hover:text-red-400"
125
142
  onClick={onTrash}
126
143
  disabled={isPending}
127
144
  >
128
145
  <IconTrash className="h-3.5 w-3.5" /> {t("navigation.trash")}
129
146
  </Button>
130
- <div className="h-4 w-px bg-border mx-1" />
147
+ <div className="mx-1 h-4 w-px bg-background/20" />
131
148
  <button
132
149
  type="button"
133
150
  onClick={onClear}
134
- className="rounded p-1 text-muted-foreground hover:bg-accent"
151
+ className="rounded p-1 text-background/70 hover:bg-background/15 hover:text-background"
135
152
  aria-label={t("clipsFinalRaw.clearSelection")}
136
153
  >
137
154
  <IconX className="h-3.5 w-3.5" />
@@ -3,8 +3,12 @@ import {
3
3
  setClientAppState,
4
4
  } from "@agent-native/core/client/hooks";
5
5
  import { useT } from "@agent-native/core/client/i18n";
6
- import { IconAlertTriangle } from "@tabler/icons-react";
7
- import { useEffect, useMemo, useState } from "react";
6
+ import {
7
+ IconAlertTriangle,
8
+ IconChevronLeft,
9
+ IconChevronRight,
10
+ } from "@tabler/icons-react";
11
+ import { useCallback, useEffect, useMemo, useState } from "react";
8
12
  import { toast } from "sonner";
9
13
 
10
14
  import { CreateFolderDialog } from "@/components/library/create-folder-dialog";
@@ -13,6 +17,7 @@ import { Button } from "@/components/ui/button";
13
17
  import {
14
18
  useFolders,
15
19
  useRecordings,
20
+ useRecordingsCount,
16
21
  useTrashRecording,
17
22
  useArchiveRecording,
18
23
  useRestoreRecording,
@@ -54,6 +59,8 @@ function Skeleton() {
54
59
  );
55
60
  }
56
61
 
62
+ const PAGE_SIZE = 100;
63
+
57
64
  interface FolderTargetRow {
58
65
  id: string;
59
66
  parentId: string | null;
@@ -105,13 +112,38 @@ export function LibraryGrid({
105
112
  const t = useT();
106
113
  const [sort, setSort] = useState<SortKey>("recent");
107
114
  const [selected, setSelected] = useState<Set<string>>(new Set());
115
+ const [lastSelectedId, setLastSelectedId] = useState<string | null>(null);
108
116
  const selectionMode = selected.size > 0;
109
117
  const [sharingRec, setSharingRec] = useState<RecordingSummary | null>(null);
110
118
  const [createFolderTarget, setCreateFolderTarget] =
111
119
  useState<CreateFolderTarget | null>(null);
112
120
  const [isBulkPending, setIsBulkPending] = useState(false);
121
+ const [page, setPage] = useState(1);
113
122
  const selectionStateKey = useMemo(() => `selection:${getBrowserTabId()}`, []);
114
123
 
124
+ useEffect(() => {
125
+ setPage(1);
126
+ setSelected(new Set());
127
+ setLastSelectedId(null);
128
+ }, [view, folderId, spaceId, tagFilter, sort]);
129
+
130
+ const countArgs = useMemo(
131
+ () => ({
132
+ view,
133
+ folderId: folderId ?? null,
134
+ spaceId: spaceId ?? null,
135
+ tag: tagFilter ?? null,
136
+ }),
137
+ [view, folderId, spaceId, tagFilter],
138
+ );
139
+ const { data: totalCount } = useRecordingsCount(countArgs);
140
+ const total = totalCount ?? 0;
141
+ const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));
142
+
143
+ useEffect(() => {
144
+ if (page > totalPages) setPage(totalPages);
145
+ }, [page, totalPages]);
146
+
115
147
  const args: ListRecordingsArgs = useMemo(
116
148
  () => ({
117
149
  view,
@@ -119,8 +151,10 @@ export function LibraryGrid({
119
151
  spaceId: spaceId ?? null,
120
152
  tag: tagFilter ?? null,
121
153
  sort,
154
+ limit: PAGE_SIZE,
155
+ offset: (page - 1) * PAGE_SIZE,
122
156
  }),
123
- [view, folderId, spaceId, tagFilter, sort],
157
+ [view, folderId, spaceId, tagFilter, sort, page],
124
158
  );
125
159
 
126
160
  const { data, isLoading, isError, refetch, isRefetching } =
@@ -189,17 +223,53 @@ export function LibraryGrid({
189
223
  };
190
224
  }, [selectionStateKey]);
191
225
 
192
- const toggleSelect = (id: string) => {
226
+ const handleToggleSelect = useCallback(
227
+ (id: string, shiftKey = false) => {
228
+ setSelected((prev) => {
229
+ if (shiftKey && lastSelectedId && lastSelectedId !== id) {
230
+ const ids = recordings.map((r) => r.id);
231
+ const fromIndex = ids.indexOf(lastSelectedId);
232
+ const toIndex = ids.indexOf(id);
233
+ if (fromIndex !== -1 && toIndex !== -1) {
234
+ const [start, end] =
235
+ fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
236
+ const next = new Set(prev);
237
+ for (let i = start; i <= end; i++) next.add(ids[i]);
238
+ return next;
239
+ }
240
+ }
241
+ const next = new Set(prev);
242
+ if (next.has(id)) next.delete(id);
243
+ else next.add(id);
244
+ return next;
245
+ });
246
+ setLastSelectedId(id);
247
+ },
248
+ [lastSelectedId, recordings],
249
+ );
250
+
251
+ const allSelected =
252
+ recordings.length > 0 && recordings.every(({ id }) => selected.has(id));
253
+
254
+ const toggleSelectAll = useCallback(() => {
193
255
  setSelected((prev) => {
194
256
  const next = new Set(prev);
195
- if (next.has(id)) next.delete(id);
196
- else next.add(id);
257
+ const visibleIds = recordings.map(({ id }) => id);
258
+ const allVisibleSelected = visibleIds.every((id) => prev.has(id));
259
+
260
+ for (const id of visibleIds) {
261
+ if (allVisibleSelected) next.delete(id);
262
+ else next.add(id);
263
+ }
264
+
197
265
  return next;
198
266
  });
199
- };
267
+ setLastSelectedId(null);
268
+ }, [recordings]);
200
269
 
201
270
  const clearSelection = () => {
202
271
  setSelected(new Set());
272
+ setLastSelectedId(null);
203
273
  };
204
274
 
205
275
  const moveRecordings = async (
@@ -321,7 +391,7 @@ export function LibraryGrid({
321
391
  )}
322
392
 
323
393
  {/* Grid body */}
324
- <div className="relative flex min-h-0 flex-1 overflow-hidden">
394
+ <div className="relative flex min-h-0 flex-1 flex-col overflow-hidden">
325
395
  <div
326
396
  className={cn(
327
397
  "min-h-0 flex-1 overflow-y-auto",
@@ -371,7 +441,7 @@ export function LibraryGrid({
371
441
  }
372
442
  selectionMode={canManageRecordings && selectionMode}
373
443
  onToggleSelect={
374
- canManageRecordings ? toggleSelect : undefined
444
+ canManageRecordings ? handleToggleSelect : undefined
375
445
  }
376
446
  onShare={(rec) => setSharingRec(rec)}
377
447
  moveTargets={moveTargets}
@@ -426,12 +496,51 @@ export function LibraryGrid({
426
496
  </div>
427
497
  </div>
428
498
 
499
+ {!isLoading && recordings.length > 0 && totalPages > 1 && (
500
+ <div className="flex shrink-0 items-center justify-between gap-3 border-t border-border px-5 py-2.5">
501
+ <span className="text-xs text-muted-foreground">
502
+ {t("libraryGrid.paginationRange", {
503
+ start: (page - 1) * PAGE_SIZE + 1,
504
+ end: (page - 1) * PAGE_SIZE + recordings.length,
505
+ total,
506
+ })}
507
+ </span>
508
+ <div className="flex items-center gap-2">
509
+ <Button
510
+ variant="outline"
511
+ size="sm"
512
+ className="gap-1"
513
+ onClick={() => setPage((p) => Math.max(1, p - 1))}
514
+ disabled={page <= 1}
515
+ >
516
+ <IconChevronLeft className="h-3.5 w-3.5" />
517
+ {t("libraryGrid.paginationPrevious")}
518
+ </Button>
519
+ <span className="text-xs text-muted-foreground">
520
+ {t("libraryGrid.paginationPage", { page, totalPages })}
521
+ </span>
522
+ <Button
523
+ variant="outline"
524
+ size="sm"
525
+ className="gap-1"
526
+ onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
527
+ disabled={page >= totalPages}
528
+ >
529
+ {t("libraryGrid.paginationNext")}
530
+ <IconChevronRight className="h-3.5 w-3.5" />
531
+ </Button>
532
+ </div>
533
+ </div>
534
+ )}
535
+
429
536
  {/* Keep selected-library actions visible while the recording list scrolls. */}
430
537
  {canManageRecordings && selected.size > 0 && (
431
538
  <div className="pointer-events-none absolute inset-x-0 bottom-0 z-30 flex justify-center px-4 pb-4">
432
539
  <div className="pointer-events-auto max-w-full overflow-x-auto">
433
540
  <BulkActionToolbar
434
541
  count={selected.size}
542
+ allSelected={allSelected}
543
+ onSelectAll={toggleSelectAll}
435
544
  moveTargets={moveTargets}
436
545
  onArchive={async () => {
437
546
  setIsBulkPending(true);
@@ -566,7 +566,7 @@ export function LibraryLayout({ children }: LibraryLayoutProps) {
566
566
  browserTabId={getBrowserTabId()}
567
567
  >
568
568
  {/* Main content area */}
569
- <div className="flex min-w-0 flex-1 flex-col">
569
+ <div className="flex min-h-0 min-w-0 flex-1 flex-col">
570
570
  {!pageOwnsToolbar && (
571
571
  <header className="flex shrink-0 items-center gap-3 border-b border-border px-5 py-3">
572
572
  <button
@@ -65,7 +65,7 @@ interface RecordingCardProps {
65
65
  recording: RecordingSummary;
66
66
  selected?: boolean;
67
67
  selectionMode?: boolean;
68
- onToggleSelect?: (id: string) => void;
68
+ onToggleSelect?: (id: string, shiftKey: boolean) => void;
69
69
  onShare?: (rec: RecordingSummary) => void;
70
70
  onMove?: (rec: RecordingSummary, folderId: string | null) => void;
71
71
  moveTargets?: BulkMoveTarget[];
@@ -147,18 +147,18 @@ export function RecordingCard({
147
147
  const handleLinkClick = useCallback(
148
148
  (event: React.MouseEvent<HTMLAnchorElement>) => {
149
149
  if (
150
- !selectionMode ||
150
+ !onToggleSelect ||
151
151
  event.button !== 0 ||
152
152
  event.metaKey ||
153
153
  event.ctrlKey ||
154
- event.shiftKey ||
155
- event.altKey
154
+ event.altKey ||
155
+ (!selectionMode && !event.shiftKey)
156
156
  ) {
157
157
  return;
158
158
  }
159
159
 
160
160
  event.preventDefault();
161
- onToggleSelect?.(recording.id);
161
+ onToggleSelect(recording.id, event.shiftKey);
162
162
  },
163
163
  [onToggleSelect, recording.id, selectionMode],
164
164
  );
@@ -166,7 +166,7 @@ export function RecordingCard({
166
166
  const handleCheckbox = useCallback(
167
167
  (e: React.MouseEvent) => {
168
168
  e.stopPropagation();
169
- onToggleSelect?.(recording.id);
169
+ onToggleSelect?.(recording.id, e.shiftKey);
170
170
  },
171
171
  [onToggleSelect, recording.id],
172
172
  );
@@ -243,8 +243,10 @@ export function RecordingCard({
243
243
  >
244
244
  <Checkbox
245
245
  checked={selected}
246
- onCheckedChange={() => onToggleSelect?.(recording.id)}
247
- onClick={(e) => e.stopPropagation()}
246
+ onClick={(e) => {
247
+ e.stopPropagation();
248
+ onToggleSelect?.(recording.id, e.shiftKey);
249
+ }}
248
250
  className="h-3.5 w-3.5"
249
251
  />
250
252
  </div>