@agent-native/core 0.90.11 → 0.91.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +34 -0
- package/corpus/core/docs/content/toolkit-settings.mdx +56 -3
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/run-ownership.ts +29 -1
- package/corpus/core/src/changelog/parse.ts +78 -0
- package/corpus/core/src/chat-threads/schema.ts +43 -0
- package/corpus/core/src/chat-threads/store.ts +144 -12
- package/corpus/core/src/cli/design-connect.ts +53 -9
- package/corpus/core/src/cli/workspace-dev.ts +25 -5
- package/corpus/core/src/client/AgentPanel.tsx +79 -14
- package/corpus/core/src/client/AssistantChat.tsx +359 -425
- package/corpus/core/src/client/analytics-session.ts +70 -0
- package/corpus/core/src/client/analytics.ts +175 -49
- package/corpus/core/src/client/chat/message-components.tsx +22 -2
- package/corpus/core/src/client/components/ui/message-scroller.tsx +131 -0
- package/corpus/core/src/client/conversation/AgentConversation.tsx +63 -41
- package/corpus/core/src/client/error-capture.ts +616 -0
- package/corpus/core/src/client/index.ts +12 -0
- package/corpus/core/src/client/session-replay.ts +57 -7
- package/corpus/core/src/client/settings/SettingsPanel.tsx +123 -1
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +292 -45
- package/corpus/core/src/client/settings/index.ts +1 -0
- package/corpus/core/src/client/sharing/ShareButton.tsx +14 -11
- package/corpus/core/src/client/sharing/ShareDialog.tsx +13 -10
- package/corpus/core/src/mcp/builtin-tools.ts +29 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +174 -79
- package/corpus/core/src/server/onboarding-html.ts +28 -16
- package/corpus/core/src/sharing/actions/list-resource-shares.ts +45 -1
- package/corpus/core/src/sharing/actions/share-resource.ts +9 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
- package/corpus/core/src/vite/client.ts +217 -35
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +8 -7
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +14 -10
- package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +15 -15
- package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -22
- package/corpus/templates/analytics/.agents/skills/data-programs/SKILL.md +114 -61
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +7 -7
- package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +1 -1
- package/corpus/templates/analytics/.builder/skills/bigquery/SKILL.md +17 -17
- package/corpus/templates/analytics/.builder/skills/gcloud/SKILL.md +5 -5
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +7 -7
- package/corpus/templates/analytics/.builder/skills/gong/SKILL.md +12 -12
- package/corpus/templates/analytics/.builder/skills/grafana/SKILL.md +7 -7
- package/corpus/templates/analytics/.builder/skills/sentry/SKILL.md +7 -7
- package/corpus/templates/analytics/.builder/skills/slack/SKILL.md +6 -6
- package/corpus/templates/analytics/.builder/skills/stripe/SKILL.md +7 -7
- package/corpus/templates/analytics/AGENTS.md +47 -2
- package/corpus/templates/analytics/actions/add-status-page-monitor.ts +36 -0
- package/corpus/templates/analytics/actions/capture-test-error.ts +33 -0
- package/corpus/templates/analytics/actions/delete-monitor.ts +24 -0
- package/corpus/templates/analytics/actions/delete-status-page.ts +23 -0
- package/corpus/templates/analytics/actions/get-error-issue.ts +36 -0
- package/corpus/templates/analytics/actions/get-monitor-stats.ts +55 -0
- package/corpus/templates/analytics/actions/get-monitor.ts +27 -0
- package/corpus/templates/analytics/actions/get-public-status-page.ts +41 -0
- package/corpus/templates/analytics/actions/get-status-page.ts +29 -0
- package/corpus/templates/analytics/actions/list-error-issues.ts +40 -0
- package/corpus/templates/analytics/actions/list-monitors.ts +21 -0
- package/corpus/templates/analytics/actions/list-status-pages.ts +21 -0
- package/corpus/templates/analytics/actions/match-error-issues.ts +51 -0
- package/corpus/templates/analytics/actions/navigate.ts +58 -4
- package/corpus/templates/analytics/actions/remove-status-page-monitor.ts +22 -0
- package/corpus/templates/analytics/actions/reorder-status-page-monitors.ts +25 -0
- package/corpus/templates/analytics/actions/resolve-error-issue.ts +38 -0
- package/corpus/templates/analytics/actions/run-monitor-check.ts +23 -0
- package/corpus/templates/analytics/actions/save-analysis.ts +1 -0
- package/corpus/templates/analytics/actions/save-monitor.ts +145 -0
- package/corpus/templates/analytics/actions/save-status-page.ts +47 -0
- package/corpus/templates/analytics/actions/view-screen.ts +212 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +10 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +134 -39
- package/corpus/templates/analytics/app/components/monitoring/PublicStatusView.tsx +351 -0
- package/corpus/templates/analytics/app/components/monitoring/ResponseTimeChart.tsx +174 -0
- package/corpus/templates/analytics/app/components/monitoring/UptimeStatCards.tsx +85 -0
- package/corpus/templates/analytics/app/components/monitoring/UptimeTimelineBars.tsx +106 -0
- package/corpus/templates/analytics/app/components/monitoring/chart-utils.ts +101 -0
- package/corpus/templates/analytics/app/components/monitoring/index.ts +28 -0
- package/corpus/templates/analytics/app/components/monitoring/types.ts +42 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +34 -0
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -0
- package/corpus/templates/analytics/app/i18n-data.ts +33 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +28 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +77 -9
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +3 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +7 -0
- package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +205 -0
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +100 -0
- package/corpus/templates/analytics/app/pages/monitoring/UptimePanel.tsx +475 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +372 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +360 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/Sparkline.tsx +55 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +106 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +75 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/utils.ts +132 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorDetail.tsx +535 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +1026 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorList.tsx +311 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +235 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPageEditor.tsx +661 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPagesView.tsx +355 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/i18n.ts +106 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/slug.ts +24 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/types.ts +20 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-summary.ts +87 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +161 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/utils.ts +210 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +76 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +74 -9
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +197 -20
- package/corpus/templates/analytics/app/root.tsx +33 -1
- package/corpus/templates/analytics/app/routes/monitoring._index.tsx +10 -0
- package/corpus/templates/analytics/app/routes/status.$slug.tsx +118 -0
- package/corpus/templates/analytics/changelog/2026-07-08-add-uptime-monitors-that-ping-your-urls-and-alert-you-when-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-analytics-chats-keep-large-data-dictionaries-compact-so-prov.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-create-public-status-pages-that-share-the-live-health-of-cho.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-extension-panels-use-clearer-open-copy.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-error-capture.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-fixed-single-panel-dashboard-drags-so-they-no-longer-rewrite.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-jump-straight-from-an-error-in-a-session-recording-to-its-fu.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitor-detail-and-list-now-show-colorful-uptime-timelines-r.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-pinned-ask-chats-now-show-a-pin-icon-in-the-sidebar.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-publish-a-public-uptime-status-page-with-colorful-uptime-tim.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sessions-now-hide-visitor-emails-in-demo-mode-and-show-clean.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +5 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +5 -0
- package/corpus/templates/analytics/changelog/2026-07-08-the-uptime-monitor-list-now-has-a-current-status-overview-wi.md +6 -0
- package/corpus/templates/analytics/docs/error-capture.md +172 -0
- package/corpus/templates/analytics/docs/uptime-monitoring.md +150 -0
- package/corpus/templates/analytics/server/db/schema-errors.ts +150 -0
- package/corpus/templates/analytics/server/db/schema-monitoring.ts +177 -0
- package/corpus/templates/analytics/server/db/schema.ts +6 -0
- package/corpus/templates/analytics/server/jobs/uptime-monitors.ts +123 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +41 -0
- package/corpus/templates/analytics/server/lib/data-dictionary-context.ts +55 -12
- package/corpus/templates/analytics/server/lib/error-capture.ts +1331 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +47 -1
- package/corpus/templates/analytics/server/lib/monitor-stats.ts +494 -0
- package/corpus/templates/analytics/server/lib/status-pages.ts +798 -0
- package/corpus/templates/analytics/server/lib/uptime-monitors.ts +1665 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -37
- package/corpus/templates/analytics/server/plugins/auth.ts +11 -1
- package/corpus/templates/analytics/server/plugins/db.ts +408 -0
- package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +63 -0
- package/corpus/templates/assets/app/routes/_index.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.tsx +22 -1
- package/corpus/templates/assets/changelog/2026-07-08-recent-drafts-keep-comfortable-side-padding.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/brain/app/routes/settings.tsx +43 -5
- package/corpus/templates/brain/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +44 -6
- package/corpus/templates/calendar/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/chat/app/routes/settings.tsx +16 -1
- package/corpus/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +79 -37
- package/corpus/templates/clips/app/components/player/player-controls.tsx +35 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +162 -18
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +63 -6
- package/corpus/templates/clips/app/routes/record.tsx +18 -1
- package/corpus/templates/clips/changelog/2026-07-07-shared-clips-start-playback-reliably-from-the-first-play-click.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-camera-and-microphone-menus-now-show-which-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-copies-new-clip-links-after-saving.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-recordings-now-continue-after-granting-came.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-mobile-shared-clips-now-have-loom-style-tap-and-skip-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-recordings-and-uploads-copy-links-after-saving.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-settings-are-cleaner-searchable-and-collapse-s3-with-builder.md +5 -0
- package/corpus/templates/clips/changelog/2026-07-08-transcripts-are-more-reliable-for-longer-desktop-recordings-.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +162 -13
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +14 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +36 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +99 -25
- package/corpus/templates/clips/chrome-extension/src/permission.ts +63 -14
- package/corpus/templates/clips/chrome-extension/src/popup.ts +123 -23
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +47 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +33 -4
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +214 -29
- package/corpus/templates/content/actions/attach-content-database-source.ts +3 -0
- package/corpus/templates/content/actions/change-content-database-source-role.ts +1 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +42 -32
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +352 -81
- package/corpus/templates/content/app/components/editor/database/settings.tsx +49 -24
- package/corpus/templates/content/app/routes/_app.settings.tsx +19 -1
- package/corpus/templates/content/changelog/2026-07-07-builder-source-tag-fields-now-import-as-multi-select.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/content/shared/api.ts +3 -0
- package/corpus/templates/content/shared/properties.ts +42 -0
- package/corpus/templates/design/AGENTS.md +9 -0
- package/corpus/templates/design/actions/generate-design.ts +3 -0
- package/corpus/templates/design/actions/get-design-system.ts +147 -1
- package/corpus/templates/design/actions/request-localhost-write-consent.ts +141 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +13 -19
- package/corpus/templates/design/app/routes/settings.tsx +16 -1
- package/corpus/templates/design/changelog/2026-07-08-design-generation-now-follows-hydrated-builder-design-system.md +6 -0
- package/corpus/templates/design/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/design/server/lib/verify-write-grant.ts +4 -2
- package/corpus/templates/dispatch/app/routes/settings.tsx +23 -2
- package/corpus/templates/dispatch/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +16 -1
- package/corpus/templates/forms/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/macros/app/routes/settings.tsx +16 -1
- package/corpus/templates/macros/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/mail/app/components/settings/GmailFiltersSection.tsx +1 -1
- package/corpus/templates/mail/app/components/settings/SnippetsSection.tsx +1 -1
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +123 -105
- package/corpus/templates/mail/changelog/2026-07-08-settings-redesigned-with-a-consistent-searchable-layout.md +5 -0
- package/corpus/templates/plan/app/routes/settings.tsx +23 -2
- package/corpus/templates/plan/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/slides/actions/add-slide.ts +1 -0
- package/corpus/templates/slides/actions/get-design-system.ts +147 -1
- package/corpus/templates/slides/app/pages/Index.tsx +46 -1
- package/corpus/templates/slides/app/routes/settings.tsx +16 -1
- package/corpus/templates/slides/changelog/2026-07-08-deck-generation-now-follows-hydrated-builder-design-system-g.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/dist/agent/run-ownership.d.ts +6 -0
- package/dist/agent/run-ownership.d.ts.map +1 -1
- package/dist/agent/run-ownership.js +11 -1
- package/dist/agent/run-ownership.js.map +1 -1
- package/dist/changelog/parse.d.ts +7 -0
- package/dist/changelog/parse.d.ts.map +1 -1
- package/dist/changelog/parse.js +64 -0
- package/dist/changelog/parse.js.map +1 -1
- package/dist/chat-threads/schema.d.ts +445 -0
- package/dist/chat-threads/schema.d.ts.map +1 -0
- package/dist/chat-threads/schema.js +39 -0
- package/dist/chat-threads/schema.js.map +1 -0
- package/dist/chat-threads/store.d.ts +12 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +99 -10
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +40 -10
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +20 -5
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +35 -7
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +105 -183
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/analytics-session.d.ts +3 -0
- package/dist/client/analytics-session.d.ts.map +1 -0
- package/dist/client/analytics-session.js +66 -0
- package/dist/client/analytics-session.js.map +1 -0
- package/dist/client/analytics.d.ts +32 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +116 -46
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +2 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +16 -6
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/components/ui/message-scroller.d.ts +16 -0
- package/dist/client/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/client/components/ui/message-scroller.js +25 -0
- package/dist/client/components/ui/message-scroller.js.map +1 -0
- package/dist/client/conversation/AgentConversation.d.ts +1 -1
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +3 -8
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/error-capture.d.ts +99 -0
- package/dist/client/error-capture.d.ts.map +1 -0
- package/dist/client/error-capture.js +437 -0
- package/dist/client/error-capture.js.map +1 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/session-replay.d.ts +22 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +45 -4
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +100 -5
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts +49 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +131 -19
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/settings/index.d.ts +1 -1
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +13 -8
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +12 -7
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +21 -2
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/org/schema.d.ts +15 -15
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +109 -73
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +28 -16
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/sharing/actions/list-resource-shares.js +30 -1
- package/dist/sharing/actions/list-resource-shares.js.map +1 -1
- package/dist/sharing/actions/share-resource.js +6 -0
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
- package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +192 -30
- package/dist/vite/client.js.map +1 -1
- package/docs/content/toolkit-settings.mdx +56 -3
- package/package.json +2 -1
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
- package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
|
@@ -64,7 +64,10 @@ import {
|
|
|
64
64
|
type ActionEntry,
|
|
65
65
|
} from "../agent/production-agent.js";
|
|
66
66
|
import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume.js";
|
|
67
|
-
import {
|
|
67
|
+
import {
|
|
68
|
+
callerHasRunAccess,
|
|
69
|
+
callerHasThreadAccess,
|
|
70
|
+
} from "../agent/run-ownership.js";
|
|
68
71
|
import type { AgentRunSummary } from "../agent/run-store.js";
|
|
69
72
|
import {
|
|
70
73
|
CLAIMED_BACKGROUND_WORKER_FAILED_ERROR_EVENT,
|
|
@@ -101,6 +104,8 @@ import {
|
|
|
101
104
|
createThread,
|
|
102
105
|
forkThread,
|
|
103
106
|
getThread,
|
|
107
|
+
registerChatThreadsShareable,
|
|
108
|
+
resolveThreadAccess,
|
|
104
109
|
listThreads,
|
|
105
110
|
searchThreads,
|
|
106
111
|
renameThread,
|
|
@@ -1963,8 +1968,10 @@ async function createChatScriptEntries(): Promise<Record<string, ActionEntry>> {
|
|
|
1963
1968
|
const owner =
|
|
1964
1969
|
getRequestRunContext()?.owner ?? getRequestUserEmail() ?? "";
|
|
1965
1970
|
if (!owner) return "No authenticated user is available.";
|
|
1966
|
-
const thread = await
|
|
1967
|
-
|
|
1971
|
+
const thread = await resolveThreadAccess(owner, id, "editor", {
|
|
1972
|
+
orgId: getRequestOrgId(),
|
|
1973
|
+
});
|
|
1974
|
+
if (!thread) {
|
|
1968
1975
|
return `Chat thread "${id}" not found.`;
|
|
1969
1976
|
}
|
|
1970
1977
|
const title = thread.title || thread.preview || "(untitled)";
|
|
@@ -1974,23 +1981,17 @@ async function createChatScriptEntries(): Promise<Record<string, ActionEntry>> {
|
|
|
1974
1981
|
? args.title.replace(/\s+/g, " ").trim().slice(0, 160)
|
|
1975
1982
|
: "";
|
|
1976
1983
|
if (!nextTitle) return "Missing required title.";
|
|
1977
|
-
const renamed = await renameThread(id, nextTitle
|
|
1978
|
-
ownerEmail: owner,
|
|
1979
|
-
});
|
|
1984
|
+
const renamed = await renameThread(id, nextTitle);
|
|
1980
1985
|
if (!renamed) return `Chat thread "${id}" could not be renamed.`;
|
|
1981
1986
|
return `Renamed chat "${title}" to "${nextTitle}".`;
|
|
1982
1987
|
}
|
|
1983
1988
|
if (args.action === "archive") {
|
|
1984
|
-
const archived = await setThreadArchived(id, true
|
|
1985
|
-
ownerEmail: owner,
|
|
1986
|
-
});
|
|
1989
|
+
const archived = await setThreadArchived(id, true);
|
|
1987
1990
|
if (!archived)
|
|
1988
1991
|
return `Chat thread "${id}" could not be archived.`;
|
|
1989
1992
|
return `Archived chat: ${title}`;
|
|
1990
1993
|
}
|
|
1991
|
-
const pinned = await setThreadPinned(id, args.action === "pin"
|
|
1992
|
-
ownerEmail: owner,
|
|
1993
|
-
});
|
|
1994
|
+
const pinned = await setThreadPinned(id, args.action === "pin");
|
|
1994
1995
|
if (!pinned) return `Chat thread "${id}" could not be updated.`;
|
|
1995
1996
|
return `${args.action === "pin" ? "Pinned" : "Unpinned"} chat: ${title}`;
|
|
1996
1997
|
}
|
|
@@ -5304,6 +5305,17 @@ export function createAgentChatPlugin(
|
|
|
5304
5305
|
): Promise<string | undefined> => {
|
|
5305
5306
|
return (await resolveOwnerContext(event)).name;
|
|
5306
5307
|
};
|
|
5308
|
+
const getOrgIdFromEvent = async (
|
|
5309
|
+
event: any,
|
|
5310
|
+
): Promise<string | undefined> => {
|
|
5311
|
+
if (options?.resolveOrgId) {
|
|
5312
|
+
return (await options.resolveOrgId(event)) ?? undefined;
|
|
5313
|
+
}
|
|
5314
|
+
const session = await getSession(event).catch(() => null);
|
|
5315
|
+
return session?.orgId ?? undefined;
|
|
5316
|
+
};
|
|
5317
|
+
|
|
5318
|
+
registerChatThreadsShareable();
|
|
5307
5319
|
|
|
5308
5320
|
// Auto-mount template actions as HTTP endpoints under /_agent-native/actions/
|
|
5309
5321
|
// Include engine management script so the UI can call manage-agent-engine.
|
|
@@ -5375,15 +5387,6 @@ export function createAgentChatPlugin(
|
|
|
5375
5387
|
`Agent chat thread ${threadId} was not found while saving run ${run.runId}.`,
|
|
5376
5388
|
);
|
|
5377
5389
|
}
|
|
5378
|
-
const runOwner =
|
|
5379
|
-
getRequestRunContext()?.owner ?? getRequestUserEmail();
|
|
5380
|
-
if (runOwner && thread.ownerEmail !== runOwner) {
|
|
5381
|
-
throw createError({
|
|
5382
|
-
statusCode: 404,
|
|
5383
|
-
statusMessage: "Thread not found",
|
|
5384
|
-
});
|
|
5385
|
-
}
|
|
5386
|
-
|
|
5387
5390
|
const assistantMsg = buildAssistantMessage(
|
|
5388
5391
|
run.events ?? [],
|
|
5389
5392
|
run.runId,
|
|
@@ -5595,7 +5598,19 @@ export function createAgentChatPlugin(
|
|
|
5595
5598
|
thread = await getThread(threadId);
|
|
5596
5599
|
}
|
|
5597
5600
|
}
|
|
5598
|
-
if (!thread
|
|
5601
|
+
if (!thread) {
|
|
5602
|
+
throw createError({
|
|
5603
|
+
statusCode: 404,
|
|
5604
|
+
statusMessage: "Thread not found",
|
|
5605
|
+
});
|
|
5606
|
+
}
|
|
5607
|
+
const access = await resolveThreadAccess(
|
|
5608
|
+
ownerEmail,
|
|
5609
|
+
threadId,
|
|
5610
|
+
"editor",
|
|
5611
|
+
{ orgId: getRequestOrgId() },
|
|
5612
|
+
);
|
|
5613
|
+
if (!access) {
|
|
5599
5614
|
throw createError({
|
|
5600
5615
|
statusCode: 404,
|
|
5601
5616
|
statusMessage: "Thread not found",
|
|
@@ -5972,6 +5987,23 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5972
5987
|
if (runCtxForPrepare && details.threadId) {
|
|
5973
5988
|
(runCtxForPrepare as any)._requestThreadId = details.threadId;
|
|
5974
5989
|
}
|
|
5990
|
+
if (details.threadId && details.ownerEmail) {
|
|
5991
|
+
const existingThread = await getThread(details.threadId);
|
|
5992
|
+
if (existingThread) {
|
|
5993
|
+
const access = await resolveThreadAccess(
|
|
5994
|
+
details.ownerEmail,
|
|
5995
|
+
details.threadId,
|
|
5996
|
+
"editor",
|
|
5997
|
+
{ orgId: await getOrgIdFromEvent(details.event) },
|
|
5998
|
+
);
|
|
5999
|
+
if (!access) {
|
|
6000
|
+
throw createError({
|
|
6001
|
+
statusCode: 404,
|
|
6002
|
+
statusMessage: "Thread not found",
|
|
6003
|
+
});
|
|
6004
|
+
}
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
5975
6007
|
|
|
5976
6008
|
// Drain any parent-completion injections queued by finished sub-agents
|
|
5977
6009
|
// and prepend them to the user message so the orchestrator sees results
|
|
@@ -6193,7 +6225,30 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
6193
6225
|
runNoProgressTimeoutMs: options?.runNoProgressTimeoutMs,
|
|
6194
6226
|
durableBackgroundRuns: options?.durableBackgroundRuns,
|
|
6195
6227
|
finalResponseGuard: options?.finalResponseGuard,
|
|
6196
|
-
prepareRequest:
|
|
6228
|
+
prepareRequest: async (details) => {
|
|
6229
|
+
const runCtxForPrepare = ensureRequestRunContext();
|
|
6230
|
+
if (runCtxForPrepare && details.threadId) {
|
|
6231
|
+
(runCtxForPrepare as any)._requestThreadId = details.threadId;
|
|
6232
|
+
}
|
|
6233
|
+
if (details.threadId && details.ownerEmail) {
|
|
6234
|
+
const existingThread = await getThread(details.threadId);
|
|
6235
|
+
if (existingThread) {
|
|
6236
|
+
const access = await resolveThreadAccess(
|
|
6237
|
+
details.ownerEmail,
|
|
6238
|
+
details.threadId,
|
|
6239
|
+
"editor",
|
|
6240
|
+
{ orgId: await getOrgIdFromEvent(details.event) },
|
|
6241
|
+
);
|
|
6242
|
+
if (!access) {
|
|
6243
|
+
throw createError({
|
|
6244
|
+
statusCode: 404,
|
|
6245
|
+
statusMessage: "Thread not found",
|
|
6246
|
+
});
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
}
|
|
6250
|
+
return options?.prepareRequest?.(details);
|
|
6251
|
+
},
|
|
6197
6252
|
skipFilesContext,
|
|
6198
6253
|
initialToolNames: options?.initialToolNames,
|
|
6199
6254
|
...(options?.toolLimits ? { toolLimits: options.toolLimits } : {}),
|
|
@@ -7290,19 +7345,19 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7290
7345
|
|
|
7291
7346
|
const method = getMethod(event);
|
|
7292
7347
|
const url = event.node?.req?.url || event.path || "";
|
|
7348
|
+
const orgId = await getOrgIdFromEvent(event);
|
|
7293
7349
|
|
|
7294
|
-
// Authorization: a run's events
|
|
7295
|
-
//
|
|
7350
|
+
// Authorization: a run's events and a thread's active-run status are
|
|
7351
|
+
// visible to anyone with viewer+ access to the thread. Mutating run
|
|
7352
|
+
// controls require editor+ access.
|
|
7296
7353
|
// agent_runs carries no owner column — ownership lives on the
|
|
7297
|
-
// chat_threads row via thread_id.
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
callerOwnsThread(owner, threadId);
|
|
7305
|
-
const ownsRun = (runId: string) => callerOwnsRun(owner, runId);
|
|
7354
|
+
// chat_threads row via thread_id.
|
|
7355
|
+
const canViewThread = (threadId: string | null | undefined) =>
|
|
7356
|
+
callerHasThreadAccess(owner, threadId, "viewer", { orgId });
|
|
7357
|
+
const canViewRun = (runId: string) =>
|
|
7358
|
+
callerHasRunAccess(owner, runId, "viewer", { orgId });
|
|
7359
|
+
const canEditRun = (runId: string) =>
|
|
7360
|
+
callerHasRunAccess(owner, runId, "editor", { orgId });
|
|
7306
7361
|
|
|
7307
7362
|
// Route: GET /runs/list?goalId=agent-team|agent-harness
|
|
7308
7363
|
// Returns background agents in the Code hub-compatible run shape.
|
|
@@ -7377,8 +7432,8 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7377
7432
|
url.match(/^\/([^/?]+)\/abort/);
|
|
7378
7433
|
if (abortMatch && method === "POST") {
|
|
7379
7434
|
const runId = decodeURIComponent(abortMatch[1]);
|
|
7380
|
-
if (!(await
|
|
7381
|
-
// 404 (not 403) so run existence isn't leaked to
|
|
7435
|
+
if (!(await canEditRun(runId))) {
|
|
7436
|
+
// 404 (not 403) so run existence isn't leaked to unauthorized users.
|
|
7382
7437
|
setResponseStatus(event, 404);
|
|
7383
7438
|
return { error: "Run not found" };
|
|
7384
7439
|
}
|
|
@@ -7448,8 +7503,8 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7448
7503
|
url.match(/^\/([^/?]+)\/events/);
|
|
7449
7504
|
if (eventsMatch && method === "GET") {
|
|
7450
7505
|
const runId = decodeURIComponent(eventsMatch[1]);
|
|
7451
|
-
if (!(await
|
|
7452
|
-
// 404 (not 403) so run existence isn't leaked to
|
|
7506
|
+
if (!(await canViewRun(runId))) {
|
|
7507
|
+
// 404 (not 403) so run existence isn't leaked to unauthorized users.
|
|
7453
7508
|
setResponseStatus(event, 404);
|
|
7454
7509
|
return { error: "Run not found" };
|
|
7455
7510
|
}
|
|
@@ -7485,11 +7540,11 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7485
7540
|
return { error: "threadId query parameter is required" };
|
|
7486
7541
|
}
|
|
7487
7542
|
|
|
7488
|
-
// Only reveal a thread's active run to
|
|
7489
|
-
// Present
|
|
7490
|
-
// 404 so thread existence isn't leaked and the client
|
|
7491
|
-
// benignly.
|
|
7492
|
-
if (!(await
|
|
7543
|
+
// Only reveal a thread's active run to viewers/editors of the
|
|
7544
|
+
// thread. Present unauthorized users (or unknown threads) as idle
|
|
7545
|
+
// rather than 404 so thread existence isn't leaked and the client
|
|
7546
|
+
// polls benignly.
|
|
7547
|
+
if (!(await canViewThread(threadId))) {
|
|
7493
7548
|
return {
|
|
7494
7549
|
active: false,
|
|
7495
7550
|
threadId,
|
|
@@ -7745,6 +7800,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7745
7800
|
`${routePath}/threads`,
|
|
7746
7801
|
defineEventHandler(async (event) => {
|
|
7747
7802
|
const owner = await getOwnerFromEvent(event);
|
|
7803
|
+
const orgId = await getOrgIdFromEvent(event);
|
|
7748
7804
|
const method = getMethod(event);
|
|
7749
7805
|
|
|
7750
7806
|
const { threadId, tail: threadTail } = parseThreadRoute(event);
|
|
@@ -7754,8 +7810,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7754
7810
|
// ── Specific thread: GET/PUT/DELETE /threads/:id ──
|
|
7755
7811
|
if (threadId) {
|
|
7756
7812
|
if (method === "GET") {
|
|
7757
|
-
const thread = await
|
|
7758
|
-
|
|
7813
|
+
const thread = await resolveThreadAccess(
|
|
7814
|
+
owner,
|
|
7815
|
+
threadId,
|
|
7816
|
+
"viewer",
|
|
7817
|
+
{ orgId },
|
|
7818
|
+
);
|
|
7819
|
+
if (!thread) {
|
|
7759
7820
|
setResponseStatus(event, 404);
|
|
7760
7821
|
return { error: "Thread not found" };
|
|
7761
7822
|
}
|
|
@@ -7770,8 +7831,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7770
7831
|
// run could clobber the assistant message the server just
|
|
7771
7832
|
// appended (and vice versa).
|
|
7772
7833
|
return await withThreadDataLock(threadId, async () => {
|
|
7773
|
-
const thread = await
|
|
7774
|
-
|
|
7834
|
+
const thread = await resolveThreadAccess(
|
|
7835
|
+
owner,
|
|
7836
|
+
threadId,
|
|
7837
|
+
"editor",
|
|
7838
|
+
{ orgId },
|
|
7839
|
+
);
|
|
7840
|
+
if (!thread) {
|
|
7775
7841
|
setResponseStatus(event, 404);
|
|
7776
7842
|
return { error: "Thread not found" };
|
|
7777
7843
|
}
|
|
@@ -7848,16 +7914,21 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7848
7914
|
// queued messages durable across reloads without piggybacking
|
|
7849
7915
|
// on full-thread saves.
|
|
7850
7916
|
if (method === "POST" && isThreadSubroute("queued")) {
|
|
7917
|
+
const thread = await resolveThreadAccess(
|
|
7918
|
+
owner,
|
|
7919
|
+
threadId,
|
|
7920
|
+
"editor",
|
|
7921
|
+
{ orgId },
|
|
7922
|
+
);
|
|
7923
|
+
if (!thread) {
|
|
7924
|
+
setResponseStatus(event, 404);
|
|
7925
|
+
return { error: "Thread not found" };
|
|
7926
|
+
}
|
|
7851
7927
|
const body = await readBody(event);
|
|
7852
7928
|
const queued = Array.isArray(body?.queuedMessages)
|
|
7853
7929
|
? body.queuedMessages
|
|
7854
7930
|
: [];
|
|
7855
|
-
|
|
7856
|
-
// the thread-data lock) — no separate getThread pre-read on
|
|
7857
|
-
// this debounced hot path.
|
|
7858
|
-
const saved = await setThreadQueuedMessages(threadId, queued, {
|
|
7859
|
-
ownerEmail: owner,
|
|
7860
|
-
});
|
|
7931
|
+
const saved = await setThreadQueuedMessages(threadId, queued);
|
|
7861
7932
|
if (!saved) {
|
|
7862
7933
|
setResponseStatus(event, 404);
|
|
7863
7934
|
return { error: "Thread not found" };
|
|
@@ -7866,8 +7937,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7866
7937
|
}
|
|
7867
7938
|
|
|
7868
7939
|
if (method === "POST" && isThreadSubroute("rename")) {
|
|
7869
|
-
const thread = await
|
|
7870
|
-
|
|
7940
|
+
const thread = await resolveThreadAccess(
|
|
7941
|
+
owner,
|
|
7942
|
+
threadId,
|
|
7943
|
+
"editor",
|
|
7944
|
+
{ orgId },
|
|
7945
|
+
);
|
|
7946
|
+
if (!thread) {
|
|
7871
7947
|
setResponseStatus(event, 404);
|
|
7872
7948
|
return { error: "Thread not found" };
|
|
7873
7949
|
}
|
|
@@ -7880,9 +7956,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7880
7956
|
setResponseStatus(event, 400);
|
|
7881
7957
|
return { error: "Title is required" };
|
|
7882
7958
|
}
|
|
7883
|
-
const renamed = await renameThread(threadId, title
|
|
7884
|
-
ownerEmail: owner,
|
|
7885
|
-
});
|
|
7959
|
+
const renamed = await renameThread(threadId, title);
|
|
7886
7960
|
if (!renamed) {
|
|
7887
7961
|
setResponseStatus(event, 404);
|
|
7888
7962
|
return { error: "Thread not found" };
|
|
@@ -7891,8 +7965,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7891
7965
|
}
|
|
7892
7966
|
|
|
7893
7967
|
if (method === "POST" && isThreadSubroute("pin")) {
|
|
7894
|
-
const thread = await
|
|
7895
|
-
|
|
7968
|
+
const thread = await resolveThreadAccess(
|
|
7969
|
+
owner,
|
|
7970
|
+
threadId,
|
|
7971
|
+
"editor",
|
|
7972
|
+
{ orgId },
|
|
7973
|
+
);
|
|
7974
|
+
if (!thread) {
|
|
7896
7975
|
setResponseStatus(event, 404);
|
|
7897
7976
|
return { error: "Thread not found" };
|
|
7898
7977
|
}
|
|
@@ -7901,9 +7980,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7901
7980
|
setResponseStatus(event, 400);
|
|
7902
7981
|
return { error: "pinned boolean is required" };
|
|
7903
7982
|
}
|
|
7904
|
-
const pinned = await setThreadPinned(threadId, body.pinned
|
|
7905
|
-
ownerEmail: owner,
|
|
7906
|
-
});
|
|
7983
|
+
const pinned = await setThreadPinned(threadId, body.pinned);
|
|
7907
7984
|
if (!pinned) {
|
|
7908
7985
|
setResponseStatus(event, 404);
|
|
7909
7986
|
return { error: "Thread not found" };
|
|
@@ -7912,8 +7989,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7912
7989
|
}
|
|
7913
7990
|
|
|
7914
7991
|
if (method === "POST" && isThreadSubroute("archive")) {
|
|
7915
|
-
const thread = await
|
|
7916
|
-
|
|
7992
|
+
const thread = await resolveThreadAccess(
|
|
7993
|
+
owner,
|
|
7994
|
+
threadId,
|
|
7995
|
+
"editor",
|
|
7996
|
+
{ orgId },
|
|
7997
|
+
);
|
|
7998
|
+
if (!thread) {
|
|
7917
7999
|
setResponseStatus(event, 404);
|
|
7918
8000
|
return { error: "Thread not found" };
|
|
7919
8001
|
}
|
|
@@ -7922,11 +8004,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7922
8004
|
setResponseStatus(event, 400);
|
|
7923
8005
|
return { error: "archived boolean is required" };
|
|
7924
8006
|
}
|
|
7925
|
-
const archived = await setThreadArchived(
|
|
7926
|
-
threadId,
|
|
7927
|
-
body.archived,
|
|
7928
|
-
{ ownerEmail: owner },
|
|
7929
|
-
);
|
|
8007
|
+
const archived = await setThreadArchived(threadId, body.archived);
|
|
7930
8008
|
if (!archived) {
|
|
7931
8009
|
setResponseStatus(event, 404);
|
|
7932
8010
|
return { error: "Thread not found" };
|
|
@@ -7936,10 +8014,21 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7936
8014
|
|
|
7937
8015
|
// POST /threads/:id/fork — duplicate a thread with all its messages
|
|
7938
8016
|
if (method === "POST" && isThreadSubroute("fork")) {
|
|
8017
|
+
const thread = await resolveThreadAccess(
|
|
8018
|
+
owner,
|
|
8019
|
+
threadId,
|
|
8020
|
+
"viewer",
|
|
8021
|
+
{ orgId },
|
|
8022
|
+
);
|
|
8023
|
+
if (!thread) {
|
|
8024
|
+
setResponseStatus(event, 404);
|
|
8025
|
+
return { error: "Thread not found" };
|
|
8026
|
+
}
|
|
7939
8027
|
const body = await readBody(event);
|
|
7940
8028
|
const forked = await forkThread(threadId, owner, {
|
|
7941
8029
|
id: body?.id,
|
|
7942
8030
|
source: parseForkSourceFromBody(body?.source),
|
|
8031
|
+
sourceAccessGranted: true,
|
|
7943
8032
|
});
|
|
7944
8033
|
if (!forked) {
|
|
7945
8034
|
setResponseStatus(event, 404);
|
|
@@ -7949,10 +8038,18 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7949
8038
|
}
|
|
7950
8039
|
|
|
7951
8040
|
if (isThreadSubroute("share")) {
|
|
8041
|
+
const thread = await resolveThreadAccess(
|
|
8042
|
+
owner,
|
|
8043
|
+
threadId,
|
|
8044
|
+
"admin",
|
|
8045
|
+
{ orgId },
|
|
8046
|
+
);
|
|
8047
|
+
if (!thread) {
|
|
8048
|
+
setResponseStatus(event, 404);
|
|
8049
|
+
return { error: "Thread not found" };
|
|
8050
|
+
}
|
|
7952
8051
|
if (method === "GET") {
|
|
7953
|
-
const state = await getThreadShareState(threadId
|
|
7954
|
-
ownerEmail: owner,
|
|
7955
|
-
});
|
|
8052
|
+
const state = await getThreadShareState(threadId);
|
|
7956
8053
|
if (!state) {
|
|
7957
8054
|
setResponseStatus(event, 404);
|
|
7958
8055
|
return { error: "Thread not found" };
|
|
@@ -7961,9 +8058,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7961
8058
|
}
|
|
7962
8059
|
|
|
7963
8060
|
if (method === "POST") {
|
|
7964
|
-
const link = await createThreadShareLink(threadId
|
|
7965
|
-
ownerEmail: owner,
|
|
7966
|
-
});
|
|
8061
|
+
const link = await createThreadShareLink(threadId);
|
|
7967
8062
|
if (!link) {
|
|
7968
8063
|
setResponseStatus(event, 404);
|
|
7969
8064
|
return { error: "Thread not found" };
|
|
@@ -7975,9 +8070,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7975
8070
|
}
|
|
7976
8071
|
|
|
7977
8072
|
if (method === "DELETE") {
|
|
7978
|
-
const state = await revokeThreadShareLink(threadId
|
|
7979
|
-
ownerEmail: owner,
|
|
7980
|
-
});
|
|
8073
|
+
const state = await revokeThreadShareLink(threadId);
|
|
7981
8074
|
if (!state) {
|
|
7982
8075
|
setResponseStatus(event, 404);
|
|
7983
8076
|
return { error: "Thread not found" };
|
|
@@ -8013,6 +8106,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
8013
8106
|
if (q) {
|
|
8014
8107
|
const threads = await searchThreads(owner, q, limit, {
|
|
8015
8108
|
scope: scope ?? undefined,
|
|
8109
|
+
orgId,
|
|
8016
8110
|
});
|
|
8017
8111
|
return { threads };
|
|
8018
8112
|
}
|
|
@@ -8022,6 +8116,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
8022
8116
|
offset,
|
|
8023
8117
|
scope: scope ?? undefined,
|
|
8024
8118
|
unscopedOnly,
|
|
8119
|
+
orgId,
|
|
8025
8120
|
});
|
|
8026
8121
|
return { threads };
|
|
8027
8122
|
}
|
|
@@ -2934,18 +2934,27 @@ ${signupLocalModeNoteHtml}
|
|
|
2934
2934
|
function __anRedirectToSignedInApp(ret) {
|
|
2935
2935
|
window.location.replace(__anWithAuthCacheBypass(ret || __anGetSignedInReturnPath()));
|
|
2936
2936
|
}
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
cache: 'no-store',
|
|
2937
|
+
function __anMaybeRedirectSignedIn(ret) {
|
|
2938
|
+
return fetch(__anPath('/_agent-native/auth/session'), {
|
|
2939
|
+
headers: { 'Accept': 'application/json' },
|
|
2940
|
+
credentials: 'include',
|
|
2941
|
+
cache: 'no-store',
|
|
2943
2942
|
}).then(function(res) {
|
|
2944
2943
|
if (!res.ok) return null;
|
|
2945
2944
|
return res.json().catch(function() { return null; });
|
|
2946
2945
|
}).then(function(data) {
|
|
2947
|
-
|
|
2948
|
-
|
|
2946
|
+
if (data && data.email && !data.error) {
|
|
2947
|
+
__anRedirectToSignedInApp(ret);
|
|
2948
|
+
return true;
|
|
2949
|
+
}
|
|
2950
|
+
return false;
|
|
2951
|
+
}).catch(function() {
|
|
2952
|
+
return false;
|
|
2953
|
+
});
|
|
2954
|
+
}
|
|
2955
|
+
${identitySsoScript}
|
|
2956
|
+
(function __anRedirectIfAlreadySignedIn() {
|
|
2957
|
+
__anMaybeRedirectSignedIn();
|
|
2949
2958
|
})();
|
|
2950
2959
|
function __anSafeAttributionValue(value) {
|
|
2951
2960
|
return typeof value === 'string' ? value.trim().slice(0, 120) : '';
|
|
@@ -3130,14 +3139,17 @@ ${identitySsoScript}
|
|
|
3130
3139
|
// in-flight exchange can still finish and navigate without a flicker.
|
|
3131
3140
|
if (!__anGoogleSignInInFlight) return;
|
|
3132
3141
|
setTimeout(function() {
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3142
|
+
__anMaybeRedirectSignedIn(__anGetSignedInReturnPath()).then(function(redirected) {
|
|
3143
|
+
if (redirected) return;
|
|
3144
|
+
if (!__anGoogleSignInInFlight) return;
|
|
3145
|
+
var btn = document.getElementById('google-btn');
|
|
3146
|
+
if (!btn || !btn.disabled) return;
|
|
3147
|
+
// Keep the desktop-exchange poll alive. Agent Native Desktop opens
|
|
3148
|
+
// Google in the system browser, so focus can return before the
|
|
3149
|
+
// callback has stored the session token.
|
|
3150
|
+
btn.disabled = false;
|
|
3151
|
+
__anGoogleSignInInFlight = false;
|
|
3152
|
+
});
|
|
3141
3153
|
}, 1200);
|
|
3142
3154
|
}
|
|
3143
3155
|
function __anBindGoogleRecover() {
|
|
@@ -1,10 +1,49 @@
|
|
|
1
|
-
import { eq } from "drizzle-orm";
|
|
1
|
+
import { eq, inArray } from "drizzle-orm";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
import { defineAction } from "../../action.js";
|
|
5
|
+
import { organizations } from "../../org/schema.js";
|
|
5
6
|
import { resolveAccess } from "../access.js";
|
|
6
7
|
import { requireShareableResource } from "../registry.js";
|
|
7
8
|
|
|
9
|
+
async function loadOrgDisplayNames(
|
|
10
|
+
db: any,
|
|
11
|
+
shares: Array<{ principalType: string; principalId: string }>,
|
|
12
|
+
): Promise<Map<string, string>> {
|
|
13
|
+
const orgIds = Array.from(
|
|
14
|
+
new Set(
|
|
15
|
+
shares
|
|
16
|
+
.filter((s) => s.principalType === "org" && s.principalId)
|
|
17
|
+
.map((s) => s.principalId),
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
if (!orgIds.length) return new Map();
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const rows = await db
|
|
24
|
+
.select({ id: organizations.id, name: organizations.name })
|
|
25
|
+
.from(organizations)
|
|
26
|
+
.where(inArray(organizations.id, orgIds));
|
|
27
|
+
return new Map(
|
|
28
|
+
rows.flatMap(
|
|
29
|
+
(row: {
|
|
30
|
+
id?: string | null;
|
|
31
|
+
name?: string | null;
|
|
32
|
+
}): Array<[string, string]> => {
|
|
33
|
+
if (typeof row.id !== "string" || typeof row.name !== "string") {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const name = row.name.trim();
|
|
37
|
+
return name ? [[row.id, name]] : [];
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
);
|
|
41
|
+
} catch {
|
|
42
|
+
// Some templates or older local databases may not have org tables yet.
|
|
43
|
+
return new Map();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
8
47
|
export default defineAction({
|
|
9
48
|
description:
|
|
10
49
|
"List the current visibility and share grants on a shareable resource. Any read access is sufficient.",
|
|
@@ -30,6 +69,7 @@ export default defineAction({
|
|
|
30
69
|
.select()
|
|
31
70
|
.from(reg.sharesTable)
|
|
32
71
|
.where(eq(reg.sharesTable.resourceId, args.resourceId));
|
|
72
|
+
const orgDisplayNames = await loadOrgDisplayNames(db, shares);
|
|
33
73
|
|
|
34
74
|
return {
|
|
35
75
|
ownerEmail: access.resource.ownerEmail ?? null,
|
|
@@ -40,6 +80,10 @@ export default defineAction({
|
|
|
40
80
|
id: s.id,
|
|
41
81
|
principalType: s.principalType,
|
|
42
82
|
principalId: s.principalId,
|
|
83
|
+
displayName:
|
|
84
|
+
s.principalType === "org"
|
|
85
|
+
? orgDisplayNames.get(s.principalId)
|
|
86
|
+
: undefined,
|
|
43
87
|
role: s.role,
|
|
44
88
|
createdAt: s.createdAt,
|
|
45
89
|
})),
|
|
@@ -99,6 +99,10 @@ function normalizePrincipalId(
|
|
|
99
99
|
: principalId;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
function isEmailPrincipalId(value: string): boolean {
|
|
103
|
+
return /^[^\s@]+@[^\s@]+$/.test(value.trim());
|
|
104
|
+
}
|
|
105
|
+
|
|
102
106
|
function principalIdMatches(
|
|
103
107
|
sharesTable: any,
|
|
104
108
|
principalType: "user" | "org",
|
|
@@ -187,6 +191,11 @@ export default defineAction({
|
|
|
187
191
|
args.principalType,
|
|
188
192
|
args.principalId,
|
|
189
193
|
);
|
|
194
|
+
if (args.principalType === "user" && !isEmailPrincipalId(principalId)) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
"User shares must use an email address, not an internal user id.",
|
|
197
|
+
);
|
|
198
|
+
}
|
|
190
199
|
const beforeExtensionTargets = await getExtensionShareChangeTargets(
|
|
191
200
|
args.resourceType,
|
|
192
201
|
args.resourceId,
|
package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md
CHANGED
|
@@ -40,8 +40,10 @@ in the moment of agent use.
|
|
|
40
40
|
|
|
41
41
|
## Reusable Kits
|
|
42
42
|
|
|
43
|
-
- **Settings kit**:
|
|
44
|
-
secrets, usage, notifications, changelog, and
|
|
43
|
+
- **Settings kit**: a searchable settings page with account, workspace, AI
|
|
44
|
+
models, LLM keys, connections, secrets, usage, notifications, changelog, and
|
|
45
|
+
app-specific panels. Search is on by default; register a `SettingsSearchEntry`
|
|
46
|
+
per control so users find settings by name across tabs.
|
|
45
47
|
- **Collaboration kit**: Yjs docs, presence, agent presence, live cursors,
|
|
46
48
|
remote selections, recent edit highlights, real-time sync indicators, and
|
|
47
49
|
undo/redo grouping.
|
|
@@ -15,8 +15,9 @@ metadata:
|
|
|
15
15
|
Every template app keeps a `CHANGELOG.md` of **user-facing** changes that
|
|
16
16
|
renders in-app via the command menu (Cmd+K → "What's new") and on the settings
|
|
17
17
|
page. The flow mirrors changesets so it survives many agents working in
|
|
18
|
-
parallel: each change drops a small **pending entry file**,
|
|
19
|
-
|
|
18
|
+
parallel: each change drops a small **pending entry file**, the in-app surface
|
|
19
|
+
reads pending files plus `CHANGELOG.md`, and a later **release** can roll those
|
|
20
|
+
pending files into dated `CHANGELOG.md` sections.
|
|
20
21
|
|
|
21
22
|
## When to add an entry
|
|
22
23
|
|
|
@@ -69,9 +70,10 @@ agent-native changelog release # uses today's date
|
|
|
69
70
|
agent-native changelog list # preview pending + released
|
|
70
71
|
```
|
|
71
72
|
|
|
72
|
-
Releasing is usually done at deploy/merge time
|
|
73
|
-
`CHANGELOG.md`,
|
|
74
|
-
|
|
73
|
+
Releasing is usually done at deploy/merge time to keep the source tree tidy.
|
|
74
|
+
The in-app surface imports `CHANGELOG.md?raw`, and the core Vite plugin merges
|
|
75
|
+
adjacent `changelog/*.md` pending entries into that raw markdown at dev/build
|
|
76
|
+
time, so product notes become visible without waiting for a manual rollup.
|
|
75
77
|
|
|
76
78
|
## Wiring the in-app surface (once per template)
|
|
77
79
|
|
|
@@ -108,4 +110,5 @@ host with no server route or runtime file access.
|
|
|
108
110
|
- [ ] Shipped a user-visible change? Run `agent-native changelog add "…"`.
|
|
109
111
|
- [ ] New template UI? Pass `changelog` to its `CommandMenu` and seed a
|
|
110
112
|
`CHANGELOG.md`.
|
|
111
|
-
- [ ] Releasing/deploying? `agent-native changelog release` rolls
|
|
113
|
+
- [ ] Releasing/deploying? Optional: `agent-native changelog release` rolls
|
|
114
|
+
pending → dated sections and deletes the pending files.
|