@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
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
} from "@/components/ui/popover";
|
|
19
19
|
import {
|
|
20
20
|
attemptOpenDesktopApp,
|
|
21
|
-
clipsChromeExtensionEnabled,
|
|
22
21
|
clipsChromeExtensionUrl,
|
|
23
22
|
hasDownloadedDesktopApp,
|
|
24
23
|
subscribeDownloaded,
|
|
24
|
+
useClipsChromeExtensionEnabled,
|
|
25
25
|
} from "@/lib/capture-install-options";
|
|
26
26
|
import { cn } from "@/lib/utils";
|
|
27
27
|
|
|
@@ -136,6 +136,7 @@ export function CaptureInstallButton({
|
|
|
136
136
|
...buttonProps
|
|
137
137
|
}: CaptureInstallButtonProps) {
|
|
138
138
|
const downloaded = useHasDownloadedDesktopApp();
|
|
139
|
+
const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
|
|
139
140
|
const label = downloaded ? (downloadedChildren ?? children) : children;
|
|
140
141
|
|
|
141
142
|
if (downloaded) {
|
|
@@ -155,7 +156,7 @@ export function CaptureInstallButton({
|
|
|
155
156
|
);
|
|
156
157
|
}
|
|
157
158
|
|
|
158
|
-
if (!
|
|
159
|
+
if (!chromeExtensionEnabled) {
|
|
159
160
|
return (
|
|
160
161
|
<Button asChild className={className} {...buttonProps}>
|
|
161
162
|
<a href={appPath(desktopHref)}>{label}</a>
|
|
@@ -187,6 +188,7 @@ export function CaptureInstallInlineLink({
|
|
|
187
188
|
side = "bottom",
|
|
188
189
|
}: CaptureInstallInlineLinkProps) {
|
|
189
190
|
const downloaded = useHasDownloadedDesktopApp();
|
|
191
|
+
const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
|
|
190
192
|
|
|
191
193
|
const label = downloaded ? (downloadedChildren ?? children) : children;
|
|
192
194
|
|
|
@@ -202,7 +204,7 @@ export function CaptureInstallInlineLink({
|
|
|
202
204
|
);
|
|
203
205
|
}
|
|
204
206
|
|
|
205
|
-
if (!
|
|
207
|
+
if (!chromeExtensionEnabled) {
|
|
206
208
|
return (
|
|
207
209
|
<a href={appPath(desktopHref)} className={className}>
|
|
208
210
|
{label}
|
|
@@ -11,11 +11,8 @@ import {
|
|
|
11
11
|
IconDownload,
|
|
12
12
|
IconCheck,
|
|
13
13
|
IconExternalLink,
|
|
14
|
-
IconKey,
|
|
15
14
|
IconLoader2,
|
|
16
15
|
IconBolt,
|
|
17
|
-
IconChevronDown,
|
|
18
|
-
IconChevronUp,
|
|
19
16
|
IconRefresh,
|
|
20
17
|
} from "@tabler/icons-react";
|
|
21
18
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
@@ -489,7 +486,6 @@ function isTranscriptionSetupNeeded(
|
|
|
489
486
|
const r = reason.toLowerCase();
|
|
490
487
|
return (
|
|
491
488
|
r.includes("openai_api_key") ||
|
|
492
|
-
r.includes("groq_api_key") ||
|
|
493
489
|
r.includes("api key") ||
|
|
494
490
|
r.includes("not configured") ||
|
|
495
491
|
r.includes("no transcription") ||
|
|
@@ -579,10 +575,9 @@ function friendlyCleanupFailure(
|
|
|
579
575
|
/**
|
|
580
576
|
* Inline card shown when transcription needs a provider set up.
|
|
581
577
|
*
|
|
582
|
-
* Builder.io is the
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
* produce a transcript. Clips does not route recording transcription to OpenAI.
|
|
578
|
+
* Builder.io is the only cloud fallback — free, one-click, no separate API
|
|
579
|
+
* key required (uses BUILDER_PRIVATE_KEY once the user connects). Clips does
|
|
580
|
+
* not route recording transcription to BYOK speech providers.
|
|
586
581
|
*/
|
|
587
582
|
function TranscriptSetupCard({
|
|
588
583
|
failureReason,
|
|
@@ -600,14 +595,6 @@ function TranscriptSetupCard({
|
|
|
600
595
|
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
601
596
|
const mountedRef = useRef(true);
|
|
602
597
|
|
|
603
|
-
const [showByok, setShowByok] = useState(false);
|
|
604
|
-
const [apiKey, setApiKey] = useState("");
|
|
605
|
-
const [saving, setSaving] = useState(false);
|
|
606
|
-
const [saveToast, setSaveToast] = useState<{
|
|
607
|
-
kind: "ok" | "err";
|
|
608
|
-
text: string;
|
|
609
|
-
} | null>(null);
|
|
610
|
-
const toastTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
611
598
|
const autoRetryRef = useRef(false);
|
|
612
599
|
const onRetryRef = useRef(onRetry);
|
|
613
600
|
|
|
@@ -630,7 +617,6 @@ function TranscriptSetupCard({
|
|
|
630
617
|
return () => {
|
|
631
618
|
mountedRef.current = false;
|
|
632
619
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
633
|
-
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
634
620
|
};
|
|
635
621
|
}, []);
|
|
636
622
|
|
|
@@ -675,44 +661,6 @@ function TranscriptSetupCard({
|
|
|
675
661
|
}, 2000);
|
|
676
662
|
}, [onRetry]);
|
|
677
663
|
|
|
678
|
-
async function saveApiKey() {
|
|
679
|
-
if (!apiKey.trim() || saving) return;
|
|
680
|
-
setSaving(true);
|
|
681
|
-
try {
|
|
682
|
-
const res = await fetch(
|
|
683
|
-
agentNativePath("/_agent-native/secrets/GROQ_API_KEY"),
|
|
684
|
-
{
|
|
685
|
-
method: "POST",
|
|
686
|
-
headers: { "Content-Type": "application/json" },
|
|
687
|
-
body: JSON.stringify({ value: apiKey.trim() }),
|
|
688
|
-
},
|
|
689
|
-
);
|
|
690
|
-
if (!mountedRef.current) return;
|
|
691
|
-
if (!res.ok) {
|
|
692
|
-
const err = await res
|
|
693
|
-
.json()
|
|
694
|
-
.then((j: { error?: string }) => j.error)
|
|
695
|
-
.catch(() => null);
|
|
696
|
-
if (!mountedRef.current) return;
|
|
697
|
-
setSaveToast({
|
|
698
|
-
kind: "err",
|
|
699
|
-
text: err ?? t("transcriptPanel.saveFailed", { status: res.status }),
|
|
700
|
-
});
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
setApiKey("");
|
|
704
|
-
setSaveToast({ kind: "ok", text: t("transcriptPanel.savedRetrying") });
|
|
705
|
-
onRetry?.();
|
|
706
|
-
if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
|
|
707
|
-
toastTimerRef.current = setTimeout(() => {
|
|
708
|
-
if (mountedRef.current) setSaveToast(null);
|
|
709
|
-
toastTimerRef.current = null;
|
|
710
|
-
}, 2500);
|
|
711
|
-
} finally {
|
|
712
|
-
if (mountedRef.current) setSaving(false);
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
|
|
716
664
|
const isProviderError =
|
|
717
665
|
!isBuilderCreditsExhaustedMessage(failureReason) &&
|
|
718
666
|
(failureReason?.toLowerCase().includes("quota") ||
|
|
@@ -817,87 +765,6 @@ function TranscriptSetupCard({
|
|
|
817
765
|
<p className="text-[11px] text-destructive mt-2">{connectError}</p>
|
|
818
766
|
)}
|
|
819
767
|
</div>
|
|
820
|
-
|
|
821
|
-
{/* BYOK — secondary option, collapsed by default. Shown even when
|
|
822
|
-
Builder is connected so users can fall back if Builder
|
|
823
|
-
transcription itself fails (quota / outage / unsupported audio
|
|
824
|
-
format) — the failure message tells them to add a key, so the
|
|
825
|
-
input must be reachable. */}
|
|
826
|
-
<div>
|
|
827
|
-
<button
|
|
828
|
-
type="button"
|
|
829
|
-
onClick={() => setShowByok((v) => !v)}
|
|
830
|
-
className="inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
|
|
831
|
-
>
|
|
832
|
-
<IconKey className="h-3.5 w-3.5" />
|
|
833
|
-
{isProviderError
|
|
834
|
-
? "Update your API key"
|
|
835
|
-
: builderConfigured
|
|
836
|
-
? "Advanced backup option"
|
|
837
|
-
: "Or use your own Groq key"}
|
|
838
|
-
{showByok ? (
|
|
839
|
-
<IconChevronUp className="h-3 w-3" />
|
|
840
|
-
) : (
|
|
841
|
-
<IconChevronDown className="h-3 w-3" />
|
|
842
|
-
)}
|
|
843
|
-
</button>
|
|
844
|
-
|
|
845
|
-
{showByok && (
|
|
846
|
-
<div className="mt-2 space-y-2 pl-1">
|
|
847
|
-
<p className="text-[11px] text-muted-foreground">
|
|
848
|
-
{t("transcriptPanel.groqKeysStart")}{" "}
|
|
849
|
-
<code className="font-mono">gsk_</code>.{" "}
|
|
850
|
-
{t("transcriptPanel.nativeSpeechPrimary")}
|
|
851
|
-
</p>
|
|
852
|
-
<div className="flex gap-1.5">
|
|
853
|
-
<Input
|
|
854
|
-
type="password"
|
|
855
|
-
value={apiKey}
|
|
856
|
-
onChange={(e) => setApiKey(e.target.value)}
|
|
857
|
-
onKeyDown={(e) => {
|
|
858
|
-
if (e.key === "Enter") saveApiKey();
|
|
859
|
-
}}
|
|
860
|
-
placeholder="gsk_…"
|
|
861
|
-
className="h-8 text-xs"
|
|
862
|
-
/>
|
|
863
|
-
<Button
|
|
864
|
-
size="sm"
|
|
865
|
-
onClick={saveApiKey}
|
|
866
|
-
disabled={!apiKey.trim() || saving}
|
|
867
|
-
>
|
|
868
|
-
{saving ? (
|
|
869
|
-
<IconLoader2 className="h-3.5 w-3.5 animate-spin" />
|
|
870
|
-
) : (
|
|
871
|
-
t("common.save")
|
|
872
|
-
)}
|
|
873
|
-
</Button>
|
|
874
|
-
</div>
|
|
875
|
-
<div className="flex items-center gap-3">
|
|
876
|
-
<a
|
|
877
|
-
href="https://console.groq.com/keys"
|
|
878
|
-
target="_blank"
|
|
879
|
-
rel="noopener noreferrer"
|
|
880
|
-
className="inline-flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground"
|
|
881
|
-
>
|
|
882
|
-
{t("transcriptPanel.getGroqKey")}
|
|
883
|
-
<IconExternalLink className="h-3 w-3" />
|
|
884
|
-
</a>
|
|
885
|
-
</div>
|
|
886
|
-
{saveToast && (
|
|
887
|
-
<p
|
|
888
|
-
className={cn(
|
|
889
|
-
"text-[11px]",
|
|
890
|
-
saveToast.kind === "ok"
|
|
891
|
-
? "text-green-600"
|
|
892
|
-
: "text-destructive",
|
|
893
|
-
)}
|
|
894
|
-
>
|
|
895
|
-
{saveToast.text}
|
|
896
|
-
</p>
|
|
897
|
-
)}
|
|
898
|
-
</div>
|
|
899
|
-
)}
|
|
900
|
-
</div>
|
|
901
768
|
</div>
|
|
902
769
|
</div>
|
|
903
770
|
);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { appPath } from "@agent-native/core/client/api-path";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
2
3
|
|
|
3
4
|
const DESKTOP_PROMO_DISMISSED_STORAGE_KEY = "clips.desktop-promo.dismissed";
|
|
4
5
|
const DESKTOP_DOWNLOADED_STORAGE_KEY = "clips.desktop-app.downloaded";
|
|
@@ -146,9 +147,19 @@ const chromeExtensionUrl =
|
|
|
146
147
|
|
|
147
148
|
// The published extension manifest only trusts first-party Clips/local origins.
|
|
148
149
|
// Custom deployments can opt in after publishing a matching extension/listing.
|
|
149
|
-
export
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
export function useClipsChromeExtensionEnabled(): boolean {
|
|
151
|
+
const [enabled, setEnabled] = useState(false);
|
|
152
|
+
|
|
153
|
+
useEffect(() => {
|
|
154
|
+
setEnabled(
|
|
155
|
+
resolveClipsChromeExtensionEnabled({
|
|
156
|
+
enabledSetting: import.meta.env.VITE_CLIPS_CHROME_EXTENSION_ENABLED,
|
|
157
|
+
hostname: getCurrentHostname(),
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
}, []);
|
|
161
|
+
|
|
162
|
+
return enabled;
|
|
163
|
+
}
|
|
153
164
|
|
|
154
165
|
export const clipsChromeExtensionUrl = chromeExtensionUrl || null;
|
|
@@ -13,9 +13,9 @@ import { Button } from "@/components/ui/button";
|
|
|
13
13
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
14
14
|
import enMessages from "@/i18n/en-US";
|
|
15
15
|
import {
|
|
16
|
-
clipsChromeExtensionEnabled,
|
|
17
16
|
clipsChromeExtensionUrl,
|
|
18
17
|
markDesktopAppDownloaded,
|
|
18
|
+
useClipsChromeExtensionEnabled,
|
|
19
19
|
} from "@/lib/capture-install-options";
|
|
20
20
|
|
|
21
21
|
export function meta() {
|
|
@@ -179,6 +179,7 @@ function secondaryDownloadButton(
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
export default function DownloadPage() {
|
|
182
|
+
const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
|
|
182
183
|
const t = useT();
|
|
183
184
|
const [manifest, setManifest] = useState<Manifest | null>(null);
|
|
184
185
|
const [manifestError, setManifestError] = useState(false);
|
|
@@ -283,7 +284,7 @@ export default function DownloadPage() {
|
|
|
283
284
|
</div>
|
|
284
285
|
</div>
|
|
285
286
|
|
|
286
|
-
{
|
|
287
|
+
{chromeExtensionEnabled && (
|
|
287
288
|
<section className="mt-10 w-full max-w-xl rounded-2xl border border-border bg-card p-4 text-start shadow-sm">
|
|
288
289
|
<div className="flex items-start gap-3">
|
|
289
290
|
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
|
|
@@ -497,13 +497,13 @@ export function transcriptStatusInstructions(
|
|
|
497
497
|
|
|
498
498
|
if (status === "failed" && lowerReason.includes("credits exhausted")) {
|
|
499
499
|
return [
|
|
500
|
-
"Transcription failed because Builder transcription credits are exhausted. Tell the user to upgrade or connect Builder.io credits
|
|
500
|
+
"Transcription failed because Builder transcription credits are exhausted. Tell the user to upgrade or connect Builder.io credits. Clips uses the browser/macOS native transcript first and Builder transcription on the original recording when native capture is unavailable.",
|
|
501
501
|
];
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
if (status === "failed" && failureReason) {
|
|
505
505
|
return [
|
|
506
|
-
`Transcription failed with reason: ${failureReason}. Explain this to the user and suggest retrying
|
|
506
|
+
`Transcription failed with reason: ${failureReason}. Explain this to the user and suggest retrying native capture or the Builder transcription fallback.`,
|
|
507
507
|
];
|
|
508
508
|
}
|
|
509
509
|
|
|
@@ -7,13 +7,14 @@ import { registerRequiredSecret } from "@agent-native/core/secrets";
|
|
|
7
7
|
// run in a separate Vite SSR module graph and write to a different Map.
|
|
8
8
|
|
|
9
9
|
// ── Transcription secrets (optional) ──────────────────────────────────
|
|
10
|
-
// Native web/macOS speech is the primary transcript source.
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// Native web/macOS speech is the primary recording transcript source. Builder
|
|
11
|
+
// is the only cloud fallback for a saved recording. Gemini/Groq BYOK remain
|
|
12
|
+
// available for desktop voice dictation and other provider-specific tools.
|
|
13
13
|
//
|
|
14
14
|
// We support two BYOK providers:
|
|
15
15
|
// 1. Gemini — recommended for fast LLM cleanup in the desktop tray.
|
|
16
|
-
// 2. Groq
|
|
16
|
+
// 2. Groq — optional voice-dictation provider, not a recording transcript
|
|
17
|
+
// fallback.
|
|
17
18
|
//
|
|
18
19
|
// Neither is strictly required — videos still upload and play back without
|
|
19
20
|
// cloud transcription.
|
|
@@ -110,9 +111,9 @@ registerRequiredSecret({
|
|
|
110
111
|
|
|
111
112
|
registerRequiredSecret({
|
|
112
113
|
key: "GROQ_API_KEY",
|
|
113
|
-
label: "Groq API Key (
|
|
114
|
+
label: "Groq API Key (voice dictation)",
|
|
114
115
|
description:
|
|
115
|
-
"
|
|
116
|
+
"Optional speech-to-text provider for desktop voice dictation. Clips recording transcripts use native browser/macOS capture first and Builder transcription for the saved recording fallback.",
|
|
116
117
|
docsUrl: "https://console.groq.com/keys",
|
|
117
118
|
scope: "user",
|
|
118
119
|
kind: "api-key",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useSendToAgentChat } from "@agent-native/core/client/agent-chat";
|
|
2
|
+
import { PromptComposer } from "@agent-native/core/client/composer";
|
|
2
3
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
4
|
import type { CreateInlineDatabaseResponse } from "@shared/api";
|
|
4
5
|
import { renderMathToHtml } from "@shared/math-rendering";
|
|
@@ -20,8 +21,7 @@ import {
|
|
|
20
21
|
IconCode,
|
|
21
22
|
IconMinus,
|
|
22
23
|
IconTable as TableIcon,
|
|
23
|
-
|
|
24
|
-
IconArrowUp,
|
|
24
|
+
IconHierarchy2,
|
|
25
25
|
IconInfoCircle,
|
|
26
26
|
IconMusic,
|
|
27
27
|
IconPhoto,
|
|
@@ -218,18 +218,6 @@ export function parseInlineGeneratePrompt(textBeforeCursor: string) {
|
|
|
218
218
|
return prompt || null;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
export function shouldOpenGenerateOnSpace(editor: Editor) {
|
|
222
|
-
const { selection } = editor.state;
|
|
223
|
-
if (!selection.empty) return false;
|
|
224
|
-
|
|
225
|
-
const { $from } = selection;
|
|
226
|
-
if (!$from.parent.isTextblock) return false;
|
|
227
|
-
if ($from.parent.type.name !== "paragraph") return false;
|
|
228
|
-
if ($from.parentOffset !== 0) return false;
|
|
229
|
-
|
|
230
|
-
return $from.parent.textContent.trim().length === 0;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
221
|
export function parseSlashCommandQuery(textBeforeCursor: string) {
|
|
234
222
|
return textBeforeCursor.match(/^\s*\/([a-zA-Z0-9]*)$/)?.[1] ?? null;
|
|
235
223
|
}
|
|
@@ -505,7 +493,7 @@ export function SlashCommandMenu({
|
|
|
505
493
|
onDraftPersisted,
|
|
506
494
|
}: SlashCommandMenuProps) {
|
|
507
495
|
const t = useT();
|
|
508
|
-
const { send } = useSendToAgentChat();
|
|
496
|
+
const { send, isGenerating } = useSendToAgentChat();
|
|
509
497
|
const navigate = useNavigate();
|
|
510
498
|
const createPage = useCreatePage({ navigate: false, awaitPersist: true });
|
|
511
499
|
const createInlineDatabase = useCreateInlineContentDatabase(
|
|
@@ -523,11 +511,9 @@ export function SlashCommandMenu({
|
|
|
523
511
|
|
|
524
512
|
// Generate prompt popover state
|
|
525
513
|
const [generateOpen, setGenerateOpen] = useState(false);
|
|
526
|
-
const [generatePrompt, setGeneratePrompt] = useState("");
|
|
527
514
|
const [generatePos, setGeneratePos] = useState<EditorMenuPosition | null>(
|
|
528
515
|
null,
|
|
529
516
|
);
|
|
530
|
-
const generateTextareaRef = useRef<HTMLTextAreaElement>(null);
|
|
531
517
|
|
|
532
518
|
const [equationDraft, setEquationDraft] = useState<EquationDraft | null>(
|
|
533
519
|
null,
|
|
@@ -552,6 +538,7 @@ export function SlashCommandMenu({
|
|
|
552
538
|
send({
|
|
553
539
|
message: trimmed,
|
|
554
540
|
context: `The user is asking you to generate content for their document (id: ${documentId}). Use the update-document action to write the generated markdown content. Do NOT use db-exec or raw SQL - use \`update-document --id ${documentId} --content "..."\` (and \`--title\` if appropriate).${content ? `\n\nCurrent document content:\n${content}` : "\n\nThe document is currently empty."}`,
|
|
541
|
+
submit: true,
|
|
555
542
|
});
|
|
556
543
|
},
|
|
557
544
|
[documentId, editor, send, t],
|
|
@@ -576,9 +563,7 @@ export function SlashCommandMenu({
|
|
|
576
563
|
if (!nextPosition) return false;
|
|
577
564
|
|
|
578
565
|
setGeneratePos(nextPosition);
|
|
579
|
-
setGeneratePrompt("");
|
|
580
566
|
setGenerateOpen(true);
|
|
581
|
-
setTimeout(() => generateTextareaRef.current?.focus(), 0);
|
|
582
567
|
return true;
|
|
583
568
|
},
|
|
584
569
|
[getSelectionMenuPosition],
|
|
@@ -602,7 +587,7 @@ export function SlashCommandMenu({
|
|
|
602
587
|
const generateCommand: CommandItem = {
|
|
603
588
|
title: t("editor.slash.generate"),
|
|
604
589
|
description: t("editor.slash.generateDescription"),
|
|
605
|
-
icon:
|
|
590
|
+
icon: IconHierarchy2,
|
|
606
591
|
action: () => {
|
|
607
592
|
openGeneratePopover(position);
|
|
608
593
|
},
|
|
@@ -912,10 +897,6 @@ export function SlashCommandMenu({
|
|
|
912
897
|
);
|
|
913
898
|
};
|
|
914
899
|
|
|
915
|
-
function handleGenerateSubmit() {
|
|
916
|
-
submitGeneratePrompt(generatePrompt);
|
|
917
|
-
}
|
|
918
|
-
|
|
919
900
|
const executeCommand = useCallback(
|
|
920
901
|
async (cmd: CommandItem) => {
|
|
921
902
|
const slashRange =
|
|
@@ -940,25 +921,6 @@ export function SlashCommandMenu({
|
|
|
940
921
|
|
|
941
922
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
942
923
|
if (!isOpen) {
|
|
943
|
-
if (
|
|
944
|
-
(e.key === " " || e.code === "Space") &&
|
|
945
|
-
!e.shiftKey &&
|
|
946
|
-
!e.metaKey &&
|
|
947
|
-
!e.ctrlKey &&
|
|
948
|
-
!e.altKey &&
|
|
949
|
-
editor.isFocused &&
|
|
950
|
-
shouldOpenGenerateOnSpace(editor)
|
|
951
|
-
) {
|
|
952
|
-
e.preventDefault();
|
|
953
|
-
e.stopPropagation();
|
|
954
|
-
setIsOpen(false);
|
|
955
|
-
setIsTurnInto(false);
|
|
956
|
-
setQuery("");
|
|
957
|
-
slashPosRef.current = null;
|
|
958
|
-
openGeneratePopover();
|
|
959
|
-
return;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
924
|
if (
|
|
963
925
|
e.key === "Enter" &&
|
|
964
926
|
!e.shiftKey &&
|
|
@@ -1195,48 +1157,18 @@ export function SlashCommandMenu({
|
|
|
1195
1157
|
<PopoverContent
|
|
1196
1158
|
align="start"
|
|
1197
1159
|
side="bottom"
|
|
1198
|
-
className="w-[calc(100vw-2rem)]
|
|
1199
|
-
onOpenAutoFocus={(e: Event) => {
|
|
1200
|
-
e.preventDefault();
|
|
1201
|
-
generateTextareaRef.current?.focus();
|
|
1202
|
-
}}
|
|
1160
|
+
className="w-[calc(100vw-2rem)] p-3 sm:w-[420px]"
|
|
1203
1161
|
>
|
|
1204
|
-
<
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
1215
|
-
e.preventDefault();
|
|
1216
|
-
handleGenerateSubmit();
|
|
1217
|
-
}
|
|
1218
|
-
if (e.key === "Escape") {
|
|
1219
|
-
setGenerateOpen(false);
|
|
1220
|
-
}
|
|
1221
|
-
}}
|
|
1222
|
-
placeholder={t("editor.describeWhatToGenerate")}
|
|
1223
|
-
className="mt-2 w-full resize-none bg-transparent text-sm placeholder:text-muted-foreground/50 focus:outline-none"
|
|
1224
|
-
rows={3}
|
|
1225
|
-
/>
|
|
1226
|
-
</div>
|
|
1227
|
-
<div className="flex items-center justify-end gap-2 border-t border-border px-4 py-2.5">
|
|
1228
|
-
<span className="text-[11px] text-muted-foreground/70">
|
|
1229
|
-
{/Mac|iPhone|iPad/.test(navigator.userAgent) ? "⌘" : "Ctrl"}
|
|
1230
|
-
{t("editor.enterToSubmit")}
|
|
1231
|
-
</span>
|
|
1232
|
-
<button
|
|
1233
|
-
className="flex h-7 w-7 items-center justify-center rounded-lg bg-muted hover:bg-accent disabled:opacity-30"
|
|
1234
|
-
onClick={handleGenerateSubmit}
|
|
1235
|
-
disabled={!generatePrompt.trim()}
|
|
1236
|
-
>
|
|
1237
|
-
<IconArrowUp size={14} />
|
|
1238
|
-
</button>
|
|
1239
|
-
</div>
|
|
1162
|
+
<p className="px-1 pb-2 text-sm font-semibold text-foreground">
|
|
1163
|
+
{t("editor.generateWithAi")}
|
|
1164
|
+
</p>
|
|
1165
|
+
<PromptComposer
|
|
1166
|
+
autoFocus
|
|
1167
|
+
disabled={isGenerating}
|
|
1168
|
+
placeholder={t("editor.describeWhatToGenerate")}
|
|
1169
|
+
draftScope={`content:generate:${documentId ?? "document"}`}
|
|
1170
|
+
onSubmit={submitGeneratePrompt}
|
|
1171
|
+
/>
|
|
1240
1172
|
</PopoverContent>
|
|
1241
1173
|
</Popover>
|
|
1242
1174
|
)}
|
|
@@ -355,8 +355,7 @@ const NotionBlockquote = Blockquote.extend({
|
|
|
355
355
|
},
|
|
356
356
|
});
|
|
357
357
|
|
|
358
|
-
const DEFAULT_EMPTY_BLOCK_PLACEHOLDER =
|
|
359
|
-
"Press ‘space’ for AI or ‘/’ for commands";
|
|
358
|
+
const DEFAULT_EMPTY_BLOCK_PLACEHOLDER = "Press ‘/’ for commands";
|
|
360
359
|
|
|
361
360
|
const CONTENT_RECENT_EDIT_TTL_MS = 6_000;
|
|
362
361
|
const RECENT_EDIT_MARKER_WIDTH = 2;
|
|
@@ -975,6 +974,7 @@ interface VisualEditorExtensionOptions {
|
|
|
975
974
|
onOpenNotionPageLink?: (documentId: string) => void;
|
|
976
975
|
localFilePath?: string | null;
|
|
977
976
|
referenceDepth?: number;
|
|
977
|
+
emptyBlockPlaceholder?: string;
|
|
978
978
|
}
|
|
979
979
|
|
|
980
980
|
function hasAncestorType(
|
|
@@ -1088,19 +1088,21 @@ function getVisualEditorPlaceholder({
|
|
|
1088
1088
|
node,
|
|
1089
1089
|
pos,
|
|
1090
1090
|
hasAnchor,
|
|
1091
|
+
emptyBlockPlaceholder = DEFAULT_EMPTY_BLOCK_PLACEHOLDER,
|
|
1091
1092
|
}: {
|
|
1092
1093
|
editor: CoreEditor;
|
|
1093
1094
|
node: ProseMirrorNode;
|
|
1094
1095
|
pos: number;
|
|
1095
1096
|
hasAnchor: boolean;
|
|
1097
|
+
emptyBlockPlaceholder?: string;
|
|
1096
1098
|
}): string {
|
|
1097
1099
|
const isToggleBody =
|
|
1098
1100
|
node.type.name === "paragraph" &&
|
|
1099
1101
|
hasAncestorType(editor, pos, "notionToggle");
|
|
1100
1102
|
|
|
1101
1103
|
if (isToggleBody) {
|
|
1102
|
-
return hasAnchor
|
|
1103
|
-
?
|
|
1104
|
+
return hasAnchor && editor.isFocused
|
|
1105
|
+
? emptyBlockPlaceholder
|
|
1104
1106
|
: EMPTY_TOGGLE_BODY_PLACEHOLDER;
|
|
1105
1107
|
}
|
|
1106
1108
|
|
|
@@ -1122,7 +1124,7 @@ function getVisualEditorPlaceholder({
|
|
|
1122
1124
|
return hasAnchor ? "Empty quote" : "";
|
|
1123
1125
|
}
|
|
1124
1126
|
|
|
1125
|
-
// Skip the
|
|
1127
|
+
// Skip the command hint inside table cells — it wraps
|
|
1126
1128
|
// awkwardly in narrow columns and the cell itself is already an affordance.
|
|
1127
1129
|
if (
|
|
1128
1130
|
node.type.name === "paragraph" &&
|
|
@@ -1132,7 +1134,7 @@ function getVisualEditorPlaceholder({
|
|
|
1132
1134
|
return "";
|
|
1133
1135
|
}
|
|
1134
1136
|
|
|
1135
|
-
return hasAnchor ?
|
|
1137
|
+
return hasAnchor && editor.isFocused ? emptyBlockPlaceholder : "";
|
|
1136
1138
|
}
|
|
1137
1139
|
|
|
1138
1140
|
export async function uploadAndInsertImageFiles(
|
|
@@ -1302,6 +1304,7 @@ export function createVisualEditorExtensions({
|
|
|
1302
1304
|
onOpenNotionPageLink,
|
|
1303
1305
|
localFilePath,
|
|
1304
1306
|
referenceDepth = 0,
|
|
1307
|
+
emptyBlockPlaceholder = DEFAULT_EMPTY_BLOCK_PLACEHOLDER,
|
|
1305
1308
|
}: VisualEditorExtensionOptions = {}): Extensions {
|
|
1306
1309
|
// Build on the SHARED editor core (StarterKit base + the Collaboration /
|
|
1307
1310
|
// CollaborationCaret wiring + collab undo/redo gating + ordering), then inject
|
|
@@ -1337,7 +1340,8 @@ export function createVisualEditorExtensions({
|
|
|
1337
1340
|
NotionBlockquote,
|
|
1338
1341
|
CodeBlock,
|
|
1339
1342
|
Placeholder.configure({
|
|
1340
|
-
placeholder:
|
|
1343
|
+
placeholder: (options) =>
|
|
1344
|
+
getVisualEditorPlaceholder({ ...options, emptyBlockPlaceholder }),
|
|
1341
1345
|
showOnlyWhenEditable: true,
|
|
1342
1346
|
showOnlyCurrent: true,
|
|
1343
1347
|
includeChildren: true,
|
|
@@ -1740,6 +1744,7 @@ export function VisualEditor({
|
|
|
1740
1744
|
onOpenNotionPageLink,
|
|
1741
1745
|
localFilePath,
|
|
1742
1746
|
referenceDepth,
|
|
1747
|
+
emptyBlockPlaceholder: t("editor.emptyBlockPlaceholder"),
|
|
1743
1748
|
}),
|
|
1744
1749
|
[
|
|
1745
1750
|
documentId,
|
|
@@ -1754,6 +1759,7 @@ export function VisualEditor({
|
|
|
1754
1759
|
onOpenNotionPageLink,
|
|
1755
1760
|
localFilePath,
|
|
1756
1761
|
referenceDepth,
|
|
1762
|
+
t,
|
|
1757
1763
|
],
|
|
1758
1764
|
);
|
|
1759
1765
|
|
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
IconCopy,
|
|
12
12
|
IconDownload,
|
|
13
13
|
IconDots,
|
|
14
|
+
IconHierarchy2,
|
|
14
15
|
IconMessageCircle,
|
|
15
16
|
IconMinus,
|
|
16
17
|
IconPhoto,
|
|
17
18
|
IconPlus,
|
|
18
19
|
IconRefresh,
|
|
19
|
-
IconWand,
|
|
20
20
|
IconTrash,
|
|
21
21
|
IconX,
|
|
22
22
|
} from "@tabler/icons-react";
|
|
@@ -1091,7 +1091,7 @@ export function ImageBlock({
|
|
|
1091
1091
|
disabled={isGeneratingAlt}
|
|
1092
1092
|
onClick={() => void handleGenerateAltText()}
|
|
1093
1093
|
>
|
|
1094
|
-
<
|
|
1094
|
+
<IconHierarchy2 size={18} />
|
|
1095
1095
|
</button>
|
|
1096
1096
|
</TooltipTrigger>
|
|
1097
1097
|
<TooltipContent>
|