@agent-native/core 0.118.0 → 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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +21 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +32 -10
- package/corpus/core/src/cli/index.ts +18 -10
- package/corpus/core/src/cli/multi-frontier-runs.ts +5 -3
- package/corpus/core/src/cli/templates-meta.ts +0 -12
- package/corpus/core/src/cli/workspace-dev.ts +1 -1
- package/corpus/core/src/client/AgentPanel.tsx +9 -1
- package/corpus/core/src/client/RunStuckBanner.tsx +39 -47
- package/corpus/core/src/client/chat/action-chat-ui-surface.tsx +32 -0
- package/corpus/core/src/client/chat/message-components.tsx +53 -8
- package/corpus/core/src/client/chat/tool-call-display.tsx +24 -9
- package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
- package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
- package/corpus/core/src/client/conversation/AgentConversation.tsx +12 -1
- package/corpus/core/src/client/error-capture.ts +2 -6
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +20 -14
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -17
- package/corpus/core/src/client/resources/mcp-integration-logos.ts +2 -2
- package/corpus/core/src/client/route-chunk-recovery.ts +5 -3
- package/corpus/core/src/client/session-replay.ts +3 -3
- package/corpus/core/src/client/settings/SettingsPanel.tsx +15 -6
- package/corpus/core/src/client/transcription/use-live-transcription.ts +64 -45
- package/corpus/core/src/deploy/build.ts +2 -1
- package/corpus/core/src/guards/db-tool-scoping.ts +1 -1
- package/corpus/core/src/integrations/adapters/slack.ts +84 -5
- package/corpus/core/src/integrations/index.ts +5 -1
- package/corpus/core/src/localization/default-messages.ts +1 -1
- package/corpus/core/src/mcp-client/oauth-routes.ts +45 -12
- package/corpus/core/src/server/realtime-voice.ts +4 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
- package/corpus/core/src/terminal/cli-registry.ts +1 -1
- package/corpus/core/src/vite/client.ts +166 -1
- package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +13 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewsMenu.tsx +10 -0
- package/corpus/templates/analytics/changelog/2026-07-22-show-a-useful-error-when-saving-a-dashboard-view-fails.md +6 -0
- package/corpus/templates/brain/app/routes/sources.tsx +181 -114
- package/corpus/templates/clips/AGENTS.md +8 -6
- package/corpus/templates/clips/actions/request-transcript.ts +90 -420
- package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -28
- package/corpus/templates/clips/app/components/capture-install-options.tsx +5 -3
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +3 -136
- package/corpus/templates/clips/app/lib/capture-install-options.ts +15 -4
- package/corpus/templates/clips/app/routes/download.tsx +3 -2
- package/corpus/templates/clips/changelog/2026-07-22-fixed-an-intermittent-hydration-error-on-the-download-page.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-22-fixed-transcript-generation-when-native-speech-capture-retur.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-22-transcript-generation-now-retries-with-backup-speech-recogni.md +6 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +2 -2
- package/corpus/templates/clips/server/register-secrets.ts +7 -6
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +16 -84
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +13 -7
- package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +2 -2
- package/corpus/templates/content/app/i18n-data.ts +10 -0
- package/corpus/templates/design/server/lib/fig-file-decoder.ts +1 -0
- package/corpus/templates/plan/app/entry.client.tsx +3 -0
- package/corpus/templates/plan/changelog/2026-07-22-recover-stale-pages-after-a-deployment-refresh-automatically.md +6 -0
- package/corpus/templates/slides/app/hooks/use-agent-generating.ts +10 -3
- package/corpus/templates/slides/app/pages/Index.tsx +1 -0
- package/corpus/templates/slides/changelog/2026-07-22-new-deck-prompts-now-open-in-their-own-visible-chat-thread.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +9 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/PromptComposer.tsx +5 -1
- package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +119 -31
- package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +30 -0
- package/corpus/toolkit/src/conformance/runner.tsx +153 -1
- package/corpus/toolkit/src/editor/SharedRichEditor.tsx +13 -2
- package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +20 -0
- package/corpus/toolkit/src/editor/index.ts +2 -0
- package/corpus/toolkit/src/styles.css +52 -23
- package/dist/a2a/client.d.ts +3 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +17 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/cli/index.js +18 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/multi-frontier-runs.js +3 -3
- package/dist/cli/multi-frontier-runs.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +0 -12
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspace-dev.js +1 -1
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +4 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/RunStuckBanner.d.ts +3 -5
- package/dist/client/RunStuckBanner.d.ts.map +1 -1
- package/dist/client/RunStuckBanner.js +17 -18
- package/dist/client/RunStuckBanner.js.map +1 -1
- package/dist/client/chat/action-chat-ui-surface.d.ts +8 -0
- package/dist/client/chat/action-chat-ui-surface.d.ts.map +1 -0
- package/dist/client/chat/action-chat-ui-surface.js +10 -0
- package/dist/client/chat/action-chat-ui-surface.js.map +1 -0
- package/dist/client/chat/message-components.d.ts +3 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +40 -7
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +3 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +13 -9
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.js +1 -1
- package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js +5 -3
- package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +3 -2
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +2 -2
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.js +9 -8
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +3 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +4 -17
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/mcp-integration-logos.js +2 -2
- package/dist/client/resources/mcp-integration-logos.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +5 -3
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.js +3 -3
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +2 -2
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/transcription/use-live-transcription.d.ts +3 -3
- package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
- package/dist/client/transcription/use-live-transcription.js +22 -11
- package/dist/client/transcription/use-live-transcription.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +1 -1
- package/dist/deploy/build.js.map +1 -1
- package/dist/guards/db-tool-scoping.js +1 -1
- package/dist/guards/db-tool-scoping.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +61 -5
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/index.d.ts +1 -1
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -1
- package/dist/integrations/index.js.map +1 -1
- package/dist/localization/default-messages.js +1 -1
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp-client/oauth-routes.d.ts +3 -0
- package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
- package/dist/mcp-client/oauth-routes.js +41 -12
- package/dist/mcp-client/oauth-routes.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +1 -1
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
- package/dist/terminal/cli-registry.js +1 -1
- package/dist/terminal/cli-registry.js.map +1 -1
- package/dist/vite/client.d.ts +8 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +113 -2
- package/dist/vite/client.js.map +1 -1
- package/package.json +2 -2
- package/src/a2a/client.ts +32 -10
- package/src/cli/index.ts +18 -10
- package/src/cli/multi-frontier-runs.ts +5 -3
- package/src/cli/templates-meta.ts +0 -12
- package/src/cli/workspace-dev.ts +1 -1
- package/src/client/AgentPanel.tsx +9 -1
- package/src/client/RunStuckBanner.tsx +39 -47
- package/src/client/chat/action-chat-ui-surface.tsx +32 -0
- package/src/client/chat/message-components.tsx +53 -8
- package/src/client/chat/tool-call-display.tsx +24 -9
- package/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
- package/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
- package/src/client/conversation/AgentConversation.tsx +12 -1
- package/src/client/error-capture.ts +2 -6
- package/src/client/resources/McpConnectionSuggestion.tsx +20 -14
- package/src/client/resources/ResourcesPanel.tsx +5 -1
- package/src/client/resources/mcp-integration-catalog.ts +7 -17
- package/src/client/resources/mcp-integration-logos.ts +2 -2
- package/src/client/route-chunk-recovery.ts +5 -3
- package/src/client/session-replay.ts +3 -3
- package/src/client/settings/SettingsPanel.tsx +15 -6
- package/src/client/transcription/use-live-transcription.ts +64 -45
- package/src/deploy/build.ts +2 -1
- package/src/guards/db-tool-scoping.ts +1 -1
- package/src/integrations/adapters/slack.ts +84 -5
- package/src/integrations/index.ts +5 -1
- package/src/localization/default-messages.ts +1 -1
- package/src/mcp-client/oauth-routes.ts +45 -12
- package/src/server/realtime-voice.ts +4 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
- package/src/terminal/cli-registry.ts +1 -1
- package/src/vite/client.ts +166 -1
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +0 -115
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
- package/corpus/templates/crm/.agents/skills/crm/SKILL.md +0 -128
- package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +0 -220
- package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +0 -169
- package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +0 -100
- package/corpus/templates/crm/.env.example +0 -5
- package/corpus/templates/crm/AGENTS.md +0 -120
- package/corpus/templates/crm/CHANGELOG.md +0 -1
- package/corpus/templates/crm/DEVELOPING.md +0 -66
- package/corpus/templates/crm/README.md +0 -106
- package/corpus/templates/crm/_gitignore +0 -12
- package/corpus/templates/crm/actions/_crm-action-utils.ts +0 -87
- package/corpus/templates/crm/actions/_crm-dashboard.ts +0 -69
- package/corpus/templates/crm/actions/_crm-data-program-actions.ts +0 -15
- package/corpus/templates/crm/actions/_crm-signal-utils.ts +0 -79
- package/corpus/templates/crm/actions/apply-crm-proposals.ts +0 -203
- package/corpus/templates/crm/actions/attach-call-evidence.ts +0 -170
- package/corpus/templates/crm/actions/configure-crm-connection.ts +0 -126
- package/corpus/templates/crm/actions/configure-native-crm.ts +0 -44
- package/corpus/templates/crm/actions/create-crm-record.ts +0 -148
- package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +0 -58
- package/corpus/templates/crm/actions/delete-staged-dataset.ts +0 -14
- package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +0 -36
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +0 -35
- package/corpus/templates/crm/actions/get-crm-dashboard.ts +0 -14
- package/corpus/templates/crm/actions/get-crm-overview.ts +0 -13
- package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +0 -61
- package/corpus/templates/crm/actions/get-crm-record.ts +0 -75
- package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +0 -81
- package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +0 -15
- package/corpus/templates/crm/actions/list-crm-dashboards.ts +0 -15
- package/corpus/templates/crm/actions/list-crm-proposals.ts +0 -31
- package/corpus/templates/crm/actions/list-crm-records.ts +0 -79
- package/corpus/templates/crm/actions/list-crm-saved-views.ts +0 -15
- package/corpus/templates/crm/actions/list-crm-signal-hits.ts +0 -43
- package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +0 -32
- package/corpus/templates/crm/actions/list-crm-tasks.ts +0 -22
- package/corpus/templates/crm/actions/list-staged-datasets.ts +0 -14
- package/corpus/templates/crm/actions/list-workspace-connections.ts +0 -47
- package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +0 -87
- package/corpus/templates/crm/actions/manage-crm-task.ts +0 -132
- package/corpus/templates/crm/actions/navigate.ts +0 -63
- package/corpus/templates/crm/actions/provider-api-catalog.ts +0 -22
- package/corpus/templates/crm/actions/provider-api-docs.ts +0 -54
- package/corpus/templates/crm/actions/provider-api-request.ts +0 -92
- package/corpus/templates/crm/actions/query-staged-dataset.ts +0 -44
- package/corpus/templates/crm/actions/record-crm-call-insight.ts +0 -160
- package/corpus/templates/crm/actions/record-crm-smart-signal.ts +0 -150
- package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +0 -23
- package/corpus/templates/crm/actions/review-crm-signal.ts +0 -31
- package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +0 -103
- package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +0 -275
- package/corpus/templates/crm/actions/run.ts +0 -7
- package/corpus/templates/crm/actions/save-crm-dashboard.ts +0 -51
- package/corpus/templates/crm/actions/save-crm-saved-view.ts +0 -119
- package/corpus/templates/crm/actions/sync-crm.ts +0 -146
- package/corpus/templates/crm/actions/update-crm-record.ts +0 -510
- package/corpus/templates/crm/actions/view-screen.ts +0 -218
- package/corpus/templates/crm/agent-native.app-skill.json +0 -58
- package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +0 -158
- package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +0 -78
- package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +0 -226
- package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +0 -414
- package/corpus/templates/crm/app/components/crm/RecordActions.tsx +0 -510
- package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +0 -134
- package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +0 -362
- package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +0 -93
- package/corpus/templates/crm/app/components/crm/Surface.tsx +0 -97
- package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +0 -180
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +0 -112
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +0 -84
- package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/badge.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/button.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/card.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/dialog.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/input.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/label.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/select.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/sheet.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/skeleton.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/switch.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/table.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/tabs.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/textarea.tsx +0 -1
- package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +0 -17
- package/corpus/templates/crm/app/design-system.ts +0 -3
- package/corpus/templates/crm/app/entry.client.tsx +0 -16
- package/corpus/templates/crm/app/entry.server.tsx +0 -10
- package/corpus/templates/crm/app/global.css +0 -167
- package/corpus/templates/crm/app/hooks/use-navigation-state.ts +0 -60
- package/corpus/templates/crm/app/i18n/en-US.ts +0 -89
- package/corpus/templates/crm/app/i18n/index.ts +0 -34
- package/corpus/templates/crm/app/lib/dashboard.ts +0 -13
- package/corpus/templates/crm/app/lib/navigation.ts +0 -54
- package/corpus/templates/crm/app/lib/tab-id.ts +0 -1
- package/corpus/templates/crm/app/lib/types.ts +0 -172
- package/corpus/templates/crm/app/lib/utils.ts +0 -1
- package/corpus/templates/crm/app/root.tsx +0 -91
- package/corpus/templates/crm/app/routes/_index.tsx +0 -26
- package/corpus/templates/crm/app/routes/accounts.tsx +0 -41
- package/corpus/templates/crm/app/routes/agent.tsx +0 -5
- package/corpus/templates/crm/app/routes/ask.tsx +0 -53
- package/corpus/templates/crm/app/routes/dashboard.tsx +0 -118
- package/corpus/templates/crm/app/routes/opportunities.tsx +0 -41
- package/corpus/templates/crm/app/routes/people.tsx +0 -41
- package/corpus/templates/crm/app/routes/proposals.tsx +0 -266
- package/corpus/templates/crm/app/routes/records.$recordId.tsx +0 -35
- package/corpus/templates/crm/app/routes/settings.tsx +0 -63
- package/corpus/templates/crm/app/routes/setup.tsx +0 -308
- package/corpus/templates/crm/app/routes/tasks.tsx +0 -252
- package/corpus/templates/crm/app/routes/views.tsx +0 -333
- package/corpus/templates/crm/app/routes.ts +0 -17
- package/corpus/templates/crm/app/vite-env.d.ts +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +0 -6
- package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
- package/corpus/templates/crm/components.json +0 -20
- package/corpus/templates/crm/docs/architecture/crm-contract.md +0 -180
- package/corpus/templates/crm/learnings.defaults.md +0 -5
- package/corpus/templates/crm/package.json +0 -59
- package/corpus/templates/crm/public/favicon.svg +0 -1
- package/corpus/templates/crm/public/icon-180.svg +0 -1
- package/corpus/templates/crm/public/manifest.json +0 -11
- package/corpus/templates/crm/react-router.config.ts +0 -7
- package/corpus/templates/crm/server/crm/adapter.ts +0 -32
- package/corpus/templates/crm/server/crm/crm-field-firewall.ts +0 -64
- package/corpus/templates/crm/server/crm/crm-mirror.ts +0 -711
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1146
- package/corpus/templates/crm/server/crm/native-adapter.ts +0 -1715
- package/corpus/templates/crm/server/crm/read-through.ts +0 -207
- package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1255
- package/corpus/templates/crm/server/db/crm-store.ts +0 -1170
- package/corpus/templates/crm/server/db/index.ts +0 -169
- package/corpus/templates/crm/server/db/schema.ts +0 -441
- package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +0 -65
- package/corpus/templates/crm/server/lib/intelligence/evidence.ts +0 -105
- package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +0 -100
- package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +0 -144
- package/corpus/templates/crm/server/lib/intelligence/summary.ts +0 -141
- package/corpus/templates/crm/server/lib/provider-api.ts +0 -64
- package/corpus/templates/crm/server/middleware/auth.ts +0 -4
- package/corpus/templates/crm/server/plugins/agent-chat.ts +0 -68
- package/corpus/templates/crm/server/plugins/auth.ts +0 -14
- package/corpus/templates/crm/server/plugins/core-routes.ts +0 -17
- package/corpus/templates/crm/server/plugins/db.ts +0 -454
- package/corpus/templates/crm/server/routes/[...page].get.ts +0 -5
- package/corpus/templates/crm/shared/crm-automation-recipes.ts +0 -132
- package/corpus/templates/crm/shared/crm-contract.ts +0 -254
- package/corpus/templates/crm/shared/crm-sales-config.ts +0 -63
- package/corpus/templates/crm/ssr-entry.ts +0 -11
- package/corpus/templates/crm/tsconfig.json +0 -24
- package/corpus/templates/crm/vite.config.ts +0 -15
- package/corpus/templates/crm/vitest.config.ts +0 -5
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# CRM — Agent Guide
|
|
2
|
-
|
|
3
|
-
CRM is a standalone Native SQL CRM and a HubSpot/Salesforce Connected/Hybrid
|
|
4
|
-
companion. Actions are the shared contract for UI, agent chat, HTTP, MCP, A2A,
|
|
5
|
-
and CLI. Read `shared/crm-contract.ts` before changing CRM semantics; it is the
|
|
6
|
-
source of truth for vocabulary, field policies, provenance, provider identity,
|
|
7
|
-
and write policy.
|
|
8
|
-
|
|
9
|
-
## Hard boundaries
|
|
10
|
-
|
|
11
|
-
- Native SQL, HubSpot, and Salesforce are the initial modes. Native SQL is
|
|
12
|
-
local-authoritative, requires no external connection, and stays portable
|
|
13
|
-
across SQLite, Postgres, and D1.
|
|
14
|
-
- Workspace Connections own provider credentials. Never ask for, store, log,
|
|
15
|
-
or expose provider tokens.
|
|
16
|
-
- The local mirror is scoped and thin. Unknown fields are remote-only;
|
|
17
|
-
sensitive fields default to redacted; only allow-listed fields are mirrored.
|
|
18
|
-
- Never store raw provider payloads, transcripts, audio, video, screenshots,
|
|
19
|
-
base64, or file bodies in SQL. Evidence is a URL/id plus bounded quote,
|
|
20
|
-
timestamp, speaker, and source metadata.
|
|
21
|
-
- Do not merge identities from email/domain matches. Preserve the provider
|
|
22
|
-
identity tuple and directional relationships.
|
|
23
|
-
|
|
24
|
-
## Actions
|
|
25
|
-
|
|
26
|
-
| Action | Purpose |
|
|
27
|
-
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
28
|
-
| `get-crm-overview` | Read the scoped CRM summary and connection/mirror health. |
|
|
29
|
-
| `configure-native-crm` | Start a local-authoritative Native SQL CRM without a provider connection. |
|
|
30
|
-
| `configure-crm-connection` | Register an authorized HubSpot or Salesforce workspace Connection for the companion mirror. |
|
|
31
|
-
| `list-crm-records` | List a bounded set of CRM records using declared filters. |
|
|
32
|
-
| `get-crm-record` | Read one record and its permitted scoped detail. |
|
|
33
|
-
| `sync-crm` | Refresh a declared mirror cohort; never treat it as an export-all operation. |
|
|
34
|
-
| `list-crm-saved-views` / `save-crm-saved-view` | List or save scoped CRM views. |
|
|
35
|
-
| `install-crm-pipeline-dashboard` | Idempotently verify and install the CRM-owned Pipeline dashboard and data program. |
|
|
36
|
-
| `get-crm-pipeline-data` | Read bounded, access-scoped opportunity totals by stage for the dashboard program. |
|
|
37
|
-
| `get-crm-dashboard` / `list-crm-dashboards` / `save-crm-dashboard` | Read, list, or revision-write access-scoped Pipeline dashboards. |
|
|
38
|
-
| `list-crm-dashboard-revisions` / `restore-crm-dashboard-revision` | Inspect and restore a dashboard's bounded revision history. |
|
|
39
|
-
| `list-crm-tasks` / `manage-crm-task` | Read and manage CRM follow-up tasks. |
|
|
40
|
-
| `update-crm-record` | Submit a typed, access-checked, revision-aware record mutation. |
|
|
41
|
-
| `list-crm-proposals` / `apply-crm-proposals` | Review provider proposals and record the upstream handoff. |
|
|
42
|
-
| `attach-call-evidence` | Attach a bounded call evidence reference; never attach a transcript or media. |
|
|
43
|
-
| `get-crm-automation-recipe` | Return the default-off, record-selected Clips call-evidence review recipe. |
|
|
44
|
-
| `create-crm-signal-tracker` / `list-crm-signal-trackers` / `manage-crm-signal-tracker` | Create, inspect, enable, disable, or delete access-scoped keyword and delegated-agent moment detectors. |
|
|
45
|
-
| `run-crm-signal-trackers` / `list-crm-signal-hits` | Find deterministic hits and prepare bounded smart/summary agent work. |
|
|
46
|
-
| `record-crm-smart-signal` / `record-crm-call-insight` | Persist only evidence-grounded delegated results as reviewable signals. |
|
|
47
|
-
| `review-crm-signal` | Confirm or dismiss one grounded CRM signal. |
|
|
48
|
-
| `view-screen` | Read current navigation, selection, and visible CRM context. |
|
|
49
|
-
| `navigate` | Move the UI to overview, records, tasks, proposals, or settings. |
|
|
50
|
-
| `provider-api-catalog` / `provider-api-docs` / `provider-api-request` | Discover and make authorized, read-only exact provider API requests. |
|
|
51
|
-
| `query-staged-dataset` | Reduce staged, paginated provider results for broad analyses. |
|
|
52
|
-
| data program, automation, extension surfaces | Use shared framework capabilities under their scoped access and data limits. |
|
|
53
|
-
|
|
54
|
-
## Agent behavior
|
|
55
|
-
|
|
56
|
-
- Call `view-screen` before acting on “this record,” “these accounts,” the
|
|
57
|
-
selected row, or a visible saved view. For standalone read requests, call the
|
|
58
|
-
focused CRM action directly.
|
|
59
|
-
- Navigate before presenting a requested CRM view. Keep visible context aligned
|
|
60
|
-
with the action result.
|
|
61
|
-
- For a standalone CRM, use `configure-native-crm`; then create and update
|
|
62
|
-
local-authoritative records through the normal CRM actions. Do not call
|
|
63
|
-
`sync-crm`, provider API actions, or require a workspace Connection for
|
|
64
|
-
Native SQL.
|
|
65
|
-
- Use first-class actions for ordinary workflows. For an exact HubSpot or Salesforce API
|
|
66
|
-
request that actions cannot express, discover it with provider API actions,
|
|
67
|
-
fetch it with explicit pagination, then stage/reduce large results. Report
|
|
68
|
-
source, scope, filters, counts, pagination, and uncertainty.
|
|
69
|
-
- Agent provider changes are normally proposals. Changes involving ownership,
|
|
70
|
-
amounts, stage, deletion, bulk scope, or external side effects require an
|
|
71
|
-
exact preview and approval. This release does not complete provider writes:
|
|
72
|
-
review the proposal, direct the user to make the change in HubSpot or
|
|
73
|
-
Salesforce, and never claim the upstream change succeeded.
|
|
74
|
-
- A stored automation may execute only the `crm-sales-routine-local-v1` pack:
|
|
75
|
-
one routine, compensatable local update to one record. The trigger dispatcher,
|
|
76
|
-
not action input, supplies that policy context. Provider updates remain
|
|
77
|
-
proposals; ownership, amount, stage, deletion, bulk, and external effects
|
|
78
|
-
stay approval-gated or denied.
|
|
79
|
-
- Use `run-crm-signal-trackers` for attached Clips evidence. Keyword detectors
|
|
80
|
-
run locally; smart detectors and call summaries are delegated through agent
|
|
81
|
-
chat. Record only exact, bounded evidence citations through the signal record
|
|
82
|
-
actions. Never pass or reconstruct a transcript.
|
|
83
|
-
- Manage a tracker only with editor access. Enabling, disabling, and deleting a
|
|
84
|
-
tracker are local CRM configuration changes: they never invoke a model or
|
|
85
|
-
mutate a connected provider. Use `navigate` with
|
|
86
|
-
`{ view: "settings", settingsSection: "intelligence" }` to open its settings tab.
|
|
87
|
-
- The Clips review recipe is default-off and always scoped to one explicit CRM
|
|
88
|
-
record. It may subscribe to `clip.created` only after the user explicitly
|
|
89
|
-
approves the exact A2A activation call. The trigger belongs to Clips, where
|
|
90
|
-
`clip.created` is registered. It must ignore the event URL, call
|
|
91
|
-
`prepare-crm-call-evidence` with the event clip ID, and send only that bounded
|
|
92
|
-
durable HTTPS `/r/<id>` reference back to `attach-call-evidence` for the
|
|
93
|
-
selected record. It rejects media, tokens, transcripts, inferred records,
|
|
94
|
-
tasks, field/provider writes, and broader scopes. Use
|
|
95
|
-
`get-crm-automation-recipe` before configuring this flow.
|
|
96
|
-
- Use `install-crm-pipeline-dashboard` to set up the Pipeline view. It owns one
|
|
97
|
-
per-user data program that calls `get-crm-pipeline-data`; do not replace it
|
|
98
|
-
with a provider-specific action or embed raw rows in dashboard config. Use
|
|
99
|
-
`save-crm-dashboard` with `expectedUpdatedAt` for dashboard edits, and
|
|
100
|
-
`restore-crm-dashboard-revision` to roll back a saved revision.
|
|
101
|
-
|
|
102
|
-
## Four-area change guide
|
|
103
|
-
|
|
104
|
-
When changing a provider workflow, keep UI, actions, agent instructions, and
|
|
105
|
-
application state aligned. The setup route records the selected native mode or
|
|
106
|
-
connection; `configure-native-crm`, `configure-crm-connection`, and `sync-crm`
|
|
107
|
-
are the shared UI/agent operations; signal selection stores record/evidence IDs
|
|
108
|
-
only; `view-screen` and `navigate` expose the selected CRM context. Do not introduce provider-specific API routes, browser
|
|
109
|
-
credential inputs, or unscoped state.
|
|
110
|
-
|
|
111
|
-
## Implementation
|
|
112
|
-
|
|
113
|
-
Before building common workspace or agent UI, read `agent-native-toolkit`; use
|
|
114
|
-
`customizing-agent-native` when composing or ejecting shared surfaces.
|
|
115
|
-
|
|
116
|
-
Use `defineAction` and action hooks rather than duplicate `/api` CRUD routes.
|
|
117
|
-
Use shared Toolkit surfaces for connections, settings, navigation, sharing,
|
|
118
|
-
automations, and extensions before adding app-local equivalents. Keep SQL
|
|
119
|
-
schema changes additive and preserve access-scope checks independently from
|
|
120
|
-
provider permissions.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# CRM changelog
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# CRM — Development Guide
|
|
2
|
-
|
|
3
|
-
CRM is a React Router + Nitro Agent Native template. The UI and agent share the
|
|
4
|
-
same `actions/` contract; normal client reads and writes use action hooks, not
|
|
5
|
-
custom CRUD routes.
|
|
6
|
-
|
|
7
|
-
## Commands
|
|
8
|
-
|
|
9
|
-
- `pnpm dev` — run the local app
|
|
10
|
-
- `pnpm typecheck` — run the framework typecheck
|
|
11
|
-
- `pnpm test` — run unit tests
|
|
12
|
-
- `pnpm build` — build the React Router and Nitro app
|
|
13
|
-
|
|
14
|
-
## Architecture boundaries
|
|
15
|
-
|
|
16
|
-
- `shared/crm-contract.ts` is the canonical CRM vocabulary and provider-neutral
|
|
17
|
-
contract.
|
|
18
|
-
- `actions/` contains UI/agent operations. Read actions are GET; mutations use
|
|
19
|
-
the shared action surface and must preserve access checks and audit behavior.
|
|
20
|
-
- `server/` owns provider adapters, scoped mirror lifecycle, and startup
|
|
21
|
-
plugins. Use a route only for protocols actions cannot model.
|
|
22
|
-
- `app/` owns the persistent workspace shell and domain views. Keep normal
|
|
23
|
-
data fetching client-side through `useActionQuery` and `useActionMutation`.
|
|
24
|
-
|
|
25
|
-
## Data and provider rules
|
|
26
|
-
|
|
27
|
-
CRM SQL is a thin projection, not a raw HubSpot backup. Only allow-listed
|
|
28
|
-
fields are mirrored; remote-only values are fetched ephemerally and redacted
|
|
29
|
-
values are never fetched or exposed. Store evidence as bounded references and
|
|
30
|
-
quotes only. Raw provider responses, transcripts, media, screenshots, and file
|
|
31
|
-
bodies belong in their source system or approved blob storage, never SQL.
|
|
32
|
-
|
|
33
|
-
Use workspace Connections for credentials. Never add provider tokens to source,
|
|
34
|
-
fixtures, docs, logs, or `.env.example`. Provider API actions are the escape
|
|
35
|
-
hatch for legitimate unmodeled HubSpot or Salesforce requests; stage large
|
|
36
|
-
results and reduce them via data programs instead of loading an unbounded
|
|
37
|
-
payload into chat.
|
|
38
|
-
|
|
39
|
-
## Dashboards
|
|
40
|
-
|
|
41
|
-
CRM owns its dashboard schema, revision history, access policy, data programs,
|
|
42
|
-
and panel resolvers. It composes `@agent-native/toolkit/dashboard` for cards,
|
|
43
|
-
tables, layout, and chart rendering only; never add fetching, provider tokens,
|
|
44
|
-
or direct SQL access to Toolkit components. The Pipeline dashboard is installed
|
|
45
|
-
idempotently through `install-crm-pipeline-dashboard` and reads its bounded
|
|
46
|
-
opportunity data through `get-crm-pipeline-data`.
|
|
47
|
-
|
|
48
|
-
`@agent-native/core/dashboard-storage` is instantiated per app. Keep CRM's
|
|
49
|
-
dashboard rows and revisions scoped through its store, and use the `program`
|
|
50
|
-
panel source for CRM-owned data programs. Add a provider panel source only when
|
|
51
|
-
the CRM adapter can enforce the workspace connection, field policy, and access
|
|
52
|
-
scope.
|
|
53
|
-
|
|
54
|
-
## Signals and provider writes
|
|
55
|
-
|
|
56
|
-
Call evidence is a Clips-owned artifact reference. CRM may store only bounded
|
|
57
|
-
quotes, timestamps, evidence references, confidence, detector/model metadata,
|
|
58
|
-
and review state; it must never store a transcript body, media, or provider
|
|
59
|
-
payload. Keyword trackers run locally. Smart trackers and call summaries must
|
|
60
|
-
delegate to the agent chat, then validate evidence before persisting a signal.
|
|
61
|
-
|
|
62
|
-
Keep provider mutations proposal-first. `update-crm-record` records a
|
|
63
|
-
revision-aware, idempotent proposal for provider-authoritative fields;
|
|
64
|
-
`apply-crm-proposals` is the only path that can invoke an adapter after
|
|
65
|
-
approval. Delegated policy is narrow, access-scoped, and never bypasses the
|
|
66
|
-
field firewall or destructive/bulk gates.
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# CRM
|
|
2
|
-
|
|
3
|
-
CRM is an agent-native CRM that runs either as a standalone Native SQL system
|
|
4
|
-
or as a scoped companion for connected HubSpot and Salesforce workspaces. It
|
|
5
|
-
provides fast record work, saved views, tasks, cadence, evidence, reviewable
|
|
6
|
-
call signals, and agent workflows without forcing a provider choice.
|
|
7
|
-
|
|
8
|
-
Native SQL is local-authoritative and portable across SQLite, Postgres, and D1.
|
|
9
|
-
The connected modes support scoped Connected and Hybrid behavior: HubSpot maps
|
|
10
|
-
companies, contacts, and deals; Salesforce maps Accounts, Contacts, and
|
|
11
|
-
Opportunities.
|
|
12
|
-
|
|
13
|
-
## Guardrails
|
|
14
|
-
|
|
15
|
-
- Native SQL requires no external connection or provider credential.
|
|
16
|
-
- Provider credentials are workspace Connections only.
|
|
17
|
-
- The mirror contains configured cohorts and allow-listed fields, not raw
|
|
18
|
-
provider exports.
|
|
19
|
-
- Sensitive fields default to redacted and unknown fields are remote-only.
|
|
20
|
-
- Evidence stores a bounded quote and source reference, never transcripts or
|
|
21
|
-
media.
|
|
22
|
-
- Signal detectors produce timestamped evidence citations. Keyword matching is
|
|
23
|
-
local; smart moments and summaries are delegated through agent chat and saved
|
|
24
|
-
only after grounding validation.
|
|
25
|
-
- Provider mutations are revision-aware, audited, and proposed when agent risk
|
|
26
|
-
requires approval.
|
|
27
|
-
|
|
28
|
-
## Start or connect CRM
|
|
29
|
-
|
|
30
|
-
1. Open **Set up CRM** and select **Start with Native SQL** to use CRM without
|
|
31
|
-
HubSpot or Salesforce. Native records and fields are local-authoritative.
|
|
32
|
-
2. To use CRM as a companion, in shared **Settings → Connections**, authorize
|
|
33
|
-
HubSpot or Salesforce and
|
|
34
|
-
grant the connection to CRM. OAuth and refresh tokens stay in workspace
|
|
35
|
-
Connections; CRM never accepts a token or key. Salesforce production is the
|
|
36
|
-
default. For a sandbox, use **Authorize the sandbox directly** on Set up CRM;
|
|
37
|
-
the selected login environment is retained for token refresh.
|
|
38
|
-
3. Choose the granted connection and select a recent
|
|
39
|
-
history window. HubSpot may be narrowed to deal pipeline IDs; Salesforce
|
|
40
|
-
starts with recently updated Accounts, Contacts, and Opportunities.
|
|
41
|
-
4. CRM mirrors the selected cohort and allow-listed fields only. Confirm the
|
|
42
|
-
connection actor's access before relying on a record in the local mirror.
|
|
43
|
-
|
|
44
|
-
## Operating model
|
|
45
|
-
|
|
46
|
-
- **Connected**: the source CRM is authoritative. CRM is a scoped companion
|
|
47
|
-
for record work, saved views, tasks, call evidence, and analysis.
|
|
48
|
-
- **Hybrid**: the source CRM remains authoritative for remote fields; CRM may
|
|
49
|
-
own explicitly configured derived-local and local-authoritative fields.
|
|
50
|
-
- **Native SQL**: CRM is the system of record for its accounts, people,
|
|
51
|
-
opportunities, relationships, saved views, tasks, cadence, and local fields.
|
|
52
|
-
It has no upstream provider, sync job, or provider token.
|
|
53
|
-
- **Signals**: attach one Clips call-evidence artifact to one or more CRM
|
|
54
|
-
records, run the default Pricing, Competitors, Objections, Next steps,
|
|
55
|
-
Budget, and Timing detectors, then confirm or dismiss the grounded results.
|
|
56
|
-
Clips remains the owner of recording, transcript, consent, and media access.
|
|
57
|
-
- **Clips review recipe**: from a chosen CRM record, prepare a default-off
|
|
58
|
-
`clip.created` recipe. After explicit activation, its Clips-owned trigger
|
|
59
|
-
ignores the event media URL, resolves the clip through an access-checked
|
|
60
|
-
read action, and attaches only its opaque ID, durable HTTPS `/r/<id>` page,
|
|
61
|
-
and capture time to that exact CRM record. It never copies media or a
|
|
62
|
-
transcript, infers another record, or authorizes a provider write.
|
|
63
|
-
- **Pipeline dashboard**: install the CRM-owned Pipeline dashboard to get
|
|
64
|
-
action-backed stage, amount, and close-date panels. Its data program and
|
|
65
|
-
dashboard revisions are access-scoped CRM records; the reusable chart and
|
|
66
|
-
table presentation comes from the Toolkit dashboard kit.
|
|
67
|
-
- **Read and write safety**: provider reads use the connection's effective
|
|
68
|
-
permissions. Upstream changes are revision-aware, access-checked proposals
|
|
69
|
-
in this release; finish the approved change in HubSpot or Salesforce and do
|
|
70
|
-
not claim a provider write completed from CRM.
|
|
71
|
-
|
|
72
|
-
## Review and delegation policy
|
|
73
|
-
|
|
74
|
-
CRM records the actor, expected remote revision, idempotency key, field-level
|
|
75
|
-
provenance, and an audit event for each mutation request. Local, reversible
|
|
76
|
-
routine work can execute in CRM. Agent-initiated provider changes become
|
|
77
|
-
reviewable proposals; destructive, bulk, and named-risk changes remain gated.
|
|
78
|
-
Delegated authority is narrow and stored as policy—it never expands record or
|
|
79
|
-
field access, bypasses the write firewall, or turns a provider result into an
|
|
80
|
-
unverified success.
|
|
81
|
-
|
|
82
|
-
Salesforce reads are validated against the current connection actor and field
|
|
83
|
-
permissions before mirrored data is returned. A service-account mirror never
|
|
84
|
-
proves a user's access; ambiguous or changed access fails closed until refresh.
|
|
85
|
-
|
|
86
|
-
## Live testing
|
|
87
|
-
|
|
88
|
-
Use a shared, already-authorized workspace Connection—never copy its secret
|
|
89
|
-
into an environment file. Choose a small recent cohort, verify the resulting
|
|
90
|
-
records and access scope in CRM, then test a proposal without applying a
|
|
91
|
-
provider change. Record only connection labels, counts, and non-sensitive
|
|
92
|
-
results in test evidence.
|
|
93
|
-
|
|
94
|
-
See [the CRM contract](docs/architecture/crm-contract.md) for field policies,
|
|
95
|
-
identity, access scope, and write decisions.
|
|
96
|
-
|
|
97
|
-
## Local development
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
pnpm install
|
|
101
|
-
pnpm dev
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Set `DATABASE_URL` for persistent deployment storage. Native SQL works without
|
|
105
|
-
external credentials. Connect HubSpot or Salesforce from the workspace
|
|
106
|
-
Connections surface; do not add provider secrets to `.env`.
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import type { ActionRunContext } from "@agent-native/core/action";
|
|
2
|
-
import {
|
|
3
|
-
getRequestOrgId,
|
|
4
|
-
getRequestUserEmail,
|
|
5
|
-
} from "@agent-native/core/server";
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
isBoundedCrmValue,
|
|
9
|
-
isSafeCrmMutationFieldName,
|
|
10
|
-
isSafeCrmMutationFields,
|
|
11
|
-
} from "../server/crm/crm-field-firewall.js";
|
|
12
|
-
|
|
13
|
-
export const MAX_CRM_FIELDS_PER_MUTATION = 20;
|
|
14
|
-
|
|
15
|
-
export function requireCrmScope(ctx?: ActionRunContext) {
|
|
16
|
-
const ownerEmail = ctx?.userEmail ?? getRequestUserEmail();
|
|
17
|
-
if (!ownerEmail) throw new Error("Sign in is required to manage CRM data.");
|
|
18
|
-
const orgId = ctx?.orgId ?? getRequestOrgId() ?? null;
|
|
19
|
-
return {
|
|
20
|
-
ownerEmail,
|
|
21
|
-
orgId,
|
|
22
|
-
visibility: orgId ? ("org" as const) : ("private" as const),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function crmInitiatedBy(ctx?: ActionRunContext) {
|
|
27
|
-
if (ctx?.caller === "automation") return "automation" as const;
|
|
28
|
-
return ctx?.caller === "tool" ||
|
|
29
|
-
ctx?.caller === "mcp" ||
|
|
30
|
-
ctx?.caller === "a2a"
|
|
31
|
-
? ("agent" as const)
|
|
32
|
-
: ("human" as const);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function crmWriteRisk(fieldNames: string[]) {
|
|
36
|
-
const names = fieldNames.map((field) => field.toLowerCase());
|
|
37
|
-
if (names.some((field) => field.includes("owner")))
|
|
38
|
-
return "ownership" as const;
|
|
39
|
-
if (names.some((field) => field === "amount" || field.includes("amount"))) {
|
|
40
|
-
return "amount" as const;
|
|
41
|
-
}
|
|
42
|
-
if (
|
|
43
|
-
names.some((field) => field.includes("stage") || field.includes("pipeline"))
|
|
44
|
-
) {
|
|
45
|
-
return "stage" as const;
|
|
46
|
-
}
|
|
47
|
-
return "routine" as const;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export async function scopedCrmIdempotencyKey(input: {
|
|
51
|
-
ownerEmail: string;
|
|
52
|
-
orgId: string | null;
|
|
53
|
-
recordId: string;
|
|
54
|
-
key: string;
|
|
55
|
-
}): Promise<string> {
|
|
56
|
-
const value = [
|
|
57
|
-
"crm-mutation-v1",
|
|
58
|
-
input.ownerEmail.toLowerCase(),
|
|
59
|
-
input.orgId ?? "",
|
|
60
|
-
input.recordId,
|
|
61
|
-
input.key,
|
|
62
|
-
].join("\u0000");
|
|
63
|
-
const bytes = new TextEncoder().encode(value);
|
|
64
|
-
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
65
|
-
return `crm:v1:${Array.from(new Uint8Array(digest), (byte) =>
|
|
66
|
-
byte.toString(16).padStart(2, "0"),
|
|
67
|
-
).join("")}`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function toJson(value: unknown, maxChars: number) {
|
|
71
|
-
const encoded = JSON.stringify(value);
|
|
72
|
-
if (encoded.length > maxChars) {
|
|
73
|
-
throw new Error(`CRM payload exceeds the ${maxChars}-character limit.`);
|
|
74
|
-
}
|
|
75
|
-
return encoded;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function parseJsonRecord(value: string): Record<string, unknown> {
|
|
79
|
-
try {
|
|
80
|
-
const parsed = JSON.parse(value) as unknown;
|
|
81
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
82
|
-
? (parsed as Record<string, unknown>)
|
|
83
|
-
: {};
|
|
84
|
-
} catch {
|
|
85
|
-
return {};
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
|
|
3
|
-
import type { ActionRunContext } from "@agent-native/core/action";
|
|
4
|
-
import type { AccessContext } from "@agent-native/core/sharing";
|
|
5
|
-
|
|
6
|
-
import type { CrmDashboardConfig } from "../server/db/index.js";
|
|
7
|
-
|
|
8
|
-
export const CRM_PIPELINE_DASHBOARD_TITLE = "Pipeline";
|
|
9
|
-
export const CRM_PIPELINE_PROGRAM_NAME = "crm-pipeline-by-stage";
|
|
10
|
-
export const CRM_PIPELINE_PROGRAM_TITLE = "CRM pipeline by stage";
|
|
11
|
-
export const CRM_PIPELINE_REFRESH_TTL_MS = 5 * 60_000;
|
|
12
|
-
|
|
13
|
-
export const CRM_PIPELINE_PROGRAM_COLUMNS = [
|
|
14
|
-
{ name: "stage", type: "string" },
|
|
15
|
-
{ name: "pipelineValue", type: "number" },
|
|
16
|
-
{ name: "opportunities", type: "number" },
|
|
17
|
-
] as const;
|
|
18
|
-
|
|
19
|
-
export const CRM_PIPELINE_PROGRAM_CODE = `const result = await appAction("get-crm-pipeline-data");
|
|
20
|
-
emit(result.rows, ${JSON.stringify(CRM_PIPELINE_PROGRAM_COLUMNS, null, 2)});`;
|
|
21
|
-
|
|
22
|
-
export function requireDashboardAccess(
|
|
23
|
-
ctx?: ActionRunContext,
|
|
24
|
-
): AccessContext & { userEmail: string } {
|
|
25
|
-
const userEmail = ctx?.userEmail?.trim().toLowerCase();
|
|
26
|
-
if (!userEmail) {
|
|
27
|
-
throw new Error("CRM dashboards require an authenticated user.");
|
|
28
|
-
}
|
|
29
|
-
return { userEmail, orgId: ctx?.orgId ?? undefined };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function crmPipelineDashboardId(ctx: AccessContext): string {
|
|
33
|
-
const owner = ctx.userEmail?.trim().toLowerCase();
|
|
34
|
-
if (!owner) throw new Error("CRM dashboards require an authenticated user.");
|
|
35
|
-
const scope = `${ctx.orgId ?? "personal"}:${owner}`;
|
|
36
|
-
return `crm-pipeline-${createHash("sha256").update(scope).digest("hex").slice(0, 24)}`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function createPipelineDashboardConfig(
|
|
40
|
-
programId: string,
|
|
41
|
-
): CrmDashboardConfig {
|
|
42
|
-
const query = JSON.stringify({ programId });
|
|
43
|
-
return {
|
|
44
|
-
version: 1,
|
|
45
|
-
panels: [
|
|
46
|
-
{
|
|
47
|
-
id: "pipeline-total",
|
|
48
|
-
title: "Pipeline value",
|
|
49
|
-
source: "program",
|
|
50
|
-
query,
|
|
51
|
-
chartType: "metric",
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
id: "pipeline-by-stage",
|
|
55
|
-
title: "Pipeline by stage",
|
|
56
|
-
source: "program",
|
|
57
|
-
query,
|
|
58
|
-
chartType: "bar",
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
id: "pipeline-table",
|
|
62
|
-
title: "Stage detail",
|
|
63
|
-
source: "program",
|
|
64
|
-
query,
|
|
65
|
-
chartType: "table",
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
};
|
|
69
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { initDataPrograms } from "@agent-native/core/data-programs";
|
|
2
|
-
|
|
3
|
-
import { CRM_APP_ID } from "../server/lib/provider-api.js";
|
|
4
|
-
import getCrmPipelineData from "./get-crm-pipeline-data.js";
|
|
5
|
-
|
|
6
|
-
export function getCrmDataProgramActions() {
|
|
7
|
-
return { "get-crm-pipeline-data": getCrmPipelineData };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function initCrmDataPrograms(): void {
|
|
11
|
-
initDataPrograms({
|
|
12
|
-
appId: CRM_APP_ID,
|
|
13
|
-
getActions: getCrmDataProgramActions,
|
|
14
|
-
});
|
|
15
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { ActionRunContext } from "@agent-native/core/action";
|
|
2
|
-
import { accessFilter, assertAccess } from "@agent-native/core/sharing";
|
|
3
|
-
import { and, eq, inArray } from "drizzle-orm";
|
|
4
|
-
|
|
5
|
-
import { getDb, schema } from "../server/db/index.js";
|
|
6
|
-
import type { CallEvidenceExcerpt } from "../server/lib/intelligence/evidence.js";
|
|
7
|
-
import {
|
|
8
|
-
requireCrmScope,
|
|
9
|
-
scopedCrmIdempotencyKey,
|
|
10
|
-
} from "./_crm-action-utils.js";
|
|
11
|
-
|
|
12
|
-
export async function loadCrmSignalEvidence(args: {
|
|
13
|
-
recordId: string;
|
|
14
|
-
evidenceIds?: string[];
|
|
15
|
-
role?: "viewer" | "editor";
|
|
16
|
-
}) {
|
|
17
|
-
await assertAccess("crm-record", args.recordId, args.role ?? "viewer");
|
|
18
|
-
const db = getDb();
|
|
19
|
-
const predicates = [
|
|
20
|
-
eq(schema.crmCallEvidence.recordId, args.recordId),
|
|
21
|
-
accessFilter(schema.crmCallEvidence, schema.crmCallEvidenceShares),
|
|
22
|
-
];
|
|
23
|
-
if (args.evidenceIds?.length) {
|
|
24
|
-
predicates.push(inArray(schema.crmCallEvidence.id, args.evidenceIds));
|
|
25
|
-
}
|
|
26
|
-
const rows = await db
|
|
27
|
-
.select()
|
|
28
|
-
.from(schema.crmCallEvidence)
|
|
29
|
-
.where(and(...predicates))
|
|
30
|
-
.limit(20);
|
|
31
|
-
if (
|
|
32
|
-
args.evidenceIds?.length &&
|
|
33
|
-
rows.length !== new Set(args.evidenceIds).size
|
|
34
|
-
) {
|
|
35
|
-
throw new Error("One or more call-evidence references are unavailable.");
|
|
36
|
-
}
|
|
37
|
-
return rows;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function evidenceExcerpts(
|
|
41
|
-
rows: Awaited<ReturnType<typeof loadCrmSignalEvidence>>,
|
|
42
|
-
): CallEvidenceExcerpt[] {
|
|
43
|
-
return rows.flatMap((row) => {
|
|
44
|
-
const quote = row.quote.trim() || row.summary.trim();
|
|
45
|
-
if (!quote) return [];
|
|
46
|
-
return [
|
|
47
|
-
{
|
|
48
|
-
evidenceRef: row.id,
|
|
49
|
-
quote,
|
|
50
|
-
...(row.speaker ? { speaker: row.speaker } : {}),
|
|
51
|
-
startSeconds: row.startSeconds ?? 0,
|
|
52
|
-
...(row.endSeconds !== null ? { endSeconds: row.endSeconds } : {}),
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function crmSignalIdempotencyKey(
|
|
59
|
-
ctx: ActionRunContext | undefined,
|
|
60
|
-
recordId: string,
|
|
61
|
-
key: string,
|
|
62
|
-
) {
|
|
63
|
-
const scope = requireCrmScope(ctx);
|
|
64
|
-
return {
|
|
65
|
-
scope,
|
|
66
|
-
key: await scopedCrmIdempotencyKey({
|
|
67
|
-
ownerEmail: scope.ownerEmail,
|
|
68
|
-
orgId: scope.orgId,
|
|
69
|
-
recordId,
|
|
70
|
-
key: `signal:${key}`,
|
|
71
|
-
}),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function signalTupleError(message: string): never {
|
|
76
|
-
const error = new Error(message) as Error & { statusCode?: number };
|
|
77
|
-
error.statusCode = 404;
|
|
78
|
-
throw error;
|
|
79
|
-
}
|