@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
|
@@ -2995,6 +2995,7 @@ const enUS = {
|
|
|
2995
2995
|
toggleField: "Toggle {{name}}",
|
|
2996
2996
|
creatingDatabase: "Creating inline database...",
|
|
2997
2997
|
databaseCreated: "Inline database created",
|
|
2998
|
+
emptyBlockPlaceholder: "Press ‘/’ for commands",
|
|
2998
2999
|
describeWhatToGenerate: "Describe what to generate...",
|
|
2999
3000
|
enterToSubmit: "Enter to submit",
|
|
3000
3001
|
failedToCreateDatabase: "Failed to create inline database",
|
|
@@ -5462,6 +5463,7 @@ const editorMessagesByLocale = {
|
|
|
5462
5463
|
"同步 Builder 正文完成前会暂停编辑,避免覆盖现有文章内容。",
|
|
5463
5464
|
creatingDatabase: "正在创建内联数据库...",
|
|
5464
5465
|
databaseCreated: "内联数据库已创建",
|
|
5466
|
+
emptyBlockPlaceholder: "按“/”使用命令",
|
|
5465
5467
|
describeWhatToGenerate: "描述要生成什么...",
|
|
5466
5468
|
enterToSubmit: "输入提交",
|
|
5467
5469
|
failedToCreateDatabase: "创建内联数据库失败",
|
|
@@ -5806,6 +5808,7 @@ const editorMessagesByLocale = {
|
|
|
5806
5808
|
"La edición está en pausa hasta que el cuerpo de Builder termine de sincronizarse, para no sobrescribir el contenido existente del artículo.",
|
|
5807
5809
|
creatingDatabase: "Creando base de datos integrada...",
|
|
5808
5810
|
databaseCreated: "Base de datos integrada creada",
|
|
5811
|
+
emptyBlockPlaceholder: "Pulsa «/» para ver los comandos",
|
|
5809
5812
|
describeWhatToGenerate: "Describe qué generar...",
|
|
5810
5813
|
enterToSubmit: "Entra para enviar",
|
|
5811
5814
|
failedToCreateDatabase: "No se pudo crear la base de datos integrada",
|
|
@@ -6162,6 +6165,7 @@ const editorMessagesByLocale = {
|
|
|
6162
6165
|
"La modification est suspendue jusqu'à la fin de la synchronisation du corps Builder, afin de ne pas écraser le contenu existant de l'article.",
|
|
6163
6166
|
creatingDatabase: "Création d'une base de données intégrée...",
|
|
6164
6167
|
databaseCreated: "Base de données intégrée créée",
|
|
6168
|
+
emptyBlockPlaceholder: "Appuyez sur « / » pour afficher les commandes",
|
|
6165
6169
|
describeWhatToGenerate: "Décrivez ce qu'il faut générer...",
|
|
6166
6170
|
enterToSubmit: "Entrez pour soumettre",
|
|
6167
6171
|
failedToCreateDatabase:
|
|
@@ -6520,6 +6524,7 @@ const editorMessagesByLocale = {
|
|
|
6520
6524
|
"Die Bearbeitung ist pausiert, bis der Builder-Textkörper fertig synchronisiert ist, damit der bestehende Artikelinhalt nicht überschrieben wird.",
|
|
6521
6525
|
creatingDatabase: "Inline-Datenbank wird erstellt...",
|
|
6522
6526
|
databaseCreated: "Inline-Datenbank erstellt",
|
|
6527
|
+
emptyBlockPlaceholder: "Drücke „/“ für Befehle",
|
|
6523
6528
|
describeWhatToGenerate: "Beschreiben Sie, was generiert werden soll ...",
|
|
6524
6529
|
enterToSubmit: "Zum Absenden eintreten",
|
|
6525
6530
|
failedToCreateDatabase: "Inline-Datenbank konnte nicht erstellt werden",
|
|
@@ -6883,6 +6888,7 @@ const editorMessagesByLocale = {
|
|
|
6883
6888
|
"既存の記事内容を上書きしないよう、Builder 本文の同期が完了するまで編集は一時停止されます。",
|
|
6884
6889
|
creatingDatabase: "インラインデータベースを作成しています...",
|
|
6885
6890
|
databaseCreated: "インラインデータベースが作成されました",
|
|
6891
|
+
emptyBlockPlaceholder: "「/」でコマンドを表示",
|
|
6886
6892
|
describeWhatToGenerate: "何を生成するかを説明します...",
|
|
6887
6893
|
enterToSubmit: "入力して送信してください",
|
|
6888
6894
|
failedToCreateDatabase: "インラインデータベースの作成に失敗しました",
|
|
@@ -7235,6 +7241,7 @@ const editorMessagesByLocale = {
|
|
|
7235
7241
|
"기존 문서 내용을 덮어쓰지 않도록 Builder 본문 동기화가 완료될 때까지 편집이 일시 중지됩니다.",
|
|
7236
7242
|
creatingDatabase: "인라인 데이터베이스 생성 중...",
|
|
7237
7243
|
databaseCreated: "인라인 데이터베이스가 생성되었습니다.",
|
|
7244
|
+
emptyBlockPlaceholder: "‘/’를 눌러 명령 사용",
|
|
7238
7245
|
describeWhatToGenerate: "무엇을 생성할지 설명하세요...",
|
|
7239
7246
|
enterToSubmit: "제출하려면 입력하세요.",
|
|
7240
7247
|
failedToCreateDatabase: "인라인 데이터베이스를 생성하지 못했습니다.",
|
|
@@ -7586,6 +7593,7 @@ const editorMessagesByLocale = {
|
|
|
7586
7593
|
"A edição fica pausada até o corpo do Builder terminar de sincronizar, para não sobrescrever o conteúdo existente do artigo.",
|
|
7587
7594
|
creatingDatabase: "Criando banco de dados embutido...",
|
|
7588
7595
|
databaseCreated: "Banco de dados embutido criado",
|
|
7596
|
+
emptyBlockPlaceholder: "Pressione “/” para comandos",
|
|
7589
7597
|
describeWhatToGenerate: "Descreva o que gerar...",
|
|
7590
7598
|
enterToSubmit: "Entre para enviar",
|
|
7591
7599
|
failedToCreateDatabase: "Falha ao criar banco de dados embutido",
|
|
@@ -7943,6 +7951,7 @@ const editorMessagesByLocale = {
|
|
|
7943
7951
|
"Builder का मुख्य भाग सिंक पूरा होने तक संपादन रोका गया है, ताकि मौजूदा लेख सामग्री अधिलेखित न हो।",
|
|
7944
7952
|
creatingDatabase: "इनलाइन डेटाबेस बनाया जा रहा है...",
|
|
7945
7953
|
databaseCreated: "इनलाइन डेटाबेस बनाया गया",
|
|
7954
|
+
emptyBlockPlaceholder: "कमांड के लिए '/' दबाएं",
|
|
7946
7955
|
describeWhatToGenerate: "वर्णन करें कि क्या उत्पन्न करना है...",
|
|
7947
7956
|
enterToSubmit: "सबमिट करने के लिए दर्ज करें",
|
|
7948
7957
|
failedToCreateDatabase: "इनलाइन डेटाबेस बनाने में विफल",
|
|
@@ -8289,6 +8298,7 @@ const editorMessagesByLocale = {
|
|
|
8289
8298
|
"يتم إيقاف التحرير مؤقتًا حتى تكتمل مزامنة نص Builder، حتى لا يتم استبدال محتوى المقالة الحالي.",
|
|
8290
8299
|
creatingDatabase: "جارٍ إنشاء قاعدة بيانات مضمنة...",
|
|
8291
8300
|
databaseCreated: "تم إنشاء قاعدة البيانات المضمنة",
|
|
8301
|
+
emptyBlockPlaceholder: 'اضغط على "/" للأوامر',
|
|
8292
8302
|
describeWhatToGenerate: "وصف ما سيتم إنشاؤه...",
|
|
8293
8303
|
enterToSubmit: "أدخل لتقديم",
|
|
8294
8304
|
failedToCreateDatabase: "فشل في إنشاء قاعدة البيانات المضمنة",
|
|
@@ -162,6 +162,7 @@ function decompressZstdChunk(buf: Buffer): Buffer {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
function decompressChunk(buf: Buffer): Buffer {
|
|
165
|
+
if (buf.length === 0) return Buffer.alloc(0);
|
|
165
166
|
if (buf.length >= 4 && buf.subarray(0, 4).equals(ZSTD_MAGIC)) {
|
|
166
167
|
return decompressZstdChunk(buf);
|
|
167
168
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { appBasePath } from "@agent-native/core/client/api-path";
|
|
2
|
+
import { installRouteChunkRecovery } from "@agent-native/core/client/route-chunk-recovery";
|
|
2
3
|
import { hydrateRoot } from "react-dom/client";
|
|
3
4
|
import { HydratedRouter } from "react-router/dom";
|
|
4
5
|
|
|
6
|
+
installRouteChunkRecovery();
|
|
7
|
+
|
|
5
8
|
const basePath = appBasePath();
|
|
6
9
|
const pathname = window.location.pathname;
|
|
7
10
|
const routerBasePath =
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useAgentChatGenerating,
|
|
3
|
+
type AgentChatMessage,
|
|
4
|
+
} from "@agent-native/core/client/agent-chat";
|
|
2
5
|
import { useCallback } from "react";
|
|
3
6
|
|
|
4
7
|
/**
|
|
@@ -9,8 +12,12 @@ export function useAgentGenerating() {
|
|
|
9
12
|
const [generating, send] = useAgentChatGenerating();
|
|
10
13
|
|
|
11
14
|
const submit = useCallback(
|
|
12
|
-
(
|
|
13
|
-
|
|
15
|
+
(
|
|
16
|
+
message: string,
|
|
17
|
+
context: string,
|
|
18
|
+
options?: Pick<AgentChatMessage, "newTab" | "openSidebar">,
|
|
19
|
+
) => {
|
|
20
|
+
send({ message, context, submit: true, ...options });
|
|
14
21
|
},
|
|
15
22
|
[send],
|
|
16
23
|
);
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @agent-native/toolkit
|
|
2
2
|
|
|
3
|
+
## 0.10.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c15d20f: Harden browser and CLI error handling and hide editor commands for disabled features.
|
|
8
|
+
- c15d20f: Expand design-system conformance coverage for uncontrolled tooltip and menu
|
|
9
|
+
opening, and align the example adapters with those default-open semantics.
|
|
10
|
+
- c15d20f: Show a soft rotating blue glow for live realtime voice sessions and brighten it while the agent is working.
|
|
11
|
+
|
|
3
12
|
## 0.10.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
|
@@ -61,6 +61,10 @@ import type {
|
|
|
61
61
|
const MAX_INLINE_TEXT_FILE_CHARS = 60_000;
|
|
62
62
|
const SUBMIT_ENGINE_STATUS_TIMEOUT_MS = 1000;
|
|
63
63
|
|
|
64
|
+
export function canSubmitWithAgentEngineState(state: string): boolean {
|
|
65
|
+
return state === "configured";
|
|
66
|
+
}
|
|
67
|
+
|
|
64
68
|
/**
|
|
65
69
|
* Files the user attached via the "+" button in PromptComposer. The host owns
|
|
66
70
|
* what to do with them — typically POST to a per-app upload endpoint and pass
|
|
@@ -550,7 +554,7 @@ function PromptComposerInner({
|
|
|
550
554
|
if (typeof window !== "undefined") {
|
|
551
555
|
window.dispatchEvent(new Event("agent-engine:configured-changed"));
|
|
552
556
|
}
|
|
553
|
-
return
|
|
557
|
+
return canSubmitWithAgentEngineState(state);
|
|
554
558
|
}, [
|
|
555
559
|
agentEngineConfigured.state,
|
|
556
560
|
bounceMissingKeySetup,
|
|
@@ -10,10 +10,12 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
IconAlertTriangle,
|
|
12
12
|
IconBrain,
|
|
13
|
+
IconKey,
|
|
13
14
|
IconLanguage,
|
|
14
15
|
IconLoader2,
|
|
15
16
|
IconMicrophone,
|
|
16
17
|
IconPhoneOff,
|
|
18
|
+
IconPlugConnected,
|
|
17
19
|
IconSettings,
|
|
18
20
|
IconVolume,
|
|
19
21
|
} from "@tabler/icons-react";
|
|
@@ -225,72 +227,90 @@ export function RealtimeVoiceModeEntry({
|
|
|
225
227
|
collisionPadding={16}
|
|
226
228
|
data-collision-boundary={collisionBoundary ? "agent-panel" : "viewport"}
|
|
227
229
|
className={cn(
|
|
228
|
-
setupRequired ? "p-
|
|
230
|
+
setupRequired ? "p-3.5" : "p-3",
|
|
229
231
|
setupRequired
|
|
230
|
-
? "w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,
|
|
232
|
+
? "w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,24rem),24rem)]"
|
|
231
233
|
: "w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,18rem),18rem)]",
|
|
232
234
|
)}
|
|
233
235
|
aria-labelledby={titleId}
|
|
234
236
|
aria-describedby={setupRequired ? descriptionId : undefined}
|
|
235
237
|
>
|
|
236
|
-
<div className={cn("grid", setupRequired ? "gap-3" : "gap-2.5")}>
|
|
237
|
-
<div
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
<div className={cn("grid", setupRequired ? "gap-3.5" : "gap-2.5")}>
|
|
239
|
+
<div
|
|
240
|
+
className={cn(
|
|
241
|
+
setupRequired ? "flex items-start gap-3" : "grid gap-1",
|
|
242
|
+
)}
|
|
243
|
+
>
|
|
241
244
|
{setupRequired ? (
|
|
242
|
-
<
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
>
|
|
246
|
-
{copy.setupDescription}
|
|
247
|
-
</p>
|
|
245
|
+
<div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
|
246
|
+
<IconMicrophone aria-hidden="true" />
|
|
247
|
+
</div>
|
|
248
248
|
) : null}
|
|
249
|
+
<div className="grid gap-1">
|
|
250
|
+
<h2
|
|
251
|
+
id={titleId}
|
|
252
|
+
className="text-sm font-semibold leading-5 text-foreground"
|
|
253
|
+
>
|
|
254
|
+
{setupRequired ? copy.setupTitle : copy.promptTitle}
|
|
255
|
+
</h2>
|
|
256
|
+
{setupRequired ? (
|
|
257
|
+
<p
|
|
258
|
+
id={descriptionId}
|
|
259
|
+
className="text-xs leading-5 text-muted-foreground"
|
|
260
|
+
>
|
|
261
|
+
{copy.setupDescription}
|
|
262
|
+
</p>
|
|
263
|
+
) : null}
|
|
264
|
+
</div>
|
|
249
265
|
</div>
|
|
250
266
|
|
|
251
267
|
<div
|
|
252
268
|
className={cn(
|
|
253
|
-
"gap-2",
|
|
254
|
-
setupRequired
|
|
255
|
-
? "flex flex-col-reverse sm:flex-row sm:flex-wrap sm:justify-end"
|
|
256
|
-
: "grid",
|
|
269
|
+
"grid gap-2",
|
|
270
|
+
setupRequired ? "rounded-lg bg-muted/30 p-1" : null,
|
|
257
271
|
)}
|
|
258
272
|
>
|
|
259
273
|
{setupRequired ? (
|
|
260
274
|
<>
|
|
261
275
|
<Button
|
|
262
276
|
type="button"
|
|
263
|
-
variant="ghost"
|
|
264
277
|
size="sm"
|
|
265
|
-
|
|
278
|
+
className="w-full justify-start px-3"
|
|
279
|
+
disabled={connectingBuilder}
|
|
280
|
+
onClick={() =>
|
|
281
|
+
choose("realtime", onConnectBuilder ?? onStartVoiceMode)
|
|
282
|
+
}
|
|
266
283
|
>
|
|
267
|
-
{
|
|
284
|
+
{connectingBuilder ? (
|
|
285
|
+
<IconLoader2 className="animate-spin" />
|
|
286
|
+
) : (
|
|
287
|
+
<IconPlugConnected aria-hidden="true" />
|
|
288
|
+
)}
|
|
289
|
+
{copy.connectBuilder}
|
|
268
290
|
</Button>
|
|
269
291
|
<Button
|
|
270
292
|
type="button"
|
|
271
293
|
variant="outline"
|
|
272
294
|
size="sm"
|
|
295
|
+
className="w-full justify-start bg-background px-3"
|
|
273
296
|
onClick={() =>
|
|
274
297
|
choose("realtime", onUseOpenAiKey ?? onStartVoiceMode)
|
|
275
298
|
}
|
|
276
299
|
>
|
|
300
|
+
<IconKey aria-hidden="true" />
|
|
277
301
|
{openAiConfigured
|
|
278
302
|
? copy.startWithOpenAiKey
|
|
279
303
|
: copy.useOpenAiKey}
|
|
280
304
|
</Button>
|
|
281
305
|
<Button
|
|
282
306
|
type="button"
|
|
307
|
+
variant="ghost"
|
|
283
308
|
size="sm"
|
|
284
|
-
className="
|
|
285
|
-
|
|
286
|
-
onClick={() =>
|
|
287
|
-
choose("realtime", onConnectBuilder ?? onStartVoiceMode)
|
|
288
|
-
}
|
|
309
|
+
className="w-full justify-start px-3 text-muted-foreground"
|
|
310
|
+
onClick={() => choose("dictation", onKeepDictating)}
|
|
289
311
|
>
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
) : null}
|
|
293
|
-
{copy.connectBuilder}
|
|
312
|
+
<IconMicrophone aria-hidden="true" />
|
|
313
|
+
{copy.keepDictating}
|
|
294
314
|
</Button>
|
|
295
315
|
</>
|
|
296
316
|
) : (
|
|
@@ -382,9 +402,14 @@ export interface RealtimeVoiceModeInlineSettings {
|
|
|
382
402
|
const SILENT_AUDIO_LEVELS = createRealtimeVoiceAudioLevelStore();
|
|
383
403
|
const WAVEFORM_WEIGHTS = [0.55, 0.82, 1, 0.82, 0.55];
|
|
384
404
|
const AUDIO_ACTIVITY_THRESHOLD = 0.1;
|
|
405
|
+
const WORKING_GLOW_HOLD_MS = 800;
|
|
385
406
|
|
|
386
407
|
function usePrefersReducedMotion(): boolean {
|
|
387
|
-
const [reduced, setReduced] = useState(
|
|
408
|
+
const [reduced, setReduced] = useState(
|
|
409
|
+
() =>
|
|
410
|
+
typeof window !== "undefined" &&
|
|
411
|
+
Boolean(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches),
|
|
412
|
+
);
|
|
388
413
|
useEffect(() => {
|
|
389
414
|
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
390
415
|
const query = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
@@ -697,6 +722,9 @@ export function RealtimeVoiceModeDock({
|
|
|
697
722
|
const controlsId = useId();
|
|
698
723
|
const [controlsOpen, setControlsOpen] = useState(false);
|
|
699
724
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
725
|
+
const [workingGlowHeld, setWorkingGlowHeld] = useState(state === "working");
|
|
726
|
+
const glowRef = useRef<HTMLSpanElement>(null);
|
|
727
|
+
const glowAnimationRef = useRef<Animation | null>(null);
|
|
700
728
|
const selectInteractionRef = useRef(false);
|
|
701
729
|
const selectInteractionFrameRef = useRef<number | null>(null);
|
|
702
730
|
const levels = useSyncExternalStore(
|
|
@@ -724,6 +752,56 @@ export function RealtimeVoiceModeDock({
|
|
|
724
752
|
const errorDetailVisible = state === "error" && Boolean(errorMessage);
|
|
725
753
|
const controlsVisible = controlsOpen || settingsOpen;
|
|
726
754
|
const chatPanelTranslation = useChatPanelTranslation(chatVisible);
|
|
755
|
+
const workingGlowActive = state === "working" || workingGlowHeld;
|
|
756
|
+
|
|
757
|
+
useEffect(() => {
|
|
758
|
+
if (state === "working") {
|
|
759
|
+
setWorkingGlowHeld(true);
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
if (!workingGlowHeld) return;
|
|
763
|
+
const timer = window.setTimeout(
|
|
764
|
+
() => setWorkingGlowHeld(false),
|
|
765
|
+
WORKING_GLOW_HOLD_MS,
|
|
766
|
+
);
|
|
767
|
+
return () => window.clearTimeout(timer);
|
|
768
|
+
}, [state, workingGlowHeld]);
|
|
769
|
+
|
|
770
|
+
useEffect(() => {
|
|
771
|
+
if (!connected || reducedMotion || !glowRef.current) {
|
|
772
|
+
glowAnimationRef.current?.cancel();
|
|
773
|
+
glowAnimationRef.current = null;
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
const animation = glowRef.current.animate(
|
|
778
|
+
[{ transform: "rotate(0turn)" }, { transform: "rotate(1turn)" }],
|
|
779
|
+
{
|
|
780
|
+
duration: 12_000,
|
|
781
|
+
easing: "linear",
|
|
782
|
+
iterations: Number.POSITIVE_INFINITY,
|
|
783
|
+
},
|
|
784
|
+
);
|
|
785
|
+
glowAnimationRef.current = animation;
|
|
786
|
+
|
|
787
|
+
return () => {
|
|
788
|
+
animation.cancel();
|
|
789
|
+
if (glowAnimationRef.current === animation) {
|
|
790
|
+
glowAnimationRef.current = null;
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
}, [connected, reducedMotion]);
|
|
794
|
+
|
|
795
|
+
useEffect(() => {
|
|
796
|
+
const animation = glowAnimationRef.current;
|
|
797
|
+
if (!animation) return;
|
|
798
|
+
const playbackRate = workingGlowActive ? 2.4 : 1;
|
|
799
|
+
if (typeof animation.updatePlaybackRate === "function") {
|
|
800
|
+
animation.updatePlaybackRate(playbackRate);
|
|
801
|
+
} else {
|
|
802
|
+
animation.playbackRate = playbackRate;
|
|
803
|
+
}
|
|
804
|
+
}, [workingGlowActive]);
|
|
727
805
|
|
|
728
806
|
const handleSelectOpenChange = useCallback((open: boolean) => {
|
|
729
807
|
if (selectInteractionFrameRef.current !== null) {
|
|
@@ -900,9 +978,19 @@ export function RealtimeVoiceModeDock({
|
|
|
900
978
|
className={cn(
|
|
901
979
|
"relative isolate size-16 overflow-visible rounded-full ring-1 backdrop-blur-xl transition-transform duration-150 ease-out focus-visible:ring-offset-2 active:scale-[0.97] motion-reduce:transition-none",
|
|
902
980
|
ORB_STATE_CLASSES[state],
|
|
903
|
-
state === "working" && "agent-realtime-voice-working",
|
|
904
981
|
)}
|
|
905
982
|
>
|
|
983
|
+
{connected ? (
|
|
984
|
+
<span
|
|
985
|
+
ref={glowRef}
|
|
986
|
+
aria-hidden="true"
|
|
987
|
+
data-realtime-voice-glow="true"
|
|
988
|
+
className={cn(
|
|
989
|
+
"agent-realtime-voice-glow",
|
|
990
|
+
workingGlowActive && "agent-realtime-voice-working",
|
|
991
|
+
)}
|
|
992
|
+
/>
|
|
993
|
+
) : null}
|
|
906
994
|
<span className="relative z-10 flex items-center justify-center">
|
|
907
995
|
{state === "connecting" ? (
|
|
908
996
|
<VoiceConnectingIndicator />
|
|
@@ -1005,6 +1005,36 @@ export function createRealtimeVoiceToolManifestCoordinator(
|
|
|
1005
1005
|
export function extractRealtimeVoiceFunctionCalls(
|
|
1006
1006
|
event: RealtimeServerEvent,
|
|
1007
1007
|
): Array<{ name: string; callId: string; argumentsText: string }> {
|
|
1008
|
+
if (event.type === "response.function_call_arguments.done") {
|
|
1009
|
+
const name = typeof event.name === "string" ? event.name : "";
|
|
1010
|
+
const callId = typeof event.call_id === "string" ? event.call_id : "";
|
|
1011
|
+
if (!name || !callId) return [];
|
|
1012
|
+
return [
|
|
1013
|
+
{
|
|
1014
|
+
name,
|
|
1015
|
+
callId,
|
|
1016
|
+
argumentsText:
|
|
1017
|
+
typeof event.arguments === "string" ? event.arguments : "{}",
|
|
1018
|
+
},
|
|
1019
|
+
];
|
|
1020
|
+
}
|
|
1021
|
+
if (event.type === "response.output_item.done") {
|
|
1022
|
+
const item = event.item;
|
|
1023
|
+
if (!item || typeof item !== "object") return [];
|
|
1024
|
+
const record = item as Record<string, unknown>;
|
|
1025
|
+
if (record.type !== "function_call") return [];
|
|
1026
|
+
const name = typeof record.name === "string" ? record.name : "";
|
|
1027
|
+
const callId = typeof record.call_id === "string" ? record.call_id : "";
|
|
1028
|
+
if (!name || !callId) return [];
|
|
1029
|
+
return [
|
|
1030
|
+
{
|
|
1031
|
+
name,
|
|
1032
|
+
callId,
|
|
1033
|
+
argumentsText:
|
|
1034
|
+
typeof record.arguments === "string" ? record.arguments : "{}",
|
|
1035
|
+
},
|
|
1036
|
+
];
|
|
1037
|
+
}
|
|
1008
1038
|
if (event.type !== "response.done") return [];
|
|
1009
1039
|
const response = event.response;
|
|
1010
1040
|
if (!response || typeof response !== "object") return [];
|
|
@@ -122,6 +122,87 @@ function elementWithText(document: Document, selector: string, text: string) {
|
|
|
122
122
|
);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
function assertInlineLayout(
|
|
126
|
+
container: Element,
|
|
127
|
+
iconSelector: string,
|
|
128
|
+
labelSelector: string,
|
|
129
|
+
message: string,
|
|
130
|
+
) {
|
|
131
|
+
const icon = container.querySelector<HTMLElement>(iconSelector);
|
|
132
|
+
const label = container.querySelector<HTMLElement>(labelSelector);
|
|
133
|
+
invariant(icon && label, message);
|
|
134
|
+
|
|
135
|
+
const iconRect = icon.getBoundingClientRect();
|
|
136
|
+
const labelRect = label.getBoundingClientRect();
|
|
137
|
+
const hasGeometry =
|
|
138
|
+
iconRect.width > 0 ||
|
|
139
|
+
iconRect.height > 0 ||
|
|
140
|
+
labelRect.width > 0 ||
|
|
141
|
+
labelRect.height > 0;
|
|
142
|
+
if (hasGeometry) {
|
|
143
|
+
const verticalOverlap =
|
|
144
|
+
Math.min(iconRect.bottom, labelRect.bottom) -
|
|
145
|
+
Math.max(iconRect.top, labelRect.top);
|
|
146
|
+
invariant(
|
|
147
|
+
verticalOverlap > 0 || Math.abs(iconRect.top - labelRect.top) <= 2,
|
|
148
|
+
message,
|
|
149
|
+
);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// happy-dom does not calculate layout. Still reject adapters that explicitly
|
|
154
|
+
// stack the tab contents, while browser-backed runs use the geometry check.
|
|
155
|
+
const commonAncestor = (() => {
|
|
156
|
+
let candidate: Element | null = icon;
|
|
157
|
+
while (candidate && !candidate.contains(label)) {
|
|
158
|
+
candidate = candidate.parentElement;
|
|
159
|
+
}
|
|
160
|
+
return candidate;
|
|
161
|
+
})();
|
|
162
|
+
const styles = [
|
|
163
|
+
container,
|
|
164
|
+
commonAncestor,
|
|
165
|
+
icon.parentElement,
|
|
166
|
+
label.parentElement,
|
|
167
|
+
]
|
|
168
|
+
.filter((element): element is Element => Boolean(element))
|
|
169
|
+
.map((element) =>
|
|
170
|
+
element.ownerDocument.defaultView?.getComputedStyle(element),
|
|
171
|
+
);
|
|
172
|
+
invariant(
|
|
173
|
+
!styles.some(
|
|
174
|
+
(style) => style?.display === "flex" && style.flexDirection === "column",
|
|
175
|
+
),
|
|
176
|
+
message,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function assertContainedFooter(dialog: Element, footerSelector: string) {
|
|
181
|
+
const footer = dialog.querySelector<HTMLElement>(footerSelector);
|
|
182
|
+
invariant(
|
|
183
|
+
footer,
|
|
184
|
+
"Dialog footer controls must be rendered inside the dialog surface.",
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const dialogRect = (dialog as HTMLElement).getBoundingClientRect();
|
|
188
|
+
const footerRect = footer.getBoundingClientRect();
|
|
189
|
+
const hasGeometry =
|
|
190
|
+
dialogRect.width > 0 ||
|
|
191
|
+
dialogRect.height > 0 ||
|
|
192
|
+
footerRect.width > 0 ||
|
|
193
|
+
footerRect.height > 0;
|
|
194
|
+
if (!hasGeometry) return;
|
|
195
|
+
|
|
196
|
+
const epsilon = 2;
|
|
197
|
+
invariant(
|
|
198
|
+
footerRect.top >= dialogRect.top - epsilon &&
|
|
199
|
+
footerRect.bottom <= dialogRect.bottom + epsilon &&
|
|
200
|
+
footerRect.left >= dialogRect.left - epsilon &&
|
|
201
|
+
footerRect.right <= dialogRect.right + epsilon,
|
|
202
|
+
"Dialog footer controls must remain within the dialog surface bounds.",
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
125
206
|
const checks: readonly ConformanceCheck[] = [
|
|
126
207
|
{
|
|
127
208
|
id: "contract.components",
|
|
@@ -308,6 +389,21 @@ const checks: readonly ConformanceCheck[] = [
|
|
|
308
389
|
"Tooltip must honor controlled open and portalContainer.",
|
|
309
390
|
);
|
|
310
391
|
unmount(probe);
|
|
392
|
+
|
|
393
|
+
const defaultOpenProbe = mount(
|
|
394
|
+
<components.Tooltip
|
|
395
|
+
trigger={<button>Help by default</button>}
|
|
396
|
+
content="Default tooltip"
|
|
397
|
+
defaultOpen
|
|
398
|
+
portalContainer={portal}
|
|
399
|
+
/>,
|
|
400
|
+
);
|
|
401
|
+
await settle();
|
|
402
|
+
invariant(
|
|
403
|
+
portal.textContent?.includes("Default tooltip"),
|
|
404
|
+
"Tooltip must honor defaultOpen and portalContainer.",
|
|
405
|
+
);
|
|
406
|
+
unmount(defaultOpenProbe);
|
|
311
407
|
portal.remove();
|
|
312
408
|
},
|
|
313
409
|
},
|
|
@@ -331,6 +427,21 @@ const checks: readonly ConformanceCheck[] = [
|
|
|
331
427
|
click(item, document);
|
|
332
428
|
invariant(selected === "archive", "Menu must report selected item ids.");
|
|
333
429
|
unmount(probe);
|
|
430
|
+
|
|
431
|
+
const defaultOpenProbe = mount(
|
|
432
|
+
<components.Menu
|
|
433
|
+
trigger={<button>Default actions</button>}
|
|
434
|
+
items={[{ id: "restore", label: "Restore" }]}
|
|
435
|
+
defaultOpen
|
|
436
|
+
onAction={() => {}}
|
|
437
|
+
/>,
|
|
438
|
+
);
|
|
439
|
+
await settle();
|
|
440
|
+
invariant(
|
|
441
|
+
elementWithText(document, '[role="menuitem"]', "Restore"),
|
|
442
|
+
"Menu must honor defaultOpen.",
|
|
443
|
+
);
|
|
444
|
+
unmount(defaultOpenProbe);
|
|
334
445
|
},
|
|
335
446
|
},
|
|
336
447
|
{
|
|
@@ -393,6 +504,30 @@ const checks: readonly ConformanceCheck[] = [
|
|
|
393
504
|
"Dialog must not invent actions when footer is omitted.",
|
|
394
505
|
);
|
|
395
506
|
unmount(probe);
|
|
507
|
+
|
|
508
|
+
const footerProbe = mount(
|
|
509
|
+
<components.Dialog
|
|
510
|
+
open
|
|
511
|
+
onOpenChange={() => {}}
|
|
512
|
+
title="Footer probe"
|
|
513
|
+
portalContainer={portal}
|
|
514
|
+
footer={
|
|
515
|
+
<button data-conformance-dialog-footer-action="true" type="button">
|
|
516
|
+
Save
|
|
517
|
+
</button>
|
|
518
|
+
}
|
|
519
|
+
>
|
|
520
|
+
Footer content
|
|
521
|
+
</components.Dialog>,
|
|
522
|
+
);
|
|
523
|
+
await settle();
|
|
524
|
+
const footerDialog = portal.querySelector('[role="dialog"]');
|
|
525
|
+
invariant(footerDialog, "Dialog footer probe did not render a dialog.");
|
|
526
|
+
assertContainedFooter(
|
|
527
|
+
footerDialog,
|
|
528
|
+
'[data-conformance-dialog-footer-action="true"]',
|
|
529
|
+
);
|
|
530
|
+
unmount(footerProbe);
|
|
396
531
|
portal.remove();
|
|
397
532
|
},
|
|
398
533
|
},
|
|
@@ -466,7 +601,16 @@ const checks: readonly ConformanceCheck[] = [
|
|
|
466
601
|
orientation="vertical"
|
|
467
602
|
onChange={(next) => (value = next)}
|
|
468
603
|
items={[
|
|
469
|
-
{
|
|
604
|
+
{
|
|
605
|
+
value: "first",
|
|
606
|
+
label: <span data-conformance-tab-label="true">First</span>,
|
|
607
|
+
icon: (
|
|
608
|
+
<span data-conformance-tab-icon="true" aria-hidden="true">
|
|
609
|
+
●
|
|
610
|
+
</span>
|
|
611
|
+
),
|
|
612
|
+
content: "One",
|
|
613
|
+
},
|
|
470
614
|
{ value: "second", label: "Second", content: "Two" },
|
|
471
615
|
]}
|
|
472
616
|
/>,
|
|
@@ -477,6 +621,14 @@ const checks: readonly ConformanceCheck[] = [
|
|
|
477
621
|
tabList.getAttribute("aria-orientation") === "vertical",
|
|
478
622
|
"Tabs must honor vertical orientation in their tablist semantics.",
|
|
479
623
|
);
|
|
624
|
+
const first = elementWithText(document, '[role="tab"]', "First");
|
|
625
|
+
invariant(first, "Tabs must expose the icon-bearing tab.");
|
|
626
|
+
assertInlineLayout(
|
|
627
|
+
first,
|
|
628
|
+
'[data-conformance-tab-icon="true"]',
|
|
629
|
+
'[data-conformance-tab-label="true"]',
|
|
630
|
+
"Tabs must lay out an icon and its label on the same row.",
|
|
631
|
+
);
|
|
480
632
|
const second = elementWithText(document, '[role="tab"]', "Second");
|
|
481
633
|
invariant(second, "Tabs must expose tab semantics.");
|
|
482
634
|
click(second, document);
|