@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,55 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { createError, defineEventHandler, getHeader } from "h3";
|
|
4
|
+
|
|
5
|
+
import { processBrainIngestQueueOnce } from "../../../../../jobs/process-ingest-queue.js";
|
|
6
|
+
import { syncDueBrainSourcesOnce } from "../../../../jobs/sync-sources.js";
|
|
7
|
+
import { expireSensitivityQuarantines } from "../../../../lib/brain.js";
|
|
8
|
+
|
|
9
|
+
declare global {
|
|
10
|
+
var __AGENT_NATIVE_BRAIN_SCHEDULED_RUNTIME__: boolean | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function productionLike() {
|
|
14
|
+
return (
|
|
15
|
+
process.env.NODE_ENV === "production" || process.env.NETLIFY === "true"
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function scheduledFunctionRuntime() {
|
|
20
|
+
return globalThis.__AGENT_NATIVE_BRAIN_SCHEDULED_RUNTIME__ === true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function headerMatchesSecret(header: string | undefined, secret: string) {
|
|
24
|
+
const expected = `Bearer ${secret}`;
|
|
25
|
+
const value = header?.trim() ?? "";
|
|
26
|
+
return (
|
|
27
|
+
value.length === expected.length &&
|
|
28
|
+
timingSafeEqual(Buffer.from(value), Buffer.from(expected))
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default defineEventHandler(async (event) => {
|
|
33
|
+
const secret = process.env.BRAIN_JOBS_SECRET?.trim(); // guard:allow-env-credential — deployment-level scheduler route secret
|
|
34
|
+
const scheduled = scheduledFunctionRuntime();
|
|
35
|
+
if (!secret && productionLike() && !scheduled) {
|
|
36
|
+
throw createError({
|
|
37
|
+
statusCode: 503,
|
|
38
|
+
statusMessage: "BRAIN_JOBS_SECRET is required",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (
|
|
42
|
+
secret &&
|
|
43
|
+
!scheduled &&
|
|
44
|
+
!headerMatchesSecret(getHeader(event, "authorization"), secret)
|
|
45
|
+
) {
|
|
46
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const [sync, queue, expiredSensitivityQuarantines] = await Promise.all([
|
|
50
|
+
syncDueBrainSourcesOnce({ system: true, limit: 5 }),
|
|
51
|
+
processBrainIngestQueueOnce({ limit: 1, runDistillation: true }),
|
|
52
|
+
expireSensitivityQuarantines(),
|
|
53
|
+
]);
|
|
54
|
+
return { ok: true, sync, queue, expiredSensitivityQuarantines };
|
|
55
|
+
});
|
|
@@ -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
|
|
|
@@ -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
|
|
|
@@ -9,7 +9,7 @@ import { useT } from "@agent-native/core/client/i18n";
|
|
|
9
9
|
import { OrgSwitcher } from "@agent-native/core/client/org";
|
|
10
10
|
import { FeedbackButton } from "@agent-native/core/client/ui";
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
ChatHistoryRail,
|
|
13
13
|
type ChatHistoryItem,
|
|
14
14
|
} from "@agent-native/toolkit/chat-history";
|
|
15
15
|
import {
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
IconLayoutSidebarLeftCollapse,
|
|
18
18
|
IconLayoutSidebarLeftExpand,
|
|
19
19
|
IconMessageCircle,
|
|
20
|
-
IconPlus,
|
|
21
20
|
IconSettings,
|
|
22
21
|
} from "@tabler/icons-react";
|
|
23
22
|
import { useEffect, useMemo } from "react";
|
|
@@ -104,6 +103,12 @@ function persistedActiveThreadId() {
|
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
|
|
106
|
+
function persistActiveThreadId(threadId: string) {
|
|
107
|
+
try {
|
|
108
|
+
localStorage.setItem(CHAT_ACTIVE_THREAD_KEY, threadId);
|
|
109
|
+
} catch {}
|
|
110
|
+
}
|
|
111
|
+
|
|
107
112
|
function threadIdFromPath(pathname: string) {
|
|
108
113
|
const match = pathname.match(/^\/chat\/([^/]+)/);
|
|
109
114
|
if (!match) return null;
|
|
@@ -142,7 +147,7 @@ function ChatThreadsSection() {
|
|
|
142
147
|
threads
|
|
143
148
|
.filter((thread) => thread.messageCount > 0 && !thread.archivedAt)
|
|
144
149
|
.sort(compareThreads)
|
|
145
|
-
.slice(0,
|
|
150
|
+
.slice(0, 15),
|
|
146
151
|
[threads],
|
|
147
152
|
);
|
|
148
153
|
const displayedActiveThreadId =
|
|
@@ -184,6 +189,7 @@ function ChatThreadsSection() {
|
|
|
184
189
|
|
|
185
190
|
function openThread(threadId: string, options?: { isNew?: boolean }) {
|
|
186
191
|
switchThread(threadId);
|
|
192
|
+
persistActiveThreadId(threadId);
|
|
187
193
|
navigateWithAgentChatViewTransition(
|
|
188
194
|
navigate,
|
|
189
195
|
options?.isNew ? "/" : chatThreadPath(threadId),
|
|
@@ -223,50 +229,35 @@ function ChatThreadsSection() {
|
|
|
223
229
|
|
|
224
230
|
return (
|
|
225
231
|
<div className="mt-2 border-s border-sidebar-border/70 ps-3">
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
256
|
-
labels={{
|
|
257
|
-
options: (item) =>
|
|
258
|
-
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
259
|
-
renameInput: (item) =>
|
|
260
|
-
t("chat.renameThread", { title: item.titleText ?? "" }),
|
|
261
|
-
rename: t("chat.renameChat"),
|
|
262
|
-
pin: t("chat.pinChat"),
|
|
263
|
-
unpin: t("chat.unpinChat"),
|
|
264
|
-
delete: t("chat.archiveChat"),
|
|
265
|
-
}}
|
|
266
|
-
variant="rail"
|
|
267
|
-
className="min-w-0"
|
|
268
|
-
/>
|
|
269
|
-
)}
|
|
232
|
+
<ChatHistoryRail
|
|
233
|
+
items={chatItems}
|
|
234
|
+
activeId={displayedActiveThreadId}
|
|
235
|
+
onSelect={(threadId) => openThread(threadId)}
|
|
236
|
+
onNewChat={() => void handleNewChat()}
|
|
237
|
+
railLabels={{
|
|
238
|
+
newChat: t("chat.newChat"),
|
|
239
|
+
showMore: t("chat.chats"),
|
|
240
|
+
showLess: t("chat.chats"),
|
|
241
|
+
}}
|
|
242
|
+
renameMaxLength={160}
|
|
243
|
+
onTogglePin={(threadId) => {
|
|
244
|
+
const thread = visibleThreads.find((item) => item.id === threadId);
|
|
245
|
+
if (thread) void pinThread(threadId, !thread.pinnedAt);
|
|
246
|
+
}}
|
|
247
|
+
onRename={handleRenameThread}
|
|
248
|
+
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
249
|
+
labels={{
|
|
250
|
+
options: (item) =>
|
|
251
|
+
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
252
|
+
renameInput: (item) =>
|
|
253
|
+
t("chat.renameThread", { title: item.titleText ?? "" }),
|
|
254
|
+
rename: t("chat.renameChat"),
|
|
255
|
+
pin: t("chat.pinChat"),
|
|
256
|
+
unpin: t("chat.unpinChat"),
|
|
257
|
+
delete: t("chat.archiveChat"),
|
|
258
|
+
}}
|
|
259
|
+
className="min-w-0"
|
|
260
|
+
/>
|
|
270
261
|
</div>
|
|
271
262
|
);
|
|
272
263
|
}
|
|
@@ -445,28 +436,13 @@ export function Sidebar({
|
|
|
445
436
|
/>
|
|
446
437
|
</div>
|
|
447
438
|
|
|
448
|
-
|
|
449
|
-
className=
|
|
450
|
-
|
|
451
|
-
)}
|
|
452
|
-
>
|
|
453
|
-
<FeedbackButton
|
|
454
|
-
variant={collapsed ? "icon" : "sidebar"}
|
|
455
|
-
side="right"
|
|
456
|
-
align={collapsed ? "center" : "end"}
|
|
457
|
-
/>
|
|
458
|
-
</div>
|
|
459
|
-
|
|
460
|
-
{collapseButton ? (
|
|
461
|
-
<div
|
|
462
|
-
className={cn(
|
|
463
|
-
collapsed
|
|
464
|
-
? "flex justify-center px-1 py-1"
|
|
465
|
-
: "flex justify-end px-3 py-2",
|
|
466
|
-
)}
|
|
467
|
-
>
|
|
439
|
+
{!collapsed ? (
|
|
440
|
+
<div className="flex items-center justify-end gap-1 px-3 py-2">
|
|
441
|
+
<FeedbackButton className="min-w-0 flex-1" side="right" />
|
|
468
442
|
{collapseButton}
|
|
469
443
|
</div>
|
|
444
|
+
) : collapseButton ? (
|
|
445
|
+
<div className="flex justify-center px-1 py-1">{collapseButton}</div>
|
|
470
446
|
) : null}
|
|
471
447
|
</div>
|
|
472
448
|
</aside>
|
|
@@ -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 { appBasePath, appPath } from "@agent-native/core/client/api-path";
|
|
6
3
|
import { useAgentRouteState } from "@agent-native/core/client/navigation";
|
|
7
4
|
import { useLocation } from "react-router";
|
|
@@ -34,9 +31,7 @@ export function useNavigationState() {
|
|
|
34
31
|
isChatPath(location.pathname) &&
|
|
35
32
|
!isChatPath(pathnameFromPath(path))
|
|
36
33
|
) {
|
|
37
|
-
|
|
38
|
-
markAgentChatHomeHandoff("chat");
|
|
39
|
-
}
|
|
34
|
+
markAgentChatHomeHandoff("chat");
|
|
40
35
|
}
|
|
41
36
|
},
|
|
42
37
|
});
|
|
@@ -36,6 +36,13 @@ export default function ChatRoute() {
|
|
|
36
36
|
const { threadId } = useParams();
|
|
37
37
|
const navigate = useNavigate();
|
|
38
38
|
const t = useT();
|
|
39
|
+
const threadUrlSync = threadId
|
|
40
|
+
? {
|
|
41
|
+
routeThreadId: threadId,
|
|
42
|
+
getPath: chatThreadPath,
|
|
43
|
+
navigate,
|
|
44
|
+
}
|
|
45
|
+
: undefined;
|
|
39
46
|
|
|
40
47
|
useEffect(() => {
|
|
41
48
|
function handleChatRunning(event: Event) {
|
|
@@ -56,11 +63,7 @@ export default function ChatRoute() {
|
|
|
56
63
|
className="h-full"
|
|
57
64
|
defaultMode="chat"
|
|
58
65
|
storageKey="chat"
|
|
59
|
-
threadUrlSync={
|
|
60
|
-
routeThreadId: threadId ?? null,
|
|
61
|
-
getPath: chatThreadPath,
|
|
62
|
-
navigate,
|
|
63
|
-
}}
|
|
66
|
+
threadUrlSync={threadUrlSync}
|
|
64
67
|
browserTabId={TAB_ID}
|
|
65
68
|
showHeader={false}
|
|
66
69
|
showTabBar={false}
|
|
@@ -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
|
|
@@ -69,7 +69,15 @@ ladder.
|
|
|
69
69
|
current-user recordings with ready transcripts in the active organization
|
|
70
70
|
and reports exported, quarantined, skipped, and failed counts. Both
|
|
71
71
|
`BRAIN_INGEST_URL` and `BRAIN_INGEST_TOKEN` must be available as scoped Clips
|
|
72
|
-
secrets.
|
|
72
|
+
secrets. Transcript completion persists a pending export before handing it to
|
|
73
|
+
the durable post-finalize worker; delivery receipts include the Brain capture
|
|
74
|
+
or sensitivity receipt id, while transient failures are swept and retried.
|
|
75
|
+
The sweep also discovers ready transcripts from the last seven days that
|
|
76
|
+
predate export-state tracking, in bounded batches, so recent recordings are
|
|
77
|
+
backfilled after the connection is configured.
|
|
78
|
+
Netlify builds emit a protected per-minute scheduled sweep because in-process
|
|
79
|
+
intervals are not durable there. Other serverless hosts must invoke
|
|
80
|
+
`runBrainExportSweepOnce` from their own scheduler.
|
|
73
81
|
- The transcript embedded by `view-screen` is a bounded preview. If
|
|
74
82
|
`previewTruncated` is true, it may end mid-sentence and does not show where
|
|
75
83
|
transcription ended. Call `get-recording-player-data` before judging
|
|
@@ -18,6 +18,7 @@ import { and, asc, eq, gt, gte, isNull, lte, or, sql } from "drizzle-orm";
|
|
|
18
18
|
import { z } from "zod";
|
|
19
19
|
|
|
20
20
|
import { getDb, schema } from "../server/db/index.js";
|
|
21
|
+
import { writeBrainExportState } from "../server/lib/brain-export-state.js";
|
|
21
22
|
import {
|
|
22
23
|
getActiveOrganizationId,
|
|
23
24
|
getCurrentOwnerEmail,
|
|
@@ -232,6 +233,11 @@ async function buildPayload(
|
|
|
232
233
|
.orderBy(asc(schema.recordingTags.tag)),
|
|
233
234
|
]);
|
|
234
235
|
|
|
236
|
+
const summary = meeting?.summaryMd?.trim();
|
|
237
|
+
const captureText = summary
|
|
238
|
+
? `Summary\n${summary}\n\nTranscript\n${transcriptText}`
|
|
239
|
+
: transcriptText;
|
|
240
|
+
|
|
235
241
|
return {
|
|
236
242
|
sourceKey: "clips",
|
|
237
243
|
externalId: `clips:recording:${recording.id}`,
|
|
@@ -246,7 +252,7 @@ async function buildPayload(
|
|
|
246
252
|
meeting?.scheduledStart ||
|
|
247
253
|
recording.createdAt ||
|
|
248
254
|
new Date().toISOString(),
|
|
249
|
-
transcript:
|
|
255
|
+
transcript: captureText,
|
|
250
256
|
segments,
|
|
251
257
|
sourceUrl: resolveSourceUrl(recording.id),
|
|
252
258
|
tags: tags.map((row) => row.tag).filter(Boolean),
|
|
@@ -346,14 +352,17 @@ async function exportRecording(
|
|
|
346
352
|
recording: Recording,
|
|
347
353
|
transcript: RecordingTranscript,
|
|
348
354
|
destination: BrainDestination,
|
|
355
|
+
attempt = 1,
|
|
349
356
|
): Promise<BrainExportResult> {
|
|
350
357
|
const payload = await buildPayload(recording, transcript);
|
|
351
358
|
if (!payload) {
|
|
352
|
-
|
|
359
|
+
const result: BrainExportResult = {
|
|
353
360
|
recordingId: recording.id,
|
|
354
361
|
status: "skipped",
|
|
355
362
|
reason: "empty-transcript",
|
|
356
363
|
};
|
|
364
|
+
await persistBrainExportResult(result, attempt);
|
|
365
|
+
return result;
|
|
357
366
|
}
|
|
358
367
|
|
|
359
368
|
try {
|
|
@@ -370,7 +379,9 @@ async function exportRecording(
|
|
|
370
379
|
},
|
|
371
380
|
{ maxRedirects: 0 },
|
|
372
381
|
);
|
|
373
|
-
|
|
382
|
+
const result = await interpretBrainResponse(recording.id, response);
|
|
383
|
+
await persistBrainExportResult(result, attempt);
|
|
384
|
+
return result;
|
|
374
385
|
} catch (err) {
|
|
375
386
|
const reason =
|
|
376
387
|
(err as Error)?.name === "TimeoutError" ||
|
|
@@ -382,10 +393,65 @@ async function exportRecording(
|
|
|
382
393
|
reason,
|
|
383
394
|
error: (err as Error)?.message ?? String(err),
|
|
384
395
|
});
|
|
385
|
-
|
|
396
|
+
const result: BrainExportResult = {
|
|
397
|
+
recordingId: recording.id,
|
|
398
|
+
status: "failed",
|
|
399
|
+
reason,
|
|
400
|
+
};
|
|
401
|
+
await persistBrainExportResult(result, attempt);
|
|
402
|
+
return result;
|
|
386
403
|
}
|
|
387
404
|
}
|
|
388
405
|
|
|
406
|
+
async function persistBrainExportResult(
|
|
407
|
+
result: BrainExportResult,
|
|
408
|
+
attempts: number,
|
|
409
|
+
): Promise<void> {
|
|
410
|
+
const updatedAt = new Date().toISOString();
|
|
411
|
+
await writeBrainExportState({
|
|
412
|
+
recordingId: result.recordingId,
|
|
413
|
+
status: result.status,
|
|
414
|
+
attempts,
|
|
415
|
+
updatedAt,
|
|
416
|
+
...(result.status === "exported" ? { captureId: result.captureId } : {}),
|
|
417
|
+
...(result.status === "quarantined"
|
|
418
|
+
? {
|
|
419
|
+
sensitivityReceiptId: result.sensitivityReceiptId,
|
|
420
|
+
sensitivityDisposition: result.sensitivityDisposition,
|
|
421
|
+
}
|
|
422
|
+
: {}),
|
|
423
|
+
...(result.status === "failed"
|
|
424
|
+
? {
|
|
425
|
+
reason: result.reason,
|
|
426
|
+
nextAttemptAt: new Date(
|
|
427
|
+
Date.now() +
|
|
428
|
+
Math.min(15 * 60_000, 30_000 * 2 ** Math.max(0, attempts - 1)),
|
|
429
|
+
).toISOString(),
|
|
430
|
+
}
|
|
431
|
+
: result.status === "skipped"
|
|
432
|
+
? { reason: result.reason }
|
|
433
|
+
: {}),
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async function persistRetryableBrainExportFailure(
|
|
438
|
+
recordingId: string,
|
|
439
|
+
reason: string,
|
|
440
|
+
attempts: number,
|
|
441
|
+
): Promise<void> {
|
|
442
|
+
await writeBrainExportState({
|
|
443
|
+
recordingId,
|
|
444
|
+
status: "failed",
|
|
445
|
+
attempts,
|
|
446
|
+
reason,
|
|
447
|
+
updatedAt: new Date().toISOString(),
|
|
448
|
+
nextAttemptAt: new Date(
|
|
449
|
+
Date.now() +
|
|
450
|
+
Math.min(15 * 60_000, 30_000 * 2 ** Math.max(0, attempts - 1)),
|
|
451
|
+
).toISOString(),
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
389
455
|
async function mapWithConcurrency<T, R>(
|
|
390
456
|
values: T[],
|
|
391
457
|
concurrency: number,
|
|
@@ -535,6 +601,7 @@ export default defineAction({
|
|
|
535
601
|
.min(1)
|
|
536
602
|
.max(8)
|
|
537
603
|
.default(DEFAULT_CONCURRENCY),
|
|
604
|
+
retryAttempt: z.coerce.number().int().min(1).max(8).optional(),
|
|
538
605
|
cursor: z
|
|
539
606
|
.string()
|
|
540
607
|
.min(1)
|
|
@@ -552,11 +619,17 @@ export default defineAction({
|
|
|
552
619
|
);
|
|
553
620
|
const destinationResult = await resolveBrainDestination();
|
|
554
621
|
if (!destinationResult.destination) {
|
|
555
|
-
|
|
622
|
+
const result: BrainExportResult = {
|
|
556
623
|
recordingId: args.recordingId,
|
|
557
624
|
status: "skipped" as const,
|
|
558
625
|
reason: destinationResult.reason,
|
|
559
626
|
};
|
|
627
|
+
await persistRetryableBrainExportFailure(
|
|
628
|
+
result.recordingId,
|
|
629
|
+
result.reason,
|
|
630
|
+
0,
|
|
631
|
+
);
|
|
632
|
+
return result;
|
|
560
633
|
}
|
|
561
634
|
const [transcript] = await getDb()
|
|
562
635
|
.select()
|
|
@@ -564,16 +637,19 @@ export default defineAction({
|
|
|
564
637
|
.where(eq(schema.recordingTranscripts.recordingId, args.recordingId))
|
|
565
638
|
.limit(1);
|
|
566
639
|
if (!transcript) {
|
|
567
|
-
|
|
640
|
+
const result: BrainExportResult = {
|
|
568
641
|
recordingId: args.recordingId,
|
|
569
642
|
status: "skipped" as const,
|
|
570
643
|
reason: "empty-transcript",
|
|
571
644
|
};
|
|
645
|
+
await persistBrainExportResult(result, args.retryAttempt ?? 0);
|
|
646
|
+
return result;
|
|
572
647
|
}
|
|
573
648
|
return exportRecording(
|
|
574
649
|
access.resource as Recording,
|
|
575
650
|
transcript,
|
|
576
651
|
destinationResult.destination,
|
|
652
|
+
args.retryAttempt ?? 1,
|
|
577
653
|
);
|
|
578
654
|
}
|
|
579
655
|
|
|
@@ -53,6 +53,7 @@ import { and, eq } from "drizzle-orm";
|
|
|
53
53
|
import { z } from "zod";
|
|
54
54
|
|
|
55
55
|
import { getDb, schema } from "../server/db/index.js";
|
|
56
|
+
import { writeBrainExportState } from "../server/lib/brain-export-state.js";
|
|
56
57
|
import { dispatchPostFinalizeJob } from "../server/lib/post-finalize-dispatch.js";
|
|
57
58
|
import {
|
|
58
59
|
getCurrentOwnerEmail,
|
|
@@ -66,7 +67,6 @@ import {
|
|
|
66
67
|
parseTranscriptSegments,
|
|
67
68
|
} from "../shared/transcript-segments.js";
|
|
68
69
|
import cleanupTranscript from "./cleanup-transcript.js";
|
|
69
|
-
import exportToBrain from "./export-to-brain.js";
|
|
70
70
|
import { loadAgentsMdContext } from "./lib/agents-md-context.js";
|
|
71
71
|
import {
|
|
72
72
|
AudioOnlyExtractionError,
|
|
@@ -309,15 +309,26 @@ function scheduleAutoTranscriptRetry({
|
|
|
309
309
|
});
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
function queueBrainExport(recordingId: string): void {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
312
|
+
async function queueBrainExport(recordingId: string): Promise<void> {
|
|
313
|
+
await writeBrainExportState({
|
|
314
|
+
recordingId,
|
|
315
|
+
status: "pending",
|
|
316
|
+
attempts: 0,
|
|
317
|
+
updatedAt: new Date().toISOString(),
|
|
318
|
+
nextAttemptAt: new Date(Date.now() + 60_000).toISOString(),
|
|
319
|
+
});
|
|
320
|
+
try {
|
|
321
|
+
await dispatchPostFinalizeJob({
|
|
322
|
+
recordingId,
|
|
323
|
+
kind: "brain-export",
|
|
324
|
+
requireAccepted: true,
|
|
325
|
+
});
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.warn(
|
|
328
|
+
`[clips] Brain export dispatch failed for ${recordingId}:`,
|
|
329
|
+
error instanceof Error ? error.message : String(error),
|
|
330
|
+
);
|
|
331
|
+
}
|
|
321
332
|
}
|
|
322
333
|
|
|
323
334
|
function verboseTranscriptErrors(): boolean {
|
|
@@ -542,7 +553,7 @@ export async function importLoomTranscriptForRecording({
|
|
|
542
553
|
now,
|
|
543
554
|
});
|
|
544
555
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
545
|
-
queueBrainExport(recordingId);
|
|
556
|
+
await queueBrainExport(recordingId);
|
|
546
557
|
return {
|
|
547
558
|
recordingId,
|
|
548
559
|
status: "ready" as const,
|
|
@@ -955,7 +966,7 @@ async function completeReadyTranscript({
|
|
|
955
966
|
// (`transcript-cleanup-${recordingId}`) before its next 2s tick lands —
|
|
956
967
|
// otherwise the "Cleaning up…" badge can lag for one full poll interval.
|
|
957
968
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
958
|
-
queueBrainExport(recordingId);
|
|
969
|
+
await queueBrainExport(recordingId);
|
|
959
970
|
|
|
960
971
|
return {
|
|
961
972
|
recordingId,
|
|
@@ -1385,7 +1396,7 @@ const requestTranscriptAction = defineAction({
|
|
|
1385
1396
|
now,
|
|
1386
1397
|
});
|
|
1387
1398
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
1388
|
-
queueBrainExport(args.recordingId);
|
|
1399
|
+
await queueBrainExport(args.recordingId);
|
|
1389
1400
|
await clearBuilderCreditsExhausted();
|
|
1390
1401
|
|
|
1391
1402
|
// Re-read title fresh — `rec.title` was fetched before the 30+ s
|
|
@@ -1647,7 +1658,7 @@ const requestTranscriptAction = defineAction({
|
|
|
1647
1658
|
});
|
|
1648
1659
|
|
|
1649
1660
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
1650
|
-
queueBrainExport(args.recordingId);
|
|
1661
|
+
await queueBrainExport(args.recordingId);
|
|
1651
1662
|
|
|
1652
1663
|
// Generate transcript-backed metadata without replacing a human title or
|
|
1653
1664
|
// description. The title action keeps any local heuristic replaceable
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
IconCheck,
|
|
8
8
|
IconCopy,
|
|
9
9
|
IconLock,
|
|
10
|
+
IconSend2,
|
|
10
11
|
IconTrash,
|
|
11
12
|
IconUsersGroup,
|
|
12
13
|
IconWorld,
|
|
@@ -414,6 +415,17 @@ export function SharePeopleTab({
|
|
|
414
415
|
))}
|
|
415
416
|
</SelectContent>
|
|
416
417
|
</Select>
|
|
418
|
+
<Button
|
|
419
|
+
type="button"
|
|
420
|
+
size="icon"
|
|
421
|
+
onClick={handleAdd}
|
|
422
|
+
disabled={!hasInviteEmail || share.isPending}
|
|
423
|
+
aria-label={t("shareUi.invite")}
|
|
424
|
+
title={t("shareUi.invite")}
|
|
425
|
+
className="h-9 w-9 shrink-0"
|
|
426
|
+
>
|
|
427
|
+
<IconSend2 size={16} />
|
|
428
|
+
</Button>
|
|
417
429
|
</div>
|
|
418
430
|
{hasInviteEmail ? (
|
|
419
431
|
<label className="flex items-center gap-2 text-xs text-muted-foreground">
|