@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
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { IconHistory, IconSettings, IconUsers } from "@tabler/icons-react";
|
|
2
1
|
import {
|
|
2
|
+
IconHistory,
|
|
3
|
+
IconSearch,
|
|
4
|
+
IconSettings,
|
|
5
|
+
IconUsers,
|
|
6
|
+
IconX,
|
|
7
|
+
} from "@tabler/icons-react";
|
|
8
|
+
import {
|
|
9
|
+
useCallback,
|
|
3
10
|
useEffect,
|
|
4
11
|
useMemo,
|
|
5
12
|
useState,
|
|
@@ -11,11 +18,40 @@ import { cn } from "../utils.js";
|
|
|
11
18
|
|
|
12
19
|
type SettingsTabIcon = ComponentType<{ className?: string }>;
|
|
13
20
|
|
|
21
|
+
/**
|
|
22
|
+
* A single deep-link target inside settings that the settings search can jump
|
|
23
|
+
* to. Entries usually map to a section within a tab (via a `hash`/anchor id),
|
|
24
|
+
* making individual controls discoverable without hunting through every tab.
|
|
25
|
+
*/
|
|
26
|
+
export interface SettingsSearchEntry {
|
|
27
|
+
/** Stable unique id for the entry. */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Primary label shown in the search results. */
|
|
30
|
+
label: string;
|
|
31
|
+
/** Extra space-separated terms to match against (synonyms, provider names). */
|
|
32
|
+
keywords?: string;
|
|
33
|
+
/** Optional secondary description shown under the label. */
|
|
34
|
+
description?: string;
|
|
35
|
+
/** Tab to activate when the entry is picked. Defaults to the owning tab. */
|
|
36
|
+
tabId?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional section id / DOM element id to open + scroll to after switching
|
|
39
|
+
* tabs. Handled by the inner panels' own hash listeners.
|
|
40
|
+
*/
|
|
41
|
+
hash?: string;
|
|
42
|
+
/** Optional icon override; defaults to the owning tab's icon. */
|
|
43
|
+
icon?: SettingsTabIcon;
|
|
44
|
+
}
|
|
45
|
+
|
|
14
46
|
export interface SettingsTabItem {
|
|
15
47
|
id: string;
|
|
16
48
|
label: string;
|
|
17
49
|
icon?: SettingsTabIcon;
|
|
18
50
|
content: ReactNode;
|
|
51
|
+
/** Extra space-separated terms so this tab is findable via search. */
|
|
52
|
+
keywords?: string;
|
|
53
|
+
/** Deep-link entries within this tab for the settings search. */
|
|
54
|
+
searchEntries?: SettingsSearchEntry[];
|
|
19
55
|
}
|
|
20
56
|
|
|
21
57
|
export interface SettingsTabsPageProps {
|
|
@@ -31,6 +67,33 @@ export interface SettingsTabsPageProps {
|
|
|
31
67
|
className?: string;
|
|
32
68
|
navClassName?: string;
|
|
33
69
|
contentClassName?: string;
|
|
70
|
+
/** Whether to render the settings search box. Defaults to true. */
|
|
71
|
+
enableSearch?: boolean;
|
|
72
|
+
/** Placeholder for the settings search box. */
|
|
73
|
+
searchPlaceholder?: string;
|
|
74
|
+
/** Extra global search entries (e.g. anchors within the General tab). */
|
|
75
|
+
searchEntries?: SettingsSearchEntry[];
|
|
76
|
+
/** Deep-link entries for the General tab. */
|
|
77
|
+
generalSearchEntries?: SettingsSearchEntry[];
|
|
78
|
+
/**
|
|
79
|
+
* Controlled active tab id. When provided, the parent owns tab state (and is
|
|
80
|
+
* responsible for URL/app-state sync); the component skips its own hash-based
|
|
81
|
+
* tab tracking. Leave undefined for the default uncontrolled, hash-driven
|
|
82
|
+
* behavior.
|
|
83
|
+
*/
|
|
84
|
+
value?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Called whenever the active tab changes via a tab click or a search result
|
|
87
|
+
* selection. Fires in both controlled and uncontrolled modes.
|
|
88
|
+
*/
|
|
89
|
+
onValueChange?: (tabId: string) => void;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface ResolvedSearchEntry extends SettingsSearchEntry {
|
|
93
|
+
tabId: string;
|
|
94
|
+
tabLabel: string;
|
|
95
|
+
icon?: SettingsTabIcon;
|
|
96
|
+
haystack: string;
|
|
34
97
|
}
|
|
35
98
|
|
|
36
99
|
function normalizeTabId(value?: string | null): string | null {
|
|
@@ -88,6 +151,12 @@ export function SettingsTabsPage({
|
|
|
88
151
|
className,
|
|
89
152
|
navClassName,
|
|
90
153
|
contentClassName,
|
|
154
|
+
enableSearch = true,
|
|
155
|
+
searchPlaceholder = "Search settings",
|
|
156
|
+
searchEntries,
|
|
157
|
+
generalSearchEntries,
|
|
158
|
+
value,
|
|
159
|
+
onValueChange,
|
|
91
160
|
}: SettingsTabsPageProps) {
|
|
92
161
|
const tabs = useMemo<SettingsTabItem[]>(() => {
|
|
93
162
|
const next: SettingsTabItem[] = [
|
|
@@ -96,6 +165,7 @@ export function SettingsTabsPage({
|
|
|
96
165
|
label: generalLabel,
|
|
97
166
|
icon: IconSettings,
|
|
98
167
|
content: general,
|
|
168
|
+
searchEntries: generalSearchEntries,
|
|
99
169
|
},
|
|
100
170
|
];
|
|
101
171
|
next.push(...extraTabs);
|
|
@@ -120,6 +190,7 @@ export function SettingsTabsPage({
|
|
|
120
190
|
extraTabs,
|
|
121
191
|
general,
|
|
122
192
|
generalLabel,
|
|
193
|
+
generalSearchEntries,
|
|
123
194
|
team,
|
|
124
195
|
teamLabel,
|
|
125
196
|
whatsNew,
|
|
@@ -129,81 +200,257 @@ export function SettingsTabsPage({
|
|
|
129
200
|
const fallbackTab = tabs.some((tab) => tab.id === defaultTab)
|
|
130
201
|
? defaultTab
|
|
131
202
|
: (tabs[0]?.id ?? "general");
|
|
132
|
-
const
|
|
203
|
+
const isControlled = value !== undefined;
|
|
204
|
+
const [internalTab, setInternalTab] = useState(() =>
|
|
133
205
|
activeTabFromHash(tabs, fallbackTab),
|
|
134
206
|
);
|
|
207
|
+
const activeTab = isControlled ? value : internalTab;
|
|
208
|
+
const [query, setQuery] = useState("");
|
|
209
|
+
|
|
210
|
+
const changeTab = useCallback(
|
|
211
|
+
(tabId: string) => {
|
|
212
|
+
if (!isControlled) setInternalTab(tabId);
|
|
213
|
+
onValueChange?.(tabId);
|
|
214
|
+
},
|
|
215
|
+
[isControlled, onValueChange],
|
|
216
|
+
);
|
|
135
217
|
|
|
136
218
|
useEffect(() => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
219
|
+
// In controlled mode the parent owns (and validates) the active tab.
|
|
220
|
+
if (isControlled) return;
|
|
221
|
+
if (tabs.some((tab) => tab.id === internalTab)) return;
|
|
222
|
+
setInternalTab(fallbackTab);
|
|
223
|
+
}, [fallbackTab, internalTab, isControlled, tabs]);
|
|
140
224
|
|
|
141
225
|
useEffect(() => {
|
|
226
|
+
// Hash-driven tab tracking only applies to the uncontrolled mode. Only
|
|
227
|
+
// react to hashes that name a top-level tab. Section-level hashes
|
|
228
|
+
// (e.g. `#llm`, `#secrets`) are consumed by the inner panels, so leave
|
|
229
|
+
// the active tab untouched to avoid bouncing back to General.
|
|
230
|
+
if (isControlled) return;
|
|
142
231
|
const handleHashChange = () => {
|
|
143
|
-
|
|
232
|
+
const fromHash = normalizeTabId(window.location.hash);
|
|
233
|
+
if (fromHash && tabs.some((tab) => tab.id === fromHash)) {
|
|
234
|
+
setInternalTab(fromHash);
|
|
235
|
+
}
|
|
144
236
|
};
|
|
145
237
|
window.addEventListener("hashchange", handleHashChange);
|
|
146
238
|
return () => window.removeEventListener("hashchange", handleHashChange);
|
|
147
|
-
}, [
|
|
239
|
+
}, [isControlled, tabs]);
|
|
148
240
|
|
|
149
241
|
const selectedTab = tabs.find((tab) => tab.id === activeTab) ?? tabs[0];
|
|
150
242
|
|
|
243
|
+
// Flatten tab + deep-link entries into one searchable index.
|
|
244
|
+
const searchIndex = useMemo<ResolvedSearchEntry[]>(() => {
|
|
245
|
+
const entries: ResolvedSearchEntry[] = [];
|
|
246
|
+
const seen = new Set<string>();
|
|
247
|
+
const add = (entry: ResolvedSearchEntry) => {
|
|
248
|
+
if (seen.has(entry.id)) return;
|
|
249
|
+
seen.add(entry.id);
|
|
250
|
+
entries.push(entry);
|
|
251
|
+
};
|
|
252
|
+
for (const tab of tabs) {
|
|
253
|
+
add({
|
|
254
|
+
id: `tab:${tab.id}`,
|
|
255
|
+
label: tab.label,
|
|
256
|
+
keywords: tab.keywords,
|
|
257
|
+
tabId: tab.id,
|
|
258
|
+
tabLabel: tab.label,
|
|
259
|
+
icon: tab.icon,
|
|
260
|
+
haystack: `${tab.label} ${tab.keywords ?? ""}`.toLowerCase(),
|
|
261
|
+
});
|
|
262
|
+
for (const sub of tab.searchEntries ?? []) {
|
|
263
|
+
add({
|
|
264
|
+
...sub,
|
|
265
|
+
tabId: sub.tabId ?? tab.id,
|
|
266
|
+
tabLabel: tab.label,
|
|
267
|
+
icon: sub.icon ?? tab.icon,
|
|
268
|
+
haystack:
|
|
269
|
+
`${sub.label} ${sub.keywords ?? ""} ${sub.description ?? ""} ${tab.label}`.toLowerCase(),
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
for (const sub of searchEntries ?? []) {
|
|
274
|
+
const owner = tabs.find((tab) => tab.id === (sub.tabId ?? "general"));
|
|
275
|
+
add({
|
|
276
|
+
...sub,
|
|
277
|
+
tabId: sub.tabId ?? "general",
|
|
278
|
+
tabLabel: owner?.label ?? sub.tabId ?? "General",
|
|
279
|
+
icon: sub.icon ?? owner?.icon,
|
|
280
|
+
haystack:
|
|
281
|
+
`${sub.label} ${sub.keywords ?? ""} ${sub.description ?? ""} ${owner?.label ?? ""}`.toLowerCase(),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
return entries;
|
|
285
|
+
}, [searchEntries, tabs]);
|
|
286
|
+
|
|
287
|
+
const trimmedQuery = query.trim().toLowerCase();
|
|
288
|
+
const results = useMemo<ResolvedSearchEntry[]>(() => {
|
|
289
|
+
if (!trimmedQuery) return [];
|
|
290
|
+
const terms = trimmedQuery.split(/\s+/).filter(Boolean);
|
|
291
|
+
return searchIndex
|
|
292
|
+
.filter((entry) => terms.every((term) => entry.haystack.includes(term)))
|
|
293
|
+
.sort((a, b) => {
|
|
294
|
+
const aStarts = a.label.toLowerCase().startsWith(trimmedQuery) ? 0 : 1;
|
|
295
|
+
const bStarts = b.label.toLowerCase().startsWith(trimmedQuery) ? 0 : 1;
|
|
296
|
+
if (aStarts !== bStarts) return aStarts - bStarts;
|
|
297
|
+
return a.label.localeCompare(b.label);
|
|
298
|
+
});
|
|
299
|
+
}, [searchIndex, trimmedQuery]);
|
|
300
|
+
|
|
301
|
+
const selectEntry = (entry: ResolvedSearchEntry) => {
|
|
302
|
+
changeTab(entry.tabId);
|
|
303
|
+
setQuery("");
|
|
304
|
+
if (typeof window === "undefined") return;
|
|
305
|
+
const hash = entry.hash?.replace(/^#/, "");
|
|
306
|
+
if (hash) {
|
|
307
|
+
const { pathname, search } = window.location;
|
|
308
|
+
window.history.pushState(null, "", `${pathname}${search}#${hash}`);
|
|
309
|
+
// Let the inner panels open + scroll to their section.
|
|
310
|
+
window.dispatchEvent(new Event("hashchange"));
|
|
311
|
+
window.requestAnimationFrame(() => {
|
|
312
|
+
document
|
|
313
|
+
.getElementById(hash)
|
|
314
|
+
?.scrollIntoView({ block: "start", behavior: "smooth" });
|
|
315
|
+
});
|
|
316
|
+
} else if (!isControlled) {
|
|
317
|
+
updateHashForTab(entry.tabId);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const searching = enableSearch && trimmedQuery.length > 0;
|
|
322
|
+
|
|
151
323
|
return (
|
|
152
324
|
<div
|
|
153
325
|
className={cn(
|
|
154
|
-
"flex min-h-
|
|
326
|
+
"flex h-full min-h-0 w-full flex-col overflow-hidden bg-background sm:flex-row",
|
|
155
327
|
className,
|
|
156
328
|
)}
|
|
157
329
|
>
|
|
158
|
-
<
|
|
159
|
-
aria-label={ariaLabel}
|
|
160
|
-
role="tablist"
|
|
330
|
+
<div
|
|
161
331
|
className={cn(
|
|
162
|
-
"flex shrink-0
|
|
332
|
+
"flex shrink-0 flex-col gap-2 border-b border-border bg-background p-2 sm:min-h-0 sm:w-56 sm:overflow-y-auto sm:border-b-0 sm:border-e sm:p-3",
|
|
163
333
|
navClassName,
|
|
164
334
|
)}
|
|
165
335
|
>
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
updateHashForTab(tab.id);
|
|
336
|
+
{enableSearch ? (
|
|
337
|
+
<div className="relative sm:mb-1">
|
|
338
|
+
<IconSearch className="pointer-events-none absolute start-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
|
|
339
|
+
<input
|
|
340
|
+
type="search"
|
|
341
|
+
value={query}
|
|
342
|
+
onChange={(event) => setQuery(event.target.value)}
|
|
343
|
+
onKeyDown={(event) => {
|
|
344
|
+
if (event.key === "Escape") setQuery("");
|
|
345
|
+
if (event.key === "Enter" && results[0]) {
|
|
346
|
+
event.preventDefault();
|
|
347
|
+
selectEntry(results[0]);
|
|
348
|
+
}
|
|
180
349
|
}}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
350
|
+
placeholder={searchPlaceholder}
|
|
351
|
+
aria-label={searchPlaceholder}
|
|
352
|
+
className="h-8 w-full rounded-md border border-border bg-background ps-8 pe-7 text-[13px] text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-foreground/30 focus:ring-2 focus:ring-accent/40"
|
|
353
|
+
/>
|
|
354
|
+
{query ? (
|
|
355
|
+
<button
|
|
356
|
+
type="button"
|
|
357
|
+
onClick={() => setQuery("")}
|
|
358
|
+
aria-label="Clear search"
|
|
359
|
+
className="absolute end-1.5 top-1/2 flex size-5 -translate-y-1/2 items-center justify-center rounded text-muted-foreground hover:bg-accent/60 hover:text-foreground"
|
|
360
|
+
>
|
|
361
|
+
<IconX className="size-3.5" />
|
|
362
|
+
</button>
|
|
363
|
+
) : null}
|
|
364
|
+
</div>
|
|
365
|
+
) : null}
|
|
366
|
+
|
|
367
|
+
{searching ? (
|
|
368
|
+
<div
|
|
369
|
+
role="listbox"
|
|
370
|
+
aria-label="Settings search results"
|
|
371
|
+
className="flex flex-col gap-0.5"
|
|
372
|
+
>
|
|
373
|
+
{results.length === 0 ? (
|
|
374
|
+
<p className="px-2 py-6 text-center text-[12px] text-muted-foreground">
|
|
375
|
+
No matching settings
|
|
376
|
+
</p>
|
|
377
|
+
) : (
|
|
378
|
+
results.map((entry) => {
|
|
379
|
+
const Icon = entry.icon;
|
|
380
|
+
return (
|
|
381
|
+
<button
|
|
382
|
+
key={entry.id}
|
|
383
|
+
type="button"
|
|
384
|
+
role="option"
|
|
385
|
+
aria-selected={false}
|
|
386
|
+
onClick={() => selectEntry(entry)}
|
|
387
|
+
className="flex items-start gap-2 rounded-md px-2.5 py-2 text-start text-sm text-foreground transition-colors hover:bg-accent/60"
|
|
388
|
+
>
|
|
389
|
+
{Icon ? (
|
|
390
|
+
<Icon className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
|
|
391
|
+
) : null}
|
|
392
|
+
<span className="flex min-w-0 flex-col">
|
|
393
|
+
<span className="truncate font-medium">
|
|
394
|
+
{entry.label}
|
|
395
|
+
</span>
|
|
396
|
+
<span className="truncate text-[11px] text-muted-foreground">
|
|
397
|
+
{entry.description ?? entry.tabLabel}
|
|
398
|
+
</span>
|
|
399
|
+
</span>
|
|
400
|
+
</button>
|
|
401
|
+
);
|
|
402
|
+
})
|
|
403
|
+
)}
|
|
404
|
+
</div>
|
|
405
|
+
) : (
|
|
406
|
+
<nav
|
|
407
|
+
aria-label={ariaLabel}
|
|
408
|
+
role="tablist"
|
|
409
|
+
className="flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible"
|
|
410
|
+
>
|
|
411
|
+
{tabs.map((tab) => {
|
|
412
|
+
const Icon = tab.icon;
|
|
413
|
+
const selected = tab.id === selectedTab?.id;
|
|
414
|
+
return (
|
|
415
|
+
<button
|
|
416
|
+
key={tab.id}
|
|
417
|
+
type="button"
|
|
418
|
+
role="tab"
|
|
419
|
+
aria-selected={selected}
|
|
420
|
+
aria-controls={`settings-tabpanel-${tab.id}`}
|
|
421
|
+
id={`settings-tab-${tab.id}`}
|
|
422
|
+
onClick={() => {
|
|
423
|
+
changeTab(tab.id);
|
|
424
|
+
if (!isControlled) updateHashForTab(tab.id);
|
|
425
|
+
}}
|
|
190
426
|
className={cn(
|
|
191
|
-
"
|
|
192
|
-
selected
|
|
427
|
+
"flex min-h-9 shrink-0 items-center gap-2 rounded-md px-3 py-2 text-start text-sm font-medium transition-colors sm:w-full",
|
|
428
|
+
selected
|
|
429
|
+
? "bg-accent text-foreground"
|
|
430
|
+
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
|
|
193
431
|
)}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
432
|
+
>
|
|
433
|
+
{Icon ? (
|
|
434
|
+
<Icon
|
|
435
|
+
className={cn(
|
|
436
|
+
"size-4 shrink-0",
|
|
437
|
+
selected ? "text-foreground" : "text-muted-foreground",
|
|
438
|
+
)}
|
|
439
|
+
/>
|
|
440
|
+
) : null}
|
|
441
|
+
<span className="truncate">{tab.label}</span>
|
|
442
|
+
</button>
|
|
443
|
+
);
|
|
444
|
+
})}
|
|
445
|
+
</nav>
|
|
446
|
+
)}
|
|
447
|
+
</div>
|
|
201
448
|
<div
|
|
202
449
|
id={`settings-tabpanel-${selectedTab?.id ?? "general"}`}
|
|
203
450
|
role="tabpanel"
|
|
204
451
|
aria-labelledby={`settings-tab-${selectedTab?.id ?? "general"}`}
|
|
205
452
|
className={cn(
|
|
206
|
-
"min-w-0 flex-1 overflow-y-auto p-4 sm:p-6",
|
|
453
|
+
"min-h-0 min-w-0 flex-1 overflow-y-auto p-4 sm:p-6",
|
|
207
454
|
contentClassName,
|
|
208
455
|
)}
|
|
209
456
|
>
|
|
@@ -142,6 +142,7 @@ interface Share {
|
|
|
142
142
|
id: string;
|
|
143
143
|
principalType: "user" | "org";
|
|
144
144
|
principalId: string;
|
|
145
|
+
displayName?: string | null;
|
|
145
146
|
role: Role;
|
|
146
147
|
}
|
|
147
148
|
|
|
@@ -962,17 +963,11 @@ function SharePanel(
|
|
|
962
963
|
)}
|
|
963
964
|
>
|
|
964
965
|
<Avatar
|
|
965
|
-
label={
|
|
966
|
-
s.principalType === "org"
|
|
967
|
-
? s.principalId
|
|
968
|
-
: displayName(s.principalId, knownMembers)
|
|
969
|
-
}
|
|
966
|
+
label={principalLabel(s, knownMembers)}
|
|
970
967
|
org={s.principalType === "org"}
|
|
971
968
|
/>
|
|
972
969
|
<span className="flex-1 min-w-0 truncate">
|
|
973
|
-
{s
|
|
974
|
-
? s.principalId
|
|
975
|
-
: displayName(s.principalId, knownMembers)}
|
|
970
|
+
{principalLabel(s, knownMembers)}
|
|
976
971
|
</span>
|
|
977
972
|
{canManage ? (
|
|
978
973
|
<RoleSelect
|
|
@@ -1717,8 +1712,16 @@ function initials(s: string): string {
|
|
|
1717
1712
|
return (name[0] ?? "?").toUpperCase();
|
|
1718
1713
|
}
|
|
1719
1714
|
|
|
1720
|
-
function
|
|
1721
|
-
const
|
|
1715
|
+
function principalLabel(share: Share, members: OrgMember[]): string {
|
|
1716
|
+
const serverLabel = share.displayName?.trim();
|
|
1717
|
+
if (serverLabel) return serverLabel;
|
|
1718
|
+
if (share.principalType === "org") return "Organization";
|
|
1719
|
+
return displayName(share.principalId, members);
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
function displayName(emailOrId: string, members: OrgMember[]): string {
|
|
1723
|
+
const normalized = emailOrId.trim().toLowerCase();
|
|
1724
|
+
const match = members.find((m) => m.email.toLowerCase() === normalized);
|
|
1722
1725
|
if (match?.name && match.name.trim()) return match.name;
|
|
1723
|
-
return
|
|
1726
|
+
return normalized.includes("@") ? emailOrId : "Unknown person";
|
|
1724
1727
|
}
|
|
@@ -52,6 +52,7 @@ interface Share {
|
|
|
52
52
|
id: string;
|
|
53
53
|
principalType: "user" | "org";
|
|
54
54
|
principalId: string;
|
|
55
|
+
displayName?: string | null;
|
|
55
56
|
role: Role;
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -95,9 +96,10 @@ function useOrgMembers(): OrgMember[] {
|
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
function displayName(email: string, members: OrgMember[]): string {
|
|
98
|
-
const
|
|
99
|
+
const normalized = email.trim().toLowerCase();
|
|
100
|
+
const match = members.find((m) => m.email.toLowerCase() === normalized);
|
|
99
101
|
if (match?.name && match.name.trim()) return match.name;
|
|
100
|
-
return email;
|
|
102
|
+
return normalized.includes("@") ? email : "Unknown person";
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
const BUTTON_BASE =
|
|
@@ -552,17 +554,11 @@ function InviteTab(props: {
|
|
|
552
554
|
className="flex items-center gap-3 px-1 py-1.5 text-sm"
|
|
553
555
|
>
|
|
554
556
|
<Avatar
|
|
555
|
-
label={
|
|
556
|
-
s.principalType === "org"
|
|
557
|
-
? s.principalId
|
|
558
|
-
: displayName(s.principalId, orgMembers)
|
|
559
|
-
}
|
|
557
|
+
label={principalLabel(s, orgMembers)}
|
|
560
558
|
org={s.principalType === "org"}
|
|
561
559
|
/>
|
|
562
560
|
<span className="flex-1 min-w-0 truncate">
|
|
563
|
-
{s
|
|
564
|
-
? s.principalId
|
|
565
|
-
: displayName(s.principalId, orgMembers)}
|
|
561
|
+
{principalLabel(s, orgMembers)}
|
|
566
562
|
</span>
|
|
567
563
|
<span className="text-xs text-muted-foreground">
|
|
568
564
|
{cap(s.role)}
|
|
@@ -841,3 +837,10 @@ function getNotificationUrl(explicit?: string): string | undefined {
|
|
|
841
837
|
function cap(s: string): string {
|
|
842
838
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
843
839
|
}
|
|
840
|
+
|
|
841
|
+
function principalLabel(share: Share, members: OrgMember[]): string {
|
|
842
|
+
const serverLabel = share.displayName?.trim();
|
|
843
|
+
if (serverLabel) return serverLabel;
|
|
844
|
+
if (share.principalType === "org") return "Organization";
|
|
845
|
+
return displayName(share.principalId, members);
|
|
846
|
+
}
|
|
@@ -83,6 +83,7 @@ const ASK_APP_DEFAULT_INLINE_WAIT_MS = 20_000;
|
|
|
83
83
|
const ASK_APP_MAX_INLINE_WAIT_MS = 25_000;
|
|
84
84
|
const ASK_APP_POLL_INTERVAL_MS = 1_500;
|
|
85
85
|
const ASK_APP_A2A_REQUEST_TIMEOUT_MS = 10_000;
|
|
86
|
+
const ASK_APP_STATUS_RETRY_DELAYS_MS = [250, 750, 1_500] as const;
|
|
86
87
|
const ASK_APP_TERMINAL_STATES = new Set<string>([
|
|
87
88
|
"completed",
|
|
88
89
|
"failed",
|
|
@@ -321,8 +322,34 @@ async function fetchAskAppA2ATask(
|
|
|
321
322
|
taskId: string,
|
|
322
323
|
): Promise<AskAppTaskResult> {
|
|
323
324
|
const { client } = await createA2AClientForAskApp(route.origin);
|
|
324
|
-
|
|
325
|
-
|
|
325
|
+
let lastError: unknown;
|
|
326
|
+
for (
|
|
327
|
+
let attempt = 0;
|
|
328
|
+
attempt <= ASK_APP_STATUS_RETRY_DELAYS_MS.length;
|
|
329
|
+
attempt++
|
|
330
|
+
) {
|
|
331
|
+
try {
|
|
332
|
+
const task = await client.getTask(taskId);
|
|
333
|
+
return askAppTaskResult(route, task);
|
|
334
|
+
} catch (err) {
|
|
335
|
+
lastError = err;
|
|
336
|
+
const delayMs = ASK_APP_STATUS_RETRY_DELAYS_MS[attempt];
|
|
337
|
+
if (delayMs == null || !isTransientAskAppStatusError(err)) {
|
|
338
|
+
throw err;
|
|
339
|
+
}
|
|
340
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
throw lastError;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function isTransientAskAppStatusError(err: unknown): boolean {
|
|
347
|
+
const message = err instanceof Error ? err.message : String(err ?? "");
|
|
348
|
+
return (
|
|
349
|
+
/\bfetch failed\b|failed to fetch|networkerror|socket hang up|econnreset|etimedout|timeout|aborted/i.test(
|
|
350
|
+
message,
|
|
351
|
+
) || /A2A request failed \((?:429|500|502|503|504)\)/i.test(message)
|
|
352
|
+
);
|
|
326
353
|
}
|
|
327
354
|
|
|
328
355
|
/**
|