@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
|
@@ -13,10 +13,12 @@ import React from "react";
|
|
|
13
13
|
import ReactMarkdown, { defaultUrlTransform } from "react-markdown";
|
|
14
14
|
import remarkGfm from "remark-gfm";
|
|
15
15
|
|
|
16
|
+
import { ActionChatUiSurface } from "../chat/action-chat-ui-surface.js";
|
|
16
17
|
import { resolveToolRenderer } from "../chat/tool-render-registry.js";
|
|
17
18
|
import {
|
|
18
19
|
resolveBuiltinActionChatRenderer,
|
|
19
20
|
resolveBuiltinFallbackToolRenderer,
|
|
21
|
+
isBuiltinDataWidgetActionRenderer,
|
|
20
22
|
} from "../chat/widgets/builtin-tool-renderers.js";
|
|
21
23
|
import {
|
|
22
24
|
MessageScroller,
|
|
@@ -414,7 +416,16 @@ function ConversationToolCall({ tool }: { tool: AgentConversationToolCall }) {
|
|
|
414
416
|
resolveToolRenderer(nativeToolContext) ??
|
|
415
417
|
resolveBuiltinFallbackToolRenderer(nativeToolContext);
|
|
416
418
|
if (NativeToolRenderer) {
|
|
417
|
-
return
|
|
419
|
+
return (
|
|
420
|
+
<ActionChatUiSurface
|
|
421
|
+
context={nativeToolContext}
|
|
422
|
+
isBuiltinDataWidget={isBuiltinDataWidgetActionRenderer(
|
|
423
|
+
nativeToolContext,
|
|
424
|
+
)}
|
|
425
|
+
>
|
|
426
|
+
<NativeToolRenderer context={nativeToolContext} />
|
|
427
|
+
</ActionChatUiSurface>
|
|
428
|
+
);
|
|
418
429
|
}
|
|
419
430
|
|
|
420
431
|
const hasDetails = Boolean(tool.input || tool.result || tool.mcpApp);
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* the server normalizes + groups it. That keeps one tested source of truth for
|
|
22
22
|
* grouping instead of duplicating parser logic across the wire.
|
|
23
23
|
*/
|
|
24
|
+
import { isDynamicImportFailureMessage } from "./route-chunk-recovery.js";
|
|
24
25
|
import { scrubUrl } from "./url-scrub.js";
|
|
25
26
|
|
|
26
27
|
export type ExceptionLevel = "fatal" | "error" | "warning" | "info" | "debug";
|
|
@@ -358,12 +359,7 @@ function shouldIgnoreAutoCapturedError(normalized: {
|
|
|
358
359
|
// Route-chunk recovery reloads the current page after stale lazy chunks or
|
|
359
360
|
// module scripts fail. Browser-level failures have no useful stack, so do
|
|
360
361
|
// not retain the transient loader noise as an application issue.
|
|
361
|
-
if (
|
|
362
|
-
!stack &&
|
|
363
|
-
/^(?:Importing a module script failed\.?|(?:Failed to fetch|error loading) dynamically imported module(?::.*)?)$/i.test(
|
|
364
|
-
message,
|
|
365
|
-
)
|
|
366
|
-
) {
|
|
362
|
+
if (!stack && isDynamicImportFailureMessage(message)) {
|
|
367
363
|
return true;
|
|
368
364
|
}
|
|
369
365
|
|
|
@@ -39,6 +39,18 @@ export interface McpConnectionSuggestionProps {
|
|
|
39
39
|
integrations?: DefaultMcpIntegration[];
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
export function findMcpConnectionSuggestionIntegration({
|
|
43
|
+
text,
|
|
44
|
+
contextText = "",
|
|
45
|
+
variant = "composer",
|
|
46
|
+
integrations = getDefaultMcpIntegrations(),
|
|
47
|
+
}: McpConnectionSuggestionProps): DefaultMcpIntegration | null {
|
|
48
|
+
return findMcpIntegrationForText(
|
|
49
|
+
variant === "response" ? contextText : text,
|
|
50
|
+
integrations,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
function compareUrl(value: string): string {
|
|
43
55
|
try {
|
|
44
56
|
const url = new URL(value.trim());
|
|
@@ -99,22 +111,16 @@ export function McpConnectionSuggestion({
|
|
|
99
111
|
() => integrationOptions ?? getDefaultMcpIntegrations(),
|
|
100
112
|
[integrationOptions],
|
|
101
113
|
);
|
|
102
|
-
const
|
|
103
|
-
() => findMcpIntegrationForText(text, integrations),
|
|
104
|
-
[integrations, text],
|
|
105
|
-
);
|
|
106
|
-
const contextIntegration = useMemo(
|
|
114
|
+
const integration = useMemo(
|
|
107
115
|
() =>
|
|
108
|
-
|
|
109
|
-
|
|
116
|
+
findMcpConnectionSuggestionIntegration({
|
|
117
|
+
text,
|
|
118
|
+
contextText,
|
|
119
|
+
variant,
|
|
120
|
+
integrations,
|
|
121
|
+
}),
|
|
122
|
+
[contextText, integrations, text, variant],
|
|
110
123
|
);
|
|
111
|
-
const integration =
|
|
112
|
-
variant === "response" &&
|
|
113
|
-
textIntegration &&
|
|
114
|
-
contextIntegration &&
|
|
115
|
-
textIntegration.id !== contextIntegration.id
|
|
116
|
-
? null
|
|
117
|
-
: (textIntegration ?? contextIntegration);
|
|
118
124
|
const apiFallback = integration
|
|
119
125
|
? getMcpIntegrationApiFallback(integration)
|
|
120
126
|
: null;
|
|
@@ -338,7 +338,11 @@ function CreateMenu({
|
|
|
338
338
|
window.clearTimeout(skillFlyoutCloseTimerRef.current);
|
|
339
339
|
skillFlyoutCloseTimerRef.current = null;
|
|
340
340
|
}
|
|
341
|
-
if (
|
|
341
|
+
if (
|
|
342
|
+
rowEl &&
|
|
343
|
+
typeof window !== "undefined" &&
|
|
344
|
+
typeof rowEl.getBoundingClientRect === "function"
|
|
345
|
+
) {
|
|
342
346
|
const rect = rowEl.getBoundingClientRect();
|
|
343
347
|
const FLYOUT_WIDTH = 248;
|
|
344
348
|
setSkillFlyoutSide(
|
|
@@ -49,6 +49,7 @@ export interface DefaultMcpIntegration {
|
|
|
49
49
|
templateUses?: readonly string[];
|
|
50
50
|
};
|
|
51
51
|
headerPlaceholder?: string;
|
|
52
|
+
brandAliases?: string[];
|
|
52
53
|
aliases?: string[];
|
|
53
54
|
keywords: string[];
|
|
54
55
|
}
|
|
@@ -138,16 +139,6 @@ export const DEFAULT_MCP_INTEGRATIONS: DefaultMcpIntegration[] = [
|
|
|
138
139
|
logoUrl: mcpIntegrationLogo("granola"),
|
|
139
140
|
docsUrl: "https://docs.granola.ai/help-center/sharing/integrations/mcp",
|
|
140
141
|
setupNoteKey: "mcpIntegrations.catalog.granola.setupNote",
|
|
141
|
-
aliases: [
|
|
142
|
-
"meeting notes",
|
|
143
|
-
"meeting recordings",
|
|
144
|
-
"recordings",
|
|
145
|
-
"transcripts",
|
|
146
|
-
"action items",
|
|
147
|
-
"follow-ups",
|
|
148
|
-
"follow ups",
|
|
149
|
-
"decisions",
|
|
150
|
-
],
|
|
151
142
|
keywords: [
|
|
152
143
|
"meetings",
|
|
153
144
|
"meeting notes",
|
|
@@ -210,7 +201,7 @@ export const DEFAULT_MCP_INTEGRATIONS: DefaultMcpIntegration[] = [
|
|
|
210
201
|
docsUrl:
|
|
211
202
|
"https://developer.atlassian.com/cloud/rovo-mcp/guides/getting-started/",
|
|
212
203
|
setupNoteKey: "mcpIntegrations.catalog.atlassian.setupNote",
|
|
213
|
-
|
|
204
|
+
brandAliases: ["Jira", "Confluence", "Rovo"],
|
|
214
205
|
keywords: ["atlassian", "jira", "confluence", "issues", "tickets"],
|
|
215
206
|
},
|
|
216
207
|
{
|
|
@@ -721,6 +712,8 @@ export function filterMcpIntegrations(
|
|
|
721
712
|
integration.description,
|
|
722
713
|
integration.useCase,
|
|
723
714
|
integration.url,
|
|
715
|
+
...(integration.brandAliases ?? []),
|
|
716
|
+
...(integration.aliases ?? []),
|
|
724
717
|
...integration.keywords,
|
|
725
718
|
]
|
|
726
719
|
.join(" ")
|
|
@@ -802,12 +795,9 @@ export function findMcpIntegrationForText(
|
|
|
802
795
|
isMcpConnectionFailureText(normalizedText);
|
|
803
796
|
if (!hasResourceIntent) return null;
|
|
804
797
|
const matchesCanonicalName = (integration: DefaultMcpIntegration) =>
|
|
805
|
-
[
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
integration.id,
|
|
809
|
-
...(integration.aliases ?? []),
|
|
810
|
-
].some((alias) => textContainsTerm(normalizedText, alias));
|
|
798
|
+
[integration.name, ...(integration.brandAliases ?? [])].some((alias) =>
|
|
799
|
+
textContainsTerm(normalizedText, alias),
|
|
800
|
+
);
|
|
811
801
|
const canonicalMatch = integrations.find(matchesCanonicalName);
|
|
812
802
|
if (canonicalMatch) return canonicalMatch;
|
|
813
803
|
return null;
|
|
@@ -24,8 +24,8 @@ const LOGOS = {
|
|
|
24
24
|
data: "PHN2ZyBmaWxsPSIjMDAwMDAwIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+Tm90aW9uPC90aXRsZT48cGF0aCBkPSJNNC40NTkgNC4yMDhjLjc0Ni42MDYgMS4wMjYuNTYgMi40MjguNDY2bDEzLjIxNS0uNzkzYy4yOCAwIC4wNDctLjI4LS4wNDYtLjMyNkwxNy44NiAxLjk2OGMtLjQyLS4zMjYtLjk4MS0uNy0yLjA1NS0uNjA3TDMuMDEgMi4yOTVjLS40NjYuMDQ2LS41Ni4yOC0uMzc0LjQ2NnptLjc5MyAzLjA4djEzLjkwNGMwIC43NDcuMzczIDEuMDI3IDEuMjE0Ljk4bDE0LjUyMy0uODRjLjg0MS0uMDQ2LjkzNS0uNTYuOTM1LTEuMTY3VjYuMzU0YzAtLjYwNi0uMjMzLS45MzMtLjc0OC0uODg3bC0xNS4xNzcuODg3Yy0uNTYuMDQ3LS43NDcuMzI3LS43NDcuOTMzem0xNC4zMzcuNzQ1Yy4wOTMuNDIgMCAuODQtLjQyLjg4OGwtLjcuMTR2MTAuMjY0Yy0uNjA4LjMyNy0xLjE2OC41MTQtMS42MzUuNTE0LS43NDggMC0uOTM1LS4yMzQtMS40OTUtLjkzM2wtNC41NzctNy4xODZ2Ni45NTJMMTIuMjEgMTlzMCAuODQtMS4xNjguODRsLTMuMjIyLjE4NmMtLjA5My0uMTg2IDAtLjY1My4zMjctLjc0NmwuODQtLjIzM1Y5Ljg1NEw3LjgyMiA5Ljc2Yy0uMDk0LS40Mi4xNC0xLjAyNi43OTMtMS4wNzNsMy40NTYtLjIzMyA0Ljc2NCA3LjI3OXYtNi40NGwtMS4yMTUtLjEzOWMtLjA5My0uNTE0LjI4LS44ODcuNzQ3LS45MzN6TTEuOTM2IDEuMDM1bDEzLjMxLS45OGMxLjYzNC0uMTQgMi4wNTUtLjA0NyAzLjA4Mi43bDQuMjQ5IDIuOTg2Yy43LjUxMy45MzQuNjUzLjkzNCAxLjIxM3YxNi4zNzhjMCAxLjAyNi0uMzczIDEuNjM0LTEuNjggMS43MjZsLTE1LjQ1OC45MzRjLS45OC4wNDctMS40NDgtLjA5My0xLjk2Mi0uNzQ3bC0zLjEyOS00LjA2Yy0uNTYtLjc0Ny0uNzkzLTEuMzA2LS43OTMtMS45NlYyLjY2N2MwLS44MzkuMzc0LTEuNTQgMS40NDctMS42MzJ6Ii8+PC9zdmc+",
|
|
25
25
|
},
|
|
26
26
|
granola: {
|
|
27
|
-
mime: "image/
|
|
28
|
-
data: "
|
|
27
|
+
mime: "image/png",
|
|
28
|
+
data: "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",
|
|
29
29
|
},
|
|
30
30
|
linear: {
|
|
31
31
|
mime: "image/svg+xml",
|
|
@@ -33,10 +33,12 @@ export function isRouteModuleReloadMessage(value: unknown): boolean {
|
|
|
33
33
|
|
|
34
34
|
export function isDynamicImportFailureMessage(value: unknown): boolean {
|
|
35
35
|
if (typeof value !== "string") return false;
|
|
36
|
+
const message = value.toLowerCase();
|
|
36
37
|
return (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
message.includes("failed to fetch dynamically imported module") ||
|
|
39
|
+
message.includes("error loading dynamically imported module") ||
|
|
40
|
+
message.includes("importing a module script failed") ||
|
|
41
|
+
message.includes("failed to fetch dynamically imported")
|
|
40
42
|
);
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -1158,13 +1158,13 @@ function updateReplayResourceNode(
|
|
|
1158
1158
|
): ReplayResourceNode {
|
|
1159
1159
|
return {
|
|
1160
1160
|
tagName: current.tagName,
|
|
1161
|
-
rel: Object.
|
|
1161
|
+
rel: Object.prototype.hasOwnProperty.call(attributes, "rel")
|
|
1162
1162
|
? replayAttributeString(attributes, "rel")
|
|
1163
1163
|
: current.rel,
|
|
1164
|
-
as: Object.
|
|
1164
|
+
as: Object.prototype.hasOwnProperty.call(attributes, "as")
|
|
1165
1165
|
? replayAttributeString(attributes, "as")
|
|
1166
1166
|
: current.as,
|
|
1167
|
-
type: Object.
|
|
1167
|
+
type: Object.prototype.hasOwnProperty.call(attributes, "type")
|
|
1168
1168
|
? replayAttributeString(attributes, "type")
|
|
1169
1169
|
: current.type,
|
|
1170
1170
|
};
|
|
@@ -1119,12 +1119,7 @@ function LLMSectionInner({
|
|
|
1119
1119
|
label="Connect Builder.io"
|
|
1120
1120
|
/>
|
|
1121
1121
|
{!builderConnected && (
|
|
1122
|
-
<ManualSetupCard
|
|
1123
|
-
hint={manualSetupHint}
|
|
1124
|
-
docsUrl={PROVIDER_DOCS[selectedEngine]}
|
|
1125
|
-
sourceBadge={sourceBadge}
|
|
1126
|
-
docsLabel="Get an API key"
|
|
1127
|
-
>
|
|
1122
|
+
<ManualSetupCard hint={manualSetupHint} sourceBadge={sourceBadge}>
|
|
1128
1123
|
<div className="space-y-2 mb-1">
|
|
1129
1124
|
<SettingsSelect
|
|
1130
1125
|
label="Provider"
|
|
@@ -1330,6 +1325,20 @@ function LLMSectionInner({
|
|
|
1330
1325
|
"Test"
|
|
1331
1326
|
)}
|
|
1332
1327
|
</Button>
|
|
1328
|
+
{PROVIDER_DOCS[selectedEngine] ? (
|
|
1329
|
+
<a
|
|
1330
|
+
href={PROVIDER_DOCS[selectedEngine]}
|
|
1331
|
+
target="_blank"
|
|
1332
|
+
rel="noopener noreferrer"
|
|
1333
|
+
className={cn(
|
|
1334
|
+
pillButtonClass(isPage, "outline"),
|
|
1335
|
+
"no-underline",
|
|
1336
|
+
)}
|
|
1337
|
+
>
|
|
1338
|
+
Get an API key
|
|
1339
|
+
<IconExternalLink size={isPage ? 14 : 10} />
|
|
1340
|
+
</a>
|
|
1341
|
+
) : null}
|
|
1333
1342
|
{engineChanged && (
|
|
1334
1343
|
<Button
|
|
1335
1344
|
intent="primary"
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* stop when the user hits stop. The accumulated transcript is available
|
|
7
7
|
* immediately — no round-trip to Whisper needed.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Builder can transcribe the original recording afterward if native capture
|
|
10
|
+
* produces no text, but this gives users something useful from second zero
|
|
11
|
+
* without a cloud transcription request.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -58,12 +58,21 @@ export function useLiveTranscription(
|
|
|
58
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
59
|
const recognitionRef = useRef<any>(null);
|
|
60
60
|
const transcriptRef = useRef("");
|
|
61
|
+
const interimRef = useRef("");
|
|
61
62
|
const stoppedManuallyRef = useRef(false);
|
|
62
63
|
const stopWaiterRef = useRef<((text: string) => void) | null>(null);
|
|
63
64
|
const restartTimerRef = useRef<number | null>(null);
|
|
64
65
|
const networkErrorCountRef = useRef(0);
|
|
65
66
|
const restartDelayRef = useRef(0);
|
|
66
67
|
|
|
68
|
+
const currentTranscript = useCallback(
|
|
69
|
+
() =>
|
|
70
|
+
[transcriptRef.current.trim(), interimRef.current.trim()]
|
|
71
|
+
.filter(Boolean)
|
|
72
|
+
.join(" "),
|
|
73
|
+
[],
|
|
74
|
+
);
|
|
75
|
+
|
|
67
76
|
const supported = !!getSpeechRecognitionCtor();
|
|
68
77
|
|
|
69
78
|
const start = useCallback(() => {
|
|
@@ -89,6 +98,7 @@ export function useLiveTranscription(
|
|
|
89
98
|
recognition.lang = lang;
|
|
90
99
|
recognitionRef.current = recognition;
|
|
91
100
|
transcriptRef.current = "";
|
|
101
|
+
interimRef.current = "";
|
|
92
102
|
stoppedManuallyRef.current = false;
|
|
93
103
|
networkErrorCountRef.current = 0;
|
|
94
104
|
restartDelayRef.current = 0;
|
|
@@ -107,6 +117,7 @@ export function useLiveTranscription(
|
|
|
107
117
|
interim += text;
|
|
108
118
|
}
|
|
109
119
|
}
|
|
120
|
+
interimRef.current = interim;
|
|
110
121
|
setInterimText(interim);
|
|
111
122
|
if (event.results.length > 0) {
|
|
112
123
|
networkErrorCountRef.current = 0;
|
|
@@ -167,7 +178,7 @@ export function useLiveTranscription(
|
|
|
167
178
|
}
|
|
168
179
|
setIsActive(false);
|
|
169
180
|
if (stopWaiterRef.current) {
|
|
170
|
-
stopWaiterRef.current(
|
|
181
|
+
stopWaiterRef.current(currentTranscript());
|
|
171
182
|
}
|
|
172
183
|
};
|
|
173
184
|
|
|
@@ -177,14 +188,16 @@ export function useLiveTranscription(
|
|
|
177
188
|
} catch {
|
|
178
189
|
/* browser may block without user gesture */
|
|
179
190
|
}
|
|
180
|
-
}, [lang]);
|
|
191
|
+
}, [currentTranscript, lang]);
|
|
181
192
|
|
|
182
193
|
const stop = useCallback((): string => {
|
|
194
|
+
const text = currentTranscript();
|
|
183
195
|
stoppedManuallyRef.current = true;
|
|
184
196
|
if (restartTimerRef.current !== null) {
|
|
185
197
|
window.clearTimeout(restartTimerRef.current);
|
|
186
198
|
restartTimerRef.current = null;
|
|
187
199
|
}
|
|
200
|
+
interimRef.current = "";
|
|
188
201
|
setInterimText("");
|
|
189
202
|
if (recognitionRef.current) {
|
|
190
203
|
try {
|
|
@@ -195,51 +208,57 @@ export function useLiveTranscription(
|
|
|
195
208
|
recognitionRef.current = null;
|
|
196
209
|
}
|
|
197
210
|
setIsActive(false);
|
|
198
|
-
return
|
|
199
|
-
}, []);
|
|
211
|
+
return text;
|
|
212
|
+
}, [currentTranscript]);
|
|
200
213
|
|
|
201
|
-
const stopAndWait = useCallback(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const recognition = recognitionRef.current;
|
|
210
|
-
if (!recognition) {
|
|
211
|
-
setIsActive(false);
|
|
212
|
-
return Promise.resolve(transcriptRef.current);
|
|
213
|
-
}
|
|
214
|
+
const stopAndWait = useCallback(
|
|
215
|
+
(timeoutMs = 1200): Promise<string> => {
|
|
216
|
+
stoppedManuallyRef.current = true;
|
|
217
|
+
if (restartTimerRef.current !== null) {
|
|
218
|
+
window.clearTimeout(restartTimerRef.current);
|
|
219
|
+
restartTimerRef.current = null;
|
|
220
|
+
}
|
|
221
|
+
setInterimText("");
|
|
214
222
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
settled = true;
|
|
220
|
-
window.clearTimeout(timeout);
|
|
221
|
-
if (stopWaiterRef.current === finish) {
|
|
222
|
-
stopWaiterRef.current = null;
|
|
223
|
-
}
|
|
224
|
-
if (recognitionRef.current === recognition) {
|
|
225
|
-
recognitionRef.current = null;
|
|
226
|
-
}
|
|
223
|
+
const recognition = recognitionRef.current;
|
|
224
|
+
if (!recognition) {
|
|
225
|
+
const text = currentTranscript();
|
|
226
|
+
interimRef.current = "";
|
|
227
227
|
setIsActive(false);
|
|
228
|
-
resolve(text);
|
|
229
|
-
}
|
|
228
|
+
return Promise.resolve(text);
|
|
229
|
+
}
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
return new Promise((resolve) => {
|
|
232
|
+
let settled = false;
|
|
233
|
+
const finish = (text: string) => {
|
|
234
|
+
if (settled) return;
|
|
235
|
+
settled = true;
|
|
236
|
+
window.clearTimeout(timeout);
|
|
237
|
+
if (stopWaiterRef.current === finish) {
|
|
238
|
+
stopWaiterRef.current = null;
|
|
239
|
+
}
|
|
240
|
+
if (recognitionRef.current === recognition) {
|
|
241
|
+
recognitionRef.current = null;
|
|
242
|
+
}
|
|
243
|
+
interimRef.current = "";
|
|
244
|
+
setIsActive(false);
|
|
245
|
+
resolve(text);
|
|
246
|
+
};
|
|
234
247
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
248
|
+
const timeout = window.setTimeout(() => {
|
|
249
|
+
finish(currentTranscript());
|
|
250
|
+
}, timeoutMs);
|
|
251
|
+
|
|
252
|
+
stopWaiterRef.current = finish;
|
|
253
|
+
try {
|
|
254
|
+
recognition.stop();
|
|
255
|
+
} catch {
|
|
256
|
+
finish(currentTranscript());
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
},
|
|
260
|
+
[currentTranscript],
|
|
261
|
+
);
|
|
243
262
|
|
|
244
263
|
const pause = useCallback(() => {
|
|
245
264
|
if (!recognitionRef.current) return;
|
package/src/deploy/build.ts
CHANGED
|
@@ -1805,7 +1805,8 @@ async function buildCloudflarePages() {
|
|
|
1805
1805
|
// fails: context-xray token counts fall back to char/4 estimates and the
|
|
1806
1806
|
// OG image route falls back to SVG.
|
|
1807
1807
|
const heavyClientExternals = CLOUDFLARE_WORKER_ESBUILD_EXTERNALS.filter(
|
|
1808
|
-
(p) =>
|
|
1808
|
+
(p) =>
|
|
1809
|
+
!Object.prototype.hasOwnProperty.call(CLOUDFLARE_WORKER_STUB_MODULES, p),
|
|
1809
1810
|
).map((p) => `--external:${p}`);
|
|
1810
1811
|
|
|
1811
1812
|
execFileSync(
|
|
@@ -103,7 +103,7 @@ export function scanDbToolScoping(options: DbToolScopingOptions): GuardResult {
|
|
|
103
103
|
const tables = extractTableCalls(contents);
|
|
104
104
|
for (const table of tables) {
|
|
105
105
|
if (hasRawDbScope(table.body)) continue;
|
|
106
|
-
if (Object.
|
|
106
|
+
if (Object.prototype.hasOwnProperty.call(denylist, table.sqlName)) {
|
|
107
107
|
seenAllowed.add(table.sqlName);
|
|
108
108
|
continue;
|
|
109
109
|
}
|
|
@@ -45,6 +45,17 @@ const SLACK_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
|
|
|
45
45
|
// API blip must not fail-close a sender's identity (and DMs) for 10 minutes.
|
|
46
46
|
const SLACK_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
|
|
47
47
|
const SLACK_IDENTITY_CACHE_MAX_ENTRIES = 1_000;
|
|
48
|
+
const SLACK_TOKEN_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
|
|
49
|
+
const SLACK_TOKEN_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
|
|
50
|
+
|
|
51
|
+
type SlackTokenIdentity = {
|
|
52
|
+
teamId: string | null;
|
|
53
|
+
appId: string | null;
|
|
54
|
+
valid: boolean;
|
|
55
|
+
expiresAt: number;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const slackTokenIdentityCache = new Map<string, SlackTokenIdentity>();
|
|
48
59
|
|
|
49
60
|
interface SlackUserIdentity {
|
|
50
61
|
email: string | null;
|
|
@@ -116,8 +127,7 @@ export function slackAdapter(
|
|
|
116
127
|
): PlatformAdapter {
|
|
117
128
|
const resolveBotToken = async (incoming: IncomingMessage) =>
|
|
118
129
|
(await options.resolveBotToken?.(incoming)) ??
|
|
119
|
-
(await
|
|
120
|
-
(await resolveSecret("SLACK_BOT_TOKEN")) ??
|
|
130
|
+
(await resolveSlackBotTokenForIncoming(incoming)) ??
|
|
121
131
|
undefined;
|
|
122
132
|
|
|
123
133
|
return {
|
|
@@ -713,6 +723,19 @@ function parseAllowlistEnv(name: string): Set<string> | null {
|
|
|
713
723
|
return new Set(values);
|
|
714
724
|
}
|
|
715
725
|
|
|
726
|
+
export async function resolveSlackBotTokenForIncoming(
|
|
727
|
+
incoming: IncomingMessage,
|
|
728
|
+
): Promise<string | undefined> {
|
|
729
|
+
const managedToken = await resolveManagedSlackBotToken(incoming);
|
|
730
|
+
if (managedToken) return managedToken;
|
|
731
|
+
|
|
732
|
+
const legacyToken = await resolveSecret("SLACK_BOT_TOKEN");
|
|
733
|
+
if (!legacyToken) return undefined;
|
|
734
|
+
return (await isSlackTokenForIncoming(legacyToken, incoming))
|
|
735
|
+
? legacyToken
|
|
736
|
+
: undefined;
|
|
737
|
+
}
|
|
738
|
+
|
|
716
739
|
async function resolveManagedSlackBotToken(
|
|
717
740
|
incoming: IncomingMessage,
|
|
718
741
|
): Promise<string | undefined> {
|
|
@@ -736,13 +759,13 @@ async function resolveManagedSlackBotToken(
|
|
|
736
759
|
slackInstallationKey({ teamId, enterpriseId, apiAppId }),
|
|
737
760
|
)
|
|
738
761
|
: null;
|
|
739
|
-
if (!installation && teamId) {
|
|
762
|
+
if (!installation && !apiAppId && teamId) {
|
|
740
763
|
installation = await getActiveIntegrationInstallationForTenant(
|
|
741
764
|
"slack",
|
|
742
765
|
teamId,
|
|
743
766
|
);
|
|
744
767
|
}
|
|
745
|
-
if (!installation && enterpriseId) {
|
|
768
|
+
if (!installation && !apiAppId && enterpriseId) {
|
|
746
769
|
installation = await getActiveIntegrationInstallationForTenant(
|
|
747
770
|
"slack",
|
|
748
771
|
enterpriseId,
|
|
@@ -757,6 +780,62 @@ async function resolveManagedSlackBotToken(
|
|
|
757
780
|
}
|
|
758
781
|
}
|
|
759
782
|
|
|
783
|
+
async function isSlackTokenForIncoming(
|
|
784
|
+
token: string,
|
|
785
|
+
incoming: IncomingMessage,
|
|
786
|
+
): Promise<boolean> {
|
|
787
|
+
const teamId = slackIdentityValue(incoming.platformContext.teamId);
|
|
788
|
+
const apiAppId = slackIdentityValue(incoming.platformContext.apiAppId);
|
|
789
|
+
if (!teamId && !apiAppId) return true;
|
|
790
|
+
|
|
791
|
+
const cached = slackTokenIdentityCache.get(token);
|
|
792
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
793
|
+
return (
|
|
794
|
+
cached.valid &&
|
|
795
|
+
(!teamId || cached.teamId === teamId) &&
|
|
796
|
+
(!apiAppId || cached.appId === apiAppId)
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
const auth = await slackJson(token, "auth.test", {});
|
|
801
|
+
const authTeamId = slackIdentityValue(auth?.team_id);
|
|
802
|
+
const botId = slackIdentityValue(auth?.bot_id);
|
|
803
|
+
let appId: string | null = null;
|
|
804
|
+
let valid = !!auth;
|
|
805
|
+
|
|
806
|
+
if (valid && apiAppId) {
|
|
807
|
+
const bot = botId
|
|
808
|
+
? await slackJson(token, "bots.info", { bot: botId })
|
|
809
|
+
: null;
|
|
810
|
+
appId = slackIdentityValue(bot?.bot?.app_id);
|
|
811
|
+
valid = !!appId;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
const identity: SlackTokenIdentity = {
|
|
815
|
+
teamId: authTeamId,
|
|
816
|
+
appId,
|
|
817
|
+
valid,
|
|
818
|
+
expiresAt:
|
|
819
|
+
Date.now() +
|
|
820
|
+
(valid
|
|
821
|
+
? SLACK_TOKEN_IDENTITY_CACHE_TTL_MS
|
|
822
|
+
: SLACK_TOKEN_IDENTITY_NEGATIVE_CACHE_TTL_MS),
|
|
823
|
+
};
|
|
824
|
+
slackTokenIdentityCache.set(token, identity);
|
|
825
|
+
|
|
826
|
+
return (
|
|
827
|
+
valid &&
|
|
828
|
+
(!teamId || identity.teamId === teamId) &&
|
|
829
|
+
(!apiAppId || identity.appId === apiAppId)
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function slackIdentityValue(value: unknown): string | null {
|
|
834
|
+
if (typeof value !== "string") return null;
|
|
835
|
+
const normalized = value.trim();
|
|
836
|
+
return normalized && normalized !== "unknown" ? normalized : null;
|
|
837
|
+
}
|
|
838
|
+
|
|
760
839
|
let _missingAllowlistWarned = false;
|
|
761
840
|
|
|
762
841
|
/**
|
|
@@ -1079,7 +1158,7 @@ async function resolveSlackThreadPermalink(
|
|
|
1079
1158
|
if (typeof channelId !== "string" || typeof threadTs !== "string") {
|
|
1080
1159
|
return undefined;
|
|
1081
1160
|
}
|
|
1082
|
-
const token = resolvedToken
|
|
1161
|
+
const token = resolvedToken;
|
|
1083
1162
|
if (!token) return undefined;
|
|
1084
1163
|
|
|
1085
1164
|
try {
|
|
@@ -114,7 +114,11 @@ export type {
|
|
|
114
114
|
} from "./remote-types.js";
|
|
115
115
|
|
|
116
116
|
// Adapters
|
|
117
|
-
export {
|
|
117
|
+
export {
|
|
118
|
+
resolveSlackBotTokenForIncoming,
|
|
119
|
+
slackAdapter,
|
|
120
|
+
type SlackAdapterOptions,
|
|
121
|
+
} from "./adapters/slack.js";
|
|
118
122
|
export { telegramAdapter } from "./adapters/telegram.js";
|
|
119
123
|
export { whatsappAdapter } from "./adapters/whatsapp.js";
|
|
120
124
|
export { discordAdapter } from "./adapters/discord.js";
|
|
@@ -806,7 +806,7 @@ const messages = {
|
|
|
806
806
|
connected: "Connected",
|
|
807
807
|
configure: "Configure",
|
|
808
808
|
connect: "Connect",
|
|
809
|
-
connectWithOAuth: "Connect
|
|
809
|
+
connectWithOAuth: "Connect",
|
|
810
810
|
useApiToken: "Use API token",
|
|
811
811
|
connectSuggestion: "Connect {{name}} to use it in chat",
|
|
812
812
|
connectSuggestionWithApiToken:
|