@agent-native/core 0.114.16 → 0.115.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +29 -0
  4. package/corpus/core/agent-native.eject.json +2 -0
  5. package/corpus/core/docs/content/agent-native-toolkit.mdx +16 -0
  6. package/corpus/core/docs/content/recurring-jobs.mdx +35 -6
  7. package/corpus/core/export-snapshot.json +4 -0
  8. package/corpus/core/package.json +5 -1
  9. package/corpus/core/src/action.ts +22 -1
  10. package/corpus/core/src/agent/production-agent.ts +105 -3
  11. package/corpus/core/src/cli/templates-meta.ts +12 -0
  12. package/corpus/core/src/client/AssistantChat.tsx +53 -26
  13. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +19 -0
  14. package/corpus/core/src/client/agent-page/use-jobs.ts +1 -0
  15. package/corpus/core/src/client/chat/message-components.tsx +35 -1
  16. package/corpus/core/src/client/chat/tool-call-display.tsx +38 -3
  17. package/corpus/core/src/connections/catalog.ts +20 -1
  18. package/corpus/core/src/connections/reader.ts +65 -0
  19. package/corpus/core/src/dashboard-storage/index.ts +27 -0
  20. package/corpus/core/src/dashboard-storage/panel-source.ts +168 -0
  21. package/corpus/core/src/dashboard-storage/schema.ts +62 -0
  22. package/corpus/core/src/dashboard-storage/store.ts +333 -0
  23. package/corpus/core/src/deploy/build.ts +95 -16
  24. package/corpus/core/src/eject/provider-api-definitions.ts +1 -0
  25. package/corpus/core/src/eject/workspace-connections.ts +1 -0
  26. package/corpus/core/src/extensions/actions.ts +199 -73
  27. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +2 -0
  28. package/corpus/core/src/jobs/scheduler.ts +71 -4
  29. package/corpus/core/src/jobs/tools.ts +31 -1
  30. package/corpus/core/src/localization/default-messages.ts +1 -0
  31. package/corpus/core/src/mcp-client/index.ts +6 -0
  32. package/corpus/core/src/provider-api/actions/provider-api.ts +1 -1
  33. package/corpus/core/src/provider-api/index.ts +190 -5
  34. package/corpus/core/src/secrets/register-framework-secrets.ts +8 -0
  35. package/corpus/core/src/server/agent-chat/context-tools.ts +9 -0
  36. package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
  37. package/corpus/core/src/server/agent-chat-plugin.ts +22 -2
  38. package/corpus/core/src/server/core-routes-plugin.ts +1 -0
  39. package/corpus/core/src/server/credential-provider.ts +9 -3
  40. package/corpus/core/src/server/workspace-provider-oauth.ts +181 -4
  41. package/corpus/core/src/styles/agent-native.css +45 -2
  42. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
  43. package/corpus/core/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
  44. package/corpus/core/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
  45. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
  46. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
  47. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
  48. package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
  49. package/corpus/core/src/triggers/actions.ts +11 -2
  50. package/corpus/core/src/triggers/dispatcher.ts +20 -1
  51. package/corpus/core/src/triggers/types.ts +5 -0
  52. package/corpus/core/src/vite/action-types-plugin.ts +9 -1
  53. package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +115 -0
  54. package/corpus/templates/analytics/AGENTS.md +11 -11
  55. package/corpus/templates/analytics/_gitignore +39 -0
  56. package/corpus/templates/analytics/actions/query-dashboard-panel.ts +30 -0
  57. package/corpus/templates/analytics/actions/update-dashboard.ts +2 -1
  58. package/corpus/templates/analytics/app/lib/sql-query.ts +11 -25
  59. package/corpus/templates/analytics/changelog/2026-07-21-fixed-extension-updates-failing-before-changes-could-be-appl.md +6 -0
  60. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +1 -0
  61. package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +51 -0
  62. package/corpus/templates/analytics/server/lib/prometheus.ts +1 -1
  63. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
  64. package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +115 -0
  65. package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +115 -0
  66. package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +115 -0
  67. package/corpus/templates/calendar/_gitignore +39 -0
  68. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
  69. package/corpus/templates/chat/AGENTS.md +1 -1
  70. package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +115 -0
  71. package/corpus/templates/clips/AGENTS.md +7 -0
  72. package/corpus/templates/clips/actions/prepare-crm-call-evidence.ts +58 -0
  73. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +88 -11
  74. package/corpus/templates/clips/changelog/2026-07-21-crm-call-evidence-handoff.md +6 -0
  75. package/corpus/templates/clips/changelog/2026-07-21-recording-retries-and-restarts-keep-their-upload-session-so-.md +6 -0
  76. package/corpus/templates/clips/chrome-extension/src/background.ts +20 -5
  77. package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +19 -0
  78. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -0
  79. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +9 -0
  80. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +54 -28
  81. package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
  82. package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +115 -0
  83. package/corpus/templates/content/_gitignore +39 -0
  84. package/corpus/templates/content/learnings.defaults.md +5 -0
  85. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +115 -0
  86. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
  87. package/corpus/templates/crm/.agents/skills/crm/SKILL.md +128 -0
  88. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  89. package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +169 -0
  90. package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
  91. package/corpus/templates/crm/.env.example +5 -0
  92. package/corpus/templates/crm/AGENTS.md +120 -0
  93. package/corpus/templates/crm/CHANGELOG.md +1 -0
  94. package/corpus/templates/crm/DEVELOPING.md +66 -0
  95. package/corpus/templates/crm/README.md +106 -0
  96. package/corpus/templates/crm/_gitignore +12 -0
  97. package/corpus/templates/crm/actions/_crm-action-utils.ts +87 -0
  98. package/corpus/templates/crm/actions/_crm-dashboard.ts +69 -0
  99. package/corpus/templates/crm/actions/_crm-signal-utils.ts +79 -0
  100. package/corpus/templates/crm/actions/apply-crm-proposals.ts +203 -0
  101. package/corpus/templates/crm/actions/attach-call-evidence.ts +170 -0
  102. package/corpus/templates/crm/actions/configure-crm-connection.ts +126 -0
  103. package/corpus/templates/crm/actions/configure-native-crm.ts +44 -0
  104. package/corpus/templates/crm/actions/create-crm-record.ts +148 -0
  105. package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +58 -0
  106. package/corpus/templates/crm/actions/delete-staged-dataset.ts +14 -0
  107. package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +36 -0
  108. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +33 -0
  109. package/corpus/templates/crm/actions/get-crm-dashboard.ts +14 -0
  110. package/corpus/templates/crm/actions/get-crm-overview.ts +13 -0
  111. package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +61 -0
  112. package/corpus/templates/crm/actions/get-crm-record.ts +75 -0
  113. package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +81 -0
  114. package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +15 -0
  115. package/corpus/templates/crm/actions/list-crm-dashboards.ts +15 -0
  116. package/corpus/templates/crm/actions/list-crm-proposals.ts +31 -0
  117. package/corpus/templates/crm/actions/list-crm-records.ts +79 -0
  118. package/corpus/templates/crm/actions/list-crm-saved-views.ts +15 -0
  119. package/corpus/templates/crm/actions/list-crm-signal-hits.ts +43 -0
  120. package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +32 -0
  121. package/corpus/templates/crm/actions/list-crm-tasks.ts +22 -0
  122. package/corpus/templates/crm/actions/list-staged-datasets.ts +14 -0
  123. package/corpus/templates/crm/actions/list-workspace-connections.ts +47 -0
  124. package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +87 -0
  125. package/corpus/templates/crm/actions/manage-crm-task.ts +132 -0
  126. package/corpus/templates/crm/actions/navigate.ts +63 -0
  127. package/corpus/templates/crm/actions/provider-api-catalog.ts +22 -0
  128. package/corpus/templates/crm/actions/provider-api-docs.ts +54 -0
  129. package/corpus/templates/crm/actions/provider-api-request.ts +92 -0
  130. package/corpus/templates/crm/actions/query-staged-dataset.ts +44 -0
  131. package/corpus/templates/crm/actions/record-crm-call-insight.ts +160 -0
  132. package/corpus/templates/crm/actions/record-crm-smart-signal.ts +150 -0
  133. package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +23 -0
  134. package/corpus/templates/crm/actions/review-crm-signal.ts +31 -0
  135. package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +103 -0
  136. package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +275 -0
  137. package/corpus/templates/crm/actions/run.ts +11 -0
  138. package/corpus/templates/crm/actions/save-crm-dashboard.ts +51 -0
  139. package/corpus/templates/crm/actions/save-crm-saved-view.ts +119 -0
  140. package/corpus/templates/crm/actions/sync-crm.ts +146 -0
  141. package/corpus/templates/crm/actions/update-crm-record.ts +508 -0
  142. package/corpus/templates/crm/actions/view-screen.ts +218 -0
  143. package/corpus/templates/crm/agent-native.app-skill.json +58 -0
  144. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +158 -0
  145. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +83 -0
  146. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +225 -0
  147. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +413 -0
  148. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +510 -0
  149. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +134 -0
  150. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +367 -0
  151. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +92 -0
  152. package/corpus/templates/crm/app/components/crm/Surface.tsx +96 -0
  153. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +180 -0
  154. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +106 -0
  155. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +84 -0
  156. package/corpus/templates/crm/app/entry.client.tsx +16 -0
  157. package/corpus/templates/crm/app/entry.server.tsx +10 -0
  158. package/corpus/templates/crm/app/global.css +167 -0
  159. package/corpus/templates/crm/app/hooks/use-navigation-state.ts +60 -0
  160. package/corpus/templates/crm/app/i18n/en-US.ts +89 -0
  161. package/corpus/templates/crm/app/i18n/index.ts +34 -0
  162. package/corpus/templates/crm/app/lib/dashboard.ts +13 -0
  163. package/corpus/templates/crm/app/lib/navigation.ts +54 -0
  164. package/corpus/templates/crm/app/lib/tab-id.ts +1 -0
  165. package/corpus/templates/crm/app/lib/types.ts +172 -0
  166. package/corpus/templates/crm/app/lib/utils.ts +1 -0
  167. package/corpus/templates/crm/app/root.tsx +88 -0
  168. package/corpus/templates/crm/app/routes/_index.tsx +26 -0
  169. package/corpus/templates/crm/app/routes/accounts.tsx +41 -0
  170. package/corpus/templates/crm/app/routes/agent.tsx +5 -0
  171. package/corpus/templates/crm/app/routes/ask.tsx +53 -0
  172. package/corpus/templates/crm/app/routes/dashboard.tsx +118 -0
  173. package/corpus/templates/crm/app/routes/opportunities.tsx +41 -0
  174. package/corpus/templates/crm/app/routes/people.tsx +41 -0
  175. package/corpus/templates/crm/app/routes/proposals.tsx +266 -0
  176. package/corpus/templates/crm/app/routes/records.$recordId.tsx +35 -0
  177. package/corpus/templates/crm/app/routes/settings.tsx +63 -0
  178. package/corpus/templates/crm/app/routes/setup.tsx +308 -0
  179. package/corpus/templates/crm/app/routes/tasks.tsx +252 -0
  180. package/corpus/templates/crm/app/routes/views.tsx +333 -0
  181. package/corpus/templates/crm/app/routes.ts +17 -0
  182. package/corpus/templates/crm/app/vite-env.d.ts +6 -0
  183. package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +6 -0
  184. package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +6 -0
  185. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +6 -0
  186. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +6 -0
  187. package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +6 -0
  188. package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +6 -0
  189. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +6 -0
  190. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +6 -0
  191. package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +6 -0
  192. package/corpus/templates/crm/components.json +20 -0
  193. package/corpus/templates/crm/docs/architecture/crm-contract.md +180 -0
  194. package/corpus/templates/crm/learnings.defaults.md +5 -0
  195. package/corpus/templates/crm/package.json +59 -0
  196. package/corpus/templates/crm/public/favicon.svg +1 -0
  197. package/corpus/templates/crm/public/icon-180.svg +1 -0
  198. package/corpus/templates/crm/public/manifest.json +11 -0
  199. package/corpus/templates/crm/react-router.config.ts +7 -0
  200. package/corpus/templates/crm/server/crm/adapter.ts +32 -0
  201. package/corpus/templates/crm/server/crm/crm-field-firewall.ts +64 -0
  202. package/corpus/templates/crm/server/crm/crm-mirror.ts +711 -0
  203. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +1143 -0
  204. package/corpus/templates/crm/server/crm/native-adapter.ts +1715 -0
  205. package/corpus/templates/crm/server/crm/read-through.ts +207 -0
  206. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +1255 -0
  207. package/corpus/templates/crm/server/db/crm-store.ts +1170 -0
  208. package/corpus/templates/crm/server/db/index.ts +169 -0
  209. package/corpus/templates/crm/server/db/schema.ts +441 -0
  210. package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +65 -0
  211. package/corpus/templates/crm/server/lib/intelligence/evidence.ts +105 -0
  212. package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +100 -0
  213. package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +144 -0
  214. package/corpus/templates/crm/server/lib/intelligence/summary.ts +141 -0
  215. package/corpus/templates/crm/server/lib/provider-api.ts +64 -0
  216. package/corpus/templates/crm/server/middleware/auth.ts +4 -0
  217. package/corpus/templates/crm/server/plugins/agent-chat.ts +68 -0
  218. package/corpus/templates/crm/server/plugins/auth.ts +14 -0
  219. package/corpus/templates/crm/server/plugins/core-routes.ts +17 -0
  220. package/corpus/templates/crm/server/plugins/db.ts +454 -0
  221. package/corpus/templates/crm/server/routes/[...page].get.ts +5 -0
  222. package/corpus/templates/crm/shared/crm-automation-recipes.ts +132 -0
  223. package/corpus/templates/crm/shared/crm-contract.ts +254 -0
  224. package/corpus/templates/crm/shared/crm-sales-config.ts +63 -0
  225. package/corpus/templates/crm/ssr-entry.ts +11 -0
  226. package/corpus/templates/crm/tsconfig.json +24 -0
  227. package/corpus/templates/crm/vite.config.ts +15 -0
  228. package/corpus/templates/crm/vitest.config.ts +5 -0
  229. package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +115 -0
  230. package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +115 -0
  231. package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +115 -0
  232. package/corpus/templates/forms/_gitignore +39 -0
  233. package/corpus/templates/forms/learnings.defaults.md +5 -0
  234. package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +115 -0
  235. package/corpus/templates/macros/_gitignore +39 -0
  236. package/corpus/templates/macros/learnings.defaults.md +5 -0
  237. package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +115 -0
  238. package/corpus/templates/mail/_gitignore +39 -0
  239. package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +115 -0
  240. package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +115 -0
  241. package/corpus/templates/slides/_gitignore +39 -0
  242. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +27 -0
  243. package/corpus/templates/tasks/_gitignore +39 -0
  244. package/corpus/toolkit/CHANGELOG.md +12 -0
  245. package/corpus/toolkit/README.md +30 -0
  246. package/corpus/toolkit/agent-native.eject.json +33 -0
  247. package/corpus/toolkit/package.json +15 -1
  248. package/corpus/toolkit/src/dashboard/DataTable.tsx +273 -0
  249. package/corpus/toolkit/src/dashboard/DateRangePicker.tsx +57 -0
  250. package/corpus/toolkit/src/dashboard/GenericChartPanel.tsx +461 -0
  251. package/corpus/toolkit/src/dashboard/MetricCard.tsx +54 -0
  252. package/corpus/toolkit/src/dashboard/StatsCard.tsx +49 -0
  253. package/corpus/toolkit/src/dashboard/dashboard-layout.ts +329 -0
  254. package/corpus/toolkit/src/dashboard/index.ts +6 -0
  255. package/corpus/toolkit/src/index.ts +1 -0
  256. package/corpus/toolkit/src/ui/calendar.tsx +8 -8
  257. package/corpus/toolkit/src/ui/date-picker.tsx +4 -1
  258. package/dist/action.d.ts +14 -1
  259. package/dist/action.d.ts.map +1 -1
  260. package/dist/action.js.map +1 -1
  261. package/dist/agent/production-agent.d.ts +3 -1
  262. package/dist/agent/production-agent.d.ts.map +1 -1
  263. package/dist/agent/production-agent.js +83 -3
  264. package/dist/agent/production-agent.js.map +1 -1
  265. package/dist/cli/templates-meta.d.ts.map +1 -1
  266. package/dist/cli/templates-meta.js +12 -0
  267. package/dist/cli/templates-meta.js.map +1 -1
  268. package/dist/client/AssistantChat.d.ts +4 -0
  269. package/dist/client/AssistantChat.d.ts.map +1 -1
  270. package/dist/client/AssistantChat.js +30 -17
  271. package/dist/client/AssistantChat.js.map +1 -1
  272. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
  273. package/dist/client/agent-page/AgentJobsTab.js +3 -1
  274. package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
  275. package/dist/client/agent-page/use-jobs.d.ts +1 -0
  276. package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
  277. package/dist/client/agent-page/use-jobs.js.map +1 -1
  278. package/dist/client/chat/message-components.d.ts +5 -0
  279. package/dist/client/chat/message-components.d.ts.map +1 -1
  280. package/dist/client/chat/message-components.js +17 -1
  281. package/dist/client/chat/message-components.js.map +1 -1
  282. package/dist/client/chat/tool-call-display.d.ts +3 -1
  283. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  284. package/dist/client/chat/tool-call-display.js +17 -7
  285. package/dist/client/chat/tool-call-display.js.map +1 -1
  286. package/dist/collab/awareness.d.ts +2 -2
  287. package/dist/collab/awareness.d.ts.map +1 -1
  288. package/dist/collab/routes.d.ts +1 -1
  289. package/dist/collab/struct-routes.d.ts +1 -1
  290. package/dist/connections/catalog.d.ts +17 -3
  291. package/dist/connections/catalog.d.ts.map +1 -1
  292. package/dist/connections/catalog.js +16 -1
  293. package/dist/connections/catalog.js.map +1 -1
  294. package/dist/connections/reader.d.ts +18 -0
  295. package/dist/connections/reader.d.ts.map +1 -1
  296. package/dist/connections/reader.js +41 -0
  297. package/dist/connections/reader.js.map +1 -1
  298. package/dist/dashboard-storage/index.d.ts +4 -0
  299. package/dist/dashboard-storage/index.d.ts.map +1 -0
  300. package/dist/dashboard-storage/index.js +4 -0
  301. package/dist/dashboard-storage/index.js.map +1 -0
  302. package/dist/dashboard-storage/panel-source.d.ts +68 -0
  303. package/dist/dashboard-storage/panel-source.d.ts.map +1 -0
  304. package/dist/dashboard-storage/panel-source.js +76 -0
  305. package/dist/dashboard-storage/panel-source.js.map +1 -0
  306. package/dist/dashboard-storage/schema.d.ts +562 -0
  307. package/dist/dashboard-storage/schema.d.ts.map +1 -0
  308. package/dist/dashboard-storage/schema.js +32 -0
  309. package/dist/dashboard-storage/schema.js.map +1 -0
  310. package/dist/dashboard-storage/store.d.ts +62 -0
  311. package/dist/dashboard-storage/store.d.ts.map +1 -0
  312. package/dist/dashboard-storage/store.js +227 -0
  313. package/dist/dashboard-storage/store.js.map +1 -0
  314. package/dist/deploy/build.d.ts +7 -0
  315. package/dist/deploy/build.d.ts.map +1 -1
  316. package/dist/deploy/build.js +78 -14
  317. package/dist/deploy/build.js.map +1 -1
  318. package/dist/eject/provider-api-definitions.d.ts +2 -1
  319. package/dist/eject/provider-api-definitions.d.ts.map +1 -1
  320. package/dist/eject/provider-api-definitions.js +1 -0
  321. package/dist/eject/provider-api-definitions.js.map +1 -1
  322. package/dist/eject/workspace-connections.d.ts.map +1 -1
  323. package/dist/eject/workspace-connections.js +1 -0
  324. package/dist/eject/workspace-connections.js.map +1 -1
  325. package/dist/extensions/actions.d.ts.map +1 -1
  326. package/dist/extensions/actions.js +165 -67
  327. package/dist/extensions/actions.js.map +1 -1
  328. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  329. package/dist/jobs/actions/list-recurring-jobs.d.ts +1 -0
  330. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
  331. package/dist/jobs/actions/list-recurring-jobs.js +1 -0
  332. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
  333. package/dist/jobs/scheduler.d.ts +17 -2
  334. package/dist/jobs/scheduler.d.ts.map +1 -1
  335. package/dist/jobs/scheduler.js +51 -2
  336. package/dist/jobs/scheduler.js.map +1 -1
  337. package/dist/jobs/tools.d.ts.map +1 -1
  338. package/dist/jobs/tools.js +32 -2
  339. package/dist/jobs/tools.js.map +1 -1
  340. package/dist/localization/default-messages.d.ts +1 -0
  341. package/dist/localization/default-messages.d.ts.map +1 -1
  342. package/dist/localization/default-messages.js +1 -0
  343. package/dist/localization/default-messages.js.map +1 -1
  344. package/dist/mcp-client/index.d.ts +2 -0
  345. package/dist/mcp-client/index.d.ts.map +1 -1
  346. package/dist/mcp-client/index.js +5 -0
  347. package/dist/mcp-client/index.js.map +1 -1
  348. package/dist/notifications/routes.d.ts +3 -3
  349. package/dist/observability/routes.d.ts +5 -5
  350. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  351. package/dist/provider-api/actions/provider-api.d.ts +8 -6
  352. package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
  353. package/dist/provider-api/actions/provider-api.js +1 -1
  354. package/dist/provider-api/actions/provider-api.js.map +1 -1
  355. package/dist/provider-api/index.d.ts +11 -7
  356. package/dist/provider-api/index.d.ts.map +1 -1
  357. package/dist/provider-api/index.js +143 -5
  358. package/dist/provider-api/index.js.map +1 -1
  359. package/dist/resources/handlers.d.ts +1 -1
  360. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  361. package/dist/secrets/register-framework-secrets.js +7 -0
  362. package/dist/secrets/register-framework-secrets.js.map +1 -1
  363. package/dist/secrets/routes.d.ts +9 -9
  364. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  365. package/dist/server/agent-chat/context-tools.js +9 -0
  366. package/dist/server/agent-chat/context-tools.js.map +1 -1
  367. package/dist/server/agent-chat/framework-prompts.js +2 -2
  368. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  369. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  370. package/dist/server/agent-chat-plugin.js +18 -2
  371. package/dist/server/agent-chat-plugin.js.map +1 -1
  372. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  373. package/dist/server/core-routes-plugin.js +1 -0
  374. package/dist/server/core-routes-plugin.js.map +1 -1
  375. package/dist/server/credential-provider.d.ts +4 -3
  376. package/dist/server/credential-provider.d.ts.map +1 -1
  377. package/dist/server/credential-provider.js +9 -3
  378. package/dist/server/credential-provider.js.map +1 -1
  379. package/dist/server/transcribe-voice.d.ts +1 -1
  380. package/dist/server/workspace-provider-oauth.d.ts +6 -1
  381. package/dist/server/workspace-provider-oauth.d.ts.map +1 -1
  382. package/dist/server/workspace-provider-oauth.js +141 -4
  383. package/dist/server/workspace-provider-oauth.js.map +1 -1
  384. package/dist/styles/agent-native.css +45 -2
  385. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
  386. package/dist/templates/chat/AGENTS.md +1 -1
  387. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
  388. package/dist/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
  389. package/dist/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
  390. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
  391. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
  392. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
  393. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
  394. package/dist/triggers/actions.d.ts.map +1 -1
  395. package/dist/triggers/actions.js +10 -2
  396. package/dist/triggers/actions.js.map +1 -1
  397. package/dist/triggers/dispatcher.d.ts.map +1 -1
  398. package/dist/triggers/dispatcher.js +15 -0
  399. package/dist/triggers/dispatcher.js.map +1 -1
  400. package/dist/triggers/types.d.ts +5 -0
  401. package/dist/triggers/types.d.ts.map +1 -1
  402. package/dist/triggers/types.js.map +1 -1
  403. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  404. package/dist/vite/action-types-plugin.js +4 -1
  405. package/dist/vite/action-types-plugin.js.map +1 -1
  406. package/docs/content/agent-native-toolkit.mdx +16 -0
  407. package/docs/content/recurring-jobs.mdx +35 -6
  408. package/package.json +6 -2
  409. package/src/action.ts +22 -1
  410. package/src/agent/production-agent.ts +105 -3
  411. package/src/cli/templates-meta.ts +12 -0
  412. package/src/client/AssistantChat.tsx +53 -26
  413. package/src/client/agent-page/AgentJobsTab.tsx +19 -0
  414. package/src/client/agent-page/use-jobs.ts +1 -0
  415. package/src/client/chat/message-components.tsx +35 -1
  416. package/src/client/chat/tool-call-display.tsx +38 -3
  417. package/src/connections/catalog.ts +20 -1
  418. package/src/connections/reader.ts +65 -0
  419. package/src/dashboard-storage/index.ts +27 -0
  420. package/src/dashboard-storage/panel-source.ts +168 -0
  421. package/src/dashboard-storage/schema.ts +62 -0
  422. package/src/dashboard-storage/store.ts +333 -0
  423. package/src/deploy/build.ts +95 -16
  424. package/src/eject/provider-api-definitions.ts +1 -0
  425. package/src/eject/workspace-connections.ts +1 -0
  426. package/src/extensions/actions.ts +199 -73
  427. package/src/jobs/actions/list-recurring-jobs.ts +2 -0
  428. package/src/jobs/scheduler.ts +71 -4
  429. package/src/jobs/tools.ts +31 -1
  430. package/src/localization/default-messages.ts +1 -0
  431. package/src/mcp-client/index.ts +6 -0
  432. package/src/provider-api/actions/provider-api.ts +1 -1
  433. package/src/provider-api/index.ts +190 -5
  434. package/src/secrets/register-framework-secrets.ts +8 -0
  435. package/src/server/agent-chat/context-tools.ts +9 -0
  436. package/src/server/agent-chat/framework-prompts.ts +2 -2
  437. package/src/server/agent-chat-plugin.ts +22 -2
  438. package/src/server/core-routes-plugin.ts +1 -0
  439. package/src/server/credential-provider.ts +9 -3
  440. package/src/server/workspace-provider-oauth.ts +181 -4
  441. package/src/styles/agent-native.css +45 -2
  442. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
  443. package/src/templates/chat/AGENTS.md +1 -1
  444. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
  445. package/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
  446. package/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
  447. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
  448. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
  449. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
  450. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
  451. package/src/triggers/actions.ts +11 -2
  452. package/src/triggers/dispatcher.ts +20 -1
  453. package/src/triggers/types.ts +5 -0
  454. package/src/vite/action-types-plugin.ts +9 -1
  455. package/corpus/templates/analytics/server/handlers/sql-query.ts +0 -36
  456. package/corpus/templates/analytics/server/routes/api/sql-query.post.ts +0 -1
@@ -73,6 +73,7 @@ export const PROVIDER_API_IDS = [
73
73
  "granola",
74
74
  "grafana",
75
75
  "hubspot",
76
+ "salesforce",
76
77
  "jira",
77
78
  "mixpanel",
78
79
  "notion",
@@ -384,6 +385,7 @@ export interface ProviderApiConfig {
384
385
  id: ProviderApiId;
385
386
  label: string;
386
387
  defaultBaseUrl: string;
388
+ requiresConnectionId?: boolean;
387
389
  baseUrlCredentialKey?: string;
388
390
  auth: ProviderApiAuthKind;
389
391
  credentialKeys: readonly string[];
@@ -1212,6 +1214,43 @@ const PROVIDER_CONFIGS: Record<ProviderApiId, ProviderApiConfig> = {
1212
1214
  },
1213
1215
  ],
1214
1216
  },
1217
+ salesforce: {
1218
+ id: "salesforce",
1219
+ label: "Salesforce",
1220
+ defaultBaseUrl: "https://login.salesforce.com",
1221
+ requiresConnectionId: true,
1222
+ auth: {
1223
+ type: "oauth-bearer",
1224
+ oauthProvider: "salesforce",
1225
+ tokenLabel: "Salesforce OAuth token",
1226
+ workspaceProvider: "salesforce",
1227
+ },
1228
+ credentialKeys: ["SALESFORCE_OAUTH_ACCOUNT"],
1229
+ docsUrls: [
1230
+ "https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/",
1231
+ ],
1232
+ allowedHostSuffixes: [],
1233
+ templateUses: ["analytics", "brain", "crm", "dispatch"],
1234
+ examples: [
1235
+ {
1236
+ label: "List recent Accounts",
1237
+ method: "GET",
1238
+ path: "/services/data/v60.0/sobjects/Account",
1239
+ },
1240
+ {
1241
+ label: "Query Opportunity records with SOQL",
1242
+ method: "GET",
1243
+ path: "/services/data/v60.0/query",
1244
+ query: {
1245
+ q: "SELECT Id, Name, StageName, Amount, CloseDate FROM Opportunity LIMIT 100",
1246
+ },
1247
+ },
1248
+ ],
1249
+ notes: [
1250
+ "Workspace OAuth stores the Salesforce instance URL on the connection. Requests with a connectionId use that instance instead of the login host.",
1251
+ "CRM templates own object allow-lists, field projections, and API-version selection.",
1252
+ ],
1253
+ },
1215
1254
  jira: {
1216
1255
  id: "jira",
1217
1256
  label: "Jira Cloud",
@@ -1574,6 +1613,7 @@ export function listProviderApiCatalog(
1574
1613
  id: config.id,
1575
1614
  label: config.label,
1576
1615
  defaultBaseUrl: config.defaultBaseUrl,
1616
+ requiresConnectionId: config.requiresConnectionId ?? false,
1577
1617
  baseUrlCredentialKey: config.baseUrlCredentialKey ?? null,
1578
1618
  auth: describeAuth(config.auth),
1579
1619
  credentialKeys: config.credentialKeys,
@@ -1749,6 +1789,11 @@ export async function executeProviderApiRequest(
1749
1789
 
1750
1790
  // --- built-in provider path (original code) ---
1751
1791
  const config = builtIn!;
1792
+ if (config.requiresConnectionId && !args.connectionId?.trim()) {
1793
+ throw new Error(
1794
+ `${config.label} Provider API requests require a workspace connectionId.`,
1795
+ );
1796
+ }
1752
1797
  const ctx = requireRuntimeCredentialContext(
1753
1798
  runtime,
1754
1799
  config.credentialKeys[0] ?? config.id,
@@ -1951,9 +1996,9 @@ export async function executeProviderApiRequest(
1951
1996
  }
1952
1997
 
1953
1998
  /**
1954
- * Resolve a provider OAuth token for a trusted server-side UI bridge such as
1955
- * Google Picker. Callers must keep the result out of agent, MCP, A2A, logs,
1956
- * persistence, and extension/tool surfaces.
1999
+ * Resolve a provider OAuth token for a trusted server-side integration bridge
2000
+ * such as a CRM adapter or Google Picker. Callers must keep the result out of
2001
+ * agent, MCP, A2A, logs, persistence, and extension/tool surfaces.
1957
2002
  */
1958
2003
  export async function resolveProviderApiOAuthAccessToken(
1959
2004
  args: {
@@ -3304,7 +3349,9 @@ async function resolveWorkspaceOAuthBaseUrl(
3304
3349
  auth.type === "oauth-bearer-or-basic"
3305
3350
  ? auth.workspaceProvider
3306
3351
  : undefined;
3307
- if (workspaceProvider !== "jira") return null;
3352
+ if (workspaceProvider !== "jira" && workspaceProvider !== "salesforce") {
3353
+ return null;
3354
+ }
3308
3355
  let resolved: Awaited<ReturnType<typeof resolveWorkspaceConnectionForApp>>;
3309
3356
  try {
3310
3357
  resolved = await resolveWorkspaceConnectionForApp({
@@ -3325,11 +3372,33 @@ async function resolveWorkspaceOAuthBaseUrl(
3325
3372
  if (!resolved.available || !resolved.connection) return null;
3326
3373
  const connectionConfig = resolved.connection.config;
3327
3374
  if (connectionConfig.credentialMode !== "oauth") return null;
3328
- const baseUrl = connectionConfig.atlassianApiBaseUrl;
3375
+ const baseUrl =
3376
+ workspaceProvider === "salesforce"
3377
+ ? connectionConfig.salesforceInstanceUrl
3378
+ : connectionConfig.atlassianApiBaseUrl;
3329
3379
  if (typeof baseUrl !== "string" || !baseUrl.trim()) return null;
3380
+ if (workspaceProvider === "salesforce" && !isSalesforceInstanceUrl(baseUrl)) {
3381
+ return null;
3382
+ }
3330
3383
  return baseUrl.replace(/\/+$/, "");
3331
3384
  }
3332
3385
 
3386
+ function isSalesforceInstanceUrl(value: string): boolean {
3387
+ try {
3388
+ const url = new URL(value);
3389
+ const host = url.hostname.toLowerCase();
3390
+ return (
3391
+ url.protocol === "https:" &&
3392
+ !url.username &&
3393
+ !url.password &&
3394
+ !url.port &&
3395
+ (host === "salesforce.com" || host.endsWith(".salesforce.com"))
3396
+ );
3397
+ } catch {
3398
+ return false;
3399
+ }
3400
+ }
3401
+
3333
3402
  async function resolvePlaceholders(
3334
3403
  config: ProviderApiConfig,
3335
3404
  runtime: ProviderApiRuntimeOptions,
@@ -4024,6 +4093,7 @@ async function resolveOAuthBearerToken(options: {
4024
4093
  ctx: CredentialContext;
4025
4094
  accountId?: string | null;
4026
4095
  ownerEmail?: string | null;
4096
+ salesforceLoginUrl?: string | null;
4027
4097
  }): Promise<ProviderApiResolvedCredential> {
4028
4098
  const ownerEmail = options.ownerEmail?.trim() || options.ctx.userEmail;
4029
4099
  const accounts = await listOAuthAccountsByOwner(
@@ -4050,6 +4120,7 @@ async function resolveOAuthBearerToken(options: {
4050
4120
  accountId: account.accountId,
4051
4121
  ownerEmail,
4052
4122
  tokens,
4123
+ salesforceLoginUrl: options.salesforceLoginUrl,
4053
4124
  });
4054
4125
  return {
4055
4126
  key: `${options.auth.oauthProvider.toUpperCase()}_OAUTH_TOKEN`,
@@ -4126,6 +4197,11 @@ async function resolveOptionalConnectionBoundOAuthBearerToken(options: {
4126
4197
  ctx: options.ctx,
4127
4198
  accountId: connectionAccountId,
4128
4199
  ownerEmail: resolved.connection.ownerEmail,
4200
+ salesforceLoginUrl:
4201
+ options.auth.oauthProvider === "salesforce" &&
4202
+ typeof resolved.connection.config?.salesforceLoginUrl === "string"
4203
+ ? resolved.connection.config.salesforceLoginUrl
4204
+ : null,
4129
4205
  });
4130
4206
  return {
4131
4207
  ...credential,
@@ -4139,6 +4215,7 @@ async function getValidOAuthAccessToken(options: {
4139
4215
  accountId: string;
4140
4216
  ownerEmail: string;
4141
4217
  tokens: OAuthTokens;
4218
+ salesforceLoginUrl?: string | null;
4142
4219
  }): Promise<string> {
4143
4220
  const accessToken =
4144
4221
  options.tokens.access_token ?? options.tokens.accessToken ?? "";
@@ -4177,6 +4254,9 @@ async function getValidOAuthAccessToken(options: {
4177
4254
  if (options.oauthProvider === "hubspot") {
4178
4255
  return refreshHubSpotOAuthToken(options, refreshToken);
4179
4256
  }
4257
+ if (options.oauthProvider === "salesforce") {
4258
+ return refreshSalesforceOAuthToken(options, refreshToken);
4259
+ }
4180
4260
  if (options.oauthProvider === "jira") {
4181
4261
  return refreshJiraOAuthToken(options, refreshToken);
4182
4262
  }
@@ -4484,6 +4564,102 @@ async function refreshHubSpotOAuthToken(
4484
4564
  return data.access_token;
4485
4565
  }
4486
4566
 
4567
+ async function refreshSalesforceOAuthToken(
4568
+ options: {
4569
+ oauthProvider: string;
4570
+ accountId: string;
4571
+ ownerEmail: string;
4572
+ tokens: OAuthTokens;
4573
+ salesforceLoginUrl?: string | null;
4574
+ },
4575
+ refreshToken: string,
4576
+ ): Promise<string> {
4577
+ const credentials =
4578
+ await resolveOAuthClientCredentialCandidates("SALESFORCE");
4579
+ if (!credentials.length) {
4580
+ throw new Error(
4581
+ "SALESFORCE_CLIENT_ID/SECRET not set for Salesforce OAuth refresh.",
4582
+ );
4583
+ }
4584
+
4585
+ let response: Response | null = null;
4586
+ let data: {
4587
+ access_token?: string;
4588
+ refresh_token?: string;
4589
+ expires_in?: number;
4590
+ token_type?: string;
4591
+ } = {};
4592
+ for (const credential of credentials) {
4593
+ const result = await fetchBoundedOAuthRefreshJson<{
4594
+ access_token?: string;
4595
+ refresh_token?: string;
4596
+ expires_in?: number;
4597
+ token_type?: string;
4598
+ }>(
4599
+ salesforceOAuthRefreshUrl(options.salesforceLoginUrl),
4600
+ {
4601
+ method: "POST",
4602
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
4603
+ body: new URLSearchParams({
4604
+ grant_type: "refresh_token",
4605
+ client_id: credential.clientId,
4606
+ client_secret: credential.clientSecret,
4607
+ refresh_token: refreshToken,
4608
+ }),
4609
+ },
4610
+ "Salesforce",
4611
+ );
4612
+ response = result.response;
4613
+ data = result.data;
4614
+ if (response.ok && data.access_token) break;
4615
+ }
4616
+
4617
+ if (!response?.ok || !data.access_token) {
4618
+ throw new Error(
4619
+ `Salesforce OAuth refresh failed (${response?.status ?? 0}).`,
4620
+ );
4621
+ }
4622
+ const updated = {
4623
+ ...options.tokens,
4624
+ access_token: data.access_token,
4625
+ refresh_token: data.refresh_token ?? refreshToken,
4626
+ token_type: data.token_type ?? options.tokens.token_type,
4627
+ ...(Number.isFinite(data.expires_in) && (data.expires_in ?? 0) > 0
4628
+ ? { expiry_date: Date.now() + (data.expires_in as number) * 1_000 }
4629
+ : {}),
4630
+ };
4631
+ await saveOAuthTokens(
4632
+ options.oauthProvider,
4633
+ options.accountId,
4634
+ updated as unknown as Record<string, unknown>,
4635
+ options.ownerEmail,
4636
+ );
4637
+ return data.access_token;
4638
+ }
4639
+
4640
+ function salesforceOAuthRefreshUrl(value: string | null | undefined): string {
4641
+ const loginUrl = value?.trim() || "https://login.salesforce.com";
4642
+ try {
4643
+ const url = new URL(loginUrl);
4644
+ if (
4645
+ url.protocol !== "https:" ||
4646
+ url.username ||
4647
+ url.password ||
4648
+ url.port ||
4649
+ url.pathname !== "/" ||
4650
+ url.search ||
4651
+ url.hash ||
4652
+ (url.hostname !== "login.salesforce.com" &&
4653
+ url.hostname !== "test.salesforce.com")
4654
+ ) {
4655
+ throw new Error("Invalid Salesforce OAuth login URL.");
4656
+ }
4657
+ return `${url.origin}/services/oauth2/token`;
4658
+ } catch {
4659
+ throw new Error("Invalid Salesforce OAuth login URL.");
4660
+ }
4661
+ }
4662
+
4487
4663
  async function refreshJiraOAuthToken(
4488
4664
  options: {
4489
4665
  oauthProvider: string;
@@ -4796,6 +4972,15 @@ async function resolveOAuthClientCredentialCandidates(
4796
4972
  ].filter((value): value is { clientId: string; clientSecret: string } =>
4797
4973
  Boolean(value),
4798
4974
  );
4975
+ if (provider === "SALESFORCE") {
4976
+ const [consumerKey, consumerSecret] = await Promise.all([
4977
+ resolveSecret("SALESFORCE_CONSUMER_KEY"),
4978
+ resolveSecret("SALESFORCE_CONSUMER_SECRET"),
4979
+ ]);
4980
+ if (consumerKey && consumerSecret) {
4981
+ candidates.push({ clientId: consumerKey, clientSecret: consumerSecret });
4982
+ }
4983
+ }
4799
4984
  const seen = new Set<string>();
4800
4985
  return candidates.filter((candidate) => {
4801
4986
  if (seen.has(candidate.clientId)) return false;
@@ -48,6 +48,14 @@ export function registerFrameworkSecrets(): void {
48
48
  docsUrl:
49
49
  "https://developers.hubspot.com/docs/apps/developer-platform/build-apps/authentication/oauth/oauth-quickstart-guide",
50
50
  },
51
+ {
52
+ id: "salesforce",
53
+ credentialPrefix: "SALESFORCE",
54
+ oauthProvider: "salesforce",
55
+ label: "Salesforce",
56
+ docsUrl:
57
+ "https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_web_server_oauth_flow.htm",
58
+ },
51
59
  {
52
60
  id: "jira",
53
61
  credentialPrefix: "JIRA",
@@ -97,6 +97,15 @@ Convert natural language to 5-field cron format:
97
97
  - "every hour" → \`0 * * * *\`
98
98
  - "every monday at 9am" → \`0 9 * * 1\`
99
99
 
100
+ When a recurring job needs a connected MCP, discover the exact MCP tool names
101
+ available in the current user/org context and pass them in the create call's
102
+ \`mcpTools\` array. Bind only the tools the job needs; do not put an MCP URL,
103
+ OAuth token, or arbitrary endpoint in the instructions. The scheduler resolves
104
+ the selected tools with the job owner's existing connector grant and fails
105
+ clearly if a connector is revoked or a selected tool disappears. For imports,
106
+ normalize the provider response and call the app's bounded idempotent import
107
+ action once with the full batch rather than issuing one write per item.
108
+
100
109
  #### Suggesting "Save as automation"
101
110
 
102
111
  When you finish a task that has obvious recurring value — daily inbox triage, weekly metrics summaries, archive sweeps, status digests, anything the user would plausibly want re-run on a fresh cadence — close the response with ONE short line offering to save it. Examples:
@@ -74,7 +74,7 @@ Keep \`create-extension\` payloads compact enough to finish quickly. For complex
74
74
 
75
75
  Generated UI content can use appAction(), appFetch(), dbQuery(), extensionFetch(), extensionData, agentNative.ui.output(value, opts?), and agentNative.chat.send(...)/sendToAgentChat(...). Use appAction() for app data writes, and dbQuery() only for read-only inspection of known app SQL tables. It can receive chat inputs through slotContext/window.onSlotContext. Use agentNative.ui.output for passive current values from knobs, sliders, selections, and controls; it writes application state at \`inline-ui:<extensionId>:output\` scoped to the inline extension id returned by \`render-inline-extension\` or \`show-extension-inline\`. When the user later says "use that value", "apply the current setting", or similar, read it with \`readAppState("inline-ui:<id>:output")\` instead of asking them to send it again. Use agentNative.chat.send for visible submit/apply actions that should put a message into chat. Transient extensionData is browser-local and not agent-readable, synced, promoted, or garbage-collected; use application_state/appFetch, appAction, ui.output, or chat.send for anything the agent or app must observe. Use semantic Tailwind classes like bg-background, text-foreground, bg-primary, border-border, and text-muted-foreground so the UI inherits the parent app theme.
76
76
 
77
- If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then \`update-extension\` with that id. After one content read, keep the body in working memory and move to focused \`update-extension\` \`edits\`/\`patches\`; do not loop on repeated \`get-extension\` + \`run-code\` string scans before writing. For a data-only repair, preserve the existing layout, CSS, copy, and interactions: never send a reconstructed full \`content\` body. The update action blocks full-body replacement by default; use \`allowFullReplacement=true\` only when the user explicitly requests a broad visual rewrite or supplies a complete replacement body. If a focused patch fails, read the current body and change the target rather than retrying identical arguments. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes, even when the request says "change the UI" or "fix this". Do **NOT** call \`connect-builder\` for existing extension edits.
77
+ If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then call \`update-extension\` with exactly \`id\`, \`operation\`, and \`payloadJson\`; encode the operation payload as a JSON string and never send empty placeholder fields. After one content read, keep the body in working memory and use \`operation="edit"\` with focused \`edits\`/\`patches\` inside \`payloadJson\`; do not loop on repeated \`get-extension\` + \`run-code\` string scans before writing. For a data-only repair, preserve the existing layout, CSS, copy, and interactions. Use \`operation="replace"\` only when the user explicitly requests a broad visual rewrite or supplies a complete replacement body. Use \`operation="metadata"\` for name/description/icon, and use \`set-resource-visibility\` for sharing changes. If a focused patch fails, read the current body and change the target rather than retrying identical arguments. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes, even when the request says "change the UI" or "fix this". Do **NOT** call \`connect-builder\` for existing extension edits.
78
78
 
79
79
  In Act mode, when in doubt — if the request asks for a new small interactive utility and does not need reuse, choose \`render-inline-extension\`; if it mentions saving/reuse or asks for an extension/widget/dashboard/calculator/mini-app, choose \`create-extension\`. If it references an existing one or the current extension page, choose \`update-extension\`. Do **not** preface the call with planning text like "let me build the dashboard…" — just call the right extension action directly.
80
80
 
@@ -115,7 +115,7 @@ Keep the first \`create-extension\` call compact and working. If the request is
115
115
 
116
116
  Generated UI can read chat inputs from slotContext/window.onSlotContext, see/update app state through appFetch/appAction, use extensionData, record passive current values through agentNative.ui.output(value, opts?), and send visible results through agentNative.chat.send(...) or sendToAgentChat(...). ui.output writes \`inline-ui:<extensionId>:output\` in application state; when the user asks to use the current slider/selection/value, read \`readAppState("inline-ui:<id>:output")\`. Transient extensionData is browser-local only, so do not rely on it for values the agent or app must observe. Use semantic Tailwind theme classes.
117
117
 
118
- If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then \`update-extension\` with that id. After one content read, use focused \`update-extension\` \`edits\`/\`patches\`; do not repeatedly re-read and scan the same HTML with \`run-code\` before writing. For a data-only repair, preserve the existing layout, CSS, copy, and interactions: never send a reconstructed full \`content\` body. The update action blocks full-body replacement by default; use \`allowFullReplacement=true\` only when the user explicitly requests a broad visual rewrite or supplies a complete replacement body. If a focused patch fails, read the current body and change the target rather than retrying identical arguments. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes. Do NOT call \`connect-builder\` for them.
118
+ If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then call \`update-extension\` with exactly \`id\`, \`operation\`, and \`payloadJson\`; encode the operation payload as a JSON string and never send empty placeholder fields. After one content read, use \`operation="edit"\` with focused \`edits\`/\`patches\` inside \`payloadJson\`; do not repeatedly re-read and scan the same HTML with \`run-code\` before writing. For a data-only repair, preserve the existing layout, CSS, copy, and interactions. Use \`operation="replace"\` only when the user explicitly requests a broad visual rewrite or supplies a complete replacement body. Use \`operation="metadata"\` for name/description/icon, and use \`set-resource-visibility\` for sharing changes. If a focused patch fails, read the current body and change the target rather than retrying identical arguments. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes. Do NOT call \`connect-builder\` for them.
119
119
 
120
120
  For existing extensions, use \`get-extension\` or \`update-extension\` directly when \`<current-screen>\` or \`<current-url>\` provides an \`extensionId\`. Use \`list-extensions\` only to browse or resolve an unknown name. Use \`hide-extension\` when the user wants a shared extension removed only from their own view. Do not query the legacy \`tools\` table directly.
121
121
 
@@ -124,6 +124,7 @@ import {
124
124
  verifyInternalToken,
125
125
  extractBearerToken,
126
126
  } from "../integrations/internal-token.js";
127
+ import type { RecurringJobContext } from "../jobs/scheduler.js";
127
128
  import {
128
129
  McpClientManager,
129
130
  loadMcpConfig,
@@ -575,6 +576,22 @@ export function createAgentChatPlugin(
575
576
  }
576
577
  setGlobalMcpManager(mcpManager);
577
578
  const mcpActionEntries = mcpToolsToActionEntries(mcpManager);
579
+ const getJobMcpActionEntries = (
580
+ job?: RecurringJobContext,
581
+ ): Record<string, ActionEntry> => {
582
+ const requested = job?.meta.mcpTools ?? [];
583
+ if (requested.length === 0) return {};
584
+ const entries = mcpToolsToActionEntries(mcpManager, {
585
+ toolNames: requested,
586
+ });
587
+ const missing = requested.filter((toolName) => !entries[toolName]);
588
+ if (missing.length > 0) {
589
+ throw new Error(
590
+ `Configured MCP tools are unavailable in this run: ${missing.join(", ")}. Reconnect the MCP server or update the job's capability list.`,
591
+ );
592
+ }
593
+ return entries;
594
+ };
578
595
 
579
596
  // Mount status + management routes so the settings UI can list / add /
580
597
  // remove remote MCP servers and hot-reload the running manager.
@@ -2632,6 +2649,7 @@ export function createAgentChatPlugin(
2632
2649
  // through the settings UI). getEngineTools() in production-agent re-reads
2633
2650
  // the registry per request, so updates here propagate without restart.
2634
2651
  mcpManager.onChange(() => {
2652
+ syncMcpActionEntries(mcpManager, mcpActionEntries);
2635
2653
  syncMcpActionEntries(mcpManager, prodActions);
2636
2654
  });
2637
2655
 
@@ -5524,7 +5542,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5524
5542
  const { processRecurringJobs } = await import("../jobs/scheduler.js");
5525
5543
 
5526
5544
  const schedulerDeps = {
5527
- getActions: () => ({
5545
+ getActions: (job?: RecurringJobContext) => ({
5528
5546
  ...templateScripts,
5529
5547
  ...resourceScripts,
5530
5548
  ...docsScripts,
@@ -5537,6 +5555,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5537
5555
  ...fetchTool,
5538
5556
  ...webSearchTool,
5539
5557
  ...toolActions,
5558
+ ...getJobMcpActionEntries(job),
5540
5559
  }),
5541
5560
  getSystemPrompt: async (owner: string) => {
5542
5561
  const resources = await loadResourcesForPrompt(
@@ -5557,10 +5576,11 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5557
5576
  // first request on the same compact surface as interactive chat
5558
5577
  // instead of the full jobTools/automationTools/notificationTools/
5559
5578
  // fetchTool/webSearchTool/toolActions catalog every tick.
5560
- getInitialToolNames: () => [
5579
+ getInitialToolNames: (job?: RecurringJobContext) => [
5561
5580
  ...effectiveInitialToolNames,
5562
5581
  "manage-jobs",
5563
5582
  "manage-progress",
5583
+ ...(job?.meta.mcpTools ?? []),
5564
5584
  ],
5565
5585
  apiKey: options?.apiKey,
5566
5586
  model: options?.model,
@@ -1233,6 +1233,7 @@ export function createCoreRoutesPlugin(
1233
1233
  "google_drive",
1234
1234
  "github",
1235
1235
  "hubspot",
1236
+ "salesforce",
1236
1237
  "jira",
1237
1238
  "sentry",
1238
1239
  "notion",
@@ -75,6 +75,9 @@ export function readDeployCredentialEnv(key: string): string | undefined {
75
75
 
76
76
  const APP_PROVIDED_DEPLOY_CREDENTIAL_KEYS = new Set([
77
77
  "ANTHROPIC_API_KEY",
78
+ "EMAIL_FROM",
79
+ "EMAIL_INBOUND_WEBHOOK_SECRET",
80
+ "EMAIL_AGENT_ADDRESS",
78
81
  "OPENAI_API_KEY",
79
82
  "OPENAI_BASE_URL",
80
83
  "OPENROUTER_API_KEY",
@@ -84,6 +87,8 @@ const APP_PROVIDED_DEPLOY_CREDENTIAL_KEYS = new Set([
84
87
  "GROQ_API_KEY",
85
88
  "MISTRAL_API_KEY",
86
89
  "COHERE_API_KEY",
90
+ "RESEND_API_KEY",
91
+ "SENDGRID_API_KEY",
87
92
  ]);
88
93
 
89
94
  function isAppProvidedDeployCredentialKey(key: string | undefined): boolean {
@@ -97,9 +102,10 @@ function isAppProvidedDeployCredentialKey(key: string | undefined): boolean {
97
102
  * identity-bearing provider keys so one deploy key does not silently
98
103
  * impersonate another tenant. App-provided service credentials are different:
99
104
  * they configure the deployed app itself rather than identifying a user. This
100
- * includes LLM keys that let the app developer pay for model usage and OAuth
101
- * client credentials whose per-user identity remains in scoped OAuth tokens.
102
- * Key-aware callers may use those env vars.
105
+ * includes LLM keys that let the app developer pay for model usage, email
106
+ * transport configuration owned by the deployment, and OAuth client
107
+ * credentials whose per-user identity remains in scoped OAuth tokens. Key-aware
108
+ * callers may use those env vars.
103
109
  *
104
110
  * @deprecated Use `canUseDeployCredentialFallbackForRequest()` for generic
105
111
  * provider secrets. This stricter helper remains for legacy call sites with