@agent-native/core 0.117.2 → 0.118.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 (776) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +51 -0
  3. package/corpus/core/docs/content/custom-design-system.mdx +445 -0
  4. package/corpus/core/docs/content/toolkit-ui.mdx +16 -0
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/a2a/client.ts +32 -10
  7. package/corpus/core/src/a2a/types.ts +1 -0
  8. package/corpus/core/src/agent/types.ts +1 -1
  9. package/corpus/core/src/cli/index.ts +18 -10
  10. package/corpus/core/src/cli/multi-frontier-runs.ts +5 -3
  11. package/corpus/core/src/cli/templates-meta.ts +0 -12
  12. package/corpus/core/src/cli/workspace-dev.ts +1 -1
  13. package/corpus/core/src/client/AgentPanel.tsx +99 -108
  14. package/corpus/core/src/client/AssistantChat.tsx +30 -13
  15. package/corpus/core/src/client/CommandMenu.tsx +68 -178
  16. package/corpus/core/src/client/RunStuckBanner.tsx +39 -47
  17. package/corpus/core/src/client/agent-chat-adapter.ts +3 -1
  18. package/corpus/core/src/client/app-providers.tsx +1 -1
  19. package/corpus/core/src/client/chat/action-chat-ui-surface.tsx +32 -0
  20. package/corpus/core/src/client/chat/message-components.tsx +169 -18
  21. package/corpus/core/src/client/chat/tool-call-display.tsx +50 -14
  22. package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +13 -40
  23. package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
  24. package/corpus/core/src/client/components/ui/message-scroller.tsx +15 -1
  25. package/corpus/core/src/client/conversation/AgentConversation.tsx +12 -1
  26. package/corpus/core/src/client/error-capture.ts +2 -6
  27. package/corpus/core/src/client/i18n.tsx +22 -0
  28. package/corpus/core/src/client/index.ts +17 -0
  29. package/corpus/core/src/client/org/TeamPage.tsx +257 -153
  30. package/corpus/core/src/client/progress/RunsTray.tsx +89 -88
  31. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +25 -16
  32. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +34 -13
  33. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  34. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +20 -17
  35. package/corpus/core/src/client/resources/mcp-integration-logos.ts +2 -2
  36. package/corpus/core/src/client/route-chunk-recovery.ts +5 -3
  37. package/corpus/core/src/client/session-replay.ts +3 -3
  38. package/corpus/core/src/client/settings/DemoModeSection.tsx +6 -18
  39. package/corpus/core/src/client/settings/SecretsSection.tsx +97 -52
  40. package/corpus/core/src/client/settings/SettingsPanel.tsx +217 -252
  41. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +23 -2
  42. package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +7 -18
  43. package/corpus/core/src/client/settings/index.ts +7 -0
  44. package/corpus/core/src/client/settings/useSettingsPanelController.ts +155 -0
  45. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +116 -51
  46. package/corpus/core/src/client/setup-connections/index.ts +10 -0
  47. package/corpus/core/src/client/setup-connections/useBuilderConnectCardController.ts +82 -0
  48. package/corpus/core/src/client/sharing/ShareButton.tsx +64 -586
  49. package/corpus/core/src/client/sharing/ShareDialog.tsx +299 -633
  50. package/corpus/core/src/client/sharing/index.ts +42 -0
  51. package/corpus/core/src/client/sharing/share-controller-helpers.ts +318 -0
  52. package/corpus/core/src/client/sharing/useShareButtonController.ts +600 -0
  53. package/corpus/core/src/client/sharing/useShareDialogController.ts +559 -0
  54. package/corpus/core/src/client/sse-event-processor.ts +23 -0
  55. package/corpus/core/src/client/tool-display.ts +71 -0
  56. package/corpus/core/src/client/transcription/use-live-transcription.ts +64 -45
  57. package/corpus/core/src/client/use-agent-engine-configured.ts +12 -19
  58. package/corpus/core/src/client/use-chat-threads.ts +33 -12
  59. package/corpus/core/src/deploy/build.ts +2 -1
  60. package/corpus/core/src/guards/db-tool-scoping.ts +1 -1
  61. package/corpus/core/src/integrations/adapters/slack.ts +84 -5
  62. package/corpus/core/src/integrations/index.ts +5 -1
  63. package/corpus/core/src/localization/default-messages.ts +6 -1
  64. package/corpus/core/src/mcp-client/oauth-routes.ts +61 -14
  65. package/corpus/core/src/scripts/call-agent.ts +5 -1
  66. package/corpus/core/src/server/realtime-voice.ts +5 -2
  67. package/corpus/core/src/styles/agent-native.css +0 -24
  68. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  69. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  70. package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  71. package/corpus/core/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  72. package/corpus/core/src/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  73. package/corpus/core/src/templates/default/app/design-system.ts +3 -0
  74. package/corpus/core/src/templates/default/app/root.tsx +5 -2
  75. package/corpus/core/src/templates/default/package.json +1 -0
  76. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  77. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  78. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  79. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  80. package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  81. package/corpus/core/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  82. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  83. package/corpus/core/src/terminal/cli-registry.ts +1 -1
  84. package/corpus/core/src/vite/client.ts +205 -1
  85. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  86. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  87. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +22 -2
  88. package/corpus/templates/analytics/.agents/skills/shadcn-ui/SKILL.md +28 -4
  89. package/corpus/templates/analytics/app/components/ui/toolkit-provider.tsx +6 -1
  90. package/corpus/templates/analytics/app/design-system.ts +3 -0
  91. package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +13 -1
  92. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewsMenu.tsx +10 -0
  93. package/corpus/templates/analytics/changelog/2026-07-22-show-a-useful-error-when-saving-a-dashboard-view-fails.md +6 -0
  94. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  95. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  96. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +22 -2
  97. package/corpus/templates/assets/.agents/skills/shadcn-ui/SKILL.md +28 -4
  98. package/corpus/templates/assets/app/components/ui/alert.tsx +1 -0
  99. package/corpus/templates/assets/app/components/ui/toolkit-provider.tsx +6 -1
  100. package/corpus/templates/assets/app/design-system.ts +3 -0
  101. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +26 -30
  102. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  103. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  104. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +22 -2
  105. package/corpus/templates/brain/.agents/skills/shadcn-ui/SKILL.md +28 -4
  106. package/corpus/templates/brain/app/components/ui/dialog.tsx +1 -0
  107. package/corpus/templates/brain/app/components/ui/toolkit-provider.tsx +6 -1
  108. package/corpus/templates/brain/app/design-system.ts +3 -0
  109. package/corpus/templates/brain/app/routes/sources.tsx +189 -122
  110. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  111. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  112. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +22 -2
  113. package/corpus/templates/calendar/.agents/skills/shadcn-ui/SKILL.md +28 -4
  114. package/corpus/templates/calendar/app/components/ui/toolkit-provider.tsx +6 -1
  115. package/corpus/templates/calendar/app/design-system.ts +3 -0
  116. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  117. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  118. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  119. package/corpus/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  120. package/corpus/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  121. package/corpus/templates/chat/app/design-system.ts +3 -0
  122. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  123. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  124. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +22 -2
  125. package/corpus/templates/clips/.agents/skills/shadcn-ui/SKILL.md +28 -4
  126. package/corpus/templates/clips/AGENTS.md +8 -6
  127. package/corpus/templates/clips/actions/request-transcript.ts +90 -420
  128. package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -28
  129. package/corpus/templates/clips/app/components/capture-install-options.tsx +5 -3
  130. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +3 -136
  131. package/corpus/templates/clips/app/components/ui/toolkit-provider.tsx +6 -1
  132. package/corpus/templates/clips/app/design-system.ts +3 -0
  133. package/corpus/templates/clips/app/lib/capture-install-options.ts +15 -4
  134. package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
  135. package/corpus/templates/clips/app/routes/download.tsx +3 -2
  136. package/corpus/templates/clips/changelog/2026-07-22-fixed-an-intermittent-hydration-error-on-the-download-page.md +6 -0
  137. package/corpus/templates/clips/changelog/2026-07-22-fixed-transcript-generation-when-native-speech-capture-retur.md +6 -0
  138. package/corpus/templates/clips/changelog/2026-07-22-fixed-windows-recordings-aborting-during-the-countdown.md +6 -0
  139. package/corpus/templates/clips/changelog/2026-07-22-permissions-and-rewind-controls-are-now-grouped-with-clearer.md +6 -0
  140. package/corpus/templates/clips/changelog/2026-07-22-the-desktop-popover-opens-centered-under-the-menu-bar-icon-o.md +6 -0
  141. package/corpus/templates/clips/changelog/2026-07-22-transcript-generation-now-retries-with-backup-speech-recogni.md +6 -0
  142. package/corpus/templates/clips/desktop/src/app.tsx +86 -82
  143. package/corpus/templates/clips/desktop/src/styles.css +13 -0
  144. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +10 -1
  145. package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +37 -2
  146. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -0
  147. package/corpus/templates/clips/server/lib/public-agent-context.ts +2 -2
  148. package/corpus/templates/clips/server/register-secrets.ts +7 -6
  149. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  150. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  151. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +22 -2
  152. package/corpus/templates/content/.agents/skills/shadcn-ui/SKILL.md +28 -4
  153. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +41 -59
  154. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +16 -84
  155. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +13 -7
  156. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +41 -41
  157. package/corpus/templates/content/app/components/editor/database/GalleryView.tsx +2 -1
  158. package/corpus/templates/content/app/components/editor/database/ListView.tsx +2 -1
  159. package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +9 -9
  160. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +7 -7
  161. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +11 -11
  162. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +2 -2
  163. package/corpus/templates/content/app/components/ui/checkbox.tsx +1 -0
  164. package/corpus/templates/content/app/components/ui/collapsible.tsx +1 -0
  165. package/corpus/templates/content/app/components/ui/toolkit-provider.tsx +6 -1
  166. package/corpus/templates/content/app/design-system.ts +3 -0
  167. package/corpus/templates/content/app/global.css +29 -3
  168. package/corpus/templates/content/app/i18n-data.ts +10 -0
  169. package/corpus/templates/content/changelog/2026-07-22-page-actions-are-grouped-into-the-three-dots-menu-for-a-clea.md +6 -0
  170. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  171. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  172. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +22 -2
  173. package/corpus/templates/design/.agents/skills/shadcn-ui/SKILL.md +28 -4
  174. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +8 -8
  175. package/corpus/templates/design/app/components/ui/command.tsx +1 -0
  176. package/corpus/templates/design/app/components/ui/toolkit-provider.tsx +6 -1
  177. package/corpus/templates/design/app/design-system.ts +3 -0
  178. package/corpus/templates/design/server/lib/fig-file-decoder.ts +1 -0
  179. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  180. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  181. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +22 -2
  182. package/corpus/templates/dispatch/.agents/skills/shadcn-ui/SKILL.md +28 -4
  183. package/corpus/templates/dispatch/app/components/ui/button.tsx +1 -0
  184. package/corpus/templates/dispatch/app/components/ui/toolkit-provider.tsx +17 -0
  185. package/corpus/templates/dispatch/app/design-system.ts +3 -0
  186. package/corpus/templates/dispatch/app/root.tsx +10 -7
  187. package/corpus/templates/dispatch/package.json +1 -0
  188. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  189. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  190. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +22 -2
  191. package/corpus/templates/forms/.agents/skills/shadcn-ui/SKILL.md +28 -4
  192. package/corpus/templates/forms/app/components/ui/toolkit-provider.tsx +6 -1
  193. package/corpus/templates/forms/app/design-system.ts +3 -0
  194. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  195. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  196. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +22 -2
  197. package/corpus/templates/macros/.agents/skills/shadcn-ui/SKILL.md +28 -4
  198. package/corpus/templates/macros/app/components/ui/toolkit-provider.tsx +6 -1
  199. package/corpus/templates/macros/app/design-system.ts +3 -0
  200. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  201. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  202. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +22 -2
  203. package/corpus/templates/mail/.agents/skills/shadcn-ui/SKILL.md +28 -4
  204. package/corpus/templates/mail/app/components/email/EmailThread.tsx +134 -93
  205. package/corpus/templates/mail/app/components/email/email-iframe-document.ts +8 -2
  206. package/corpus/templates/mail/app/components/ui/textarea.tsx +1 -21
  207. package/corpus/templates/mail/app/components/ui/toolkit-provider.tsx +6 -1
  208. package/corpus/templates/mail/app/design-system.ts +3 -0
  209. package/corpus/templates/mail/changelog/2026-07-22-email-messages-no-longer-flash-with-an-unstyled-page-while-l.md +6 -0
  210. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  211. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  212. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +22 -2
  213. package/corpus/templates/plan/.agents/skills/shadcn-ui/SKILL.md +28 -4
  214. package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +1 -1
  215. package/corpus/templates/plan/app/components/ui/toolkit-provider.tsx +6 -1
  216. package/corpus/templates/plan/app/design-system.ts +3 -0
  217. package/corpus/templates/plan/app/entry.client.tsx +3 -0
  218. package/corpus/templates/plan/changelog/2026-07-22-recover-stale-pages-after-a-deployment-refresh-automatically.md +6 -0
  219. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  220. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  221. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +22 -2
  222. package/corpus/templates/slides/.agents/skills/shadcn-ui/SKILL.md +28 -4
  223. package/corpus/templates/slides/app/components/ui/toolkit-provider.tsx +6 -1
  224. package/corpus/templates/slides/app/design-system.ts +3 -0
  225. package/corpus/templates/slides/app/hooks/use-agent-generating.ts +10 -3
  226. package/corpus/templates/slides/app/pages/Index.tsx +1 -0
  227. package/corpus/templates/slides/changelog/2026-07-22-new-deck-prompts-now-open-in-their-own-visible-chat-thread.md +6 -0
  228. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  229. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  230. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +22 -2
  231. package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +28 -4
  232. package/corpus/templates/tasks/app/components/ui/toolkit-provider.tsx +17 -0
  233. package/corpus/templates/tasks/app/design-system.ts +3 -0
  234. package/corpus/templates/tasks/app/root.tsx +5 -2
  235. package/corpus/toolkit/CHANGELOG.md +23 -0
  236. package/corpus/toolkit/agent-native.eject.json +71 -0
  237. package/corpus/toolkit/package.json +31 -1
  238. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +100 -39
  239. package/corpus/toolkit/src/chat-history/index.ts +9 -0
  240. package/corpus/toolkit/src/chat-history/useChatHistoryRailController.ts +76 -0
  241. package/corpus/toolkit/src/chat-history.css +2 -0
  242. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +11 -8
  243. package/corpus/toolkit/src/composer/PromptComposer.tsx +32 -7
  244. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +119 -31
  245. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +124 -9
  246. package/corpus/toolkit/src/conformance/__fixtures__/css-in-js-adapter.tsx +401 -0
  247. package/corpus/toolkit/src/conformance/index.ts +3 -0
  248. package/corpus/toolkit/src/conformance/runner.tsx +862 -0
  249. package/corpus/toolkit/src/conformance/types.ts +45 -0
  250. package/corpus/toolkit/src/conformance/version.ts +22 -0
  251. package/corpus/toolkit/src/design-system/components.tsx +146 -0
  252. package/corpus/toolkit/src/design-system/context.tsx +31 -0
  253. package/corpus/toolkit/src/design-system/default-adapter.tsx +915 -0
  254. package/corpus/toolkit/src/design-system/definition.ts +14 -0
  255. package/corpus/toolkit/src/design-system/error-boundary.tsx +37 -0
  256. package/corpus/toolkit/src/design-system/index.ts +7 -0
  257. package/corpus/toolkit/src/design-system/theme.ts +145 -0
  258. package/corpus/toolkit/src/design-system/types.ts +363 -0
  259. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +13 -2
  260. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +20 -0
  261. package/corpus/toolkit/src/editor/index.ts +2 -0
  262. package/corpus/toolkit/src/provider.tsx +98 -5
  263. package/corpus/toolkit/src/styles.css +52 -23
  264. package/corpus/toolkit/src/ui/button.tsx +95 -6
  265. package/corpus/toolkit/src/ui/dialog.tsx +48 -23
  266. package/corpus/toolkit/src/ui/popover.tsx +16 -2
  267. package/corpus/toolkit/src/ui/select.tsx +7 -3
  268. package/corpus/toolkit/src/ui/sidebar.tsx +47 -48
  269. package/corpus/toolkit/src/ui/tooltip.tsx +7 -3
  270. package/dist/a2a/client.d.ts +3 -1
  271. package/dist/a2a/client.d.ts.map +1 -1
  272. package/dist/a2a/client.js +17 -12
  273. package/dist/a2a/client.js.map +1 -1
  274. package/dist/a2a/types.d.ts +1 -1
  275. package/dist/a2a/types.d.ts.map +1 -1
  276. package/dist/a2a/types.js.map +1 -1
  277. package/dist/agent/types.d.ts +1 -1
  278. package/dist/agent/types.d.ts.map +1 -1
  279. package/dist/agent/types.js.map +1 -1
  280. package/dist/cli/index.js +18 -8
  281. package/dist/cli/index.js.map +1 -1
  282. package/dist/cli/multi-frontier-runs.js +3 -3
  283. package/dist/cli/multi-frontier-runs.js.map +1 -1
  284. package/dist/cli/templates-meta.d.ts.map +1 -1
  285. package/dist/cli/templates-meta.js +0 -12
  286. package/dist/cli/templates-meta.js.map +1 -1
  287. package/dist/cli/workspace-dev.js +1 -1
  288. package/dist/cli/workspace-dev.js.map +1 -1
  289. package/dist/client/AgentPanel.d.ts.map +1 -1
  290. package/dist/client/AgentPanel.js +18 -15
  291. package/dist/client/AgentPanel.js.map +1 -1
  292. package/dist/client/AssistantChat.d.ts.map +1 -1
  293. package/dist/client/AssistantChat.js +26 -15
  294. package/dist/client/AssistantChat.js.map +1 -1
  295. package/dist/client/CommandMenu.d.ts.map +1 -1
  296. package/dist/client/CommandMenu.js +18 -106
  297. package/dist/client/CommandMenu.js.map +1 -1
  298. package/dist/client/RunStuckBanner.d.ts +3 -5
  299. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  300. package/dist/client/RunStuckBanner.js +17 -18
  301. package/dist/client/RunStuckBanner.js.map +1 -1
  302. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  303. package/dist/client/agent-chat-adapter.js +2 -1
  304. package/dist/client/agent-chat-adapter.js.map +1 -1
  305. package/dist/client/app-providers.d.ts.map +1 -1
  306. package/dist/client/app-providers.js +1 -1
  307. package/dist/client/app-providers.js.map +1 -1
  308. package/dist/client/chat/action-chat-ui-surface.d.ts +8 -0
  309. package/dist/client/chat/action-chat-ui-surface.d.ts.map +1 -0
  310. package/dist/client/chat/action-chat-ui-surface.js +10 -0
  311. package/dist/client/chat/action-chat-ui-surface.js.map +1 -0
  312. package/dist/client/chat/message-components.d.ts +12 -1
  313. package/dist/client/chat/message-components.d.ts.map +1 -1
  314. package/dist/client/chat/message-components.js +102 -14
  315. package/dist/client/chat/message-components.js.map +1 -1
  316. package/dist/client/chat/tool-call-display.d.ts +3 -1
  317. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  318. package/dist/client/chat/tool-call-display.js +33 -14
  319. package/dist/client/chat/tool-call-display.js.map +1 -1
  320. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
  321. package/dist/client/chat/widgets/InlineExtensionWidget.js +9 -12
  322. package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
  323. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  324. package/dist/client/chat/widgets/builtin-tool-renderers.js +5 -3
  325. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  326. package/dist/client/components/ui/message-scroller.d.ts +1 -1
  327. package/dist/client/components/ui/message-scroller.d.ts.map +1 -1
  328. package/dist/client/components/ui/message-scroller.js +4 -3
  329. package/dist/client/components/ui/message-scroller.js.map +1 -1
  330. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  331. package/dist/client/conversation/AgentConversation.js +3 -2
  332. package/dist/client/conversation/AgentConversation.js.map +1 -1
  333. package/dist/client/error-capture.d.ts.map +1 -1
  334. package/dist/client/error-capture.js +2 -2
  335. package/dist/client/error-capture.js.map +1 -1
  336. package/dist/client/i18n.d.ts.map +1 -1
  337. package/dist/client/i18n.js +9 -0
  338. package/dist/client/i18n.js.map +1 -1
  339. package/dist/client/index.d.ts +2 -2
  340. package/dist/client/index.d.ts.map +1 -1
  341. package/dist/client/index.js +2 -2
  342. package/dist/client/index.js.map +1 -1
  343. package/dist/client/org/TeamPage.d.ts.map +1 -1
  344. package/dist/client/org/TeamPage.js +41 -33
  345. package/dist/client/org/TeamPage.js.map +1 -1
  346. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  347. package/dist/client/progress/RunsTray.js +9 -10
  348. package/dist/client/progress/RunsTray.js.map +1 -1
  349. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  350. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  351. package/dist/client/resources/McpConnectionSuggestion.js +14 -12
  352. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  353. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  354. package/dist/client/resources/McpIntegrationDialog.js +10 -8
  355. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  356. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  357. package/dist/client/resources/ResourcesPanel.js +3 -1
  358. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  359. package/dist/client/resources/mcp-integration-catalog.d.ts +2 -0
  360. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  361. package/dist/client/resources/mcp-integration-catalog.js +17 -17
  362. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  363. package/dist/client/resources/mcp-integration-logos.js +2 -2
  364. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  365. package/dist/client/route-chunk-recovery.d.ts.map +1 -1
  366. package/dist/client/route-chunk-recovery.js +5 -3
  367. package/dist/client/route-chunk-recovery.js.map +1 -1
  368. package/dist/client/session-replay.js +3 -3
  369. package/dist/client/session-replay.js.map +1 -1
  370. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  371. package/dist/client/settings/DemoModeSection.js +2 -5
  372. package/dist/client/settings/DemoModeSection.js.map +1 -1
  373. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  374. package/dist/client/settings/SecretsSection.js +18 -6
  375. package/dist/client/settings/SecretsSection.js.map +1 -1
  376. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  377. package/dist/client/settings/SettingsPanel.js +53 -118
  378. package/dist/client/settings/SettingsPanel.js.map +1 -1
  379. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  380. package/dist/client/settings/SettingsTabsPage.js +16 -1
  381. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  382. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  383. package/dist/client/settings/VoiceTranscriptionSection.js +2 -5
  384. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  385. package/dist/client/settings/index.d.ts +1 -0
  386. package/dist/client/settings/index.d.ts.map +1 -1
  387. package/dist/client/settings/index.js +1 -0
  388. package/dist/client/settings/index.js.map +1 -1
  389. package/dist/client/settings/useSettingsPanelController.d.ts +22 -0
  390. package/dist/client/settings/useSettingsPanelController.d.ts.map +1 -0
  391. package/dist/client/settings/useSettingsPanelController.js +103 -0
  392. package/dist/client/settings/useSettingsPanelController.js.map +1 -0
  393. package/dist/client/setup-connections/BuilderConnectCard.d.ts +14 -6
  394. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
  395. package/dist/client/setup-connections/BuilderConnectCard.js +24 -16
  396. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
  397. package/dist/client/setup-connections/index.d.ts +2 -1
  398. package/dist/client/setup-connections/index.d.ts.map +1 -1
  399. package/dist/client/setup-connections/index.js +2 -1
  400. package/dist/client/setup-connections/index.js.map +1 -1
  401. package/dist/client/setup-connections/useBuilderConnectCardController.d.ts +34 -0
  402. package/dist/client/setup-connections/useBuilderConnectCardController.d.ts.map +1 -0
  403. package/dist/client/setup-connections/useBuilderConnectCardController.js +39 -0
  404. package/dist/client/setup-connections/useBuilderConnectCardController.js.map +1 -0
  405. package/dist/client/sharing/ShareButton.d.ts +2 -1
  406. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  407. package/dist/client/sharing/ShareButton.js +17 -463
  408. package/dist/client/sharing/ShareButton.js.map +1 -1
  409. package/dist/client/sharing/ShareDialog.d.ts +6 -6
  410. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  411. package/dist/client/sharing/ShareDialog.js +69 -283
  412. package/dist/client/sharing/ShareDialog.js.map +1 -1
  413. package/dist/client/sharing/index.d.ts +3 -0
  414. package/dist/client/sharing/index.d.ts.map +1 -1
  415. package/dist/client/sharing/index.js +3 -0
  416. package/dist/client/sharing/index.js.map +1 -1
  417. package/dist/client/sharing/share-controller-helpers.d.ts +70 -0
  418. package/dist/client/sharing/share-controller-helpers.d.ts.map +1 -0
  419. package/dist/client/sharing/share-controller-helpers.js +224 -0
  420. package/dist/client/sharing/share-controller-helpers.js.map +1 -0
  421. package/dist/client/sharing/useShareButtonController.d.ts +91 -0
  422. package/dist/client/sharing/useShareButtonController.d.ts.map +1 -0
  423. package/dist/client/sharing/useShareButtonController.js +397 -0
  424. package/dist/client/sharing/useShareButtonController.js.map +1 -0
  425. package/dist/client/sharing/useShareDialogController.d.ts +109 -0
  426. package/dist/client/sharing/useShareDialogController.d.ts.map +1 -0
  427. package/dist/client/sharing/useShareDialogController.js +348 -0
  428. package/dist/client/sharing/useShareDialogController.js.map +1 -0
  429. package/dist/client/sse-event-processor.d.ts.map +1 -1
  430. package/dist/client/sse-event-processor.js +21 -0
  431. package/dist/client/sse-event-processor.js.map +1 -1
  432. package/dist/client/tool-display.d.ts +16 -0
  433. package/dist/client/tool-display.d.ts.map +1 -1
  434. package/dist/client/tool-display.js +52 -0
  435. package/dist/client/tool-display.js.map +1 -1
  436. package/dist/client/transcription/use-live-transcription.d.ts +3 -3
  437. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  438. package/dist/client/transcription/use-live-transcription.js +22 -11
  439. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  440. package/dist/client/use-agent-engine-configured.d.ts +3 -2
  441. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  442. package/dist/client/use-agent-engine-configured.js +7 -19
  443. package/dist/client/use-agent-engine-configured.js.map +1 -1
  444. package/dist/client/use-chat-threads.d.ts.map +1 -1
  445. package/dist/client/use-chat-threads.js +21 -8
  446. package/dist/client/use-chat-threads.js.map +1 -1
  447. package/dist/collab/routes.d.ts +1 -1
  448. package/dist/collab/struct-routes.d.ts +1 -1
  449. package/dist/deploy/build.d.ts.map +1 -1
  450. package/dist/deploy/build.js +1 -1
  451. package/dist/deploy/build.js.map +1 -1
  452. package/dist/guards/db-tool-scoping.js +1 -1
  453. package/dist/guards/db-tool-scoping.js.map +1 -1
  454. package/dist/integrations/adapters/slack.d.ts +1 -0
  455. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  456. package/dist/integrations/adapters/slack.js +61 -5
  457. package/dist/integrations/adapters/slack.js.map +1 -1
  458. package/dist/integrations/index.d.ts +1 -1
  459. package/dist/integrations/index.d.ts.map +1 -1
  460. package/dist/integrations/index.js +1 -1
  461. package/dist/integrations/index.js.map +1 -1
  462. package/dist/localization/default-messages.d.ts +4 -0
  463. package/dist/localization/default-messages.d.ts.map +1 -1
  464. package/dist/localization/default-messages.js +5 -1
  465. package/dist/localization/default-messages.js.map +1 -1
  466. package/dist/mcp-client/oauth-routes.d.ts +5 -0
  467. package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
  468. package/dist/mcp-client/oauth-routes.js +53 -14
  469. package/dist/mcp-client/oauth-routes.js.map +1 -1
  470. package/dist/notifications/routes.d.ts +2 -2
  471. package/dist/observability/routes.d.ts +1 -1
  472. package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
  473. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  474. package/dist/scripts/call-agent.d.ts.map +1 -1
  475. package/dist/scripts/call-agent.js +5 -1
  476. package/dist/scripts/call-agent.js.map +1 -1
  477. package/dist/secrets/routes.d.ts +6 -6
  478. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  479. package/dist/server/realtime-voice.d.ts.map +1 -1
  480. package/dist/server/realtime-voice.js +2 -2
  481. package/dist/server/realtime-voice.js.map +1 -1
  482. package/dist/styles/agent-native.css +0 -24
  483. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  484. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  485. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  486. package/dist/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  487. package/dist/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  488. package/dist/templates/chat/app/design-system.ts +3 -0
  489. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  490. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  491. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  492. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  493. package/dist/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  494. package/dist/templates/default/app/design-system.ts +3 -0
  495. package/dist/templates/default/app/root.tsx +5 -2
  496. package/dist/templates/default/package.json +1 -0
  497. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  498. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  499. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  500. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  501. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  502. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  503. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  504. package/dist/terminal/cli-registry.js +1 -1
  505. package/dist/terminal/cli-registry.js.map +1 -1
  506. package/dist/vite/client.d.ts +11 -1
  507. package/dist/vite/client.d.ts.map +1 -1
  508. package/dist/vite/client.js +144 -2
  509. package/dist/vite/client.js.map +1 -1
  510. package/docs/content/custom-design-system.mdx +445 -0
  511. package/docs/content/toolkit-ui.mdx +16 -0
  512. package/package.json +2 -2
  513. package/src/a2a/client.ts +32 -10
  514. package/src/a2a/types.ts +1 -0
  515. package/src/agent/types.ts +1 -1
  516. package/src/cli/index.ts +18 -10
  517. package/src/cli/multi-frontier-runs.ts +5 -3
  518. package/src/cli/templates-meta.ts +0 -12
  519. package/src/cli/workspace-dev.ts +1 -1
  520. package/src/client/AgentPanel.tsx +99 -108
  521. package/src/client/AssistantChat.tsx +30 -13
  522. package/src/client/CommandMenu.tsx +68 -178
  523. package/src/client/RunStuckBanner.tsx +39 -47
  524. package/src/client/agent-chat-adapter.ts +3 -1
  525. package/src/client/app-providers.tsx +1 -1
  526. package/src/client/chat/action-chat-ui-surface.tsx +32 -0
  527. package/src/client/chat/message-components.tsx +169 -18
  528. package/src/client/chat/tool-call-display.tsx +50 -14
  529. package/src/client/chat/widgets/InlineExtensionWidget.tsx +13 -40
  530. package/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
  531. package/src/client/components/ui/message-scroller.tsx +15 -1
  532. package/src/client/conversation/AgentConversation.tsx +12 -1
  533. package/src/client/error-capture.ts +2 -6
  534. package/src/client/i18n.tsx +22 -0
  535. package/src/client/index.ts +17 -0
  536. package/src/client/org/TeamPage.tsx +257 -153
  537. package/src/client/progress/RunsTray.tsx +89 -88
  538. package/src/client/resources/McpConnectionSuggestion.tsx +25 -16
  539. package/src/client/resources/McpIntegrationDialog.tsx +34 -13
  540. package/src/client/resources/ResourcesPanel.tsx +5 -1
  541. package/src/client/resources/mcp-integration-catalog.ts +20 -17
  542. package/src/client/resources/mcp-integration-logos.ts +2 -2
  543. package/src/client/route-chunk-recovery.ts +5 -3
  544. package/src/client/session-replay.ts +3 -3
  545. package/src/client/settings/DemoModeSection.tsx +6 -18
  546. package/src/client/settings/SecretsSection.tsx +97 -52
  547. package/src/client/settings/SettingsPanel.tsx +217 -252
  548. package/src/client/settings/SettingsTabsPage.tsx +23 -2
  549. package/src/client/settings/VoiceTranscriptionSection.tsx +7 -18
  550. package/src/client/settings/index.ts +7 -0
  551. package/src/client/settings/useSettingsPanelController.ts +155 -0
  552. package/src/client/setup-connections/BuilderConnectCard.tsx +116 -51
  553. package/src/client/setup-connections/index.ts +10 -0
  554. package/src/client/setup-connections/useBuilderConnectCardController.ts +82 -0
  555. package/src/client/sharing/ShareButton.tsx +64 -586
  556. package/src/client/sharing/ShareDialog.tsx +299 -633
  557. package/src/client/sharing/index.ts +42 -0
  558. package/src/client/sharing/share-controller-helpers.ts +318 -0
  559. package/src/client/sharing/useShareButtonController.ts +600 -0
  560. package/src/client/sharing/useShareDialogController.ts +559 -0
  561. package/src/client/sse-event-processor.ts +23 -0
  562. package/src/client/tool-display.ts +71 -0
  563. package/src/client/transcription/use-live-transcription.ts +64 -45
  564. package/src/client/use-agent-engine-configured.ts +12 -19
  565. package/src/client/use-chat-threads.ts +33 -12
  566. package/src/deploy/build.ts +2 -1
  567. package/src/guards/db-tool-scoping.ts +1 -1
  568. package/src/integrations/adapters/slack.ts +84 -5
  569. package/src/integrations/index.ts +5 -1
  570. package/src/localization/default-messages.ts +6 -1
  571. package/src/mcp-client/oauth-routes.ts +61 -14
  572. package/src/scripts/call-agent.ts +5 -1
  573. package/src/server/realtime-voice.ts +5 -2
  574. package/src/styles/agent-native.css +0 -24
  575. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  576. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  577. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  578. package/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  579. package/src/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  580. package/src/templates/chat/app/design-system.ts +3 -0
  581. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  582. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  583. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  584. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  585. package/src/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  586. package/src/templates/default/app/design-system.ts +3 -0
  587. package/src/templates/default/app/root.tsx +5 -2
  588. package/src/templates/default/package.json +1 -0
  589. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  590. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  591. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  592. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  593. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  594. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  595. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  596. package/src/terminal/cli-registry.ts +1 -1
  597. package/src/vite/client.ts +205 -1
  598. package/corpus/templates/analytics/app/components/ui/calendar.tsx +0 -70
  599. package/corpus/templates/analytics/app/components/ui/chart.tsx +0 -386
  600. package/corpus/templates/calendar/app/components/ui/sonner.tsx +0 -58
  601. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +0 -115
  602. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +0 -142
  603. package/corpus/templates/crm/.agents/skills/crm/SKILL.md +0 -128
  604. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +0 -145
  605. package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +0 -169
  606. package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +0 -100
  607. package/corpus/templates/crm/.env.example +0 -5
  608. package/corpus/templates/crm/AGENTS.md +0 -120
  609. package/corpus/templates/crm/CHANGELOG.md +0 -1
  610. package/corpus/templates/crm/DEVELOPING.md +0 -66
  611. package/corpus/templates/crm/README.md +0 -106
  612. package/corpus/templates/crm/_gitignore +0 -12
  613. package/corpus/templates/crm/actions/_crm-action-utils.ts +0 -87
  614. package/corpus/templates/crm/actions/_crm-dashboard.ts +0 -69
  615. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +0 -15
  616. package/corpus/templates/crm/actions/_crm-signal-utils.ts +0 -79
  617. package/corpus/templates/crm/actions/apply-crm-proposals.ts +0 -203
  618. package/corpus/templates/crm/actions/attach-call-evidence.ts +0 -170
  619. package/corpus/templates/crm/actions/configure-crm-connection.ts +0 -126
  620. package/corpus/templates/crm/actions/configure-native-crm.ts +0 -44
  621. package/corpus/templates/crm/actions/create-crm-record.ts +0 -148
  622. package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +0 -58
  623. package/corpus/templates/crm/actions/delete-staged-dataset.ts +0 -14
  624. package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +0 -36
  625. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +0 -35
  626. package/corpus/templates/crm/actions/get-crm-dashboard.ts +0 -14
  627. package/corpus/templates/crm/actions/get-crm-overview.ts +0 -13
  628. package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +0 -61
  629. package/corpus/templates/crm/actions/get-crm-record.ts +0 -75
  630. package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +0 -81
  631. package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +0 -15
  632. package/corpus/templates/crm/actions/list-crm-dashboards.ts +0 -15
  633. package/corpus/templates/crm/actions/list-crm-proposals.ts +0 -31
  634. package/corpus/templates/crm/actions/list-crm-records.ts +0 -79
  635. package/corpus/templates/crm/actions/list-crm-saved-views.ts +0 -15
  636. package/corpus/templates/crm/actions/list-crm-signal-hits.ts +0 -43
  637. package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +0 -32
  638. package/corpus/templates/crm/actions/list-crm-tasks.ts +0 -22
  639. package/corpus/templates/crm/actions/list-staged-datasets.ts +0 -14
  640. package/corpus/templates/crm/actions/list-workspace-connections.ts +0 -47
  641. package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +0 -87
  642. package/corpus/templates/crm/actions/manage-crm-task.ts +0 -132
  643. package/corpus/templates/crm/actions/navigate.ts +0 -63
  644. package/corpus/templates/crm/actions/provider-api-catalog.ts +0 -22
  645. package/corpus/templates/crm/actions/provider-api-docs.ts +0 -54
  646. package/corpus/templates/crm/actions/provider-api-request.ts +0 -92
  647. package/corpus/templates/crm/actions/query-staged-dataset.ts +0 -44
  648. package/corpus/templates/crm/actions/record-crm-call-insight.ts +0 -160
  649. package/corpus/templates/crm/actions/record-crm-smart-signal.ts +0 -150
  650. package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +0 -23
  651. package/corpus/templates/crm/actions/review-crm-signal.ts +0 -31
  652. package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +0 -103
  653. package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +0 -275
  654. package/corpus/templates/crm/actions/run.ts +0 -7
  655. package/corpus/templates/crm/actions/save-crm-dashboard.ts +0 -51
  656. package/corpus/templates/crm/actions/save-crm-saved-view.ts +0 -119
  657. package/corpus/templates/crm/actions/sync-crm.ts +0 -146
  658. package/corpus/templates/crm/actions/update-crm-record.ts +0 -510
  659. package/corpus/templates/crm/actions/view-screen.ts +0 -218
  660. package/corpus/templates/crm/agent-native.app-skill.json +0 -58
  661. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +0 -158
  662. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +0 -83
  663. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +0 -225
  664. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +0 -413
  665. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +0 -510
  666. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +0 -134
  667. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +0 -367
  668. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +0 -92
  669. package/corpus/templates/crm/app/components/crm/Surface.tsx +0 -96
  670. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +0 -180
  671. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +0 -112
  672. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +0 -84
  673. package/corpus/templates/crm/app/entry.client.tsx +0 -16
  674. package/corpus/templates/crm/app/entry.server.tsx +0 -10
  675. package/corpus/templates/crm/app/global.css +0 -167
  676. package/corpus/templates/crm/app/hooks/use-navigation-state.ts +0 -60
  677. package/corpus/templates/crm/app/i18n/en-US.ts +0 -89
  678. package/corpus/templates/crm/app/i18n/index.ts +0 -34
  679. package/corpus/templates/crm/app/lib/dashboard.ts +0 -13
  680. package/corpus/templates/crm/app/lib/navigation.ts +0 -54
  681. package/corpus/templates/crm/app/lib/tab-id.ts +0 -1
  682. package/corpus/templates/crm/app/lib/types.ts +0 -172
  683. package/corpus/templates/crm/app/lib/utils.ts +0 -1
  684. package/corpus/templates/crm/app/root.tsx +0 -88
  685. package/corpus/templates/crm/app/routes/_index.tsx +0 -26
  686. package/corpus/templates/crm/app/routes/accounts.tsx +0 -41
  687. package/corpus/templates/crm/app/routes/agent.tsx +0 -5
  688. package/corpus/templates/crm/app/routes/ask.tsx +0 -53
  689. package/corpus/templates/crm/app/routes/dashboard.tsx +0 -118
  690. package/corpus/templates/crm/app/routes/opportunities.tsx +0 -41
  691. package/corpus/templates/crm/app/routes/people.tsx +0 -41
  692. package/corpus/templates/crm/app/routes/proposals.tsx +0 -266
  693. package/corpus/templates/crm/app/routes/records.$recordId.tsx +0 -35
  694. package/corpus/templates/crm/app/routes/settings.tsx +0 -63
  695. package/corpus/templates/crm/app/routes/setup.tsx +0 -308
  696. package/corpus/templates/crm/app/routes/tasks.tsx +0 -252
  697. package/corpus/templates/crm/app/routes/views.tsx +0 -333
  698. package/corpus/templates/crm/app/routes.ts +0 -17
  699. package/corpus/templates/crm/app/vite-env.d.ts +0 -6
  700. package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +0 -6
  701. package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +0 -6
  702. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +0 -6
  703. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +0 -6
  704. package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +0 -6
  705. package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +0 -6
  706. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +0 -6
  707. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +0 -6
  708. package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +0 -6
  709. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +0 -6
  710. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +0 -6
  711. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +0 -6
  712. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  713. package/corpus/templates/crm/components.json +0 -20
  714. package/corpus/templates/crm/docs/architecture/crm-contract.md +0 -180
  715. package/corpus/templates/crm/learnings.defaults.md +0 -5
  716. package/corpus/templates/crm/package.json +0 -59
  717. package/corpus/templates/crm/public/favicon.svg +0 -1
  718. package/corpus/templates/crm/public/icon-180.svg +0 -1
  719. package/corpus/templates/crm/public/manifest.json +0 -11
  720. package/corpus/templates/crm/react-router.config.ts +0 -7
  721. package/corpus/templates/crm/server/crm/adapter.ts +0 -32
  722. package/corpus/templates/crm/server/crm/crm-field-firewall.ts +0 -64
  723. package/corpus/templates/crm/server/crm/crm-mirror.ts +0 -711
  724. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1146
  725. package/corpus/templates/crm/server/crm/native-adapter.ts +0 -1715
  726. package/corpus/templates/crm/server/crm/read-through.ts +0 -207
  727. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1255
  728. package/corpus/templates/crm/server/db/crm-store.ts +0 -1170
  729. package/corpus/templates/crm/server/db/index.ts +0 -169
  730. package/corpus/templates/crm/server/db/schema.ts +0 -441
  731. package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +0 -65
  732. package/corpus/templates/crm/server/lib/intelligence/evidence.ts +0 -105
  733. package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +0 -100
  734. package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +0 -144
  735. package/corpus/templates/crm/server/lib/intelligence/summary.ts +0 -141
  736. package/corpus/templates/crm/server/lib/provider-api.ts +0 -64
  737. package/corpus/templates/crm/server/middleware/auth.ts +0 -4
  738. package/corpus/templates/crm/server/plugins/agent-chat.ts +0 -68
  739. package/corpus/templates/crm/server/plugins/auth.ts +0 -14
  740. package/corpus/templates/crm/server/plugins/core-routes.ts +0 -17
  741. package/corpus/templates/crm/server/plugins/db.ts +0 -454
  742. package/corpus/templates/crm/server/routes/[...page].get.ts +0 -5
  743. package/corpus/templates/crm/shared/crm-automation-recipes.ts +0 -132
  744. package/corpus/templates/crm/shared/crm-contract.ts +0 -254
  745. package/corpus/templates/crm/shared/crm-sales-config.ts +0 -63
  746. package/corpus/templates/crm/ssr-entry.ts +0 -11
  747. package/corpus/templates/crm/tsconfig.json +0 -24
  748. package/corpus/templates/crm/vite.config.ts +0 -15
  749. package/corpus/templates/crm/vitest.config.ts +0 -5
  750. package/corpus/templates/forms/app/components/ui/calendar.tsx +0 -214
  751. package/corpus/templates/forms/app/components/ui/chart.tsx +0 -379
  752. package/corpus/templates/forms/app/components/ui/command.tsx +0 -153
  753. package/corpus/templates/forms/app/components/ui/context-menu.tsx +0 -198
  754. package/corpus/templates/forms/app/components/ui/menubar.tsx +0 -254
  755. package/corpus/templates/macros/app/components/ui/menubar.tsx +0 -238
  756. package/corpus/templates/macros/app/components/ui/progress.tsx +0 -26
  757. package/corpus/templates/mail/app/components/ui/calendar.tsx +0 -211
  758. package/corpus/templates/mail/app/components/ui/chart.tsx +0 -379
  759. package/corpus/templates/mail/app/components/ui/command.tsx +0 -153
  760. package/corpus/templates/mail/app/components/ui/context-menu.tsx +0 -198
  761. package/corpus/templates/mail/app/components/ui/menubar.tsx +0 -254
  762. package/corpus/templates/tasks/app/components/ui/accordion.tsx +0 -56
  763. package/corpus/templates/tasks/app/components/ui/aspect-ratio.tsx +0 -5
  764. package/corpus/templates/tasks/app/components/ui/breadcrumb.tsx +0 -115
  765. package/corpus/templates/tasks/app/components/ui/calendar.tsx +0 -70
  766. package/corpus/templates/tasks/app/components/ui/carousel.tsx +0 -260
  767. package/corpus/templates/tasks/app/components/ui/chart.tsx +0 -379
  768. package/corpus/templates/tasks/app/components/ui/form.tsx +0 -177
  769. package/corpus/templates/tasks/app/components/ui/hover-card.tsx +0 -27
  770. package/corpus/templates/tasks/app/components/ui/input-otp.tsx +0 -69
  771. package/corpus/templates/tasks/app/components/ui/menubar.tsx +0 -254
  772. package/corpus/templates/tasks/app/components/ui/navigation-menu.tsx +0 -128
  773. package/corpus/templates/tasks/app/components/ui/pagination.tsx +0 -121
  774. package/corpus/templates/tasks/app/components/ui/resizable.tsx +0 -43
  775. package/corpus/templates/tasks/app/components/ui/sidebar.tsx +0 -782
  776. package/corpus/templates/tasks/app/components/ui/toggle.tsx +0 -43
@@ -1,1170 +0,0 @@
1
- import { accessFilter, assertAccess } from "@agent-native/core/sharing";
2
- import { and, asc, desc, eq, exists, inArray, isNull, like } from "drizzle-orm";
3
-
4
- import type {
5
- CrmAccessScope,
6
- CrmRelationship,
7
- CrmValue,
8
- } from "../../shared/crm-contract.js";
9
- import {
10
- createConnectedCrmAdapter,
11
- isConnectedCrmProvider,
12
- } from "../crm/adapter.js";
13
- import {
14
- isBoundedCrmValue,
15
- isSafeCrmMutationFieldName,
16
- } from "../crm/crm-field-firewall.js";
17
- import { resolveNativeCrmAccessScope } from "../crm/native-adapter.js";
18
- import {
19
- parseCrmAccessScope,
20
- relatedSummaries,
21
- scopesAreCompatible,
22
- type RelatedRecordSummary,
23
- } from "../crm/read-through.js";
24
- import { getDb, schema } from "./index.js";
25
-
26
- const MAX_RECORD_LIMIT = 100;
27
- const RECORD_DETAIL_LIMIT = 20;
28
- const MAX_SCOPE_VALIDATIONS = 20;
29
- const SAFE_VIEW_COLUMNS = new Set([
30
- "displayName",
31
- "primaryEmail",
32
- "domain",
33
- "stage",
34
- "ownerName",
35
- "nextContactAt",
36
- "remoteUpdatedAt",
37
- "updatedAt",
38
- ]);
39
- const SAFE_VIEW_SORTS = new Set([
40
- "displayName",
41
- "stage",
42
- "ownerName",
43
- "nextContactAt",
44
- "remoteUpdatedAt",
45
- "updatedAt",
46
- ]);
47
-
48
- export type CrmListKind =
49
- | "account"
50
- | "person"
51
- | "opportunity"
52
- | "activity"
53
- | "task"
54
- | "custom";
55
-
56
- type Primitive = string | number | boolean | null;
57
-
58
- type SavedViewConfig = {
59
- id: string;
60
- name: string;
61
- kind?: CrmListKind;
62
- dataProgramId?: string;
63
- query?: string;
64
- fieldEquals: Record<string, Primitive>;
65
- columns: string[];
66
- sort: Array<{ field: string; direction: "asc" | "desc" }>;
67
- };
68
-
69
- type ScopeValidationTarget = {
70
- connectionId: string;
71
- workspaceConnectionId: string | null;
72
- provider: string;
73
- objectType: string;
74
- };
75
-
76
- export type CrmScopeResolver = (
77
- target: ScopeValidationTarget,
78
- ) => Promise<CrmAccessScope | null>;
79
-
80
- function decodeCursor(cursor: string | undefined): number {
81
- if (!cursor) return 0;
82
- const value = Number.parseInt(cursor, 10);
83
- return Number.isSafeInteger(value) && value >= 0 ? value : 0;
84
- }
85
-
86
- function page<T>(rows: T[], limit: number) {
87
- return {
88
- rows: rows.slice(0, limit),
89
- nextCursor:
90
- rows.length > limit ? String(decodeCursor(undefined) + limit) : undefined,
91
- };
92
- }
93
-
94
- function toRecordSummary(
95
- row: {
96
- id: string;
97
- displayName: string;
98
- kind: string;
99
- primaryEmail: string | null;
100
- domain: string | null;
101
- stage: string | null;
102
- ownerName: string | null;
103
- nextContactAt: string | null;
104
- remoteUpdatedAt: string | null;
105
- updatedAt: string;
106
- },
107
- columns?: string[],
108
- ) {
109
- const included = new Set(columns ?? SAFE_VIEW_COLUMNS);
110
- return {
111
- id: row.id,
112
- displayName: row.displayName,
113
- kind: row.kind,
114
- ...(included.has("domain") || included.has("primaryEmail")
115
- ? { subtitle: row.domain ?? row.primaryEmail ?? undefined }
116
- : {}),
117
- ...(included.has("ownerName") ? { owner: row.ownerName ?? undefined } : {}),
118
- ...(included.has("stage") ? { stage: row.stage ?? undefined } : {}),
119
- ...(included.has("nextContactAt")
120
- ? { nextStep: row.nextContactAt ?? undefined }
121
- : {}),
122
- ...(included.has("remoteUpdatedAt") || included.has("updatedAt")
123
- ? { updatedAt: row.remoteUpdatedAt ?? row.updatedAt }
124
- : {}),
125
- };
126
- }
127
-
128
- function parseStoredValue(row: {
129
- valueType: string;
130
- stringValue: string | null;
131
- numberValue: number | null;
132
- booleanValue: boolean | null;
133
- jsonValue: string | null;
134
- }): unknown {
135
- if (row.booleanValue !== null) return row.booleanValue;
136
- if (row.numberValue !== null) return row.numberValue;
137
- if (row.stringValue !== null) return row.stringValue;
138
- if (!row.jsonValue) return null;
139
- try {
140
- return JSON.parse(row.jsonValue) as unknown;
141
- } catch {
142
- return null;
143
- }
144
- }
145
-
146
- function parsePrimitive(value: unknown): value is Primitive {
147
- return (
148
- value === null ||
149
- typeof value === "boolean" ||
150
- (typeof value === "number" && Number.isFinite(value)) ||
151
- (typeof value === "string" && value.length <= 2_000)
152
- );
153
- }
154
-
155
- function parseJsonObject(value: string): Record<string, unknown> | null {
156
- try {
157
- const parsed = JSON.parse(value) as unknown;
158
- return parsed && typeof parsed === "object" && !Array.isArray(parsed)
159
- ? (parsed as Record<string, unknown>)
160
- : null;
161
- } catch {
162
- return null;
163
- }
164
- }
165
-
166
- function parseSavedViewConfig(input: {
167
- id: string;
168
- name: string;
169
- kind: string | null;
170
- filtersJson: string;
171
- columnsJson: string;
172
- sortJson: string;
173
- dataProgramId: string | null;
174
- }): SavedViewConfig {
175
- if (
176
- input.kind !== null &&
177
- input.kind !== "account" &&
178
- input.kind !== "person" &&
179
- input.kind !== "opportunity"
180
- ) {
181
- throw new Error("CRM saved view has an unsupported record kind.");
182
- }
183
- const filters = parseJsonObject(input.filtersJson);
184
- if (!filters) throw new Error("CRM saved view filters are invalid.");
185
- const filterKeys = Object.keys(filters);
186
- if (filterKeys.some((key) => key !== "query" && key !== "fieldEquals")) {
187
- throw new Error("CRM saved view contains unsupported filters.");
188
- }
189
- const query = filters.query;
190
- if (
191
- query !== undefined &&
192
- (typeof query !== "string" || query.length > 120)
193
- ) {
194
- throw new Error("CRM saved view query is invalid.");
195
- }
196
- const rawFieldEquals = filters.fieldEquals;
197
- if (
198
- rawFieldEquals !== undefined &&
199
- (!rawFieldEquals ||
200
- typeof rawFieldEquals !== "object" ||
201
- Array.isArray(rawFieldEquals))
202
- ) {
203
- throw new Error("CRM saved view field filters are invalid.");
204
- }
205
- const fieldEquals = Object.entries(
206
- (rawFieldEquals ?? {}) as Record<string, unknown>,
207
- );
208
- if (
209
- fieldEquals.length > 12 ||
210
- fieldEquals.some(
211
- ([fieldName, value]) =>
212
- !fieldName.trim() || fieldName.length > 120 || !parsePrimitive(value),
213
- )
214
- ) {
215
- throw new Error("CRM saved view field filters must be bounded primitives.");
216
- }
217
- const columns = JSON.parse(input.columnsJson) as unknown;
218
- if (
219
- !Array.isArray(columns) ||
220
- columns.length > 20 ||
221
- columns.some(
222
- (column) => typeof column !== "string" || !SAFE_VIEW_COLUMNS.has(column),
223
- )
224
- ) {
225
- throw new Error("CRM saved view columns are unsupported.");
226
- }
227
- const sort = JSON.parse(input.sortJson) as unknown;
228
- if (
229
- !Array.isArray(sort) ||
230
- sort.length > 2 ||
231
- sort.some(
232
- (entry) =>
233
- !entry ||
234
- typeof entry !== "object" ||
235
- !SAFE_VIEW_SORTS.has((entry as { field?: string }).field ?? "") ||
236
- ((entry as { direction?: string }).direction !== "asc" &&
237
- (entry as { direction?: string }).direction !== "desc"),
238
- )
239
- ) {
240
- throw new Error("CRM saved view sort is unsupported.");
241
- }
242
- return {
243
- id: input.id,
244
- name: input.name,
245
- ...(input.kind ? { kind: input.kind } : {}),
246
- ...(input.dataProgramId ? { dataProgramId: input.dataProgramId } : {}),
247
- ...(query ? { query } : {}),
248
- fieldEquals: Object.fromEntries(fieldEquals) as Record<string, Primitive>,
249
- columns,
250
- sort: sort as Array<{ field: string; direction: "asc" | "desc" }>,
251
- };
252
- }
253
-
254
- function fieldEqualsCondition(fieldName: string, value: Primitive) {
255
- const scalarCondition =
256
- value === null
257
- ? and(
258
- isNull(schema.crmRecordFields.stringValue),
259
- isNull(schema.crmRecordFields.numberValue),
260
- isNull(schema.crmRecordFields.booleanValue),
261
- isNull(schema.crmRecordFields.jsonValue),
262
- )
263
- : typeof value === "string"
264
- ? eq(schema.crmRecordFields.stringValue, value)
265
- : typeof value === "number"
266
- ? eq(schema.crmRecordFields.numberValue, value)
267
- : eq(schema.crmRecordFields.booleanValue, value);
268
- return exists(
269
- getDb()
270
- .select({ id: schema.crmRecordFields.id })
271
- .from(schema.crmRecordFields)
272
- .where(
273
- and(
274
- eq(schema.crmRecordFields.recordId, schema.crmRecords.id),
275
- eq(schema.crmRecordFields.fieldName, fieldName),
276
- inArray(schema.crmRecordFields.storagePolicy, [
277
- "mirrored",
278
- "derived-local",
279
- "local-authoritative",
280
- ]),
281
- accessFilter(schema.crmRecordFields, schema.crmRecordFieldShares),
282
- scalarCondition,
283
- ),
284
- ),
285
- );
286
- }
287
-
288
- function orderForSavedView(view: SavedViewConfig | undefined) {
289
- const sort = view?.sort[0];
290
- const column =
291
- sort?.field === "displayName"
292
- ? schema.crmRecords.displayName
293
- : sort?.field === "stage"
294
- ? schema.crmRecords.stage
295
- : sort?.field === "ownerName"
296
- ? schema.crmRecords.ownerName
297
- : sort?.field === "nextContactAt"
298
- ? schema.crmRecords.nextContactAt
299
- : sort?.field === "updatedAt"
300
- ? schema.crmRecords.updatedAt
301
- : schema.crmRecords.remoteUpdatedAt;
302
- const direction = sort?.direction === "asc" ? asc : desc;
303
- return [direction(column), desc(schema.crmRecords.id)];
304
- }
305
-
306
- async function defaultScopeResolver(
307
- target: ScopeValidationTarget,
308
- ): Promise<CrmAccessScope | null> {
309
- if (target.provider === "native") {
310
- return resolveNativeCrmAccessScope({
311
- connectionId: target.connectionId,
312
- objectType: target.objectType,
313
- });
314
- }
315
- if (!isConnectedCrmProvider(target.provider) || !target.workspaceConnectionId)
316
- return null;
317
- const adapter = await createConnectedCrmAdapter({
318
- provider: target.provider,
319
- connectionId: target.workspaceConnectionId,
320
- });
321
- return adapter.getAccessScope(target.objectType);
322
- }
323
-
324
- export async function listCrmRecords(
325
- input: {
326
- kind?: CrmListKind;
327
- connectionId?: string;
328
- query?: string;
329
- viewId?: string;
330
- limit: number;
331
- cursor?: string;
332
- },
333
- options: { resolveScope?: CrmScopeResolver } = {},
334
- ) {
335
- const db = getDb();
336
- const offset = decodeCursor(input.cursor);
337
- const limit = Math.min(input.limit, MAX_RECORD_LIMIT);
338
- const viewRow = input.viewId
339
- ? await db
340
- .select({
341
- id: schema.crmSavedViews.id,
342
- name: schema.crmSavedViews.name,
343
- kind: schema.crmSavedViews.kind,
344
- filtersJson: schema.crmSavedViews.filtersJson,
345
- columnsJson: schema.crmSavedViews.columnsJson,
346
- sortJson: schema.crmSavedViews.sortJson,
347
- dataProgramId: schema.crmSavedViews.dataProgramId,
348
- })
349
- .from(schema.crmSavedViews)
350
- .where(
351
- and(
352
- eq(schema.crmSavedViews.id, input.viewId),
353
- accessFilter(schema.crmSavedViews, schema.crmSavedViewShares),
354
- ),
355
- )
356
- .limit(1)
357
- : [];
358
- if (input.viewId && !viewRow[0])
359
- throw new Error("CRM saved view was not found.");
360
- const view = viewRow[0] ? parseSavedViewConfig(viewRow[0]) : undefined;
361
- if (input.kind && view?.kind && input.kind !== view.kind) {
362
- throw new Error("CRM saved view kind cannot be overridden.");
363
- }
364
- if (input.query && view?.query && input.query !== view.query) {
365
- throw new Error("CRM saved view query cannot be overridden.");
366
- }
367
- const kind = view?.kind ?? input.kind;
368
- const query = view?.query ?? input.query;
369
- const conditions = [
370
- accessFilter(schema.crmRecords, schema.crmRecordShares),
371
- accessFilter(schema.crmConnections, schema.crmConnectionShares),
372
- eq(schema.crmRecords.tombstone, false),
373
- ];
374
-
375
- if (kind) conditions.push(eq(schema.crmRecords.kind, kind));
376
- if (input.connectionId) {
377
- conditions.push(eq(schema.crmRecords.connectionId, input.connectionId));
378
- }
379
- if (query) {
380
- conditions.push(like(schema.crmRecords.displayName, `%${query}%`));
381
- }
382
- for (const [fieldName, value] of Object.entries(view?.fieldEquals ?? {})) {
383
- conditions.push(fieldEqualsCondition(fieldName, value));
384
- }
385
-
386
- const rows = await db
387
- .select({
388
- id: schema.crmRecords.id,
389
- displayName: schema.crmRecords.displayName,
390
- kind: schema.crmRecords.kind,
391
- primaryEmail: schema.crmRecords.primaryEmail,
392
- domain: schema.crmRecords.domain,
393
- stage: schema.crmRecords.stage,
394
- ownerName: schema.crmRecords.ownerName,
395
- nextContactAt: schema.crmRecords.nextContactAt,
396
- remoteUpdatedAt: schema.crmRecords.remoteUpdatedAt,
397
- updatedAt: schema.crmRecords.updatedAt,
398
- connectionId: schema.crmRecords.connectionId,
399
- objectType: schema.crmRecords.objectType,
400
- provider: schema.crmRecords.provider,
401
- accessScopeJson: schema.crmRecords.accessScopeJson,
402
- workspaceConnectionId: schema.crmConnections.workspaceConnectionId,
403
- })
404
- .from(schema.crmRecords)
405
- .innerJoin(
406
- schema.crmConnections,
407
- eq(schema.crmRecords.connectionId, schema.crmConnections.id),
408
- )
409
- .where(and(...conditions))
410
- .orderBy(...orderForSavedView(view))
411
- .limit(limit + 1)
412
- .offset(offset);
413
- const result = page(rows, limit);
414
- const scopeResolver = options.resolveScope ?? defaultScopeResolver;
415
- const scopeTargets = Array.from(
416
- new Map(
417
- result.rows.map((row) => [
418
- `${row.connectionId}:${row.objectType}`,
419
- {
420
- connectionId: row.connectionId,
421
- workspaceConnectionId: row.workspaceConnectionId,
422
- provider: row.provider,
423
- objectType: row.objectType,
424
- },
425
- ]),
426
- ).values(),
427
- ).slice(0, MAX_SCOPE_VALIDATIONS);
428
- const currentScopes = new Map(
429
- await Promise.all(
430
- scopeTargets.map(
431
- async (target) =>
432
- [
433
- `${target.connectionId}:${target.objectType}`,
434
- await scopeResolver(target).catch(() => null),
435
- ] as const,
436
- ),
437
- ),
438
- );
439
- const records = result.rows
440
- .filter((row) => {
441
- const current = currentScopes.get(
442
- `${row.connectionId}:${row.objectType}`,
443
- );
444
- return Boolean(
445
- current &&
446
- scopesAreCompatible(parseCrmAccessScope(row.accessScopeJson), current),
447
- );
448
- })
449
- .map((row) => toRecordSummary(row, view?.columns));
450
-
451
- return {
452
- records,
453
- nextCursor: result.nextCursor ? String(offset + limit) : undefined,
454
- complete: !result.nextCursor,
455
- ...(view
456
- ? {
457
- appliedView: {
458
- id: view.id,
459
- name: view.name,
460
- ...(view.kind ? { kind: view.kind } : {}),
461
- ...(view.query ? { query: view.query } : {}),
462
- ...(view.dataProgramId
463
- ? { dataProgramId: view.dataProgramId }
464
- : {}),
465
- fieldEquals: view.fieldEquals,
466
- columns: view.columns,
467
- sort: view.sort,
468
- },
469
- }
470
- : {}),
471
- };
472
- }
473
-
474
- export type CrmRecordReadContext = {
475
- id: string;
476
- connectionId: string;
477
- workspaceConnectionId: string | null;
478
- provider: string;
479
- objectType: string;
480
- kind: CrmListKind;
481
- remoteId: string;
482
- accessScopeJson: string;
483
- ownerEmail: string;
484
- orgId: string | null;
485
- visibility: "private" | "org" | "public";
486
- fieldPolicies: Array<{
487
- fieldName: string;
488
- storagePolicy:
489
- | "mirrored"
490
- | "remote-only"
491
- | "redacted"
492
- | "derived-local"
493
- | "local-authoritative";
494
- readable: boolean;
495
- sensitive: boolean;
496
- }>;
497
- };
498
-
499
- export async function getCrmRecordReadContext(
500
- recordId: string,
501
- ): Promise<CrmRecordReadContext | null> {
502
- const db = getDb();
503
- const [record] = await db
504
- .select({
505
- id: schema.crmRecords.id,
506
- connectionId: schema.crmRecords.connectionId,
507
- workspaceConnectionId: schema.crmConnections.workspaceConnectionId,
508
- provider: schema.crmRecords.provider,
509
- objectType: schema.crmRecords.objectType,
510
- kind: schema.crmRecords.kind,
511
- remoteId: schema.crmRecords.remoteId,
512
- accessScopeJson: schema.crmRecords.accessScopeJson,
513
- ownerEmail: schema.crmRecords.ownerEmail,
514
- orgId: schema.crmRecords.orgId,
515
- visibility: schema.crmRecords.visibility,
516
- })
517
- .from(schema.crmRecords)
518
- .innerJoin(
519
- schema.crmConnections,
520
- eq(schema.crmRecords.connectionId, schema.crmConnections.id),
521
- )
522
- .where(
523
- and(
524
- eq(schema.crmRecords.id, recordId),
525
- eq(schema.crmRecords.tombstone, false),
526
- accessFilter(schema.crmRecords, schema.crmRecordShares),
527
- accessFilter(schema.crmConnections, schema.crmConnectionShares),
528
- ),
529
- )
530
- .limit(1);
531
- if (!record) return null;
532
- const fieldPolicies = await db
533
- .select({
534
- fieldName: schema.crmFieldPolicies.fieldName,
535
- storagePolicy: schema.crmFieldPolicies.storagePolicy,
536
- readable: schema.crmFieldPolicies.readable,
537
- sensitive: schema.crmFieldPolicies.sensitive,
538
- })
539
- .from(schema.crmFieldPolicies)
540
- .where(
541
- and(
542
- eq(schema.crmFieldPolicies.connectionId, record.connectionId),
543
- eq(schema.crmFieldPolicies.objectType, record.objectType),
544
- accessFilter(schema.crmFieldPolicies, schema.crmFieldPolicyShares),
545
- ),
546
- );
547
- return {
548
- ...record,
549
- kind: record.kind as CrmListKind,
550
- visibility: record.visibility as "private" | "org" | "public",
551
- fieldPolicies: fieldPolicies as CrmRecordReadContext["fieldPolicies"],
552
- };
553
- }
554
-
555
- type ReadThroughRelationshipLocalRecord = {
556
- id: string;
557
- remoteId: string;
558
- objectType: string;
559
- displayName: string;
560
- kind: string;
561
- primaryEmail: string | null;
562
- domain: string | null;
563
- accessScopeJson: string;
564
- };
565
-
566
- type ReadThroughRelationshipData = {
567
- relationships: CrmRelationship[];
568
- localRecords: ReadThroughRelationshipLocalRecord[];
569
- summaries: Array<
570
- RelatedRecordSummary & { localId: string; remoteId: string }
571
- >;
572
- };
573
-
574
- async function readThroughRelationshipData(input: {
575
- context: CrmRecordReadContext;
576
- relationships: CrmRelationship[];
577
- currentScopes: Map<string, CrmAccessScope>;
578
- }): Promise<ReadThroughRelationshipData> {
579
- const relationships = input.relationships
580
- .filter(
581
- (relationship) =>
582
- relationship.from.connectionId === input.context.connectionId &&
583
- relationship.from.objectType === input.context.objectType &&
584
- relationship.from.remoteId === input.context.remoteId &&
585
- relationship.to.connectionId === input.context.connectionId,
586
- )
587
- .slice(0, 100);
588
- if (!relationships.length) {
589
- return { relationships: [], localRecords: [], summaries: [] };
590
- }
591
-
592
- const db = getDb();
593
- const remoteIds = Array.from(
594
- new Set(relationships.map((relationship) => relationship.to.remoteId)),
595
- );
596
- const objectTypes = Array.from(
597
- new Set(relationships.map((relationship) => relationship.to.objectType)),
598
- );
599
- const candidates = await db
600
- .select({
601
- id: schema.crmRecords.id,
602
- remoteId: schema.crmRecords.remoteId,
603
- objectType: schema.crmRecords.objectType,
604
- displayName: schema.crmRecords.displayName,
605
- kind: schema.crmRecords.kind,
606
- primaryEmail: schema.crmRecords.primaryEmail,
607
- domain: schema.crmRecords.domain,
608
- accessScopeJson: schema.crmRecords.accessScopeJson,
609
- })
610
- .from(schema.crmRecords)
611
- .where(
612
- and(
613
- eq(schema.crmRecords.connectionId, input.context.connectionId),
614
- eq(schema.crmRecords.tombstone, false),
615
- inArray(schema.crmRecords.remoteId, remoteIds),
616
- inArray(schema.crmRecords.objectType, objectTypes),
617
- accessFilter(schema.crmRecords, schema.crmRecordShares),
618
- ),
619
- );
620
- const localRecords = candidates.filter((record) => {
621
- const current = input.currentScopes.get(record.objectType);
622
- return Boolean(
623
- current &&
624
- scopesAreCompatible(parseCrmAccessScope(record.accessScopeJson), current),
625
- );
626
- });
627
- const summaries = relatedSummaries(
628
- input.context.remoteId,
629
- relationships,
630
- localRecords,
631
- );
632
- return { relationships, localRecords, summaries };
633
- }
634
-
635
- export async function getReadThroughRelationshipSummaries(input: {
636
- context: CrmRecordReadContext;
637
- relationships: CrmRelationship[];
638
- currentScopes: Map<string, CrmAccessScope>;
639
- }): Promise<RelatedRecordSummary[]> {
640
- const { summaries } = await readThroughRelationshipData(input);
641
- return summaries;
642
- }
643
-
644
- export async function persistReadThroughRelationships(input: {
645
- context: CrmRecordReadContext;
646
- relationships: CrmRelationship[];
647
- currentScopes: Map<string, CrmAccessScope>;
648
- }): Promise<RelatedRecordSummary[]> {
649
- await assertAccess("crm-record", input.context.id, "editor");
650
- const { relationships, localRecords, summaries } =
651
- await readThroughRelationshipData(input);
652
- if (!summaries.length) return [];
653
-
654
- const db = getDb();
655
- const relationshipByTarget = new Map(
656
- relationships.map((relationship) => [
657
- `${relationship.to.objectType}:${relationship.to.remoteId}:${relationship.relationshipType}`,
658
- relationship,
659
- ]),
660
- );
661
- const now = new Date().toISOString();
662
- await db.transaction(async (tx) => {
663
- for (const summary of summaries) {
664
- const target = localRecords.find((record) => record.id === summary.id);
665
- const relationship = target
666
- ? relationshipByTarget.get(
667
- `${target.objectType}:${summary.remoteId}:${summary.relationshipType}`,
668
- )
669
- : undefined;
670
- if (!relationship) continue;
671
- const [existing] = await tx
672
- .select({ id: schema.crmRelationships.id })
673
- .from(schema.crmRelationships)
674
- .where(
675
- and(
676
- eq(
677
- schema.crmRelationships.connectionId,
678
- input.context.connectionId,
679
- ),
680
- eq(schema.crmRelationships.fromRecordId, input.context.id),
681
- eq(schema.crmRelationships.toRecordId, summary.id),
682
- eq(
683
- schema.crmRelationships.relationshipType,
684
- relationship.relationshipType,
685
- ),
686
- accessFilter(schema.crmRelationships, schema.crmRelationshipShares),
687
- ),
688
- )
689
- .limit(1);
690
- const values = {
691
- label: relationship.label ?? null,
692
- inverseLabel: relationship.inverseLabel ?? null,
693
- sourceField: relationship.sourceField ?? null,
694
- tombstone: false,
695
- lastSyncedAt: now,
696
- updatedAt: now,
697
- };
698
- if (existing) {
699
- await tx
700
- .update(schema.crmRelationships)
701
- .set(values)
702
- .where(
703
- and(
704
- eq(schema.crmRelationships.id, existing.id),
705
- accessFilter(
706
- schema.crmRelationships,
707
- schema.crmRelationshipShares,
708
- undefined,
709
- "editor",
710
- ),
711
- ),
712
- );
713
- } else {
714
- await tx.insert(schema.crmRelationships).values({
715
- id: crypto.randomUUID(),
716
- connectionId: input.context.connectionId,
717
- fromRecordId: input.context.id,
718
- toRecordId: summary.id,
719
- relationshipType: relationship.relationshipType,
720
- ...values,
721
- ownerEmail: input.context.ownerEmail,
722
- orgId: input.context.orgId,
723
- visibility: input.context.visibility,
724
- createdAt: now,
725
- });
726
- }
727
- }
728
- });
729
- return summaries;
730
- }
731
-
732
- export async function getCrmRecord(
733
- recordId: string,
734
- readThrough?: {
735
- displayName?: string;
736
- fields?: Record<string, CrmValue>;
737
- remoteRevision?: string;
738
- remoteUpdatedAt?: string;
739
- relatedRecords?: RelatedRecordSummary[];
740
- accessScope?: CrmAccessScope;
741
- },
742
- ) {
743
- const db = getDb();
744
- const [record] = await db
745
- .select({
746
- id: schema.crmRecords.id,
747
- provider: schema.crmRecords.provider,
748
- displayName: schema.crmRecords.displayName,
749
- kind: schema.crmRecords.kind,
750
- primaryEmail: schema.crmRecords.primaryEmail,
751
- domain: schema.crmRecords.domain,
752
- stage: schema.crmRecords.stage,
753
- ownerName: schema.crmRecords.ownerName,
754
- desiredCadenceDays: schema.crmRecords.desiredCadenceDays,
755
- nextContactAt: schema.crmRecords.nextContactAt,
756
- remoteRevision: schema.crmRecords.remoteRevision,
757
- remoteUpdatedAt: schema.crmRecords.remoteUpdatedAt,
758
- updatedAt: schema.crmRecords.updatedAt,
759
- accessScopeJson: schema.crmRecords.accessScopeJson,
760
- })
761
- .from(schema.crmRecords)
762
- .where(
763
- and(
764
- accessFilter(schema.crmRecords, schema.crmRecordShares),
765
- eq(schema.crmRecords.id, recordId),
766
- eq(schema.crmRecords.tombstone, false),
767
- ),
768
- )
769
- .limit(1);
770
-
771
- if (!record) return null;
772
-
773
- const [fieldRows, activityRows, evidenceRows, taskRows] = await Promise.all([
774
- db
775
- .select({
776
- fieldName: schema.crmRecordFields.fieldName,
777
- valueType: schema.crmRecordFields.valueType,
778
- stringValue: schema.crmRecordFields.stringValue,
779
- numberValue: schema.crmRecordFields.numberValue,
780
- booleanValue: schema.crmRecordFields.booleanValue,
781
- jsonValue: schema.crmRecordFields.jsonValue,
782
- accessScopeJson: schema.crmRecordFields.accessScopeJson,
783
- })
784
- .from(schema.crmRecordFields)
785
- .where(
786
- and(
787
- accessFilter(schema.crmRecordFields, schema.crmRecordFieldShares),
788
- eq(schema.crmRecordFields.recordId, recordId),
789
- ),
790
- )
791
- .orderBy(desc(schema.crmRecordFields.updatedAt))
792
- .limit(MAX_RECORD_LIMIT),
793
- db
794
- .select({
795
- id: schema.crmInteractions.id,
796
- title: schema.crmInteractions.title,
797
- summary: schema.crmInteractions.summary,
798
- occurredAt: schema.crmInteractions.occurredAt,
799
- sourceApp: schema.crmInteractions.sourceApp,
800
- })
801
- .from(schema.crmInteractions)
802
- .where(
803
- and(
804
- accessFilter(schema.crmInteractions, schema.crmInteractionShares),
805
- eq(schema.crmInteractions.recordId, recordId),
806
- ),
807
- )
808
- .orderBy(desc(schema.crmInteractions.occurredAt))
809
- .limit(RECORD_DETAIL_LIMIT),
810
- db
811
- .select({
812
- id: schema.crmCallEvidence.id,
813
- artifactType: schema.crmCallEvidence.artifactType,
814
- quote: schema.crmCallEvidence.quote,
815
- sourceUrl: schema.crmCallEvidence.sourceUrl,
816
- capturedAt: schema.crmCallEvidence.capturedAt,
817
- summary: schema.crmCallEvidence.summary,
818
- })
819
- .from(schema.crmCallEvidence)
820
- .where(
821
- and(
822
- accessFilter(schema.crmCallEvidence, schema.crmCallEvidenceShares),
823
- eq(schema.crmCallEvidence.recordId, recordId),
824
- ),
825
- )
826
- .orderBy(desc(schema.crmCallEvidence.capturedAt))
827
- .limit(RECORD_DETAIL_LIMIT),
828
- db
829
- .select({
830
- id: schema.crmTasks.id,
831
- title: schema.crmTasks.title,
832
- status: schema.crmTasks.status,
833
- dueAt: schema.crmTasks.dueAt,
834
- recordId: schema.crmTasks.recordId,
835
- })
836
- .from(schema.crmTasks)
837
- .where(
838
- and(
839
- accessFilter(schema.crmTasks, schema.crmTaskShares),
840
- eq(schema.crmTasks.recordId, recordId),
841
- ),
842
- )
843
- .orderBy(desc(schema.crmTasks.updatedAt))
844
- .limit(RECORD_DETAIL_LIMIT),
845
- ]);
846
-
847
- return {
848
- ...toRecordSummary(record),
849
- provider: record.provider,
850
- ...(readThrough?.displayName
851
- ? { displayName: readThrough.displayName }
852
- : {}),
853
- ...(readThrough?.remoteUpdatedAt
854
- ? { updatedAt: readThrough.remoteUpdatedAt }
855
- : {}),
856
- ...(readThrough?.remoteRevision
857
- ? { remoteRevision: readThrough.remoteRevision }
858
- : record.remoteRevision
859
- ? { remoteRevision: record.remoteRevision }
860
- : {}),
861
- cadence: record.desiredCadenceDays
862
- ? `Every ${record.desiredCadenceDays} days`
863
- : undefined,
864
- fields: {
865
- ...Object.fromEntries(
866
- fieldRows.flatMap((field) => {
867
- const scope =
868
- readThrough?.accessScope ??
869
- parseCrmAccessScope(record.accessScopeJson);
870
- if (
871
- !scope ||
872
- !scopesAreCompatible(
873
- parseCrmAccessScope(field.accessScopeJson),
874
- scope,
875
- )
876
- ) {
877
- return [];
878
- }
879
- const value = parseStoredValue(field);
880
- return value === null ? [] : [[field.fieldName, value]];
881
- }),
882
- ),
883
- ...(readThrough?.fields ?? {}),
884
- },
885
- activity: activityRows.map((activity) => ({
886
- ...activity,
887
- actor: activity.sourceApp ?? undefined,
888
- })),
889
- evidence: evidenceRows.map((evidence) => ({
890
- id: evidence.id,
891
- label: evidence.summary || evidence.artifactType,
892
- quote: evidence.quote || undefined,
893
- url: evidence.sourceUrl,
894
- observedAt: evidence.capturedAt,
895
- })),
896
- tasks: taskRows,
897
- relatedRecords: readThrough?.relatedRecords ?? [],
898
- };
899
- }
900
-
901
- export async function listCrmTasks(input: {
902
- recordId?: string;
903
- status?: "open" | "done" | "cancelled";
904
- limit: number;
905
- cursor?: string;
906
- }) {
907
- const db = getDb();
908
- const offset = decodeCursor(input.cursor);
909
- const limit = Math.min(input.limit, MAX_RECORD_LIMIT);
910
- const conditions = [accessFilter(schema.crmTasks, schema.crmTaskShares)];
911
- if (input.recordId)
912
- conditions.push(eq(schema.crmTasks.recordId, input.recordId));
913
- if (input.status) conditions.push(eq(schema.crmTasks.status, input.status));
914
-
915
- const rows = await db
916
- .select({
917
- id: schema.crmTasks.id,
918
- title: schema.crmTasks.title,
919
- status: schema.crmTasks.status,
920
- dueAt: schema.crmTasks.dueAt,
921
- recordId: schema.crmTasks.recordId,
922
- assignedTo: schema.crmTasks.assignedTo,
923
- authority: schema.crmTasks.authority,
924
- updatedAt: schema.crmTasks.updatedAt,
925
- })
926
- .from(schema.crmTasks)
927
- .where(and(...conditions))
928
- .orderBy(desc(schema.crmTasks.dueAt), desc(schema.crmTasks.id))
929
- .limit(limit + 1)
930
- .offset(offset);
931
- const result = page(rows, limit);
932
-
933
- return {
934
- tasks: result.rows,
935
- nextCursor: result.nextCursor ? String(offset + limit) : undefined,
936
- complete: !result.nextCursor,
937
- };
938
- }
939
-
940
- export async function listCrmSavedViews(input: { limit: number }) {
941
- const rows = await getDb()
942
- .select({
943
- id: schema.crmSavedViews.id,
944
- name: schema.crmSavedViews.name,
945
- description: schema.crmSavedViews.description,
946
- kind: schema.crmSavedViews.kind,
947
- filtersJson: schema.crmSavedViews.filtersJson,
948
- dataProgramId: schema.crmSavedViews.dataProgramId,
949
- pinned: schema.crmSavedViews.pinned,
950
- updatedAt: schema.crmSavedViews.updatedAt,
951
- })
952
- .from(schema.crmSavedViews)
953
- .where(accessFilter(schema.crmSavedViews, schema.crmSavedViewShares))
954
- .orderBy(
955
- desc(schema.crmSavedViews.pinned),
956
- desc(schema.crmSavedViews.updatedAt),
957
- )
958
- .limit(Math.min(input.limit, MAX_RECORD_LIMIT));
959
-
960
- return {
961
- views: rows.map((view) => ({
962
- id: view.id,
963
- name: view.name,
964
- description: view.description || undefined,
965
- kind: view.kind ?? undefined,
966
- query: view.filtersJson === "{}" ? undefined : view.filtersJson,
967
- dataProgramId: view.dataProgramId ?? undefined,
968
- pinned: view.pinned,
969
- updatedAt: view.updatedAt,
970
- })),
971
- };
972
- }
973
-
974
- export async function listCrmSignals(input: {
975
- recordId: string;
976
- limit: number;
977
- }) {
978
- return getDb()
979
- .select({
980
- id: schema.crmSignals.id,
981
- label: schema.crmSignals.label,
982
- kind: schema.crmSignals.kind,
983
- confidence: schema.crmSignals.confidence,
984
- reviewStatus: schema.crmSignals.reviewStatus,
985
- evidenceId: schema.crmSignals.evidenceId,
986
- startSeconds: schema.crmSignals.startSeconds,
987
- createdAt: schema.crmSignals.createdAt,
988
- })
989
- .from(schema.crmSignals)
990
- .where(
991
- and(
992
- eq(schema.crmSignals.recordId, input.recordId),
993
- accessFilter(schema.crmSignals, schema.crmSignalShares),
994
- ),
995
- )
996
- .orderBy(desc(schema.crmSignals.createdAt))
997
- .limit(Math.min(Math.max(input.limit, 1), 100));
998
- }
999
-
1000
- export function safeProposalValues(value: string): Record<string, Primitive> {
1001
- const parsed = parseJsonObject(value);
1002
- const fields = parsed?.fields;
1003
- const source =
1004
- fields && typeof fields === "object" && !Array.isArray(fields)
1005
- ? (fields as Record<string, unknown>)
1006
- : (parsed ?? {});
1007
- return Object.fromEntries(
1008
- Object.entries(source)
1009
- .filter(
1010
- ([fieldName, fieldValue]) =>
1011
- fieldName.length <= 120 &&
1012
- isSafeCrmMutationFieldName(fieldName) &&
1013
- isBoundedCrmValue(fieldValue) &&
1014
- parsePrimitive(fieldValue),
1015
- )
1016
- .slice(0, 20),
1017
- ) as Record<string, Primitive>;
1018
- }
1019
-
1020
- export async function listCrmProposals(input: {
1021
- recordId?: string;
1022
- status?:
1023
- | "pending"
1024
- | "approved"
1025
- | "applied"
1026
- | "rejected"
1027
- | "conflict"
1028
- | "failed";
1029
- limit: number;
1030
- cursor?: string;
1031
- }) {
1032
- const db = getDb();
1033
- const offset = decodeCursor(input.cursor);
1034
- const limit = Math.min(input.limit, MAX_RECORD_LIMIT);
1035
- const conditions = [
1036
- accessFilter(schema.crmMutations, schema.crmMutationShares),
1037
- ];
1038
- if (input.recordId) {
1039
- conditions.push(eq(schema.crmMutations.recordId, input.recordId));
1040
- }
1041
- if (input.status)
1042
- conditions.push(eq(schema.crmMutations.status, input.status));
1043
-
1044
- const rows = await db
1045
- .select({
1046
- id: schema.crmMutations.id,
1047
- recordId: schema.crmMutations.recordId,
1048
- operation: schema.crmMutations.operation,
1049
- initiatedBy: schema.crmMutations.initiatedBy,
1050
- target: schema.crmMutations.target,
1051
- policyDecision: schema.crmMutations.policyDecision,
1052
- risk: schema.crmMutations.risk,
1053
- status: schema.crmMutations.status,
1054
- expectedRemoteRevision: schema.crmMutations.expectedRemoteRevision,
1055
- patchJson: schema.crmMutations.patchJson,
1056
- beforeJson: schema.crmMutations.beforeJson,
1057
- afterJson: schema.crmMutations.afterJson,
1058
- createdAt: schema.crmMutations.createdAt,
1059
- appliedAt: schema.crmMutations.appliedAt,
1060
- })
1061
- .from(schema.crmMutations)
1062
- .where(and(...conditions))
1063
- .orderBy(desc(schema.crmMutations.createdAt), desc(schema.crmMutations.id))
1064
- .limit(limit + 1)
1065
- .offset(offset);
1066
- const result = page(rows, limit);
1067
- const recordIds = result.rows
1068
- .map((row) => row.recordId)
1069
- .filter((recordId): recordId is string => Boolean(recordId));
1070
- const records = recordIds.length
1071
- ? await db
1072
- .select({
1073
- id: schema.crmRecords.id,
1074
- displayName: schema.crmRecords.displayName,
1075
- provider: schema.crmRecords.provider,
1076
- })
1077
- .from(schema.crmRecords)
1078
- .where(
1079
- and(
1080
- inArray(schema.crmRecords.id, recordIds),
1081
- accessFilter(schema.crmRecords, schema.crmRecordShares),
1082
- ),
1083
- )
1084
- : [];
1085
- const displayNameByRecordId = new Map(
1086
- records.map((record) => [record.id, record.displayName]),
1087
- );
1088
- const providerByRecordId = new Map(
1089
- records.map((record) => [record.id, record.provider]),
1090
- );
1091
-
1092
- return {
1093
- proposals: result.rows.map((proposal) => {
1094
- const patch = safeProposalValues(proposal.patchJson);
1095
- const before = safeProposalValues(proposal.beforeJson);
1096
- const after = safeProposalValues(proposal.afterJson);
1097
- const fieldNames = Array.from(
1098
- new Set([
1099
- ...Object.keys(before),
1100
- ...Object.keys(after),
1101
- ...Object.keys(patch),
1102
- ]),
1103
- ).slice(0, 20);
1104
- return {
1105
- id: proposal.id,
1106
- recordId: proposal.recordId,
1107
- ...(proposal.recordId && displayNameByRecordId.get(proposal.recordId)
1108
- ? { recordName: displayNameByRecordId.get(proposal.recordId) }
1109
- : {}),
1110
- ...(proposal.recordId && providerByRecordId.get(proposal.recordId)
1111
- ? { provider: providerByRecordId.get(proposal.recordId) }
1112
- : {}),
1113
- operation: proposal.operation,
1114
- initiatedBy: proposal.initiatedBy,
1115
- target: proposal.target,
1116
- policyDecision: proposal.policyDecision,
1117
- risk: proposal.risk,
1118
- status: proposal.status,
1119
- expectedRemoteRevision: proposal.expectedRemoteRevision,
1120
- createdAt: proposal.createdAt,
1121
- appliedAt: proposal.appliedAt,
1122
- fields: fieldNames.map((name) => ({
1123
- name,
1124
- ...(Object.prototype.hasOwnProperty.call(before, name)
1125
- ? { before: before[name] }
1126
- : {}),
1127
- ...(Object.prototype.hasOwnProperty.call(
1128
- Object.keys(after).length ? after : patch,
1129
- name,
1130
- )
1131
- ? { after: (Object.keys(after).length ? after : patch)[name] }
1132
- : {}),
1133
- })),
1134
- };
1135
- }),
1136
- nextCursor: result.nextCursor ? String(offset + limit) : undefined,
1137
- complete: !result.nextCursor,
1138
- };
1139
- }
1140
-
1141
- export async function getCrmOverview() {
1142
- const [taskResult, recordResult, proposalResult] = await Promise.all([
1143
- listCrmTasks({ status: "open", limit: 8 }),
1144
- listCrmRecords({ limit: 5 }),
1145
- listCrmProposals({ status: "pending", limit: 1 }),
1146
- ]);
1147
-
1148
- return {
1149
- tasks: taskResult.tasks,
1150
- records: recordResult.records,
1151
- focus: [
1152
- {
1153
- label: "Open follow-up",
1154
- value: String(taskResult.tasks.length),
1155
- detail: taskResult.complete
1156
- ? "Tasks currently due for attention."
1157
- : "Showing the first 8 tasks due for attention.",
1158
- },
1159
- ...(proposalResult.proposals.length
1160
- ? [
1161
- {
1162
- label: "Pending proposal",
1163
- value: "1+",
1164
- detail: "A CRM write is waiting for review.",
1165
- },
1166
- ]
1167
- : []),
1168
- ],
1169
- };
1170
- }