@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
|
@@ -1942,6 +1942,25 @@ function shouldPreselectDetailField(
|
|
|
1942
1942
|
return DETAIL_FIELD_NAME_HINTS.some((hint) => key.includes(hint));
|
|
1943
1943
|
}
|
|
1944
1944
|
|
|
1945
|
+
function sourceFieldIconType(
|
|
1946
|
+
sourceFieldType: string,
|
|
1947
|
+
): DocumentPropertyType | "name" {
|
|
1948
|
+
const normalized = sourceFieldType.trim().toLowerCase();
|
|
1949
|
+
if (normalized === "number") return "number";
|
|
1950
|
+
if (normalized === "datetime" || normalized === "date") return "date";
|
|
1951
|
+
if (normalized === "url") return "url";
|
|
1952
|
+
if (normalized === "boolean" || normalized === "checkbox") return "checkbox";
|
|
1953
|
+
if (
|
|
1954
|
+
normalized === "list" ||
|
|
1955
|
+
normalized === "array" ||
|
|
1956
|
+
normalized === "tags" ||
|
|
1957
|
+
normalized === "multi_select"
|
|
1958
|
+
) {
|
|
1959
|
+
return "multi_select";
|
|
1960
|
+
}
|
|
1961
|
+
return "text";
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1945
1964
|
function SourceDetailsFieldPicker({
|
|
1946
1965
|
documentId,
|
|
1947
1966
|
source,
|
|
@@ -2039,31 +2058,37 @@ function SourceDetailsFieldPicker({
|
|
|
2039
2058
|
</div>
|
|
2040
2059
|
) : (
|
|
2041
2060
|
<div className="grid min-w-0 gap-1">
|
|
2042
|
-
{fields.map((field) =>
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
className=
|
|
2051
|
-
|
|
2052
|
-
selected.has(field.id)
|
|
2053
|
-
? "border-[#2383e2] bg-[#2383e2] text-white"
|
|
2054
|
-
: "border-muted-foreground/40 text-transparent",
|
|
2055
|
-
)}
|
|
2061
|
+
{fields.map((field) => {
|
|
2062
|
+
const iconType = sourceFieldIconType(field.sourceFieldType);
|
|
2063
|
+
const Icon =
|
|
2064
|
+
iconType === "name" ? IconFileText : TYPE_ICONS[iconType];
|
|
2065
|
+
return (
|
|
2066
|
+
<button
|
|
2067
|
+
key={field.id}
|
|
2068
|
+
type="button"
|
|
2069
|
+
className="flex min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
2070
|
+
onClick={() => toggleField(field.id)}
|
|
2056
2071
|
>
|
|
2057
|
-
<
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2072
|
+
<span
|
|
2073
|
+
className={cn(
|
|
2074
|
+
"flex size-4 shrink-0 items-center justify-center rounded border",
|
|
2075
|
+
selected.has(field.id)
|
|
2076
|
+
? "border-[#2383e2] bg-[#2383e2] text-white"
|
|
2077
|
+
: "border-muted-foreground/40 text-transparent",
|
|
2078
|
+
)}
|
|
2079
|
+
>
|
|
2080
|
+
<IconCheck className="size-3" />
|
|
2081
|
+
</span>
|
|
2082
|
+
<Icon className="size-3.5 shrink-0 text-muted-foreground" />
|
|
2083
|
+
<span className="min-w-0 flex-1 truncate">
|
|
2084
|
+
{field.sourceFieldLabel}
|
|
2085
|
+
</span>
|
|
2086
|
+
<span className="shrink-0 text-[11px] text-muted-foreground">
|
|
2087
|
+
{field.sourceFieldType}
|
|
2088
|
+
</span>
|
|
2089
|
+
</button>
|
|
2090
|
+
);
|
|
2091
|
+
})}
|
|
2067
2092
|
</div>
|
|
2068
2093
|
)}
|
|
2069
2094
|
<div className="flex justify-end gap-2">
|
|
@@ -4,9 +4,11 @@ import {
|
|
|
4
4
|
SettingsTabsPage,
|
|
5
5
|
useAgentSettingsTabs,
|
|
6
6
|
useT,
|
|
7
|
+
type SettingsSearchEntry,
|
|
7
8
|
} from "@agent-native/core/client";
|
|
8
9
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
9
10
|
import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
|
|
11
|
+
import { useMemo } from "react";
|
|
10
12
|
|
|
11
13
|
import { Label } from "@/components/ui/label";
|
|
12
14
|
import { messagesByLocale } from "@/i18n-data";
|
|
@@ -22,18 +24,34 @@ export default function SettingsRoute() {
|
|
|
22
24
|
const agentSettingsTabs = useAgentSettingsTabs();
|
|
23
25
|
useSetPageTitle(t("settings.title"));
|
|
24
26
|
|
|
27
|
+
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
28
|
+
() => [
|
|
29
|
+
{
|
|
30
|
+
id: "content-language",
|
|
31
|
+
label: t("settings.languageTitle"),
|
|
32
|
+
keywords: "language locale translation i18n",
|
|
33
|
+
hash: "language",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
[t],
|
|
37
|
+
);
|
|
38
|
+
|
|
25
39
|
return (
|
|
26
40
|
<div className="flex-1 overflow-auto">
|
|
27
41
|
<SettingsTabsPage
|
|
28
42
|
teamLabel={t("team.pageTitle")}
|
|
29
43
|
extraTabs={agentSettingsTabs}
|
|
44
|
+
generalSearchEntries={generalSearchEntries}
|
|
30
45
|
general={
|
|
31
46
|
<main className="mx-auto w-full max-w-3xl space-y-6">
|
|
32
47
|
<p className="text-sm leading-6 text-muted-foreground">
|
|
33
48
|
{t("settings.description")}
|
|
34
49
|
</p>
|
|
35
50
|
|
|
36
|
-
<section
|
|
51
|
+
<section
|
|
52
|
+
id="language"
|
|
53
|
+
className="scroll-mt-16 rounded-lg border border-border bg-card p-5"
|
|
54
|
+
>
|
|
37
55
|
<div className="space-y-1">
|
|
38
56
|
<h2 className="text-base font-semibold">
|
|
39
57
|
{t("settings.languageTitle")}
|
|
@@ -551,6 +551,48 @@ export function normalizePropertyValue(
|
|
|
551
551
|
}
|
|
552
552
|
}
|
|
553
553
|
|
|
554
|
+
function optionMatchKey(value: string) {
|
|
555
|
+
return value.trim().toLowerCase();
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export function normalizePropertyValueWithOptions(
|
|
559
|
+
type: DocumentPropertyType,
|
|
560
|
+
value: unknown,
|
|
561
|
+
options?: DocumentPropertyOptions,
|
|
562
|
+
): DocumentPropertyValue {
|
|
563
|
+
const normalized = normalizePropertyValue(type, value);
|
|
564
|
+
const optionList = options?.options ?? [];
|
|
565
|
+
if (
|
|
566
|
+
normalized === null ||
|
|
567
|
+
optionList.length === 0 ||
|
|
568
|
+
(type !== "select" && type !== "status" && type !== "multi_select")
|
|
569
|
+
) {
|
|
570
|
+
return normalized;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
const optionIdByName = new Map(
|
|
574
|
+
optionList.map((option) => [optionMatchKey(option.name), option.id]),
|
|
575
|
+
);
|
|
576
|
+
const optionIds = new Set(optionList.map((option) => option.id));
|
|
577
|
+
const resolveOptionId = (candidate: string) =>
|
|
578
|
+
optionIds.has(candidate)
|
|
579
|
+
? candidate
|
|
580
|
+
: (optionIdByName.get(optionMatchKey(candidate)) ?? candidate);
|
|
581
|
+
|
|
582
|
+
if (type === "multi_select") {
|
|
583
|
+
const resolved = new Set<string>();
|
|
584
|
+
for (const item of Array.isArray(normalized) ? normalized : []) {
|
|
585
|
+
const optionId = resolveOptionId(item);
|
|
586
|
+
if (optionId.trim()) resolved.add(optionId);
|
|
587
|
+
}
|
|
588
|
+
return Array.from(resolved);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
return typeof normalized === "string"
|
|
592
|
+
? resolveOptionId(normalized)
|
|
593
|
+
: normalized;
|
|
594
|
+
}
|
|
595
|
+
|
|
554
596
|
export function formulaValueText(value: DocumentPropertyValue): string {
|
|
555
597
|
if (value === null || value === undefined) return "";
|
|
556
598
|
if (Array.isArray(value)) return value.join(", ");
|
|
@@ -246,6 +246,15 @@ patterns live in `.agents/skills/`.
|
|
|
246
246
|
the latest localhost connection or a specific `connectionId`. Pass `routes`
|
|
247
247
|
with `path`/`url` when visualizing a flow; pass `paths` for a concise route
|
|
248
248
|
list. Then call `navigate --view editor --designId <id> --editorView overview`.
|
|
249
|
+
- `write-local-file`: writes/patches a local file through the bridge, but only
|
|
250
|
+
when a user-approved write-consent grant exists. Granting is human-only
|
|
251
|
+
(`grant-localhost-write-consent` is hidden from agents), so you cannot approve
|
|
252
|
+
it yourself.
|
|
253
|
+
- `request-localhost-write-consent`: call this when `write-local-file` fails
|
|
254
|
+
with "no write-consent grant". It opens the write-consent dialog in the
|
|
255
|
+
editor (or reports `alreadyGranted`). Tell the user to click "Allow writes",
|
|
256
|
+
then retry `write-local-file`. Do not keep retrying blindly — the write stays
|
|
257
|
+
blocked until the user approves.
|
|
249
258
|
|
|
250
259
|
## Review, Breakpoints, Screen States & Components
|
|
251
260
|
|
|
@@ -125,6 +125,9 @@ const generateDesignAction = defineAction({
|
|
|
125
125
|
"Do not use this action to replace a selected variant screen after a " +
|
|
126
126
|
"variant pick; call `get-design-snapshot` for the selected `fileId` and " +
|
|
127
127
|
"`edit-design` that same `fileId` instead. " +
|
|
128
|
+
"When `designSystemId` is provided, first use `get-design-system` and apply " +
|
|
129
|
+
"its `agentContext` tokens/docs before writing the file content; do not " +
|
|
130
|
+
"treat the id alone as enough design-system context. " +
|
|
128
131
|
"Do not report a design as ready until this action succeeds. " +
|
|
129
132
|
"When adding multiple screens or states, pass canvasFrames with filenames " +
|
|
130
133
|
"and x/y/width/height so the new screens appear placed on the overview canvas.",
|
|
@@ -8,9 +8,146 @@ import { z } from "zod";
|
|
|
8
8
|
|
|
9
9
|
import "../server/db/index.js"; // ensure registerShareableResource runs
|
|
10
10
|
|
|
11
|
+
const MAX_AGENT_CONTEXT_CHARS = 14_000;
|
|
12
|
+
const MAX_JSON_CONTEXT_CHARS = 2_500;
|
|
13
|
+
const MAX_BUILDER_DOCS = 8;
|
|
14
|
+
const MAX_BUILDER_DOC_CHARS = 1_200;
|
|
15
|
+
const MAX_TOKEN_VALUES = 48;
|
|
16
|
+
|
|
17
|
+
interface BuilderGenerationContext {
|
|
18
|
+
builderDesignSystemId: string;
|
|
19
|
+
builderJobId: string;
|
|
20
|
+
builderProjectId?: string;
|
|
21
|
+
builderUrl?: string;
|
|
22
|
+
builderStatus?: string;
|
|
23
|
+
docs: Array<{
|
|
24
|
+
name?: string;
|
|
25
|
+
type?: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
content?: string;
|
|
28
|
+
tokenValues?: Record<string, string>;
|
|
29
|
+
}>;
|
|
30
|
+
tokenValues: Record<string, string>;
|
|
31
|
+
docCount: number;
|
|
32
|
+
warning?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function truncate(value: string, maxChars: number): string {
|
|
36
|
+
if (value.length <= maxChars) return value;
|
|
37
|
+
return `${value.slice(0, maxChars).trimEnd()}\n[truncated]`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseJson(value: string | null | undefined): unknown {
|
|
41
|
+
if (!value) return null;
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(value);
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function formatJson(value: unknown, maxChars = MAX_JSON_CONTEXT_CHARS): string {
|
|
50
|
+
return truncate(JSON.stringify(value, null, 2), maxChars);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function formatTokenValues(tokenValues: Record<string, string>): string[] {
|
|
54
|
+
const entries = Object.entries(tokenValues)
|
|
55
|
+
.filter(([, value]) => typeof value === "string" && value.trim())
|
|
56
|
+
.slice(0, MAX_TOKEN_VALUES);
|
|
57
|
+
if (entries.length === 0) return [];
|
|
58
|
+
return [
|
|
59
|
+
"Builder DSI token values to apply first:",
|
|
60
|
+
...entries.map(([name, value]) => `- ${name}: ${value}`),
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function buildDesignSystemAgentContext({
|
|
65
|
+
id,
|
|
66
|
+
title,
|
|
67
|
+
description,
|
|
68
|
+
data,
|
|
69
|
+
assets,
|
|
70
|
+
customInstructions,
|
|
71
|
+
builder,
|
|
72
|
+
}: {
|
|
73
|
+
id: string;
|
|
74
|
+
title: string;
|
|
75
|
+
description?: string | null;
|
|
76
|
+
data?: string | null;
|
|
77
|
+
assets?: string | null;
|
|
78
|
+
customInstructions?: string | null;
|
|
79
|
+
builder: BuilderGenerationContext | null;
|
|
80
|
+
}): string {
|
|
81
|
+
const lines: string[] = [
|
|
82
|
+
"## Selected Design System Context",
|
|
83
|
+
`Use "${title}" (id: ${id}) as the visual source of truth for this generation.`,
|
|
84
|
+
"Apply these tokens, assets, and usage notes before choosing colors, type, spacing, radius, imagery, or component language.",
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
if (description?.trim()) {
|
|
88
|
+
lines.push("", "Description:", description.trim());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (customInstructions?.trim()) {
|
|
92
|
+
lines.push("", "Custom instructions:", customInstructions.trim());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const parsedAssets = parseJson(assets);
|
|
96
|
+
if (Array.isArray(parsedAssets) && parsedAssets.length > 0) {
|
|
97
|
+
lines.push("", "Design system assets:", formatJson(parsedAssets));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (builder) {
|
|
101
|
+
lines.push(
|
|
102
|
+
"",
|
|
103
|
+
"Builder DSI:",
|
|
104
|
+
`- Design system id: ${builder.builderDesignSystemId}`,
|
|
105
|
+
`- Job id: ${builder.builderJobId}`,
|
|
106
|
+
builder.builderProjectId
|
|
107
|
+
? `- Project id: ${builder.builderProjectId}`
|
|
108
|
+
: "",
|
|
109
|
+
builder.builderUrl ? `- URL: ${builder.builderUrl}` : "",
|
|
110
|
+
builder.builderStatus ? `- Status: ${builder.builderStatus}` : "",
|
|
111
|
+
"- Builder DSI docs and token values override local proxy placeholders.",
|
|
112
|
+
"- Do not substitute a generic style if DSI docs or tokens are unavailable; call get-design-system again or tell the user Builder indexing is not ready.",
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (builder.warning) {
|
|
116
|
+
lines.push(`- Warning: ${builder.warning}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
lines.push("", ...formatTokenValues(builder.tokenValues));
|
|
120
|
+
|
|
121
|
+
const docs = builder.docs.slice(0, MAX_BUILDER_DOCS);
|
|
122
|
+
if (docs.length > 0) {
|
|
123
|
+
lines.push("", "Builder DSI docs to follow:");
|
|
124
|
+
for (const doc of docs) {
|
|
125
|
+
const label = [doc.name, doc.type ? `(${doc.type})` : ""]
|
|
126
|
+
.filter(Boolean)
|
|
127
|
+
.join(" ");
|
|
128
|
+
lines.push(
|
|
129
|
+
"",
|
|
130
|
+
`### ${label || "Design system doc"}`,
|
|
131
|
+
doc.description?.trim() ? doc.description.trim() : "",
|
|
132
|
+
doc.content?.trim()
|
|
133
|
+
? truncate(doc.content.trim(), MAX_BUILDER_DOC_CHARS)
|
|
134
|
+
: "",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
const parsedData = parseJson(data);
|
|
140
|
+
if (parsedData) {
|
|
141
|
+
lines.push("", "Local design-system tokens:", formatJson(parsedData));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return truncate(lines.filter(Boolean).join("\n"), MAX_AGENT_CONTEXT_CHARS);
|
|
146
|
+
}
|
|
147
|
+
|
|
11
148
|
export default defineAction({
|
|
12
149
|
description:
|
|
13
|
-
"Get a design system by ID. Returns full design system data including colors, typography, spacing, and
|
|
150
|
+
"Get a design system by ID. Returns full design system data including colors, typography, spacing, assets, and a compact agentContext for generation.",
|
|
14
151
|
schema: z.object({
|
|
15
152
|
id: z.string().describe("Design system ID"),
|
|
16
153
|
}),
|
|
@@ -51,6 +188,15 @@ export default defineAction({
|
|
|
51
188
|
createdAt: row.createdAt,
|
|
52
189
|
updatedAt: row.updatedAt,
|
|
53
190
|
builder,
|
|
191
|
+
agentContext: buildDesignSystemAgentContext({
|
|
192
|
+
id: row.id,
|
|
193
|
+
title: row.title,
|
|
194
|
+
description: row.description,
|
|
195
|
+
data: row.data,
|
|
196
|
+
assets: row.assets,
|
|
197
|
+
customInstructions: row.customInstructions,
|
|
198
|
+
builder,
|
|
199
|
+
}),
|
|
54
200
|
};
|
|
55
201
|
},
|
|
56
202
|
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
readAppStateForCurrentTab,
|
|
4
|
+
writeAppState,
|
|
5
|
+
} from "@agent-native/core/application-state";
|
|
6
|
+
import { getRequestUserEmail } from "@agent-native/core/server/request-context";
|
|
7
|
+
import { assertAccess } from "@agent-native/core/sharing";
|
|
8
|
+
import { and, eq } from "drizzle-orm";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Surface the LocalhostWriteConsentDialog so the user can approve local file
|
|
15
|
+
* writes. Granting is human-only (`grant-localhost-write-consent` is
|
|
16
|
+
* `agentTool: false`), so an agent writing from chat can only *request* the
|
|
17
|
+
* prompt: this writes an app-state key the editor observes and opens the dialog.
|
|
18
|
+
* If a valid grant already exists it reports that instead of prompting again.
|
|
19
|
+
*/
|
|
20
|
+
export default defineAction({
|
|
21
|
+
description:
|
|
22
|
+
"Prompt the user to allow local file writes for a design's localhost " +
|
|
23
|
+
"connection by opening the write-consent dialog in the editor. Write " +
|
|
24
|
+
"consent itself is human-only and cannot be granted by the agent. Call " +
|
|
25
|
+
"this when write-local-file fails because no write-consent grant exists, " +
|
|
26
|
+
"then retry write-local-file after the user approves. Requires editor " +
|
|
27
|
+
"access on the design.",
|
|
28
|
+
schema: z.object({
|
|
29
|
+
designId: z.string().describe("Design ID."),
|
|
30
|
+
connectionId: z
|
|
31
|
+
.string()
|
|
32
|
+
.describe("Localhost connection ID (from list-localhost-connections)."),
|
|
33
|
+
files: z
|
|
34
|
+
.array(z.string())
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("File paths about to be written, shown in the dialog."),
|
|
37
|
+
}),
|
|
38
|
+
run: async ({ designId, connectionId, files }) => {
|
|
39
|
+
await assertAccess("design", designId, "editor");
|
|
40
|
+
|
|
41
|
+
const ownerEmail = getRequestUserEmail();
|
|
42
|
+
if (!ownerEmail) throw new Error("no authenticated user");
|
|
43
|
+
|
|
44
|
+
const db = getDb();
|
|
45
|
+
const [connection] = await db
|
|
46
|
+
.select({
|
|
47
|
+
rootPath: schema.designLocalhostConnections.rootPath,
|
|
48
|
+
bridgeToken: schema.designLocalhostConnections.bridgeToken,
|
|
49
|
+
})
|
|
50
|
+
.from(schema.designLocalhostConnections)
|
|
51
|
+
.where(
|
|
52
|
+
and(
|
|
53
|
+
eq(schema.designLocalhostConnections.id, connectionId),
|
|
54
|
+
eq(schema.designLocalhostConnections.ownerEmail, ownerEmail),
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
.limit(1);
|
|
58
|
+
|
|
59
|
+
if (!connection) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Localhost connection "${connectionId}" not found for the current user.`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Fail fast on the same preconditions grant-localhost-write-consent
|
|
66
|
+
// enforces, so we never show a dialog that would hard-fail on approval —
|
|
67
|
+
// or one labeled with the connection id instead of a real folder.
|
|
68
|
+
if (!connection.rootPath || !connection.bridgeToken) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Connection "${connectionId}" is not ready for writes (missing root ` +
|
|
71
|
+
"path or bridge token). Re-run `npx @agent-native/core@latest design " +
|
|
72
|
+
"connect` so the CLI records both, then retry.",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Skip the prompt when a non-expired grant already covers this connection —
|
|
77
|
+
// the agent can just retry write-local-file.
|
|
78
|
+
const [grant] = await db
|
|
79
|
+
.select({
|
|
80
|
+
grantedUntil: schema.designLocalhostWriteGrants.grantedUntil,
|
|
81
|
+
})
|
|
82
|
+
.from(schema.designLocalhostWriteGrants)
|
|
83
|
+
.where(
|
|
84
|
+
and(
|
|
85
|
+
eq(schema.designLocalhostWriteGrants.designId, designId),
|
|
86
|
+
eq(schema.designLocalhostWriteGrants.connectionId, connectionId),
|
|
87
|
+
eq(schema.designLocalhostWriteGrants.ownerEmail, ownerEmail),
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
.limit(1);
|
|
91
|
+
if (grant && grant.grantedUntil > new Date().toISOString()) {
|
|
92
|
+
return {
|
|
93
|
+
designId,
|
|
94
|
+
connectionId,
|
|
95
|
+
alreadyGranted: true,
|
|
96
|
+
message:
|
|
97
|
+
"A valid write-consent grant already exists. Retry write-local-file.",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
await writeAppState(`design-localhost-write-consent-request:${designId}`, {
|
|
102
|
+
designId,
|
|
103
|
+
connectionId,
|
|
104
|
+
rootPath: connection.rootPath,
|
|
105
|
+
files: files ?? [],
|
|
106
|
+
requestedAt: new Date().toISOString(),
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// The dialog only renders from this design's editor, so only claim it
|
|
110
|
+
// surfaced when the user is actually there. Otherwise the request stays
|
|
111
|
+
// queued and fires when they open the design — report that honestly instead
|
|
112
|
+
// of implying a dialog is on screen.
|
|
113
|
+
const navigation = await readAppStateForCurrentTab("navigation").catch(
|
|
114
|
+
() => null,
|
|
115
|
+
);
|
|
116
|
+
const onThisEditor =
|
|
117
|
+
navigation?.["view"] === "editor" &&
|
|
118
|
+
navigation?.["designId"] === designId;
|
|
119
|
+
|
|
120
|
+
if (onThisEditor) {
|
|
121
|
+
return {
|
|
122
|
+
designId,
|
|
123
|
+
connectionId,
|
|
124
|
+
surfaced: true,
|
|
125
|
+
message:
|
|
126
|
+
"Opened the write-consent dialog. Ask the user to click 'Allow " +
|
|
127
|
+
"writes', then retry write-local-file.",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
designId,
|
|
133
|
+
connectionId,
|
|
134
|
+
surfaced: false,
|
|
135
|
+
message:
|
|
136
|
+
"Queued a write-consent request, but the user is not on this design's " +
|
|
137
|
+
"editor so no dialog is showing yet. Ask them to open the design; the " +
|
|
138
|
+
"prompt appears then, and you can retry write-local-file after they approve.",
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
});
|
|
@@ -1315,25 +1315,21 @@ export function DesignCanvas({
|
|
|
1315
1315
|
(fetchedExternalSnapshot?.url === rawExternalPreviewUrl
|
|
1316
1316
|
? fetchedExternalSnapshot.html
|
|
1317
1317
|
: undefined);
|
|
1318
|
+
// Bake a neutral scale of 1 here (not the zoom-folded scale): this script is
|
|
1319
|
+
// registered with the localhost bridge via a large POST, so folding live zoom
|
|
1320
|
+
// in would re-fire the registration effect on every zoom tick. Live scale is
|
|
1321
|
+
// pushed separately over the `set-editor-chrome-scale` postMessage below.
|
|
1318
1322
|
const editorChromeBridgeForCurrentState = useMemo(
|
|
1319
1323
|
() =>
|
|
1320
1324
|
buildEditorChromeBridgeScript({
|
|
1321
1325
|
readOnly,
|
|
1322
1326
|
editMode,
|
|
1323
|
-
editorChromeScaleX:
|
|
1324
|
-
editorChromeScaleY:
|
|
1327
|
+
editorChromeScaleX: 1,
|
|
1328
|
+
editorChromeScaleY: 1,
|
|
1325
1329
|
screenId: screenId ?? contentKey ?? "",
|
|
1326
1330
|
boardSurface,
|
|
1327
1331
|
}),
|
|
1328
|
-
[
|
|
1329
|
-
boardSurface,
|
|
1330
|
-
contentKey,
|
|
1331
|
-
editMode,
|
|
1332
|
-
effectiveEditorChromeScaleX,
|
|
1333
|
-
effectiveEditorChromeScaleY,
|
|
1334
|
-
readOnly,
|
|
1335
|
-
screenId,
|
|
1336
|
-
],
|
|
1332
|
+
[boardSurface, contentKey, editMode, readOnly, screenId],
|
|
1337
1333
|
);
|
|
1338
1334
|
const embeddedWheelBridgeForCurrentState = useMemo(
|
|
1339
1335
|
() =>
|
|
@@ -1400,6 +1396,9 @@ export function DesignCanvas({
|
|
|
1400
1396
|
onExternalContentSnapshotRef.current = onExternalContentSnapshot;
|
|
1401
1397
|
}, [onExternalContentSnapshot]);
|
|
1402
1398
|
|
|
1399
|
+
// Register the editor bridge script with the localhost live-edit bridge so
|
|
1400
|
+
// it gets injected into the proxied preview. Re-runs only when the script
|
|
1401
|
+
// content (liveEditBridgeKey) or the bridge target changes.
|
|
1403
1402
|
useEffect(() => {
|
|
1404
1403
|
if (!usesLiveEditEditorBridge || !bridgeUrl) {
|
|
1405
1404
|
setRegisteredLiveEditBridgeKey(null);
|
|
@@ -1410,8 +1409,8 @@ export function DesignCanvas({
|
|
|
1410
1409
|
current === liveEditBridgeKey ? current : null,
|
|
1411
1410
|
);
|
|
1412
1411
|
void (async () => {
|
|
1412
|
+
const endpoint = new URL("/live-edit-bridge", bridgeUrl).toString();
|
|
1413
1413
|
try {
|
|
1414
|
-
const endpoint = new URL("/live-edit-bridge", bridgeUrl).toString();
|
|
1415
1414
|
const response = await fetch(endpoint, {
|
|
1416
1415
|
method: "POST",
|
|
1417
1416
|
headers: {
|
|
@@ -1423,15 +1422,10 @@ export function DesignCanvas({
|
|
|
1423
1422
|
if (!response.ok) {
|
|
1424
1423
|
throw new Error(`Bridge registration failed (${response.status})`);
|
|
1425
1424
|
}
|
|
1426
|
-
if (!cancelled)
|
|
1427
|
-
setRegisteredLiveEditBridgeKey(liveEditBridgeKey);
|
|
1428
|
-
}
|
|
1425
|
+
if (!cancelled) setRegisteredLiveEditBridgeKey(liveEditBridgeKey);
|
|
1429
1426
|
} catch (error) {
|
|
1430
1427
|
if (!cancelled) {
|
|
1431
|
-
console.warn(
|
|
1432
|
-
"[DesignCanvas] live edit bridge registration failed",
|
|
1433
|
-
error,
|
|
1434
|
-
);
|
|
1428
|
+
console.warn("live-edit bridge registration failed", error);
|
|
1435
1429
|
setRegisteredLiveEditBridgeKey(null);
|
|
1436
1430
|
}
|
|
1437
1431
|
}
|
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
LanguagePicker,
|
|
5
5
|
useAgentSettingsTabs,
|
|
6
6
|
useT,
|
|
7
|
+
type SettingsSearchEntry,
|
|
7
8
|
} from "@agent-native/core/client";
|
|
8
9
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
10
|
+
import { useMemo } from "react";
|
|
9
11
|
|
|
10
12
|
import {
|
|
11
13
|
Card,
|
|
@@ -27,13 +29,26 @@ export default function SettingsRoute() {
|
|
|
27
29
|
const agentSettingsTabs = useAgentSettingsTabs();
|
|
28
30
|
const t = useT();
|
|
29
31
|
|
|
32
|
+
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
33
|
+
() => [
|
|
34
|
+
{
|
|
35
|
+
id: "design-language",
|
|
36
|
+
label: t("settings.languageTitle"),
|
|
37
|
+
keywords: "language locale translation i18n",
|
|
38
|
+
hash: "language",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
[t],
|
|
42
|
+
);
|
|
43
|
+
|
|
30
44
|
return (
|
|
31
45
|
<div className="flex h-full min-h-0 flex-col overflow-y-auto bg-background">
|
|
32
46
|
<SettingsTabsPage
|
|
33
47
|
extraTabs={agentSettingsTabs}
|
|
48
|
+
generalSearchEntries={generalSearchEntries}
|
|
34
49
|
general={
|
|
35
50
|
<div className="mx-auto w-full max-w-2xl space-y-6">
|
|
36
|
-
<Card>
|
|
51
|
+
<Card id="language" className="scroll-mt-16">
|
|
37
52
|
<CardHeader>
|
|
38
53
|
<CardTitle className="text-base">
|
|
39
54
|
{t("settings.languageTitle")}
|