@agent-native/core 0.115.4 → 0.116.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 +28 -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 +1 -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/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 +16 -6
- package/corpus/core/src/connections/catalog.ts +7 -1
- 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/server/collab-plugin.ts +137 -18
- package/corpus/core/src/server/index.ts +2 -0
- 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/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/sidebar/DocumentSidebar.tsx +1 -1
- 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/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 +3 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +17 -6
- package/dist/client/use-db-sync.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/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/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- 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/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/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +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 +3 -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/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 +16 -6
- package/src/connections/catalog.ts +7 -1
- 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/server/collab-plugin.ts +137 -18
- package/src/server/index.ts +2 -0
- 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,182 @@
|
|
|
1
|
+
import { getDbExec } from "@agent-native/core/db";
|
|
2
|
+
import { runWithRequestContext } from "@agent-native/core/server";
|
|
3
|
+
import { and, eq, isNull } from "drizzle-orm";
|
|
4
|
+
|
|
5
|
+
import exportToBrain from "../../actions/export-to-brain.js";
|
|
6
|
+
import { getDb, schema } from "../db/index.js";
|
|
7
|
+
import {
|
|
8
|
+
BRAIN_EXPORT_STATE_PREFIX,
|
|
9
|
+
parseBrainExportState,
|
|
10
|
+
writeBrainExportState,
|
|
11
|
+
} from "../lib/brain-export-state.js";
|
|
12
|
+
import { ownerEmailMatches } from "../lib/recordings.js";
|
|
13
|
+
|
|
14
|
+
const SWEEP_INTERVAL_MS = 60_000;
|
|
15
|
+
const MAX_ATTEMPTS = 8;
|
|
16
|
+
const SWEEP_LIMIT = 4;
|
|
17
|
+
const DISCOVERY_LIMIT = 20;
|
|
18
|
+
const BACKFILL_DAYS = 7;
|
|
19
|
+
let skippingLogged = false;
|
|
20
|
+
|
|
21
|
+
async function seedRecentBrainExports(): Promise<void> {
|
|
22
|
+
const now = new Date();
|
|
23
|
+
const { rows } = await getDbExec().execute({
|
|
24
|
+
sql: `SELECT recordings.id, recordings.owner_email, recordings.org_id
|
|
25
|
+
FROM recordings
|
|
26
|
+
INNER JOIN recording_transcripts
|
|
27
|
+
ON recording_transcripts.recording_id = recordings.id
|
|
28
|
+
WHERE recordings.status = ?
|
|
29
|
+
AND recordings.trashed_at IS NULL
|
|
30
|
+
AND recordings.org_id IS NOT NULL
|
|
31
|
+
AND recordings.created_at >= ?
|
|
32
|
+
AND recording_transcripts.status = ?
|
|
33
|
+
AND LENGTH(TRIM(COALESCE(recording_transcripts.full_text, ''))) > 0
|
|
34
|
+
AND NOT EXISTS (
|
|
35
|
+
SELECT 1 FROM application_state
|
|
36
|
+
WHERE application_state.session_id = recordings.owner_email
|
|
37
|
+
AND application_state.key = ? || recordings.id
|
|
38
|
+
)
|
|
39
|
+
ORDER BY recordings.created_at DESC
|
|
40
|
+
LIMIT ?`,
|
|
41
|
+
args: [
|
|
42
|
+
"ready",
|
|
43
|
+
new Date(
|
|
44
|
+
now.getTime() - BACKFILL_DAYS * 24 * 60 * 60 * 1000,
|
|
45
|
+
).toISOString(),
|
|
46
|
+
"ready",
|
|
47
|
+
BRAIN_EXPORT_STATE_PREFIX,
|
|
48
|
+
DISCOVERY_LIMIT,
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
for (const row of rows as Array<{
|
|
52
|
+
id?: unknown;
|
|
53
|
+
owner_email?: unknown;
|
|
54
|
+
org_id?: unknown;
|
|
55
|
+
}>) {
|
|
56
|
+
const recordingId = typeof row.id === "string" ? row.id.trim() : "";
|
|
57
|
+
const ownerEmail =
|
|
58
|
+
typeof row.owner_email === "string" ? row.owner_email.trim() : "";
|
|
59
|
+
const orgId = typeof row.org_id === "string" ? row.org_id.trim() : "";
|
|
60
|
+
if (!recordingId || !ownerEmail || !orgId) continue;
|
|
61
|
+
await runWithRequestContext({ userEmail: ownerEmail, orgId }, () =>
|
|
62
|
+
writeBrainExportState({
|
|
63
|
+
recordingId,
|
|
64
|
+
status: "pending",
|
|
65
|
+
attempts: 0,
|
|
66
|
+
updatedAt: now.toISOString(),
|
|
67
|
+
nextAttemptAt: now.toISOString(),
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function runBrainExportSweepOnce(): Promise<void> {
|
|
74
|
+
await seedRecentBrainExports();
|
|
75
|
+
const { rows } = await getDbExec().execute({
|
|
76
|
+
sql: "SELECT session_id, key, value FROM application_state WHERE key LIKE ? AND (value LIKE ? OR value LIKE ?) ORDER BY updated_at ASC LIMIT ?",
|
|
77
|
+
args: [
|
|
78
|
+
`${BRAIN_EXPORT_STATE_PREFIX}%`,
|
|
79
|
+
'%"status":"pending"%',
|
|
80
|
+
'%"status":"failed"%',
|
|
81
|
+
SWEEP_LIMIT,
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
const now = Date.now();
|
|
85
|
+
for (const row of rows as Array<{
|
|
86
|
+
session_id?: unknown;
|
|
87
|
+
key?: unknown;
|
|
88
|
+
value?: unknown;
|
|
89
|
+
}>) {
|
|
90
|
+
const ownerEmail =
|
|
91
|
+
typeof row.session_id === "string" ? row.session_id.trim() : "";
|
|
92
|
+
const key = typeof row.key === "string" ? row.key : "";
|
|
93
|
+
const recordingId = key.slice(BRAIN_EXPORT_STATE_PREFIX.length);
|
|
94
|
+
let raw: unknown;
|
|
95
|
+
try {
|
|
96
|
+
raw = JSON.parse(typeof row.value === "string" ? row.value : "");
|
|
97
|
+
} catch {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const state = parseBrainExportState(raw);
|
|
101
|
+
if (
|
|
102
|
+
!ownerEmail ||
|
|
103
|
+
!recordingId ||
|
|
104
|
+
!state ||
|
|
105
|
+
state.recordingId !== recordingId ||
|
|
106
|
+
!["pending", "failed"].includes(state.status) ||
|
|
107
|
+
state.attempts >= MAX_ATTEMPTS ||
|
|
108
|
+
Date.parse(state.nextAttemptAt ?? "") > now
|
|
109
|
+
)
|
|
110
|
+
continue;
|
|
111
|
+
try {
|
|
112
|
+
const [recording] = await getDb()
|
|
113
|
+
.select({
|
|
114
|
+
ownerEmail: schema.recordings.ownerEmail,
|
|
115
|
+
orgId: schema.recordings.orgId,
|
|
116
|
+
})
|
|
117
|
+
.from(schema.recordings)
|
|
118
|
+
.where(
|
|
119
|
+
and(
|
|
120
|
+
eq(schema.recordings.id, recordingId),
|
|
121
|
+
ownerEmailMatches(schema.recordings.ownerEmail, ownerEmail),
|
|
122
|
+
eq(schema.recordings.status, "ready"),
|
|
123
|
+
isNull(schema.recordings.trashedAt),
|
|
124
|
+
),
|
|
125
|
+
)
|
|
126
|
+
.limit(1);
|
|
127
|
+
if (!recording) continue;
|
|
128
|
+
await runWithRequestContext(
|
|
129
|
+
{
|
|
130
|
+
userEmail: recording.ownerEmail,
|
|
131
|
+
orgId: recording.orgId ?? undefined,
|
|
132
|
+
},
|
|
133
|
+
() =>
|
|
134
|
+
exportToBrain.run({ recordingId, retryAttempt: state.attempts + 1 }),
|
|
135
|
+
);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
const attempts = state.attempts + 1;
|
|
138
|
+
await runWithRequestContext({ userEmail: ownerEmail }, () =>
|
|
139
|
+
writeBrainExportState({
|
|
140
|
+
recordingId,
|
|
141
|
+
status: "failed",
|
|
142
|
+
attempts,
|
|
143
|
+
reason: "brain-export-worker-failed",
|
|
144
|
+
updatedAt: new Date().toISOString(),
|
|
145
|
+
nextAttemptAt: new Date(
|
|
146
|
+
Date.now() +
|
|
147
|
+
Math.min(15 * 60_000, 30_000 * 2 ** Math.max(0, attempts - 1)),
|
|
148
|
+
).toISOString(),
|
|
149
|
+
}),
|
|
150
|
+
);
|
|
151
|
+
console.warn("[brain-export] sweep item failed", {
|
|
152
|
+
recordingId,
|
|
153
|
+
error: error instanceof Error ? error.message : String(error),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export default function registerBrainExportJob(): void {
|
|
160
|
+
if (process.env.NETLIFY === "true") return;
|
|
161
|
+
const enabled =
|
|
162
|
+
process.env.RUN_BACKGROUND_JOBS === "1" ||
|
|
163
|
+
(process.env.NODE_ENV === "production" &&
|
|
164
|
+
process.env.RUN_BACKGROUND_JOBS !== "0");
|
|
165
|
+
if (!enabled) {
|
|
166
|
+
if (process.env.DEBUG && !skippingLogged) {
|
|
167
|
+
console.log(
|
|
168
|
+
"[brain-export] Skipping background sweep (set RUN_BACKGROUND_JOBS=1 to enable in dev).",
|
|
169
|
+
);
|
|
170
|
+
skippingLogged = true;
|
|
171
|
+
}
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
setInterval(() => {
|
|
175
|
+
runBrainExportSweepOnce().catch((error) =>
|
|
176
|
+
console.error("[brain-export] interval failed:", error),
|
|
177
|
+
);
|
|
178
|
+
}, SWEEP_INTERVAL_MS);
|
|
179
|
+
console.log(
|
|
180
|
+
`[brain-export] Recurring recovery sweep every ${SWEEP_INTERVAL_MS / 1000}s.`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { writeAppState } from "@agent-native/core/application-state";
|
|
2
|
+
|
|
3
|
+
export const BRAIN_EXPORT_STATE_PREFIX = "clips-brain-export-";
|
|
4
|
+
|
|
5
|
+
export type BrainExportState = {
|
|
6
|
+
recordingId: string;
|
|
7
|
+
status: "pending" | "exported" | "quarantined" | "failed" | "skipped";
|
|
8
|
+
attempts: number;
|
|
9
|
+
updatedAt: string;
|
|
10
|
+
nextAttemptAt?: string;
|
|
11
|
+
captureId?: string;
|
|
12
|
+
sensitivityReceiptId?: string;
|
|
13
|
+
sensitivityDisposition?: string;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function brainExportStateKey(recordingId: string): string {
|
|
18
|
+
return `${BRAIN_EXPORT_STATE_PREFIX}${recordingId}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function writeBrainExportState(state: BrainExportState) {
|
|
22
|
+
await writeAppState(brainExportStateKey(state.recordingId), state);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function parseBrainExportState(value: unknown): BrainExportState | null {
|
|
26
|
+
if (!value || typeof value !== "object") return null;
|
|
27
|
+
const state = value as Partial<BrainExportState>;
|
|
28
|
+
if (
|
|
29
|
+
typeof state.recordingId !== "string" ||
|
|
30
|
+
!state.recordingId ||
|
|
31
|
+
!["pending", "exported", "quarantined", "failed", "skipped"].includes(
|
|
32
|
+
String(state.status),
|
|
33
|
+
) ||
|
|
34
|
+
typeof state.attempts !== "number" ||
|
|
35
|
+
!Number.isInteger(state.attempts) ||
|
|
36
|
+
state.attempts < 0 ||
|
|
37
|
+
typeof state.updatedAt !== "string"
|
|
38
|
+
) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return state as BrainExportState;
|
|
42
|
+
}
|
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
signScopedAgentAccessToken,
|
|
8
8
|
} from "@agent-native/core/server";
|
|
9
9
|
|
|
10
|
-
export type PostFinalizeJobKind =
|
|
10
|
+
export type PostFinalizeJobKind =
|
|
11
|
+
| "media-ready"
|
|
12
|
+
| "seekable"
|
|
13
|
+
| "transcript"
|
|
14
|
+
| "brain-export";
|
|
11
15
|
|
|
12
16
|
export const POST_FINALIZE_JOB_TOKEN_KIND = "clips-post-finalize-job";
|
|
13
17
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* pattern).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import registerBrainExportJob from "../jobs/brain-export.js";
|
|
8
9
|
import registerBuilderMediaCompressionJob from "../jobs/builder-media-compression.js";
|
|
9
10
|
import registerMediaVerificationJob from "../jobs/media-verification.js";
|
|
10
11
|
import registerMeetingRemindersJob from "../jobs/meeting-reminders.js";
|
|
@@ -17,6 +18,7 @@ export default () => {
|
|
|
17
18
|
// background loop is off.
|
|
18
19
|
registerMeetingRemindersJob();
|
|
19
20
|
registerBuilderMediaCompressionJob();
|
|
21
|
+
registerBrainExportJob();
|
|
20
22
|
registerMediaVerificationJob();
|
|
21
23
|
registerPollCalendarsJob();
|
|
22
24
|
registerStaleMeetingSweeperJob();
|
|
@@ -219,6 +219,48 @@ registerRequiredSecret({
|
|
|
219
219
|
required: false,
|
|
220
220
|
});
|
|
221
221
|
|
|
222
|
+
// ── Brain transcript ingest ──────────────────────────────────────────
|
|
223
|
+
// Both values are workspace-scoped: every clip in the workspace must reach
|
|
224
|
+
// the same Brain source, while the encrypted secret store keeps the token out
|
|
225
|
+
// of action responses, application state, and client bundles.
|
|
226
|
+
|
|
227
|
+
registerRequiredSecret({
|
|
228
|
+
key: "BRAIN_INGEST_URL",
|
|
229
|
+
label: "Brain ingest URL",
|
|
230
|
+
description:
|
|
231
|
+
"Signed Brain generic-ingest endpoint for ready Clips transcripts. Pair with BRAIN_INGEST_TOKEN.",
|
|
232
|
+
scope: "workspace",
|
|
233
|
+
kind: "api-key",
|
|
234
|
+
required: false,
|
|
235
|
+
validator: (value) => {
|
|
236
|
+
if (!value) return true;
|
|
237
|
+
try {
|
|
238
|
+
const url = new URL(value);
|
|
239
|
+
return url.protocol === "http:" || url.protocol === "https:"
|
|
240
|
+
? true
|
|
241
|
+
: { ok: false, error: "Use an HTTP or HTTPS URL." };
|
|
242
|
+
} catch {
|
|
243
|
+
return { ok: false, error: "Enter a valid ingest URL." };
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
registerRequiredSecret({
|
|
249
|
+
key: "BRAIN_INGEST_TOKEN",
|
|
250
|
+
label: "Brain ingest token",
|
|
251
|
+
description:
|
|
252
|
+
"Bearer token for the configured Brain ingest URL. Stored encrypted and never returned to Clips clients or export receipts.",
|
|
253
|
+
scope: "workspace",
|
|
254
|
+
kind: "api-key",
|
|
255
|
+
required: false,
|
|
256
|
+
validator: (value) => {
|
|
257
|
+
if (!value) return true;
|
|
258
|
+
return typeof value === "string" && value.trim().length >= 8
|
|
259
|
+
? true
|
|
260
|
+
: { ok: false, error: "Token looks too short." };
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
|
|
222
264
|
// ── Dark-launched media worker plumbing ──────────────────────────────
|
|
223
265
|
// These are optional until the ai-services worker is deployed. When enabled,
|
|
224
266
|
// Clips enqueues background video compression jobs there instead of using
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "h3";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
+
import exportToBrain from "../../../../actions/export-to-brain.js";
|
|
14
15
|
import finalizeRecording from "../../../../actions/finalize-recording.js";
|
|
15
16
|
import { ensureRecordingSeekable } from "../../../../actions/lib/ensure-seekable-video.js";
|
|
16
17
|
import requestTranscript from "../../../../actions/request-transcript.js";
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
|
|
24
25
|
const bodySchema = z.object({
|
|
25
26
|
recordingId: z.string().min(1).max(200),
|
|
26
|
-
kind: z.enum(["media-ready", "seekable", "transcript"]),
|
|
27
|
+
kind: z.enum(["media-ready", "seekable", "transcript", "brain-export"]),
|
|
27
28
|
token: z.string().min(1),
|
|
28
29
|
delayMs: z.number().int().min(0).max(30_000).optional(),
|
|
29
30
|
retryAttempt: z.number().int().min(1).max(10).optional(),
|
|
@@ -111,6 +112,14 @@ export default defineEventHandler(async (event: H3Event) => {
|
|
|
111
112
|
return { ok: true, kind, result };
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
if (kind === "brain-export") {
|
|
116
|
+
const result = await exportToBrain.run({
|
|
117
|
+
recordingId,
|
|
118
|
+
retryAttempt,
|
|
119
|
+
});
|
|
120
|
+
return { ok: true, kind, result };
|
|
121
|
+
}
|
|
122
|
+
|
|
114
123
|
const result = await requestTranscript.run({
|
|
115
124
|
recordingId,
|
|
116
125
|
force: true,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { createError, defineEventHandler, getHeader } from "h3";
|
|
4
|
+
|
|
5
|
+
import { runBrainExportSweepOnce } from "../../../../jobs/brain-export.js";
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
var __AGENT_NATIVE_CLIPS_BRAIN_EXPORT_SCHEDULED_RUNTIME__:
|
|
9
|
+
| boolean
|
|
10
|
+
| undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function productionLike() {
|
|
14
|
+
return (
|
|
15
|
+
process.env.NODE_ENV === "production" || process.env.NETLIFY === "true"
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function headerMatchesSecret(header: string | undefined, secret: string) {
|
|
20
|
+
const expected = `Bearer ${secret}`;
|
|
21
|
+
const value = header?.trim() ?? "";
|
|
22
|
+
return (
|
|
23
|
+
value.length === expected.length &&
|
|
24
|
+
timingSafeEqual(Buffer.from(value), Buffer.from(expected))
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default defineEventHandler(async (event) => {
|
|
29
|
+
const scheduled =
|
|
30
|
+
globalThis.__AGENT_NATIVE_CLIPS_BRAIN_EXPORT_SCHEDULED_RUNTIME__ === true;
|
|
31
|
+
const secret = process.env.CLIPS_BRAIN_EXPORT_JOBS_SECRET?.trim(); // guard:allow-env-credential — deployment scheduler route secret
|
|
32
|
+
if (!secret && productionLike() && !scheduled)
|
|
33
|
+
throw createError({
|
|
34
|
+
statusCode: 503,
|
|
35
|
+
statusMessage: "CLIPS_BRAIN_EXPORT_JOBS_SECRET is required",
|
|
36
|
+
});
|
|
37
|
+
if (
|
|
38
|
+
secret &&
|
|
39
|
+
!scheduled &&
|
|
40
|
+
!headerMatchesSecret(getHeader(event, "authorization"), secret)
|
|
41
|
+
)
|
|
42
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
43
|
+
await runBrainExportSweepOnce();
|
|
44
|
+
return { ok: true };
|
|
45
|
+
});
|
|
@@ -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
|
|
|
@@ -2093,7 +2093,7 @@ export function DocumentSidebar({
|
|
|
2093
2093
|
{/* Footer */}
|
|
2094
2094
|
<div className="shrink-0 space-y-2 px-3 py-2">
|
|
2095
2095
|
{isCodeMode ? <DevDatabaseLink /> : null}
|
|
2096
|
-
<div className="flex items-center gap-1">
|
|
2096
|
+
<div className="flex items-center justify-end gap-1">
|
|
2097
2097
|
<FeedbackButton className="h-8 min-w-0 flex-1 gap-2 rounded-md px-2 py-0" />
|
|
2098
2098
|
<div className="flex shrink-0 items-center gap-0.5">
|
|
2099
2099
|
<NotionButton />
|
|
@@ -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
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { initDataPrograms } from "@agent-native/core/data-programs";
|
|
2
|
+
|
|
3
|
+
import { CRM_APP_ID } from "../server/lib/provider-api.js";
|
|
4
|
+
import getCrmPipelineData from "./get-crm-pipeline-data.js";
|
|
5
|
+
|
|
6
|
+
export function getCrmDataProgramActions() {
|
|
7
|
+
return { "get-crm-pipeline-data": getCrmPipelineData };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function initCrmDataPrograms(): void {
|
|
11
|
+
initDataPrograms({
|
|
12
|
+
appId: CRM_APP_ID,
|
|
13
|
+
getActions: getCrmDataProgramActions,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -5,6 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
import { crmDashboardStore } from "../server/db/index.js";
|
|
6
6
|
import { CRM_APP_ID } from "../server/lib/provider-api.js";
|
|
7
7
|
import { requireDashboardAccess } from "./_crm-dashboard.js";
|
|
8
|
+
import { initCrmDataPrograms } from "./_crm-data-program-actions.js";
|
|
8
9
|
|
|
9
10
|
const programResolver = createProgramPanelSourceResolver({ appId: CRM_APP_ID });
|
|
10
11
|
|
|
@@ -25,6 +26,7 @@ export default defineAction({
|
|
|
25
26
|
if (!dashboard) throw new Error("CRM dashboard was not found.");
|
|
26
27
|
const panel = dashboard.config.panels.find((item) => item.id === panelId);
|
|
27
28
|
if (!panel) throw new Error("CRM dashboard panel was not found.");
|
|
29
|
+
initCrmDataPrograms();
|
|
28
30
|
return programResolver.resolve(
|
|
29
31
|
{ source: panel.source, query: panel.query },
|
|
30
32
|
{ userEmail: access.userEmail, orgId: access.orgId ?? null },
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { initDataPrograms } from "@agent-native/core/data-programs";
|
|
2
1
|
import { runScript } from "@agent-native/core/scripts";
|
|
3
2
|
|
|
4
|
-
import
|
|
3
|
+
import { initCrmDataPrograms } from "./_crm-data-program-actions.js";
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
appId: "crm",
|
|
8
|
-
getActions: () => ({ "get-crm-pipeline-data": getCrmPipelineData }),
|
|
9
|
-
});
|
|
5
|
+
initCrmDataPrograms();
|
|
10
6
|
|
|
11
7
|
runScript();
|
|
@@ -272,9 +272,11 @@ export default defineAction({
|
|
|
272
272
|
);
|
|
273
273
|
});
|
|
274
274
|
if (missing.length || blocked.length) {
|
|
275
|
-
|
|
275
|
+
const error = new Error(
|
|
276
276
|
`Only discovered, updateable CRM fields can be changed. Unsupported: ${[...new Set([...missing, ...blocked])].join(", ")}`,
|
|
277
|
-
);
|
|
277
|
+
) as Error & { statusCode?: number };
|
|
278
|
+
error.statusCode = 422;
|
|
279
|
+
throw error;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
const wrongAuthority = fieldNames.filter((fieldName) => {
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
focusAgentChat,
|
|
5
5
|
navigateWithAgentChatViewTransition,
|
|
6
6
|
useAgentChatHomeHandoff,
|
|
7
|
+
useAgentChatHomeHandoffLinks,
|
|
7
8
|
} from "@agent-native/core/client/agent-chat";
|
|
8
9
|
import { Button } from "@agent-native/toolkit/ui/button";
|
|
9
10
|
import {
|
|
@@ -29,6 +30,11 @@ export function CrmLayout({ children }: { children: React.ReactNode }) {
|
|
|
29
30
|
activePath: location.pathname,
|
|
30
31
|
enabled: !isAskRoute,
|
|
31
32
|
});
|
|
33
|
+
useAgentChatHomeHandoffLinks({
|
|
34
|
+
storageKey: "crm",
|
|
35
|
+
chatPath: "/ask",
|
|
36
|
+
requireActiveHandoff: false,
|
|
37
|
+
});
|
|
32
38
|
|
|
33
39
|
useEffect(() => setMobileOpen(false), [location.pathname]);
|
|
34
40
|
|
|
@@ -751,7 +751,10 @@ export class HubSpotCrmAdapter implements CrmAdapter {
|
|
|
751
751
|
}
|
|
752
752
|
if (scope.updatedAfter) {
|
|
753
753
|
filters.push({
|
|
754
|
-
propertyName:
|
|
754
|
+
propertyName:
|
|
755
|
+
scope.objectType.toLowerCase() === "contacts"
|
|
756
|
+
? "lastmodifieddate"
|
|
757
|
+
: "hs_lastmodifieddate",
|
|
755
758
|
operator: "GTE",
|
|
756
759
|
value: scope.updatedAfter,
|
|
757
760
|
});
|
|
@@ -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
|
|
@@ -168,7 +168,7 @@ export function Sidebar() {
|
|
|
168
168
|
|
|
169
169
|
<div className="px-3 py-2">
|
|
170
170
|
<DevDatabaseLink />
|
|
171
|
-
<div className="flex items-center gap-1">
|
|
171
|
+
<div className="flex items-center justify-end gap-1">
|
|
172
172
|
<FeedbackButton className="min-w-0 flex-1" />
|
|
173
173
|
<ThemeToggle className="h-8 w-8 shrink-0" />
|
|
174
174
|
</div>
|
|
@@ -8,13 +8,16 @@ export default createCollabPlugin({
|
|
|
8
8
|
contentColumn: "content",
|
|
9
9
|
idColumn: "id",
|
|
10
10
|
autoSeed: true,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
access: {
|
|
12
|
+
mode: "resource",
|
|
13
|
+
resourceType: "design",
|
|
14
|
+
resolveResourceId: async (docId) => {
|
|
15
|
+
const db = getDb();
|
|
16
|
+
const [file] = await db
|
|
17
|
+
.select({ designId: schema.designFiles.designId })
|
|
18
|
+
.from(schema.designFiles)
|
|
19
|
+
.where(eq(schema.designFiles.id, docId));
|
|
20
|
+
return file?.designId ?? null;
|
|
21
|
+
},
|
|
19
22
|
},
|
|
20
23
|
});
|
|
@@ -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
|
|
@@ -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
|
|