@agent-native/core 0.115.4 → 0.117.0
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/agent-native.eject.json +1 -0
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +43 -0
- package/corpus/core/agent-native.eject.json +1 -0
- package/corpus/core/docs/AGENTS.md +1 -1
- package/corpus/core/docs/content/agent-mentions.mdx +2 -2
- package/corpus/core/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
- package/corpus/core/docs/content/agent-teams.mdx +4 -4
- package/corpus/core/docs/content/dispatch.mdx +10 -10
- package/corpus/core/docs/content/drop-in-agent.mdx +4 -4
- package/corpus/core/docs/content/external-agents.mdx +1 -1
- package/corpus/core/docs/content/frames.mdx +1 -1
- package/corpus/core/docs/content/integrations.mdx +13 -2
- package/corpus/core/docs/content/key-concepts.mdx +2 -2
- package/corpus/core/docs/content/mcp-clients.mdx +7 -1
- package/corpus/core/docs/content/multi-app-workspace.mdx +3 -3
- package/corpus/core/docs/content/real-time-collaboration.mdx +33 -15
- package/corpus/core/docs/content/recurring-jobs.mdx +7 -7
- package/corpus/core/docs/content/skills-guide.mdx +4 -4
- package/corpus/core/docs/content/template-brain.mdx +1 -1
- package/corpus/core/docs/content/toolkit-collaboration.mdx +1 -1
- package/corpus/core/docs/content/using-your-agent.mdx +1 -1
- package/corpus/core/docs/content/what-is-agent-native.mdx +4 -4
- package/corpus/core/docs/content/workspace-management.mdx +4 -4
- package/corpus/core/package.json +4 -1
- package/corpus/core/src/agent/production-agent.ts +13 -3
- package/corpus/core/src/cli/doctor.ts +6 -1
- package/corpus/core/src/client/AgentPanel.tsx +79 -41
- package/corpus/core/src/client/AssistantChat.tsx +71 -25
- package/corpus/core/src/client/FeedbackButton.tsx +33 -7
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +6 -8
- package/corpus/core/src/client/agent-chat-adapter.ts +11 -2
- package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +22 -3
- package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +34 -19
- package/corpus/core/src/client/analytics.ts +7 -0
- package/corpus/core/src/client/chat/message-components.tsx +43 -16
- package/corpus/core/src/client/chat/tool-call-display.tsx +30 -18
- package/corpus/core/src/client/chat/tool-render-registry.tsx +2 -0
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +19 -2
- package/corpus/core/src/client/resources/ResourceTree.tsx +7 -10
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +33 -70
- package/corpus/core/src/client/resources/mcp-connection-resume.ts +107 -0
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +65 -12
- package/corpus/core/src/client/resources/mcp-integration-logos.ts +4 -0
- package/corpus/core/src/client/sse-event-processor.ts +50 -14
- package/corpus/core/src/client/use-db-sync.ts +370 -21
- package/corpus/core/src/collab/client.ts +26 -2
- package/corpus/core/src/connections/catalog.ts +7 -1
- package/corpus/core/src/db/ddl-guard.ts +49 -10
- package/corpus/core/src/deploy/build.ts +25 -2
- package/corpus/core/src/eject/remote-mcp-presets.ts +37 -5
- package/corpus/core/src/guards/explicit-collab-access.ts +229 -0
- package/corpus/core/src/guards/index.ts +1 -0
- package/corpus/core/src/localization/default-messages.ts +54 -5
- package/corpus/core/src/mcp/connect-route.ts +34 -51
- package/corpus/core/src/provider-api/index.ts +1 -1
- package/corpus/core/src/realtime-protocol.ts +92 -0
- package/corpus/core/src/server/collab-plugin.ts +137 -18
- package/corpus/core/src/server/core-routes-plugin.ts +7 -0
- package/corpus/core/src/server/index.ts +2 -0
- package/corpus/core/src/server/poll-events.ts +29 -8
- package/corpus/core/src/server/poll.ts +1123 -865
- package/corpus/core/src/server/realtime-token.ts +106 -0
- package/corpus/core/src/server/sentry-config.ts +40 -0
- package/corpus/core/src/server/short-lived-token.ts +156 -0
- package/corpus/core/src/server/sse.ts +15 -0
- package/corpus/core/src/server/ssr-handler.ts +9 -3
- package/corpus/core/src/styles/agent-native.css +40 -0
- package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/analytics/AGENTS.md +7 -2
- package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +144 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -88
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +34 -37
- package/corpus/templates/analytics/app/global.css +0 -4
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -7
- package/corpus/templates/analytics/app/i18n-data.ts +107 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +9 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +1 -2
- package/corpus/templates/analytics/app/pages/Ask.tsx +2 -7
- package/corpus/templates/analytics/app/pages/DataSources.tsx +48 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +59 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +3 -1
- package/corpus/templates/analytics/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-daily-dashboard-email-query-batches.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-export-table-panels-directly-to-google-sheets.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-recent-chats-can-expand-in-the-sidebar.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +8 -8
- package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +31 -0
- package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +3 -5
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +12 -0
- package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +3 -5
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +150 -21
- package/corpus/templates/analytics/server/lib/google-sheets-export.ts +188 -0
- package/corpus/templates/analytics/server/lib/provider-api.ts +7 -2
- package/corpus/templates/analytics/server/plugins/collab.ts +6 -3
- package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +54 -62
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -6
- package/corpus/templates/assets/app/routes/_index.tsx +8 -5
- package/corpus/templates/assets/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-22-recent-chats-expand-from-a-compact-list.md +6 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/brain/actions/rotate-source-ingest-token.ts +77 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +5 -1
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +38 -51
- package/corpus/templates/brain/app/hooks/use-navigation-state.ts +2 -9
- package/corpus/templates/brain/app/i18n-data.ts +120 -0
- package/corpus/templates/brain/app/routes/sources.tsx +156 -5
- package/corpus/templates/brain/changelog/2026-07-22-chat-runs-always-end-with-an-answer.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-long-chat-titles-stay-inside-the-sidebar.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-new-clips-and-webhook-sources-now-show-their-secure-connecti.md +6 -0
- package/corpus/templates/brain/jobs/emit-netlify-brain-queue-cron.ts +125 -0
- package/corpus/templates/brain/netlify.toml +5 -1
- package/corpus/templates/brain/scripts/configure-prod-clips-source.ts +50 -0
- package/corpus/templates/brain/server/lib/capture-sanitization.ts +64 -6
- package/corpus/templates/brain/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/brain/server/plugins/brain-jobs.ts +1 -0
- package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +55 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +43 -67
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +2 -7
- package/corpus/templates/chat/app/routes/_index.tsx +8 -5
- package/corpus/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/clips/AGENTS.md +9 -1
- package/corpus/templates/clips/actions/export-to-brain.ts +82 -6
- package/corpus/templates/clips/actions/request-transcript.ts +25 -14
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +12 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/changelog/2026-07-22-clips-transcripts-now-retry-brain-export.md +5 -0
- package/corpus/templates/clips/changelog/2026-07-22-german-umlauts-and-other-non-ascii-characters-now-paste-corr.md +6 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +26 -3
- package/corpus/templates/clips/jobs/emit-netlify-brain-export-cron.ts +118 -0
- package/corpus/templates/clips/netlify.toml +4 -1
- package/corpus/templates/clips/scripts/configure-prod-brain-export.ts +92 -0
- package/corpus/templates/clips/server/jobs/brain-export.ts +182 -0
- package/corpus/templates/clips/server/lib/brain-export-state.ts +42 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +5 -1
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/register-secrets.ts +42 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +10 -1
- package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +45 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +566 -299
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +14 -0
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
- package/corpus/templates/content/app/i18n-data.ts +90 -0
- package/corpus/templates/content/server/plugins/collab.ts +1 -1
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +2 -0
- package/corpus/templates/crm/actions/run.ts +2 -6
- package/corpus/templates/crm/actions/update-crm-record.ts +4 -2
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +4 -1
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/design/server/plugins/collab.ts +11 -8
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/forms/app/hooks/use-navigation-state.ts +2 -9
- package/corpus/templates/forms/app/root.tsx +1 -6
- package/corpus/templates/forms/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -1
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +57 -72
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +2 -9
- package/corpus/templates/plan/app/lib/create-plan-routing.ts +2 -2
- package/corpus/templates/plan/app/pages/PlanChatPage.tsx +0 -1
- package/corpus/templates/plan/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-22-recent-chats-and-sidebar-controls-are-more-compact.md +6 -0
- package/corpus/templates/plan/server/plugins/collab.ts +5 -2
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/slides/server/plugins/collab.ts +11 -8
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -22
- package/corpus/templates/tasks/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +7 -0
- package/corpus/toolkit/README.md +12 -3
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +89 -0
- package/corpus/toolkit/src/chat-history/index.ts +5 -0
- package/corpus/toolkit/src/chat-history.css +59 -0
- package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +106 -36
- package/corpus/toolkit/src/composer/VoiceButton.tsx +49 -0
- package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +2 -1
- package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +5 -3
- package/corpus/toolkit/src/styles.css +35 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +13 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +5 -2
- package/dist/cli/doctor.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +1 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +38 -18
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +55 -20
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts +4 -2
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +18 -2
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +2 -3
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +11 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-page/AgentTabFrame.d.ts +3 -1
- package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -1
- package/dist/client/agent-page/AgentTabFrame.js +3 -2
- package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.d.ts +2 -0
- package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.js +26 -15
- package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
- package/dist/client/analytics.d.ts +10 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +6 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +17 -11
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +11 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +16 -17
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/tool-render-registry.d.ts +2 -0
- package/dist/client/chat/tool-render-registry.d.ts.map +1 -1
- package/dist/client/chat/tool-render-registry.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.js +15 -1
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +3 -3
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +1 -0
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +34 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/mcp-connection-resume.d.ts +11 -0
- package/dist/client/resources/mcp-connection-resume.d.ts.map +1 -0
- package/dist/client/resources/mcp-connection-resume.js +95 -0
- package/dist/client/resources/mcp-connection-resume.js.map +1 -0
- 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 +63 -8
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-logos.js +4 -0
- package/dist/client/resources/mcp-integration-logos.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +5 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +39 -13
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +4 -3
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +332 -21
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +26 -2
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +1 -1
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +7 -1
- package/dist/connections/catalog.js.map +1 -1
- package/dist/db/ddl-guard.d.ts +7 -2
- package/dist/db/ddl-guard.d.ts.map +1 -1
- package/dist/db/ddl-guard.js +21 -9
- package/dist/db/ddl-guard.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +25 -2
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/remote-mcp-presets.d.ts.map +1 -1
- package/dist/eject/remote-mcp-presets.js +33 -3
- package/dist/eject/remote-mcp-presets.js.map +1 -1
- package/dist/guards/explicit-collab-access.d.ts +8 -0
- package/dist/guards/explicit-collab-access.d.ts.map +1 -0
- package/dist/guards/explicit-collab-access.js +214 -0
- package/dist/guards/explicit-collab-access.js.map +1 -0
- package/dist/guards/index.d.ts +1 -0
- package/dist/guards/index.d.ts.map +1 -1
- package/dist/guards/index.js +1 -0
- package/dist/guards/index.js.map +1 -1
- package/dist/localization/default-messages.d.ts +43 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +48 -5
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +34 -48
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +1 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/realtime-protocol.d.ts +40 -0
- package/dist/realtime-protocol.d.ts.map +1 -0
- package/dist/realtime-protocol.js +69 -0
- package/dist/realtime-protocol.js.map +1 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/collab-plugin.d.ts +34 -3
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +65 -12
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +3 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/poll-events.d.ts +7 -1
- package/dist/server/poll-events.d.ts.map +1 -1
- package/dist/server/poll-events.js +24 -7
- package/dist/server/poll-events.js.map +1 -1
- package/dist/server/poll.d.ts +223 -42
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +849 -737
- package/dist/server/poll.js.map +1 -1
- package/dist/server/realtime-token.d.ts +34 -0
- package/dist/server/realtime-token.d.ts.map +1 -0
- package/dist/server/realtime-token.js +85 -0
- package/dist/server/realtime-token.js.map +1 -0
- package/dist/server/sentry-config.d.ts +12 -0
- package/dist/server/sentry-config.d.ts.map +1 -1
- package/dist/server/sentry-config.js +34 -0
- package/dist/server/sentry-config.js.map +1 -1
- package/dist/server/short-lived-token.d.ts +46 -0
- package/dist/server/short-lived-token.d.ts.map +1 -1
- package/dist/server/short-lived-token.js +104 -0
- package/dist/server/short-lived-token.js.map +1 -1
- package/dist/server/sse.d.ts +1 -1
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +4 -0
- package/dist/server/sse.js.map +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +5 -3
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-native.css +40 -0
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -0
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +43 -67
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +2 -7
- package/dist/templates/chat/app/routes/_index.tsx +8 -5
- package/dist/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/dist/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/dist/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
- package/docs/AGENTS.md +1 -1
- package/docs/content/agent-mentions.mdx +2 -2
- package/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
- package/docs/content/agent-teams.mdx +4 -4
- package/docs/content/dispatch.mdx +10 -10
- package/docs/content/drop-in-agent.mdx +4 -4
- package/docs/content/external-agents.mdx +1 -1
- package/docs/content/frames.mdx +1 -1
- package/docs/content/integrations.mdx +13 -2
- package/docs/content/key-concepts.mdx +2 -2
- package/docs/content/mcp-clients.mdx +7 -1
- package/docs/content/multi-app-workspace.mdx +3 -3
- package/docs/content/real-time-collaboration.mdx +33 -15
- package/docs/content/recurring-jobs.mdx +7 -7
- package/docs/content/skills-guide.mdx +4 -4
- package/docs/content/template-brain.mdx +1 -1
- package/docs/content/toolkit-collaboration.mdx +1 -1
- package/docs/content/using-your-agent.mdx +1 -1
- package/docs/content/what-is-agent-native.mdx +4 -4
- package/docs/content/workspace-management.mdx +4 -4
- package/package.json +6 -3
- package/src/agent/production-agent.ts +13 -3
- package/src/cli/doctor.ts +6 -1
- package/src/client/AgentPanel.tsx +79 -41
- package/src/client/AssistantChat.tsx +71 -25
- package/src/client/FeedbackButton.tsx +33 -7
- package/src/client/MultiTabAssistantChat.tsx +6 -8
- package/src/client/agent-chat-adapter.ts +11 -2
- package/src/client/agent-page/AgentTabFrame.tsx +22 -3
- package/src/client/agent-page/AgentTabsPage.tsx +34 -19
- package/src/client/analytics.ts +7 -0
- package/src/client/chat/message-components.tsx +43 -16
- package/src/client/chat/tool-call-display.tsx +30 -18
- package/src/client/chat/tool-render-registry.tsx +2 -0
- package/src/client/resources/McpConnectionSuggestion.tsx +19 -2
- package/src/client/resources/ResourceTree.tsx +7 -10
- package/src/client/resources/ResourcesPanel.tsx +33 -70
- package/src/client/resources/mcp-connection-resume.ts +107 -0
- package/src/client/resources/mcp-integration-catalog.ts +65 -12
- package/src/client/resources/mcp-integration-logos.ts +4 -0
- package/src/client/sse-event-processor.ts +50 -14
- package/src/client/use-db-sync.ts +370 -21
- package/src/collab/client.ts +26 -2
- package/src/connections/catalog.ts +7 -1
- package/src/db/ddl-guard.ts +49 -10
- package/src/deploy/build.ts +25 -2
- package/src/eject/remote-mcp-presets.ts +37 -5
- package/src/guards/explicit-collab-access.ts +229 -0
- package/src/guards/index.ts +1 -0
- package/src/localization/default-messages.ts +54 -5
- package/src/mcp/connect-route.ts +34 -51
- package/src/provider-api/index.ts +1 -1
- package/src/realtime-protocol.ts +92 -0
- package/src/server/collab-plugin.ts +137 -18
- package/src/server/core-routes-plugin.ts +7 -0
- package/src/server/index.ts +2 -0
- package/src/server/poll-events.ts +29 -8
- package/src/server/poll.ts +1123 -865
- package/src/server/realtime-token.ts +106 -0
- package/src/server/sentry-config.ts +40 -0
- package/src/server/short-lived-token.ts +156 -0
- package/src/server/sse.ts +15 -0
- package/src/server/ssr-handler.ts +9 -3
- package/src/styles/agent-native.css +40 -0
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -0
- package/src/templates/chat/app/components/layout/Sidebar.tsx +43 -67
- package/src/templates/chat/app/hooks/use-navigation-state.ts +2 -7
- package/src/templates/chat/app/routes/_index.tsx +8 -5
- package/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { executeProviderApiRequest } from "./provider-api";
|
|
2
|
+
|
|
3
|
+
export interface GoogleSheetExportInput {
|
|
4
|
+
dashboardId: string;
|
|
5
|
+
dashboardTitle: string;
|
|
6
|
+
panelId: string;
|
|
7
|
+
panelTitle: string;
|
|
8
|
+
source: string;
|
|
9
|
+
rows: Record<string, unknown>[];
|
|
10
|
+
schema: { name: string; type: string }[];
|
|
11
|
+
truncated?: boolean;
|
|
12
|
+
bytesProcessed?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface GoogleSheetExportResult {
|
|
16
|
+
spreadsheetUrl: string;
|
|
17
|
+
spreadsheetId: string;
|
|
18
|
+
rowCount: number;
|
|
19
|
+
metadata: {
|
|
20
|
+
dashboardId: string;
|
|
21
|
+
dashboardTitle: string;
|
|
22
|
+
panelId: string;
|
|
23
|
+
panelTitle: string;
|
|
24
|
+
source: string;
|
|
25
|
+
chartType: "table";
|
|
26
|
+
sheetTitle: string;
|
|
27
|
+
columns: string[];
|
|
28
|
+
columnCount: number;
|
|
29
|
+
truncated: boolean;
|
|
30
|
+
bytesProcessed: number | null;
|
|
31
|
+
provider: "google_drive";
|
|
32
|
+
updatedCells: number | null;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type ProviderResponse = {
|
|
37
|
+
ok?: boolean;
|
|
38
|
+
status?: number;
|
|
39
|
+
statusText?: string;
|
|
40
|
+
json?: unknown;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function providerResponse(result: unknown, label: string): ProviderResponse {
|
|
44
|
+
const response = (result as { response?: unknown } | null)?.response;
|
|
45
|
+
if (!response || typeof response !== "object") {
|
|
46
|
+
throw new Error(`${label} returned an unexpected response.`);
|
|
47
|
+
}
|
|
48
|
+
const typed = response as ProviderResponse;
|
|
49
|
+
if (!typed.ok) {
|
|
50
|
+
const status = typed.status ? ` HTTP ${typed.status}` : "";
|
|
51
|
+
const statusText = typed.statusText ? ` ${typed.statusText}` : "";
|
|
52
|
+
throw new Error(`${label} failed${status}${statusText}.`);
|
|
53
|
+
}
|
|
54
|
+
return typed;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function asRecord(value: unknown): Record<string, unknown> {
|
|
58
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
59
|
+
? (value as Record<string, unknown>)
|
|
60
|
+
: {};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function sheetCell(value: unknown): string | number | boolean {
|
|
64
|
+
if (value === null || value === undefined) return "";
|
|
65
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
66
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : "";
|
|
67
|
+
try {
|
|
68
|
+
return JSON.stringify(value);
|
|
69
|
+
} catch {
|
|
70
|
+
return String(value);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function quoteSheetTitle(title: string): string {
|
|
75
|
+
return `'${title.replace(/'/g, "''")}'`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizeSheetTitle(
|
|
79
|
+
dashboardTitle: string,
|
|
80
|
+
panelTitle: string,
|
|
81
|
+
): string {
|
|
82
|
+
const title = `${dashboardTitle} - ${panelTitle}`
|
|
83
|
+
.replace(/[\u0000-\u001f\u007f]/g, " ")
|
|
84
|
+
.trim();
|
|
85
|
+
return (title || "Analytics export").slice(0, 100);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sheetColumnCount(
|
|
89
|
+
schema: GoogleSheetExportInput["schema"],
|
|
90
|
+
rows: GoogleSheetExportInput["rows"],
|
|
91
|
+
): string[] {
|
|
92
|
+
const names = schema
|
|
93
|
+
.map((column) => column.name.trim())
|
|
94
|
+
.filter((name, index, columns) => name && columns.indexOf(name) === index);
|
|
95
|
+
if (names.length > 0) return names;
|
|
96
|
+
return Object.keys(rows[0] ?? {});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function exportDashboardPanelToGoogleSheet(
|
|
100
|
+
input: GoogleSheetExportInput,
|
|
101
|
+
): Promise<GoogleSheetExportResult> {
|
|
102
|
+
const columns = sheetColumnCount(input.schema, input.rows);
|
|
103
|
+
const sheetTitle = normalizeSheetTitle(
|
|
104
|
+
input.dashboardTitle,
|
|
105
|
+
input.panelTitle,
|
|
106
|
+
);
|
|
107
|
+
const createResult = await executeProviderApiRequest({
|
|
108
|
+
provider: "google_drive",
|
|
109
|
+
method: "POST",
|
|
110
|
+
path: "https://sheets.googleapis.com/v4/spreadsheets",
|
|
111
|
+
query: {
|
|
112
|
+
fields: "spreadsheetId,spreadsheetUrl,properties.title,sheets.properties",
|
|
113
|
+
},
|
|
114
|
+
body: { properties: { title: sheetTitle } },
|
|
115
|
+
});
|
|
116
|
+
const createResponse = providerResponse(
|
|
117
|
+
createResult,
|
|
118
|
+
"Google Sheet creation",
|
|
119
|
+
);
|
|
120
|
+
const created = asRecord(createResponse.json);
|
|
121
|
+
const spreadsheetId =
|
|
122
|
+
typeof created.spreadsheetId === "string" ? created.spreadsheetId : "";
|
|
123
|
+
if (!spreadsheetId) {
|
|
124
|
+
throw new Error("Google Sheet creation did not return a spreadsheet id.");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const sheets = Array.isArray(created.sheets) ? created.sheets : [];
|
|
128
|
+
const firstSheet = asRecord(sheets[0]);
|
|
129
|
+
const firstProperties = asRecord(firstSheet.properties);
|
|
130
|
+
const actualSheetTitle =
|
|
131
|
+
typeof firstProperties.title === "string" && firstProperties.title
|
|
132
|
+
? firstProperties.title
|
|
133
|
+
: "Sheet1";
|
|
134
|
+
let updatedCells: number | null = null;
|
|
135
|
+
|
|
136
|
+
if (columns.length > 0) {
|
|
137
|
+
const values = [
|
|
138
|
+
columns,
|
|
139
|
+
...input.rows.map((row) =>
|
|
140
|
+
columns.map((column) => sheetCell(row[column])),
|
|
141
|
+
),
|
|
142
|
+
];
|
|
143
|
+
const updateResult = await executeProviderApiRequest({
|
|
144
|
+
provider: "google_drive",
|
|
145
|
+
method: "PUT",
|
|
146
|
+
path: `https://sheets.googleapis.com/v4/spreadsheets/${encodeURIComponent(spreadsheetId)}/values/${encodeURIComponent(`${quoteSheetTitle(actualSheetTitle)}!A1`)}`,
|
|
147
|
+
query: { valueInputOption: "RAW" },
|
|
148
|
+
body: {
|
|
149
|
+
range: `${quoteSheetTitle(actualSheetTitle)}!A1`,
|
|
150
|
+
majorDimension: "ROWS",
|
|
151
|
+
values,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
const updateResponse = providerResponse(
|
|
155
|
+
updateResult,
|
|
156
|
+
"Google Sheet values update",
|
|
157
|
+
);
|
|
158
|
+
const updated = asRecord(updateResponse.json);
|
|
159
|
+
updatedCells =
|
|
160
|
+
typeof updated.updatedCells === "number" ? updated.updatedCells : null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const spreadsheetUrl =
|
|
164
|
+
typeof created.spreadsheetUrl === "string" && created.spreadsheetUrl
|
|
165
|
+
? created.spreadsheetUrl
|
|
166
|
+
: `https://docs.google.com/spreadsheets/d/${encodeURIComponent(spreadsheetId)}/edit`;
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
spreadsheetUrl,
|
|
170
|
+
spreadsheetId,
|
|
171
|
+
rowCount: input.rows.length,
|
|
172
|
+
metadata: {
|
|
173
|
+
dashboardId: input.dashboardId,
|
|
174
|
+
dashboardTitle: input.dashboardTitle,
|
|
175
|
+
panelId: input.panelId,
|
|
176
|
+
panelTitle: input.panelTitle,
|
|
177
|
+
source: input.source,
|
|
178
|
+
chartType: "table",
|
|
179
|
+
sheetTitle: actualSheetTitle,
|
|
180
|
+
columns,
|
|
181
|
+
columnCount: columns.length,
|
|
182
|
+
truncated: input.truncated === true,
|
|
183
|
+
bytesProcessed: input.bytesProcessed ?? null,
|
|
184
|
+
provider: "google_drive",
|
|
185
|
+
updatedCells,
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
@@ -11,8 +11,13 @@ import {
|
|
|
11
11
|
import { requireRequestCredentialContext } from "./credentials-context";
|
|
12
12
|
import { resolveAnalyticsProviderCredential } from "./provider-credentials";
|
|
13
13
|
|
|
14
|
-
export const ANALYTICS_PROVIDER_API_IDS =
|
|
15
|
-
|
|
14
|
+
export const ANALYTICS_PROVIDER_API_IDS = Array.from(
|
|
15
|
+
new Set([
|
|
16
|
+
...listProviderApiIdsForTemplateUse("analytics"),
|
|
17
|
+
// Google Sheets creation and writes use the existing Google Drive OAuth
|
|
18
|
+
// connection, whose consent is limited to drive.file.
|
|
19
|
+
"google_drive" as ProviderApiId,
|
|
20
|
+
]),
|
|
16
21
|
) as [ProviderApiId, ...ProviderApiId[]];
|
|
17
22
|
export type AnalyticsProviderApiId = ProviderApiId;
|
|
18
23
|
export type { ProviderApiMethod, ProviderApiRequestArgs };
|
|
@@ -10,7 +10,10 @@ export default createCollabPlugin({
|
|
|
10
10
|
contentColumn: "config",
|
|
11
11
|
idColumn: "id",
|
|
12
12
|
autoSeed: true,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
access: {
|
|
14
|
+
mode: "resource",
|
|
15
|
+
resourceType: "dashboard",
|
|
16
|
+
resolveResourceId: (docId) =>
|
|
17
|
+
docId.startsWith("dash-") ? docId.slice("dash-".length) : docId,
|
|
18
|
+
},
|
|
16
19
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MAX_CONCURRENT_SQL_QUERIES = 4;
|
|
@@ -85,7 +85,10 @@ in the moment of agent use.
|
|
|
85
85
|
approval, generative UI, progress, and screen-state exposure.
|
|
86
86
|
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
87
|
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
-
page-to-sidebar handoff.
|
|
88
|
+
page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
|
|
89
|
+
five-item sidebar preview and a footer row with New chat followed by an
|
|
90
|
+
ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
|
|
91
|
+
actions.
|
|
89
92
|
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
93
|
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
94
|
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
@@ -16,7 +16,7 @@ metadata:
|
|
|
16
16
|
|
|
17
17
|
Collaborative editing uses Yjs CRDT via TipTap. The agent and human users are
|
|
18
18
|
equal participants — both edit the same Y.Doc and changes merge cleanly without
|
|
19
|
-
conflicts. Always
|
|
19
|
+
conflicts. Always choose an explicit `access` mode on `createCollabPlugin`.
|
|
20
20
|
|
|
21
21
|
## How It Works
|
|
22
22
|
|
|
@@ -104,7 +104,16 @@ in **different** regions merge fine through the CRDT.
|
|
|
104
104
|
|
|
105
105
|
## Security
|
|
106
106
|
|
|
107
|
-
### Always
|
|
107
|
+
### Always choose an explicit access mode
|
|
108
|
+
|
|
109
|
+
Inspect the schema and sharing registration before configuring collaboration:
|
|
110
|
+
|
|
111
|
+
- For owned or shareable records, use `mode: "resource"` and the resource type
|
|
112
|
+
registered through `registerShareableResource`.
|
|
113
|
+
- For records deliberately visible to every authenticated user on the
|
|
114
|
+
deployment, use `mode: "all-authenticated"`.
|
|
115
|
+
- Never invent a `resourceType` merely to silence a warning. Resource mode is
|
|
116
|
+
correct only when the matching ownership and sharing model exists.
|
|
108
117
|
|
|
109
118
|
```ts
|
|
110
119
|
// server/plugins/collab.ts
|
|
@@ -114,14 +123,23 @@ export default createCollabPlugin({
|
|
|
114
123
|
table: "documents",
|
|
115
124
|
contentColumn: "content",
|
|
116
125
|
idColumn: "id",
|
|
117
|
-
resourceType: "document",
|
|
126
|
+
access: { mode: "resource", resourceType: "document" },
|
|
118
127
|
});
|
|
119
128
|
```
|
|
120
129
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
For intentionally deployment-wide authenticated collaboration:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
createCollabPlugin({
|
|
134
|
+
table: "todos",
|
|
135
|
+
contentColumn: "content",
|
|
136
|
+
access: { mode: "all-authenticated" },
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Omitting `access` is supported only for legacy compatibility and is deprecated.
|
|
141
|
+
It behaves like `all-authenticated`, logs a warning, and is flagged by Doctor.
|
|
142
|
+
Choose the mode explicitly so access intent is reviewable.
|
|
125
143
|
|
|
126
144
|
Non-owner sharees who have explicit access fall back to state-vector catch-up
|
|
127
145
|
(safe, slightly higher latency). Awareness routes require the same viewer
|
|
@@ -133,7 +151,10 @@ Write routes reject payloads exceeding `maxPayloadBytes` (default 2 MB) with
|
|
|
133
151
|
HTTP 413. Override:
|
|
134
152
|
|
|
135
153
|
```ts
|
|
136
|
-
createCollabPlugin({
|
|
154
|
+
createCollabPlugin({
|
|
155
|
+
access: { mode: "resource", resourceType: "document" },
|
|
156
|
+
maxPayloadBytes: 512 * 1024,
|
|
157
|
+
});
|
|
137
158
|
```
|
|
138
159
|
|
|
139
160
|
## Enabling Collaboration
|
|
@@ -144,7 +165,7 @@ createCollabPlugin({ resourceType: "document", maxPayloadBytes: 512 * 1024 });
|
|
|
144
165
|
pnpm add @tiptap/extension-collaboration @tiptap/extension-collaboration-caret @tiptap/y-tiptap @tiptap/core
|
|
145
166
|
```
|
|
146
167
|
|
|
147
|
-
### 2. Add collab server plugin (with
|
|
168
|
+
### 2. Add collab server plugin (with explicit access)
|
|
148
169
|
|
|
149
170
|
```ts
|
|
150
171
|
// server/plugins/collab.ts
|
|
@@ -154,7 +175,7 @@ export default createCollabPlugin({
|
|
|
154
175
|
table: "documents",
|
|
155
176
|
contentColumn: "content",
|
|
156
177
|
idColumn: "id",
|
|
157
|
-
resourceType: "document",
|
|
178
|
+
access: { mode: "resource", resourceType: "document" },
|
|
158
179
|
});
|
|
159
180
|
```
|
|
160
181
|
|
|
@@ -343,9 +364,10 @@ the whole history — external/agent edits must not wipe the user's undo stack.
|
|
|
343
364
|
|
|
344
365
|
## Common Pitfalls
|
|
345
366
|
|
|
346
|
-
- **Missing `
|
|
347
|
-
|
|
348
|
-
|
|
367
|
+
- **Missing `access`** — Legacy omission behaves like `all-authenticated`, logs
|
|
368
|
+
a startup warning, and is flagged by Doctor. Choose `resource` for records
|
|
369
|
+
backed by ownership/sharing, or explicit `all-authenticated` for intentionally
|
|
370
|
+
deployment-wide records. Never invent a resource type to silence the warning.
|
|
349
371
|
- **Don't pass `content` as a TipTap prop** when Collaboration is enabled —
|
|
350
372
|
Yjs owns the content. Seed via `editor.commands.setContent()` only when the
|
|
351
373
|
Y.XmlFragment is empty.
|
|
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
|
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
|
|
75
|
+
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
|
|
76
76
|
|
|
77
77
|
## Which sources to depend on
|
|
78
78
|
|
|
@@ -71,7 +71,7 @@ export function Layout({ children }: LayoutProps) {
|
|
|
71
71
|
// A direct /chat/:id link already names the thread and must preserve the
|
|
72
72
|
// normal chat-to-sidebar transition. Only the empty home chat needs the
|
|
73
73
|
// recent marker that proves an agent handoff is in flight.
|
|
74
|
-
requireActiveHandoff:
|
|
74
|
+
requireActiveHandoff: false,
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
useEffect(() => {
|
|
@@ -12,7 +12,7 @@ import { useT } from "@agent-native/core/client/i18n";
|
|
|
12
12
|
import { OrgSwitcher } from "@agent-native/core/client/org";
|
|
13
13
|
import { FeedbackButton } from "@agent-native/core/client/ui";
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
ChatHistoryRail,
|
|
16
16
|
type ChatHistoryItem,
|
|
17
17
|
} from "@agent-native/toolkit/chat-history";
|
|
18
18
|
import {
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
IconLayoutSidebarLeftExpand,
|
|
23
23
|
IconLayoutGrid,
|
|
24
24
|
IconPhotoPlus,
|
|
25
|
-
IconPlus,
|
|
26
25
|
IconSettings,
|
|
27
26
|
IconShare3,
|
|
28
27
|
} from "@tabler/icons-react";
|
|
@@ -96,6 +95,12 @@ function persistedActiveThreadId() {
|
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
97
|
|
|
98
|
+
function persistActiveThreadId(threadId: string) {
|
|
99
|
+
try {
|
|
100
|
+
localStorage.setItem(ASSETS_ACTIVE_THREAD_KEY, threadId);
|
|
101
|
+
} catch {}
|
|
102
|
+
}
|
|
103
|
+
|
|
99
104
|
function threadIdFromPath(pathname: string) {
|
|
100
105
|
const match = pathname.match(/^\/chat\/([^/]+)/);
|
|
101
106
|
if (!match) return null;
|
|
@@ -134,8 +139,7 @@ function AssetsChatsSection() {
|
|
|
134
139
|
() =>
|
|
135
140
|
threads
|
|
136
141
|
.filter((thread) => thread.messageCount > 0 && !thread.archivedAt)
|
|
137
|
-
.sort(compareThreads)
|
|
138
|
-
.slice(0, 10),
|
|
142
|
+
.sort(compareThreads),
|
|
139
143
|
[threads],
|
|
140
144
|
);
|
|
141
145
|
const displayedActiveThreadId =
|
|
@@ -177,6 +181,7 @@ function AssetsChatsSection() {
|
|
|
177
181
|
|
|
178
182
|
function openThread(threadId: string, options?: { isNew?: boolean }) {
|
|
179
183
|
switchThread(threadId);
|
|
184
|
+
persistActiveThreadId(threadId);
|
|
180
185
|
navigateWithAgentChatViewTransition(
|
|
181
186
|
navigate,
|
|
182
187
|
options?.isNew ? "/" : chatThreadPath(threadId),
|
|
@@ -236,63 +241,50 @@ function AssetsChatsSection() {
|
|
|
236
241
|
|
|
237
242
|
return (
|
|
238
243
|
<div className="mt-2 border-s border-border/70 ps-3">
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
labels={{
|
|
284
|
-
options: (item) =>
|
|
285
|
-
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
286
|
-
renameInput: (item) => `Rename ${item.titleText ?? ""}`,
|
|
287
|
-
rename: t("chat.renameChat"),
|
|
288
|
-
pin: t("chat.pinChat"),
|
|
289
|
-
unpin: t("chat.unpinChat"),
|
|
290
|
-
delete: t("chat.archiveChat"),
|
|
291
|
-
}}
|
|
292
|
-
variant="rail"
|
|
293
|
-
className="min-w-0"
|
|
294
|
-
/>
|
|
295
|
-
)}
|
|
244
|
+
<ChatHistoryRail
|
|
245
|
+
items={chatItems}
|
|
246
|
+
activeId={displayedActiveThreadId}
|
|
247
|
+
onSelect={openThread}
|
|
248
|
+
onNewChat={() => void handleNewChat()}
|
|
249
|
+
railLabels={{
|
|
250
|
+
newChat: t("chat.newChat"),
|
|
251
|
+
showMore: t("chat.chats"),
|
|
252
|
+
showLess: t("chat.chats"),
|
|
253
|
+
}}
|
|
254
|
+
previewCount={5}
|
|
255
|
+
expandedCount={15}
|
|
256
|
+
onTogglePin={(threadId) => {
|
|
257
|
+
const thread = visibleThreads.find((item) => item.id === threadId);
|
|
258
|
+
if (thread) void pinThread(threadId, !thread.pinnedAt);
|
|
259
|
+
}}
|
|
260
|
+
onRename={handleRenameThread}
|
|
261
|
+
renameMaxLength={160}
|
|
262
|
+
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
263
|
+
renderAdditionalRowActions={(item, closeMenu) => (
|
|
264
|
+
<button
|
|
265
|
+
type="button"
|
|
266
|
+
role="menuitem"
|
|
267
|
+
className="an-chat-history-row__menu-item"
|
|
268
|
+
onClick={() => {
|
|
269
|
+
closeMenu();
|
|
270
|
+
void handleCopyShareLink(item.id);
|
|
271
|
+
}}
|
|
272
|
+
>
|
|
273
|
+
<IconShare3 size={13} strokeWidth={1.8} />
|
|
274
|
+
<span>{t("chat.copyShareLink")}</span>
|
|
275
|
+
</button>
|
|
276
|
+
)}
|
|
277
|
+
labels={{
|
|
278
|
+
options: (item) =>
|
|
279
|
+
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
280
|
+
renameInput: (item) => `Rename ${item.titleText ?? ""}`,
|
|
281
|
+
rename: t("chat.renameChat"),
|
|
282
|
+
pin: t("chat.pinChat"),
|
|
283
|
+
unpin: t("chat.unpinChat"),
|
|
284
|
+
delete: t("chat.archiveChat"),
|
|
285
|
+
}}
|
|
286
|
+
className="min-w-0"
|
|
287
|
+
/>
|
|
296
288
|
</div>
|
|
297
289
|
);
|
|
298
290
|
}
|
|
@@ -466,7 +458,7 @@ export function Sidebar() {
|
|
|
466
458
|
<OrgSwitcher />
|
|
467
459
|
</div>
|
|
468
460
|
|
|
469
|
-
<div className="px-3 py-2">
|
|
461
|
+
<div className="px-3 py-2 empty:hidden">
|
|
470
462
|
<DevDatabaseLink />
|
|
471
463
|
<FeedbackButton />
|
|
472
464
|
</div>
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isAgentChatHomeHandoffActive,
|
|
3
|
-
markAgentChatHomeHandoff,
|
|
4
|
-
} from "@agent-native/core/client/agent-chat";
|
|
1
|
+
import { markAgentChatHomeHandoff } from "@agent-native/core/client/agent-chat";
|
|
5
2
|
import { getBrowserTabId } from "@agent-native/core/client/hooks";
|
|
6
3
|
import { useAgentRouteState } from "@agent-native/core/client/navigation";
|
|
7
4
|
import { useLocation } from "react-router";
|
|
@@ -204,8 +201,7 @@ export function useNavigationState() {
|
|
|
204
201
|
onNavigate: (_command, path) => {
|
|
205
202
|
if (
|
|
206
203
|
isCreatePath(location.pathname) &&
|
|
207
|
-
!isCreatePath(pathnameFromPath(path))
|
|
208
|
-
isAgentChatHomeHandoffActive(ASSETS_CHAT_STORAGE_KEY)
|
|
204
|
+
!isCreatePath(pathnameFromPath(path))
|
|
209
205
|
) {
|
|
210
206
|
markAgentChatHomeHandoff(ASSETS_CHAT_STORAGE_KEY);
|
|
211
207
|
}
|
|
@@ -59,6 +59,13 @@ export default function CreatePage() {
|
|
|
59
59
|
const { threadId } = useParams();
|
|
60
60
|
const navigate = useNavigate();
|
|
61
61
|
const t = useT();
|
|
62
|
+
const threadUrlSync = threadId
|
|
63
|
+
? {
|
|
64
|
+
routeThreadId: threadId,
|
|
65
|
+
getPath: chatThreadPath,
|
|
66
|
+
navigate,
|
|
67
|
+
}
|
|
68
|
+
: undefined;
|
|
62
69
|
const imageModelMenu = useImageModelMenu();
|
|
63
70
|
|
|
64
71
|
useEffect(() => {
|
|
@@ -82,11 +89,7 @@ export default function CreatePage() {
|
|
|
82
89
|
className="assets-create-chat-panel"
|
|
83
90
|
defaultMode="chat"
|
|
84
91
|
storageKey={ASSETS_CHAT_STORAGE_KEY}
|
|
85
|
-
threadUrlSync={
|
|
86
|
-
routeThreadId: threadId ?? null,
|
|
87
|
-
getPath: chatThreadPath,
|
|
88
|
-
navigate,
|
|
89
|
-
}}
|
|
92
|
+
threadUrlSync={threadUrlSync}
|
|
90
93
|
browserTabId={getBrowserTabId()}
|
|
91
94
|
threadFooterSlot={({ threadId }) => (
|
|
92
95
|
<GenerationResults threadId={threadId} />
|
|
@@ -85,7 +85,10 @@ in the moment of agent use.
|
|
|
85
85
|
approval, generative UI, progress, and screen-state exposure.
|
|
86
86
|
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
87
|
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
-
page-to-sidebar handoff.
|
|
88
|
+
page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
|
|
89
|
+
five-item sidebar preview and a footer row with New chat followed by an
|
|
90
|
+
ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
|
|
91
|
+
actions.
|
|
89
92
|
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
93
|
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
94
|
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
|
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
|
|
75
|
+
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
|
|
76
76
|
|
|
77
77
|
## Which sources to depend on
|
|
78
78
|
|