@agent-native/core 0.90.10 → 0.91.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +30 -0
- package/corpus/core/docs/content/toolkit-settings.mdx +56 -3
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/durable-background.ts +5 -5
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +40 -8
- package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -7
- package/corpus/core/src/agent/engine/output-tokens.ts +94 -0
- package/corpus/core/src/agent/production-agent.ts +34 -6
- package/corpus/core/src/agent/run-ownership.ts +29 -1
- package/corpus/core/src/agent/types.ts +3 -2
- 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/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/db/client.ts +12 -9
- 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/shared/reasoning-effort.ts +23 -0
- 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/actions/regenerate-chapters.ts +7 -0
- 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/hooks/use-auto-title.ts +15 -5
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +63 -6
- package/corpus/templates/clips/app/routes/download.tsx +12 -4
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
- package/corpus/templates/clips/app/routes/record.tsx +18 -1
- package/corpus/templates/clips/changelog/2026-07-07-auto-generated-chapter-requests-now-open-the-matching-agent-.md +6 -0
- 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-07-the-clips-desktop-download-page-now-uses-the-agent-native-ap.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/actions/generate-design.ts +3 -0
- package/corpus/templates/design/actions/get-design-system.ts +147 -1
- 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/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/durable-background.d.ts +1 -1
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +5 -3
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +24 -4
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +13 -3
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/output-tokens.d.ts +27 -0
- package/dist/agent/engine/output-tokens.d.ts.map +1 -1
- package/dist/agent/engine/output-tokens.js +70 -0
- package/dist/agent/engine/output-tokens.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +28 -7
- package/dist/agent/production-agent.js.map +1 -1
- 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/agent/types.d.ts +3 -2
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.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/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/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +12 -7
- package/dist/db/client.js.map +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/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/org/schema.d.ts +15 -15
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/secrets/routes.d.ts +9 -9
- 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/agent-engine-api-key-route.d.ts +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/shared/reasoning-effort.d.ts +1 -0
- package/dist/shared/reasoning-effort.d.ts.map +1 -1
- package/dist/shared/reasoning-effort.js +18 -0
- package/dist/shared/reasoning-effort.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
|
@@ -5,4 +5,5 @@ export declare function isReasoningEffort(value: unknown): value is ReasoningEff
|
|
|
5
5
|
export declare function getReasoningEffortOptionsForModel(model: string | undefined): ReasoningEffort[];
|
|
6
6
|
export declare function normalizeReasoningEffortForModel(model: string | undefined, effort: ReasoningEffort | undefined): ReasoningEffort | undefined;
|
|
7
7
|
export declare function reasoningEffortLabel(effort: ReasoningEffort | undefined): string;
|
|
8
|
+
export declare function stepDownReasoningEffort(effort: ReasoningEffort | undefined): ReasoningEffort | undefined;
|
|
8
9
|
//# sourceMappingURL=reasoning-effort.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning-effort.d.ts","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,YAC5B,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CASnE,CAAC;AA2BF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,eAAe,EAAE,CAcnB;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,eAAe,GAAG,SAAS,CAoB7B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,UAEvE"}
|
|
1
|
+
{"version":3,"file":"reasoning-effort.d.ts","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,YAC5B,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,KAAK,CACG,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CASnE,CAAC;AA2BF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,eAAe,EAAE,CAcnB;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,eAAe,GAAG,SAAS,CAoB7B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,UAEvE;AAkBD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,eAAe,GAAG,SAAS,CAG7B"}
|
|
@@ -79,6 +79,24 @@ export function normalizeReasoningEffortForModel(model, effort) {
|
|
|
79
79
|
export function reasoningEffortLabel(effort) {
|
|
80
80
|
return REASONING_EFFORT_LABELS[effort ?? "auto"];
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* One tier down from each effort, stopping at "minimal" — "none"/"auto"
|
|
84
|
+
* (not really "tiers") and "minimal" itself are left unchanged. Used by the
|
|
85
|
+
* empty-final-response retry so a retried turn asks for meaningfully less
|
|
86
|
+
* reasoning instead of repeating the exact request that came back empty.
|
|
87
|
+
*/
|
|
88
|
+
const REASONING_EFFORT_STEP_DOWN = {
|
|
89
|
+
max: "xhigh",
|
|
90
|
+
xhigh: "high",
|
|
91
|
+
high: "medium",
|
|
92
|
+
medium: "low",
|
|
93
|
+
low: "minimal",
|
|
94
|
+
};
|
|
95
|
+
export function stepDownReasoningEffort(effort) {
|
|
96
|
+
if (!effort)
|
|
97
|
+
return effort;
|
|
98
|
+
return REASONING_EFFORT_STEP_DOWN[effort] ?? effort;
|
|
99
|
+
}
|
|
82
100
|
function isGPTReasoningModel(model) {
|
|
83
101
|
return /^gpt-5/.test(model) || /^o\d/.test(model);
|
|
84
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reasoning-effort.js","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"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","sourcesContent":["export const REASONING_EFFORTS = [\n \"auto\",\n \"none\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const;\n\nexport type ReasoningEffort = (typeof REASONING_EFFORTS)[number];\n\nexport const REASONING_EFFORT_LABELS: Record<ReasoningEffort, string> = {\n auto: \"Auto\",\n none: \"None\",\n minimal: \"Minimal\",\n low: \"Low\",\n medium: \"Medium\",\n high: \"High\",\n xhigh: \"Extra High\",\n max: \"Max\",\n};\n\nconst VISIBLE_STANDARD_EFFORTS: ReasoningEffort[] = [\n \"auto\",\n \"low\",\n \"medium\",\n \"high\",\n];\n\nconst VISIBLE_GPT_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n];\n\nconst VISIBLE_CLAUDE_BUILT_IN_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n \"max\",\n];\n\nconst VISIBLE_CLAUDE_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"max\",\n];\n\nconst effortSet = new Set<string>(REASONING_EFFORTS);\n\nexport function isReasoningEffort(value: unknown): value is ReasoningEffort {\n return typeof value === \"string\" && effortSet.has(value);\n}\n\nexport function getReasoningEffortOptionsForModel(\n model: string | undefined,\n): ReasoningEffort[] {\n if (!model) return [];\n if (isGPTReasoningModel(model)) {\n return VISIBLE_GPT_EFFORTS;\n }\n if (isClaudeReasoningModel(model)) {\n return supportsClaudeXHigh(model)\n ? VISIBLE_CLAUDE_BUILT_IN_EFFORTS\n : VISIBLE_CLAUDE_EFFORTS;\n }\n if (isGeminiReasoningModel(model)) {\n return VISIBLE_STANDARD_EFFORTS;\n }\n return [];\n}\n\nexport function normalizeReasoningEffortForModel(\n model: string | undefined,\n effort: ReasoningEffort | undefined,\n): ReasoningEffort | undefined {\n if (!model || !effort || effort === \"auto\") {\n return undefined;\n }\n let normalized = effort;\n if (\n normalized === \"xhigh\" &&\n isClaudeReasoningModel(model) &&\n !supportsClaudeXHigh(model)\n ) {\n normalized = \"high\";\n }\n if (normalized === \"max\" && isGPTReasoningModel(model)) {\n normalized = \"xhigh\";\n }\n const options = getReasoningEffortOptionsForModel(model);\n if (!options.length || !options.includes(normalized)) {\n return undefined;\n }\n return normalized;\n}\n\nexport function reasoningEffortLabel(effort: ReasoningEffort | undefined) {\n return REASONING_EFFORT_LABELS[effort ?? \"auto\"];\n}\n\nfunction isGPTReasoningModel(model: string) {\n return /^gpt-5/.test(model) || /^o\\d/.test(model);\n}\n\nfunction isClaudeReasoningModel(model: string) {\n return /^claude-/.test(model);\n}\n\nfunction supportsClaudeXHigh(model: string) {\n // Models that support the xhigh effort tier (built-in extended thinking via\n // output_config.effort). Keep this version-aware so any future Claude model\n // with a higher patch/minor number is automatically included rather than\n // silently falling back to the lower \"high\" tier.\n // claude-fable-5 is a Mythos-class model and also supports xhigh.\n if (model.includes(\"fable-5\")) return true;\n // Sonnet 5 supports the expanded effort ladder through Builder/Anthropic.\n if (model.includes(\"sonnet-5\")) return true;\n // opus-4-7 introduced xhigh; all opus-4.x successors (4-8, 4-9…) should too.\n const opusMatch = model.match(/opus-4-(\\d+)/);\n if (opusMatch) {\n return parseInt(opusMatch[1], 10) >= 7;\n }\n return false;\n}\n\nfunction isGeminiReasoningModel(model: string) {\n return /^gemini-/.test(model);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reasoning-effort.js","sourceRoot":"","sources":["../../src/shared/reasoning-effort.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,MAAM;IACN,MAAM;IACN,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACG,CAAC;AAIX,MAAM,CAAC,MAAM,uBAAuB,GAAoC;IACtE,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,KAAK;CACX,CAAC;AAEF,MAAM,wBAAwB,GAAsB;IAClD,MAAM;IACN,KAAK;IACL,QAAQ;IACR,MAAM;CACP,CAAC;AAEF,MAAM,mBAAmB,GAAsB;IAC7C,GAAG,wBAAwB;IAC3B,OAAO;CACR,CAAC;AAEF,MAAM,+BAA+B,GAAsB;IACzD,GAAG,wBAAwB;IAC3B,OAAO;IACP,KAAK;CACN,CAAC;AAEF,MAAM,sBAAsB,GAAsB;IAChD,GAAG,wBAAwB;IAC3B,KAAK;CACN,CAAC;AAEF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,iBAAiB,CAAC,CAAC;AAErD,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,KAAyB;IAEzB,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IACD,IAAI,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,mBAAmB,CAAC,KAAK,CAAC;YAC/B,CAAC,CAAC,+BAA+B;YACjC,CAAC,CAAC,sBAAsB,CAAC;IAC7B,CAAC;IACD,IAAI,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,wBAAwB,CAAC;IAClC,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,KAAyB,EACzB,MAAmC;IAEnC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,UAAU,GAAG,MAAM,CAAC;IACxB,IACE,UAAU,KAAK,OAAO;QACtB,sBAAsB,CAAC,KAAK,CAAC;QAC7B,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAC3B,CAAC;QACD,UAAU,GAAG,MAAM,CAAC;IACtB,CAAC;IACD,IAAI,UAAU,KAAK,KAAK,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,UAAU,GAAG,OAAO,CAAC;IACvB,CAAC;IACD,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,CAAC;IACzD,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAmC;IACtE,OAAO,uBAAuB,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,0BAA0B,GAE5B;IACF,GAAG,EAAE,OAAO;IACZ,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,KAAK;IACb,GAAG,EAAE,SAAS;CACf,CAAC;AAEF,MAAM,UAAU,uBAAuB,CACrC,MAAmC;IAEnC,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAC3B,OAAO,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;AACtD,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa;IAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,4EAA4E;IAC5E,4EAA4E;IAC5E,yEAAyE;IACzE,kDAAkD;IAClD,kEAAkE;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,0EAA0E;IAC1E,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,6EAA6E;IAC7E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa;IAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC","sourcesContent":["export const REASONING_EFFORTS = [\n \"auto\",\n \"none\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const;\n\nexport type ReasoningEffort = (typeof REASONING_EFFORTS)[number];\n\nexport const REASONING_EFFORT_LABELS: Record<ReasoningEffort, string> = {\n auto: \"Auto\",\n none: \"None\",\n minimal: \"Minimal\",\n low: \"Low\",\n medium: \"Medium\",\n high: \"High\",\n xhigh: \"Extra High\",\n max: \"Max\",\n};\n\nconst VISIBLE_STANDARD_EFFORTS: ReasoningEffort[] = [\n \"auto\",\n \"low\",\n \"medium\",\n \"high\",\n];\n\nconst VISIBLE_GPT_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n];\n\nconst VISIBLE_CLAUDE_BUILT_IN_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"xhigh\",\n \"max\",\n];\n\nconst VISIBLE_CLAUDE_EFFORTS: ReasoningEffort[] = [\n ...VISIBLE_STANDARD_EFFORTS,\n \"max\",\n];\n\nconst effortSet = new Set<string>(REASONING_EFFORTS);\n\nexport function isReasoningEffort(value: unknown): value is ReasoningEffort {\n return typeof value === \"string\" && effortSet.has(value);\n}\n\nexport function getReasoningEffortOptionsForModel(\n model: string | undefined,\n): ReasoningEffort[] {\n if (!model) return [];\n if (isGPTReasoningModel(model)) {\n return VISIBLE_GPT_EFFORTS;\n }\n if (isClaudeReasoningModel(model)) {\n return supportsClaudeXHigh(model)\n ? VISIBLE_CLAUDE_BUILT_IN_EFFORTS\n : VISIBLE_CLAUDE_EFFORTS;\n }\n if (isGeminiReasoningModel(model)) {\n return VISIBLE_STANDARD_EFFORTS;\n }\n return [];\n}\n\nexport function normalizeReasoningEffortForModel(\n model: string | undefined,\n effort: ReasoningEffort | undefined,\n): ReasoningEffort | undefined {\n if (!model || !effort || effort === \"auto\") {\n return undefined;\n }\n let normalized = effort;\n if (\n normalized === \"xhigh\" &&\n isClaudeReasoningModel(model) &&\n !supportsClaudeXHigh(model)\n ) {\n normalized = \"high\";\n }\n if (normalized === \"max\" && isGPTReasoningModel(model)) {\n normalized = \"xhigh\";\n }\n const options = getReasoningEffortOptionsForModel(model);\n if (!options.length || !options.includes(normalized)) {\n return undefined;\n }\n return normalized;\n}\n\nexport function reasoningEffortLabel(effort: ReasoningEffort | undefined) {\n return REASONING_EFFORT_LABELS[effort ?? \"auto\"];\n}\n\n/**\n * One tier down from each effort, stopping at \"minimal\" — \"none\"/\"auto\"\n * (not really \"tiers\") and \"minimal\" itself are left unchanged. Used by the\n * empty-final-response retry so a retried turn asks for meaningfully less\n * reasoning instead of repeating the exact request that came back empty.\n */\nconst REASONING_EFFORT_STEP_DOWN: Partial<\n Record<ReasoningEffort, ReasoningEffort>\n> = {\n max: \"xhigh\",\n xhigh: \"high\",\n high: \"medium\",\n medium: \"low\",\n low: \"minimal\",\n};\n\nexport function stepDownReasoningEffort(\n effort: ReasoningEffort | undefined,\n): ReasoningEffort | undefined {\n if (!effort) return effort;\n return REASONING_EFFORT_STEP_DOWN[effort] ?? effort;\n}\n\nfunction isGPTReasoningModel(model: string) {\n return /^gpt-5/.test(model) || /^o\\d/.test(model);\n}\n\nfunction isClaudeReasoningModel(model: string) {\n return /^claude-/.test(model);\n}\n\nfunction supportsClaudeXHigh(model: string) {\n // Models that support the xhigh effort tier (built-in extended thinking via\n // output_config.effort). Keep this version-aware so any future Claude model\n // with a higher patch/minor number is automatically included rather than\n // silently falling back to the lower \"high\" tier.\n // claude-fable-5 is a Mythos-class model and also supports xhigh.\n if (model.includes(\"fable-5\")) return true;\n // Sonnet 5 supports the expanded effort ladder through Builder/Anthropic.\n if (model.includes(\"sonnet-5\")) return true;\n // opus-4-7 introduced xhigh; all opus-4.x successors (4-8, 4-9…) should too.\n const opusMatch = model.match(/opus-4-(\\d+)/);\n if (opusMatch) {\n return parseInt(opusMatch[1], 10) >= 7;\n }\n return false;\n}\n\nfunction isGeminiReasoningModel(model: string) {\n return /^gemini-/.test(model);\n}\n"]}
|
|
@@ -1,8 +1,33 @@
|
|
|
1
|
-
import { eq } from "drizzle-orm";
|
|
1
|
+
import { eq, inArray } from "drizzle-orm";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { defineAction } from "../../action.js";
|
|
4
|
+
import { organizations } from "../../org/schema.js";
|
|
4
5
|
import { resolveAccess } from "../access.js";
|
|
5
6
|
import { requireShareableResource } from "../registry.js";
|
|
7
|
+
async function loadOrgDisplayNames(db, shares) {
|
|
8
|
+
const orgIds = Array.from(new Set(shares
|
|
9
|
+
.filter((s) => s.principalType === "org" && s.principalId)
|
|
10
|
+
.map((s) => s.principalId)));
|
|
11
|
+
if (!orgIds.length)
|
|
12
|
+
return new Map();
|
|
13
|
+
try {
|
|
14
|
+
const rows = await db
|
|
15
|
+
.select({ id: organizations.id, name: organizations.name })
|
|
16
|
+
.from(organizations)
|
|
17
|
+
.where(inArray(organizations.id, orgIds));
|
|
18
|
+
return new Map(rows.flatMap((row) => {
|
|
19
|
+
if (typeof row.id !== "string" || typeof row.name !== "string") {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const name = row.name.trim();
|
|
23
|
+
return name ? [[row.id, name]] : [];
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Some templates or older local databases may not have org tables yet.
|
|
28
|
+
return new Map();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
6
31
|
export default defineAction({
|
|
7
32
|
description: "List the current visibility and share grants on a shareable resource. Any read access is sufficient.",
|
|
8
33
|
schema: z.object({
|
|
@@ -26,6 +51,7 @@ export default defineAction({
|
|
|
26
51
|
.select()
|
|
27
52
|
.from(reg.sharesTable)
|
|
28
53
|
.where(eq(reg.sharesTable.resourceId, args.resourceId));
|
|
54
|
+
const orgDisplayNames = await loadOrgDisplayNames(db, shares);
|
|
29
55
|
return {
|
|
30
56
|
ownerEmail: access.resource.ownerEmail ?? null,
|
|
31
57
|
orgId: access.resource.orgId ?? null,
|
|
@@ -35,6 +61,9 @@ export default defineAction({
|
|
|
35
61
|
id: s.id,
|
|
36
62
|
principalType: s.principalType,
|
|
37
63
|
principalId: s.principalId,
|
|
64
|
+
displayName: s.principalType === "org"
|
|
65
|
+
? orgDisplayNames.get(s.principalId)
|
|
66
|
+
: undefined,
|
|
38
67
|
role: s.role,
|
|
39
68
|
createdAt: s.createdAt,
|
|
40
69
|
})),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-resource-shares.js","sourceRoot":"","sources":["../../../src/sharing/actions/list-resource-shares.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"list-resource-shares.js","sourceRoot":"","sources":["../../../src/sharing/actions/list-resource-shares.ts"],"names":[],"mappings":"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","sourcesContent":["import { eq, inArray } from \"drizzle-orm\";\nimport { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { organizations } from \"../../org/schema.js\";\nimport { resolveAccess } from \"../access.js\";\nimport { requireShareableResource } from \"../registry.js\";\n\nasync function loadOrgDisplayNames(\n db: any,\n shares: Array<{ principalType: string; principalId: string }>,\n): Promise<Map<string, string>> {\n const orgIds = Array.from(\n new Set(\n shares\n .filter((s) => s.principalType === \"org\" && s.principalId)\n .map((s) => s.principalId),\n ),\n );\n if (!orgIds.length) return new Map();\n\n try {\n const rows = await db\n .select({ id: organizations.id, name: organizations.name })\n .from(organizations)\n .where(inArray(organizations.id, orgIds));\n return new Map(\n rows.flatMap(\n (row: {\n id?: string | null;\n name?: string | null;\n }): Array<[string, string]> => {\n if (typeof row.id !== \"string\" || typeof row.name !== \"string\") {\n return [];\n }\n const name = row.name.trim();\n return name ? [[row.id, name]] : [];\n },\n ),\n );\n } catch {\n // Some templates or older local databases may not have org tables yet.\n return new Map();\n }\n}\n\nexport default defineAction({\n description:\n \"List the current visibility and share grants on a shareable resource. Any read access is sufficient.\",\n schema: z.object({\n resourceType: z.string(),\n resourceId: z.string(),\n }),\n http: { method: \"GET\" },\n run: async (args) => {\n const reg = requireShareableResource(args.resourceType);\n const policy = {\n // Defaults match registration defaults so the UI behaves the same for\n // resources that haven't opted into restrictions.\n allowPublic: reg.allowPublic !== false,\n requireOrgMemberForUserShares: reg.requireOrgMemberForUserShares === true,\n };\n const access = await resolveAccess(args.resourceType, args.resourceId);\n if (!access)\n return { ownerEmail: null, visibility: null, shares: [], policy };\n\n const db = reg.getDb() as any;\n const shares = await db\n .select()\n .from(reg.sharesTable)\n .where(eq(reg.sharesTable.resourceId, args.resourceId));\n const orgDisplayNames = await loadOrgDisplayNames(db, shares);\n\n return {\n ownerEmail: access.resource.ownerEmail ?? null,\n orgId: access.resource.orgId ?? null,\n visibility: access.resource.visibility ?? \"private\",\n role: access.role,\n shares: shares.map((s: any) => ({\n id: s.id,\n principalType: s.principalType,\n principalId: s.principalId,\n displayName:\n s.principalType === \"org\"\n ? orgDisplayNames.get(s.principalId)\n : undefined,\n role: s.role,\n createdAt: s.createdAt,\n })),\n policy,\n };\n },\n});\n"]}
|
|
@@ -85,6 +85,9 @@ function normalizePrincipalId(principalType, principalId) {
|
|
|
85
85
|
? principalId.trim().toLowerCase()
|
|
86
86
|
: principalId;
|
|
87
87
|
}
|
|
88
|
+
function isEmailPrincipalId(value) {
|
|
89
|
+
return /^[^\s@]+@[^\s@]+$/.test(value.trim());
|
|
90
|
+
}
|
|
88
91
|
function principalIdMatches(sharesTable, principalType, principalId) {
|
|
89
92
|
return principalType === "user"
|
|
90
93
|
? sql `lower(${sharesTable.principalId}) = ${principalId}`
|
|
@@ -155,6 +158,9 @@ export default defineAction({
|
|
|
155
158
|
if (!actor)
|
|
156
159
|
throw new ForbiddenError("Not signed in");
|
|
157
160
|
const principalId = normalizePrincipalId(args.principalType, args.principalId);
|
|
161
|
+
if (args.principalType === "user" && !isEmailPrincipalId(principalId)) {
|
|
162
|
+
throw new Error("User shares must use an email address, not an internal user id.");
|
|
163
|
+
}
|
|
158
164
|
const beforeExtensionTargets = await getExtensionShareChangeTargets(args.resourceType, args.resourceId);
|
|
159
165
|
if (reg.requireOrgMemberForUserShares) {
|
|
160
166
|
const resourceOrgId = access.resource?.orgId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share-resource.js","sourceRoot":"","sources":["../../../src/sharing/actions/share-resource.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, sql, type SQL } from \"drizzle-orm\";\nimport { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { getDbExec } from \"../../db/client.js\";\nimport { getAppProductionUrl } from \"../../server/app-url.js\";\nimport { renderEmail, emailStrong } from \"../../server/email-template.js\";\nimport { sendEmail, isEmailConfigured } from \"../../server/email.js\";\nimport { invalidateCollabAccessCache } from \"../../server/poll.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { assertAccess, ForbiddenError } from \"../access.js\";\nimport { requireShareableResource } from \"../registry.js\";\nimport {\n getExtensionShareChangeTargets,\n notifyExtensionShareChanged,\n} from \"./extension-change.js\";\n\nexport function isSyntheticQaEmail(email: string): boolean {\n const trimmed = email.trim().toLowerCase();\n const at = trimmed.lastIndexOf(\"@\");\n if (at <= 0) return false;\n const local = trimmed.slice(0, at);\n const domain = trimmed.slice(at + 1);\n return (\n local.includes(\"+qa\") &&\n (domain === \"example.test\" ||\n domain.endsWith(\".test\") ||\n domain === \"example.invalid\" ||\n domain.endsWith(\".invalid\"))\n );\n}\n\nfunction appPath(path: string): string {\n if (!path.startsWith(\"/\")) return path;\n const raw = process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH || \"\";\n const base = raw.trim().replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n if (!base) return path;\n const normalizedBase = `/${base}`;\n if (path === normalizedBase || path.startsWith(`${normalizedBase}/`)) {\n return path;\n }\n return `${normalizedBase}${path}`;\n}\n\nfunction safeNotificationUrl(value: string, appUrl: string): string | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n try {\n const base = new URL(appUrl);\n if (trimmed.startsWith(\"/\")) {\n const path = appPath(trimmed);\n const basePath = base.pathname.replace(/\\/+$/, \"\");\n const alreadyIncludesBase =\n basePath && basePath !== \"/\" && path.startsWith(`${basePath}/`);\n const joined = alreadyIncludesBase\n ? `${base.origin}${path}`\n : `${appUrl.replace(/\\/+$/, \"\")}${path}`;\n return new URL(joined).toString();\n }\n\n const url = new URL(trimmed);\n if (![\"http:\", \"https:\"].includes(url.protocol)) return null;\n if (url.origin !== base.origin) return null;\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport function resolveShareNotificationUrl(\n explicitUrl: string | undefined,\n fallbackPath: string | undefined,\n appUrl = getAppProductionUrl(),\n): string {\n for (const candidate of [explicitUrl, fallbackPath]) {\n if (!candidate) continue;\n const url = safeNotificationUrl(candidate, appUrl);\n if (url) return url;\n }\n return appUrl;\n}\n\nfunction nanoid(size = 12): string {\n const chars =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n let id = \"\";\n const bytes = crypto.getRandomValues(new Uint8Array(size));\n for (const byte of bytes) id += chars[byte % chars.length];\n return id;\n}\n\nfunction normalizePrincipalId(\n principalType: \"user\" | \"org\",\n principalId: string,\n): string {\n return principalType === \"user\"\n ? principalId.trim().toLowerCase()\n : principalId;\n}\n\nfunction principalIdMatches(\n sharesTable: any,\n principalType: \"user\" | \"org\",\n principalId: string,\n): SQL {\n return principalType === \"user\"\n ? sql`lower(${sharesTable.principalId}) = ${principalId}`\n : eq(sharesTable.principalId, principalId);\n}\n\n/**\n * Returns true if the given email is either an active member of `orgId` or\n * has a pending invitation to `orgId`. Used by resources whose registration\n * sets `requireOrgMemberForUserShares` (currently extensions) to refuse\n * cross-org user shares.\n *\n * Both `org_members` and `org_invitations` store email case-insensitively\n * via `LOWER()` in the rest of the framework, so we follow the same\n * convention here.\n */\nasync function isOrgMemberOrInvited(\n orgId: string,\n email: string,\n): Promise<boolean> {\n const lower = email.trim().toLowerCase();\n if (!lower || !orgId) return false;\n const client = getDbExec();\n const member = await client.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [orgId, lower],\n });\n if (member.rows.length > 0) return true;\n const invited = await client.execute({\n sql: `SELECT 1 FROM org_invitations WHERE org_id = ? AND LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [orgId, lower],\n });\n return invited.rows.length > 0;\n}\n\nexport default defineAction({\n description:\n \"Grant a user or org access to a shareable resource. Owner or admin role required.\",\n // (audit H5) Sharing-grant operations are admin-tier and let a caller\n // expand who can read/write a resource. Refuse from the tools iframe\n // bridge so a malicious shared tool can't silently re-share its\n // viewer's resources to an attacker-controlled email.\n toolCallable: false,\n schema: z.object({\n resourceType: z\n .string()\n .describe(\"Registered resource type, e.g. 'document', 'form'.\"),\n resourceId: z.string().describe(\"Id of the resource to share.\"),\n principalType: z\n .enum([\"user\", \"org\"])\n .describe(\"'user' for an individual, 'org' for a whole organization.\"),\n principalId: z\n .string()\n .describe(\"Email (user) or org id (org) of the principal.\"),\n role: z\n .enum([\"viewer\", \"editor\", \"admin\"])\n .default(\"viewer\")\n .describe(\"Role to grant.\"),\n notify: z\n .boolean()\n .default(true)\n .describe(\n \"Whether to email the user about a new individual share. Defaults to true.\",\n ),\n resourceUrl: z\n .string()\n .optional()\n .describe(\n \"Optional app-relative or same-origin URL recipients should open. External origins are ignored.\",\n ),\n }),\n run: async (args) => {\n const reg = requireShareableResource(args.resourceType);\n const access = await assertAccess(\n args.resourceType,\n args.resourceId,\n \"admin\",\n );\n const actor = getRequestUserEmail();\n if (!actor) throw new ForbiddenError(\"Not signed in\");\n const principalId = normalizePrincipalId(\n args.principalType,\n args.principalId,\n );\n const beforeExtensionTargets = await getExtensionShareChangeTargets(\n args.resourceType,\n args.resourceId,\n );\n\n if (reg.requireOrgMemberForUserShares) {\n const resourceOrgId = access.resource?.orgId as string | undefined | null;\n if (!resourceOrgId) {\n throw new ForbiddenError(\n `${reg.displayName} can only be shared from within an organization. Create or join an organization first.`,\n );\n }\n if (args.principalType === \"user\") {\n const ok = await isOrgMemberOrInvited(resourceOrgId, principalId);\n if (!ok) {\n throw new ForbiddenError(\n `${principalId} is not in your organization. Invite them to the organization first, then share.`,\n );\n }\n } else if (args.principalType === \"org\") {\n // Cross-org org shares would let an outside org's members run\n // extension code in the viewer's auth context — the same threat\n // model that blocks public + cross-org user shares. Pin org-\n // principal shares to the resource's own org.\n if (principalId !== resourceOrgId) {\n throw new ForbiddenError(\n `${reg.displayName} can only be shared with its own organization, not a different one.`,\n );\n }\n }\n }\n\n const db = reg.getDb() as any;\n const [existing] = await db\n .select()\n .from(reg.sharesTable)\n .where(\n and(\n eq(reg.sharesTable.resourceId, args.resourceId),\n eq(reg.sharesTable.principalType, args.principalType),\n principalIdMatches(reg.sharesTable, args.principalType, principalId),\n ),\n );\n\n if (existing) {\n await db\n .update(reg.sharesTable)\n .set({ role: args.role })\n .where(eq(reg.sharesTable.id, existing.id));\n invalidateCollabAccessCache(args.resourceType, args.resourceId);\n await notifyExtensionShareChanged(\n args.resourceType,\n args.resourceId,\n beforeExtensionTargets,\n );\n return { id: existing.id, updated: true };\n }\n\n const id = nanoid();\n await db.insert(reg.sharesTable).values({\n id,\n resourceId: args.resourceId,\n principalType: args.principalType,\n principalId,\n role: args.role,\n createdBy: actor,\n createdAt: new Date().toISOString(),\n });\n invalidateCollabAccessCache(args.resourceType, args.resourceId);\n await notifyExtensionShareChanged(\n args.resourceType,\n args.resourceId,\n beforeExtensionTargets,\n );\n\n if (\n args.notify !== false &&\n args.principalType === \"user\" &&\n (await isEmailConfigured()) &&\n !isSyntheticQaEmail(principalId)\n ) {\n try {\n const titleCol = reg.titleColumn ?? \"title\";\n const [resource] = await db\n .select()\n .from(reg.resourceTable)\n .where(eq(reg.resourceTable.id, args.resourceId));\n const resourceTitle: string =\n (resource?.[titleCol] as string | undefined) ?? args.resourceType;\n const appUrl = getAppProductionUrl();\n const resourcePath =\n resource && reg.getResourcePath\n ? reg.getResourcePath(resource)\n : undefined;\n const notificationUrl = resolveShareNotificationUrl(\n args.resourceUrl,\n resourcePath,\n appUrl,\n );\n const appName =\n process.env.APP_NAME || process.env.VITE_APP_NAME || \"Agent Native\";\n const subject = `${actor} shared \"${resourceTitle}\" with you on ${appName}`;\n const { html, text } = renderEmail({\n preheader: subject,\n heading: \"You've been given access\",\n paragraphs: [\n `${emailStrong(actor)} has shared the ${reg.displayName} ${emailStrong(resourceTitle)} with you as a ${emailStrong(args.role)}.`,\n `Use the button below to open it. If prompted, sign in with ${emailStrong(principalId)}.`,\n ],\n cta: { label: `Open ${reg.displayName}`, url: notificationUrl },\n footer: `You received this because ${actor} granted you ${args.role} access.`,\n });\n await sendEmail({ to: principalId, subject, html, text });\n } catch (err) {\n console.error(\n \"[share-resource] failed to send share notification:\",\n err,\n );\n }\n }\n\n return { id, updated: false };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"share-resource.js","sourceRoot":"","sources":["../../../src/sharing/actions/share-resource.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, sql, type SQL } from \"drizzle-orm\";\nimport { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport { getDbExec } from \"../../db/client.js\";\nimport { getAppProductionUrl } from \"../../server/app-url.js\";\nimport { renderEmail, emailStrong } from \"../../server/email-template.js\";\nimport { sendEmail, isEmailConfigured } from \"../../server/email.js\";\nimport { invalidateCollabAccessCache } from \"../../server/poll.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { assertAccess, ForbiddenError } from \"../access.js\";\nimport { requireShareableResource } from \"../registry.js\";\nimport {\n getExtensionShareChangeTargets,\n notifyExtensionShareChanged,\n} from \"./extension-change.js\";\n\nexport function isSyntheticQaEmail(email: string): boolean {\n const trimmed = email.trim().toLowerCase();\n const at = trimmed.lastIndexOf(\"@\");\n if (at <= 0) return false;\n const local = trimmed.slice(0, at);\n const domain = trimmed.slice(at + 1);\n return (\n local.includes(\"+qa\") &&\n (domain === \"example.test\" ||\n domain.endsWith(\".test\") ||\n domain === \"example.invalid\" ||\n domain.endsWith(\".invalid\"))\n );\n}\n\nfunction appPath(path: string): string {\n if (!path.startsWith(\"/\")) return path;\n const raw = process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH || \"\";\n const base = raw.trim().replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n if (!base) return path;\n const normalizedBase = `/${base}`;\n if (path === normalizedBase || path.startsWith(`${normalizedBase}/`)) {\n return path;\n }\n return `${normalizedBase}${path}`;\n}\n\nfunction safeNotificationUrl(value: string, appUrl: string): string | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n try {\n const base = new URL(appUrl);\n if (trimmed.startsWith(\"/\")) {\n const path = appPath(trimmed);\n const basePath = base.pathname.replace(/\\/+$/, \"\");\n const alreadyIncludesBase =\n basePath && basePath !== \"/\" && path.startsWith(`${basePath}/`);\n const joined = alreadyIncludesBase\n ? `${base.origin}${path}`\n : `${appUrl.replace(/\\/+$/, \"\")}${path}`;\n return new URL(joined).toString();\n }\n\n const url = new URL(trimmed);\n if (![\"http:\", \"https:\"].includes(url.protocol)) return null;\n if (url.origin !== base.origin) return null;\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport function resolveShareNotificationUrl(\n explicitUrl: string | undefined,\n fallbackPath: string | undefined,\n appUrl = getAppProductionUrl(),\n): string {\n for (const candidate of [explicitUrl, fallbackPath]) {\n if (!candidate) continue;\n const url = safeNotificationUrl(candidate, appUrl);\n if (url) return url;\n }\n return appUrl;\n}\n\nfunction nanoid(size = 12): string {\n const chars =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n let id = \"\";\n const bytes = crypto.getRandomValues(new Uint8Array(size));\n for (const byte of bytes) id += chars[byte % chars.length];\n return id;\n}\n\nfunction normalizePrincipalId(\n principalType: \"user\" | \"org\",\n principalId: string,\n): string {\n return principalType === \"user\"\n ? principalId.trim().toLowerCase()\n : principalId;\n}\n\nfunction isEmailPrincipalId(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+$/.test(value.trim());\n}\n\nfunction principalIdMatches(\n sharesTable: any,\n principalType: \"user\" | \"org\",\n principalId: string,\n): SQL {\n return principalType === \"user\"\n ? sql`lower(${sharesTable.principalId}) = ${principalId}`\n : eq(sharesTable.principalId, principalId);\n}\n\n/**\n * Returns true if the given email is either an active member of `orgId` or\n * has a pending invitation to `orgId`. Used by resources whose registration\n * sets `requireOrgMemberForUserShares` (currently extensions) to refuse\n * cross-org user shares.\n *\n * Both `org_members` and `org_invitations` store email case-insensitively\n * via `LOWER()` in the rest of the framework, so we follow the same\n * convention here.\n */\nasync function isOrgMemberOrInvited(\n orgId: string,\n email: string,\n): Promise<boolean> {\n const lower = email.trim().toLowerCase();\n if (!lower || !orgId) return false;\n const client = getDbExec();\n const member = await client.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [orgId, lower],\n });\n if (member.rows.length > 0) return true;\n const invited = await client.execute({\n sql: `SELECT 1 FROM org_invitations WHERE org_id = ? AND LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [orgId, lower],\n });\n return invited.rows.length > 0;\n}\n\nexport default defineAction({\n description:\n \"Grant a user or org access to a shareable resource. Owner or admin role required.\",\n // (audit H5) Sharing-grant operations are admin-tier and let a caller\n // expand who can read/write a resource. Refuse from the tools iframe\n // bridge so a malicious shared tool can't silently re-share its\n // viewer's resources to an attacker-controlled email.\n toolCallable: false,\n schema: z.object({\n resourceType: z\n .string()\n .describe(\"Registered resource type, e.g. 'document', 'form'.\"),\n resourceId: z.string().describe(\"Id of the resource to share.\"),\n principalType: z\n .enum([\"user\", \"org\"])\n .describe(\"'user' for an individual, 'org' for a whole organization.\"),\n principalId: z\n .string()\n .describe(\"Email (user) or org id (org) of the principal.\"),\n role: z\n .enum([\"viewer\", \"editor\", \"admin\"])\n .default(\"viewer\")\n .describe(\"Role to grant.\"),\n notify: z\n .boolean()\n .default(true)\n .describe(\n \"Whether to email the user about a new individual share. Defaults to true.\",\n ),\n resourceUrl: z\n .string()\n .optional()\n .describe(\n \"Optional app-relative or same-origin URL recipients should open. External origins are ignored.\",\n ),\n }),\n run: async (args) => {\n const reg = requireShareableResource(args.resourceType);\n const access = await assertAccess(\n args.resourceType,\n args.resourceId,\n \"admin\",\n );\n const actor = getRequestUserEmail();\n if (!actor) throw new ForbiddenError(\"Not signed in\");\n const principalId = normalizePrincipalId(\n args.principalType,\n args.principalId,\n );\n if (args.principalType === \"user\" && !isEmailPrincipalId(principalId)) {\n throw new Error(\n \"User shares must use an email address, not an internal user id.\",\n );\n }\n const beforeExtensionTargets = await getExtensionShareChangeTargets(\n args.resourceType,\n args.resourceId,\n );\n\n if (reg.requireOrgMemberForUserShares) {\n const resourceOrgId = access.resource?.orgId as string | undefined | null;\n if (!resourceOrgId) {\n throw new ForbiddenError(\n `${reg.displayName} can only be shared from within an organization. Create or join an organization first.`,\n );\n }\n if (args.principalType === \"user\") {\n const ok = await isOrgMemberOrInvited(resourceOrgId, principalId);\n if (!ok) {\n throw new ForbiddenError(\n `${principalId} is not in your organization. Invite them to the organization first, then share.`,\n );\n }\n } else if (args.principalType === \"org\") {\n // Cross-org org shares would let an outside org's members run\n // extension code in the viewer's auth context — the same threat\n // model that blocks public + cross-org user shares. Pin org-\n // principal shares to the resource's own org.\n if (principalId !== resourceOrgId) {\n throw new ForbiddenError(\n `${reg.displayName} can only be shared with its own organization, not a different one.`,\n );\n }\n }\n }\n\n const db = reg.getDb() as any;\n const [existing] = await db\n .select()\n .from(reg.sharesTable)\n .where(\n and(\n eq(reg.sharesTable.resourceId, args.resourceId),\n eq(reg.sharesTable.principalType, args.principalType),\n principalIdMatches(reg.sharesTable, args.principalType, principalId),\n ),\n );\n\n if (existing) {\n await db\n .update(reg.sharesTable)\n .set({ role: args.role })\n .where(eq(reg.sharesTable.id, existing.id));\n invalidateCollabAccessCache(args.resourceType, args.resourceId);\n await notifyExtensionShareChanged(\n args.resourceType,\n args.resourceId,\n beforeExtensionTargets,\n );\n return { id: existing.id, updated: true };\n }\n\n const id = nanoid();\n await db.insert(reg.sharesTable).values({\n id,\n resourceId: args.resourceId,\n principalType: args.principalType,\n principalId,\n role: args.role,\n createdBy: actor,\n createdAt: new Date().toISOString(),\n });\n invalidateCollabAccessCache(args.resourceType, args.resourceId);\n await notifyExtensionShareChanged(\n args.resourceType,\n args.resourceId,\n beforeExtensionTargets,\n );\n\n if (\n args.notify !== false &&\n args.principalType === \"user\" &&\n (await isEmailConfigured()) &&\n !isSyntheticQaEmail(principalId)\n ) {\n try {\n const titleCol = reg.titleColumn ?? \"title\";\n const [resource] = await db\n .select()\n .from(reg.resourceTable)\n .where(eq(reg.resourceTable.id, args.resourceId));\n const resourceTitle: string =\n (resource?.[titleCol] as string | undefined) ?? args.resourceType;\n const appUrl = getAppProductionUrl();\n const resourcePath =\n resource && reg.getResourcePath\n ? reg.getResourcePath(resource)\n : undefined;\n const notificationUrl = resolveShareNotificationUrl(\n args.resourceUrl,\n resourcePath,\n appUrl,\n );\n const appName =\n process.env.APP_NAME || process.env.VITE_APP_NAME || \"Agent Native\";\n const subject = `${actor} shared \"${resourceTitle}\" with you on ${appName}`;\n const { html, text } = renderEmail({\n preheader: subject,\n heading: \"You've been given access\",\n paragraphs: [\n `${emailStrong(actor)} has shared the ${reg.displayName} ${emailStrong(resourceTitle)} with you as a ${emailStrong(args.role)}.`,\n `Use the button below to open it. If prompted, sign in with ${emailStrong(principalId)}.`,\n ],\n cta: { label: `Open ${reg.displayName}`, url: notificationUrl },\n footer: `You received this because ${actor} granted you ${args.role} access.`,\n });\n await sendEmail({ to: principalId, subject, html, text });\n } catch (err) {\n console.error(\n \"[share-resource] failed to send share notification:\",\n err,\n );\n }\n }\n\n return { id, updated: false };\n },\n});\n"]}
|
|
@@ -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.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAa,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAa,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAqB1D,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAEL,KAAK,iCAAiC,EACvC,MAAM,kCAAkC,CAAC;AA0X1C;;;;;GAKG;AACH,iBAAS,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAgE9C;AAED;;;;;;GAMG;AACH,iBAAS,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkCvD;AAOD;;;;;GAKG;AACH,iBAAS,qBAAqB,CAC5B,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAc9C;AAoDD,iBAAS,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA2NrD;AAyKD,MAAM,WAAW,YAAY;IAC3B,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,YAAY,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IAC9E,oGAAoG;IACpG,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAClC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,iDAAiD;IACjD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,iDAAiD;IACjD,YAAY,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;IACvD,wCAAwC;IACxC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,iCAAiC,CAAC;IAChD;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,0BAA0B,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,mBAAmB,EACnB,SAAS,GAAG,aAAa,CAC1B;IACC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAkiBD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAWT;AAg7BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,OAAO,GAAE,4BAAiC,GACzC,MAAM,EAAE,CAcV;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,UAAU,CAU1E;AAED,OAAO,EACL,eAAe,IAAI,gBAAgB,EACnC,sBAAsB,IAAI,uBAAuB,EACjD,mBAAmB,IAAI,oBAAoB,EAC3C,qBAAqB,IAAI,sBAAsB,GAChD,CAAC"}
|