@agent-native/core 0.141.6 → 0.144.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-native.eject.json +9 -0
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +11 -6
- package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
- package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/AGENTS.md +37 -40
- package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
- package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
- package/corpus/templates/analytics/actions/navigate.ts +5 -6
- package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +46 -13
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
- package/corpus/templates/analytics/actions/view-screen.ts +0 -20
- package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
- package/corpus/templates/analytics/app/i18n-data.ts +682 -90
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
- package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
- package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
- package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/analytics/app/routes/team.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
- package/corpus/templates/analytics/server/db/index.ts +27 -0
- package/corpus/templates/analytics/server/db/schema.ts +10 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1147 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +34 -15
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -4
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -4
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
- package/corpus/templates/analytics/server/plugins/db.ts +52 -18
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +36 -8
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/assets/AGENTS.md +1 -0
- package/corpus/templates/assets/actions/_helpers.ts +12 -0
- package/corpus/templates/assets/actions/generate-image.ts +9 -3
- package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/assets/app/routes/settings.tsx +5 -0
- package/corpus/templates/assets/app/routes/team.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
- package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +58 -0
- package/corpus/templates/assets/shared/api.ts +12 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
- package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
- package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/brain/app/routes/sources.tsx +15 -7
- package/corpus/templates/brain/app/routes/team.tsx +1 -1
- package/corpus/templates/brain/app/routes.ts +1 -1
- package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
- package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/AGENTS.md +11 -32
- package/corpus/templates/calendar/actions/update-event.ts +107 -1
- package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/chat/app/root.tsx +1 -1
- package/corpus/templates/chat/app/routes/agent.tsx +7 -7
- package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/chat/app/routes/team.tsx +1 -1
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
- package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
- package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +48 -20
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
- package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
- package/corpus/templates/clips/server/plugins/db.ts +214 -26
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/content/e2e/global-setup.ts +1 -1
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
- package/corpus/templates/crm/server/plugins/db.ts +11 -8
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/design/actions/import-from-url.ts +6 -5
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
- package/corpus/templates/design/app/pages/Index.tsx +6 -2
- package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/design/app/routes/team.tsx +1 -1
- package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +1 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
- package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/factory/app/routes/team.tsx +1 -1
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/forms/shared/navigation.ts +1 -1
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/macros/app/routes/team.tsx +1 -1
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/plan/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +40 -2
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/AGENTS.md +7 -9
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/slides/actions/export-pptx.ts +402 -36
- package/corpus/templates/slides/actions/import-file.ts +46 -85
- package/corpus/templates/slides/actions/import-from-url.ts +6 -6
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
- package/corpus/templates/slides/actions/import-pptx.ts +85 -60
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +176 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +13 -3
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
- package/corpus/templates/slides/app/global.css +6 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +10 -6
- package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
- package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
- package/corpus/templates/slides/app/pages/Index.tsx +107 -6
- package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/slides/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
- package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
- package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
- package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
- package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
- package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
- package/corpus/templates/slides/server/lib/emails.ts +7 -2
- package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
- package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
- package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
- package/corpus/templates/slides/shared/upload-types.ts +3 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
- package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
- package/dist/agent/engine/ai-sdk-engine.js +49 -3
- package/dist/agent/production-agent.d.ts +18 -0
- package/dist/agent/production-agent.js +80 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/cli/agent-plugin.d.ts +112 -0
- package/dist/cli/agent-plugin.js +1081 -0
- package/dist/cli/app-skill.js +39 -1
- package/dist/cli/code-agent-executor.d.ts +3 -0
- package/dist/cli/code-agent-executor.js +51 -13
- package/dist/cli/index.js +13 -0
- package/dist/cli/templates-meta.js +1 -1
- package/dist/client/AgentPanel.d.ts +3 -1
- package/dist/client/AgentPanel.js +9 -2
- package/dist/client/AssistantChat.d.ts +8 -0
- package/dist/client/AssistantChat.js +23 -8
- package/dist/client/NewWorkspaceAppFlow.js +1 -0
- package/dist/client/agent-chat-adapter.d.ts +1 -1
- package/dist/client/agent-chat-adapter.js +153 -7
- package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
- package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
- package/dist/client/assistant-ui-recovery.d.ts +2 -1
- package/dist/client/assistant-ui-recovery.js +7 -3
- package/dist/client/chat/run-recovery.js +5 -1
- package/dist/client/embed-auth.js +6 -2
- package/dist/client/error-format.js +12 -0
- package/dist/client/integrations/IntegrationsPanel.js +40 -6
- package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
- package/dist/client/org/OrgSwitcher.js +2 -2
- package/dist/client/org/TeamPage.js +92 -72
- package/dist/client/require-session.d.ts +1 -1
- package/dist/client/require-session.js +4 -4
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +27 -10
- package/dist/client/resources/McpIntegrationDialog.js +77 -45
- package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
- package/dist/client/resources/mcp-integration-catalog.js +255 -2
- package/dist/client/resources/mcp-integration-logos.js +18 -2
- package/dist/client/resources/use-mcp-servers.d.ts +5 -0
- package/dist/client/resources/use-mcp-servers.js +36 -0
- package/dist/client/settings/AccountSettingsCard.js +42 -36
- package/dist/client/settings/AutomationsSection.js +1 -1
- package/dist/client/settings/DemoModeSection.d.ts +3 -1
- package/dist/client/settings/DemoModeSection.js +4 -1
- package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
- package/dist/client/settings/SchedulingTimezoneField.js +9 -5
- package/dist/client/settings/SettingsPanel.d.ts +4 -1
- package/dist/client/settings/SettingsPanel.js +21 -21
- package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
- package/dist/client/settings/SettingsTabsPage.js +98 -45
- package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
- package/dist/client/settings/useSettingsPanelController.js +47 -8
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts +9 -0
- package/dist/db/client.js +51 -16
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/ddl-guard.d.ts +11 -10
- package/dist/db/ddl-guard.js +40 -12
- package/dist/deploy/build.d.ts +2 -0
- package/dist/deploy/build.js +97 -4
- package/dist/deploy/workspace-deploy.js +0 -2
- package/dist/guards/no-env-credentials.js +9 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/pptx.d.ts +68 -0
- package/dist/ingestion/pptx.js +660 -213
- package/dist/ingestion/website.d.ts +30 -0
- package/dist/integrations/plugin.js +9 -6
- package/dist/localization/default-messages.d.ts +59 -0
- package/dist/localization/default-messages.js +62 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp-client/oauth-routes.d.ts +2 -0
- package/dist/mcp-client/oauth-routes.js +74 -7
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.js +49 -0
- package/dist/navigation/index.js +16 -5
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +11 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/store.js +15 -1
- package/dist/scripts/call-agent.js +45 -4
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +36 -1
- package/dist/server/agent-chat-plugin.js +29 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +55 -17
- package/dist/server/better-auth-instance.js +5 -3
- package/dist/server/core-routes-plugin.d.ts +8 -1
- package/dist/server/core-routes-plugin.js +28 -3
- package/dist/server/credential-provider.d.ts +3 -3
- package/dist/server/credential-provider.js +90 -4
- package/dist/server/identity-sso.js +2 -1
- package/dist/server/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +171 -62
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/self-dispatch.d.ts +5 -4
- package/dist/server/self-dispatch.js +25 -14
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.js +1 -1
- package/dist/server/workspace-provider-oauth.js +1 -1
- package/dist/setup-connections/onboarding.js +1 -1
- package/dist/shared/cache-control.d.ts +26 -2
- package/dist/shared/cache-control.js +43 -2
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/password-policy.d.ts +3 -0
- package/dist/shared/password-policy.js +3 -0
- package/dist/shared/sign-in-journey.d.ts +5 -2
- package/dist/shared/sign-in-journey.js +10 -4
- package/dist/sharing/actions/set-resource-visibility.js +16 -4
- package/dist/sharing/registry.d.ts +14 -0
- package/dist/styles/agent-native.css +6 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/dist/templates/chat/app/root.tsx +1 -1
- package/dist/templates/chat/app/routes/agent.tsx +7 -7
- package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
- package/dist/templates/chat/app/routes/team.tsx +1 -1
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-root/AGENTS.md +7 -0
- package/dist/user-profile/actions/change-password.js +8 -3
- package/dist/user-profile/actions/set-password.js +5 -1
- package/dist/vite/action-types-plugin.js +59 -0
- package/docs/content/authentication.mdx +4 -5
- package/docs/content/skills-guide.mdx +13 -0
- package/docs/content/template-analytics-developers.mdx +1 -1
- package/docs/content/template-calendar-developers.mdx +1 -1
- package/docs/content/template-chat-developers.mdx +2 -2
- package/docs/content/template-content-developers.mdx +1 -1
- package/docs/content/template-mail-developers.mdx +1 -1
- package/docs/content/template-plan-developers.mdx +1 -1
- package/docs/content/toolkit-command-navigation.mdx +6 -6
- package/docs/content/toolkit-org-team.mdx +1 -1
- package/docs/content/toolkit-settings.mdx +8 -8
- package/docs/content/toolkit-setup-connections.mdx +1 -1
- package/package.json +6 -2
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/src/templates/chat/app/root.tsx +1 -1
- package/src/templates/chat/app/routes/agent.tsx +7 -7
- package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/src/templates/chat/app/routes/settings.$.tsx +1 -0
- package/src/templates/chat/app/routes/team.tsx +1 -1
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-root/AGENTS.md +7 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
- package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
- package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
- package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
- package/src/templates/default/actions/navigate.spec.ts +0 -53
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Tabs, useDesignSystem } from "@agent-native/toolkit/design-system";
|
|
3
|
-
import {
|
|
3
|
+
import { IconArrowUpRight, IconHistory, IconSearch, IconSettings, IconUserCircle, IconUsers, IconX, } from "@tabler/icons-react";
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
5
5
|
import { Link } from "react-router";
|
|
6
|
+
import { buildSettingsRoute } from "../../navigation/index.js";
|
|
6
7
|
import { cn } from "../utils.js";
|
|
7
8
|
function normalizeTabId(value) {
|
|
8
9
|
let decoded = value?.replace(/^#/, "").trim() ?? "";
|
|
@@ -61,17 +62,52 @@ function resolveTabId(tabs, value) {
|
|
|
61
62
|
}
|
|
62
63
|
return null;
|
|
63
64
|
}
|
|
64
|
-
function
|
|
65
|
+
function activeTabFromLocation(tabs, defaultTab) {
|
|
65
66
|
if (typeof window === "undefined")
|
|
66
67
|
return defaultTab;
|
|
68
|
+
const settingsPrefix = "/settings";
|
|
69
|
+
if (window.location.pathname === settingsPrefix) {
|
|
70
|
+
return resolveTabId(tabs, window.location.hash) ?? defaultTab;
|
|
71
|
+
}
|
|
72
|
+
if (window.location.pathname.startsWith(`${settingsPrefix}/`)) {
|
|
73
|
+
const segments = window.location.pathname
|
|
74
|
+
.slice(`${settingsPrefix}/`.length)
|
|
75
|
+
.split("/")
|
|
76
|
+
.filter(Boolean)
|
|
77
|
+
.map((segment) => {
|
|
78
|
+
try {
|
|
79
|
+
return decodeURIComponent(segment);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return segment;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
for (let length = segments.length; length > 0; length -= 1) {
|
|
86
|
+
const tabId = resolveTabId(tabs, segments.slice(0, length).join(":"));
|
|
87
|
+
if (tabId)
|
|
88
|
+
return tabId;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
67
91
|
return resolveTabId(tabs, window.location.hash) ?? defaultTab;
|
|
68
92
|
}
|
|
69
|
-
function
|
|
93
|
+
function buildSettingsEntryRoute(tabId, section) {
|
|
94
|
+
const normalizedSection = section?.replace(/^#/, "").trim();
|
|
95
|
+
if (!normalizedSection || normalizedSection === tabId) {
|
|
96
|
+
return buildSettingsRoute(tabId);
|
|
97
|
+
}
|
|
98
|
+
if (normalizedSection.startsWith("agent:")) {
|
|
99
|
+
return buildSettingsRoute(normalizedSection);
|
|
100
|
+
}
|
|
101
|
+
if (normalizedSection.startsWith(`${tabId}:`)) {
|
|
102
|
+
return buildSettingsRoute(normalizedSection);
|
|
103
|
+
}
|
|
104
|
+
return buildSettingsRoute(`${tabId}:${normalizedSection}`);
|
|
105
|
+
}
|
|
106
|
+
function updateRouteForTab(tabId, section) {
|
|
70
107
|
if (typeof window === "undefined")
|
|
71
108
|
return;
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
window.history.pushState(null, "", `${pathname}${search}${hash}`);
|
|
109
|
+
const route = buildSettingsEntryRoute(tabId, section);
|
|
110
|
+
window.history.pushState(null, "", `${route}${window.location.search}`);
|
|
75
111
|
}
|
|
76
112
|
function isEditableElement(element) {
|
|
77
113
|
if (!(element instanceof HTMLElement))
|
|
@@ -82,7 +118,7 @@ function isEditableElement(element) {
|
|
|
82
118
|
tagName === "select" ||
|
|
83
119
|
element.isContentEditable);
|
|
84
120
|
}
|
|
85
|
-
export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs = [], generalLabel = "General", accountLabel = "Account", teamLabel = "Team", whatsNewLabel = "What's new", ariaLabel = "Settings sections", defaultTab = "
|
|
121
|
+
export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs = [], generalLabel = "General", accountLabel = "Account", teamLabel = "Team", whatsNewLabel = "What's new", ariaLabel = "Settings sections", defaultTab = "general", className, navClassName, contentClassName, enableSearch = true, searchPlaceholder = "Search settings", searchEntries, generalSearchEntries, value, onValueChange, }) {
|
|
86
122
|
const rootRef = useRef(null);
|
|
87
123
|
const searchInputRef = useRef(null);
|
|
88
124
|
const autoFocusedSearchRef = useRef(false);
|
|
@@ -166,7 +202,7 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
166
202
|
agent: "Agent",
|
|
167
203
|
};
|
|
168
204
|
const isControlled = value !== undefined;
|
|
169
|
-
const [internalTab, setInternalTab] = useState(() =>
|
|
205
|
+
const [internalTab, setInternalTab] = useState(() => activeTabFromLocation(tabs, fallbackTab));
|
|
170
206
|
const activeTab = isControlled ? value : internalTab;
|
|
171
207
|
const [query, setQuery] = useState("");
|
|
172
208
|
const designSystem = useDesignSystem();
|
|
@@ -186,39 +222,55 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
186
222
|
setInternalTab(fallbackTab);
|
|
187
223
|
}, [fallbackTab, internalTab, isControlled, tabs]);
|
|
188
224
|
useEffect(() => {
|
|
189
|
-
// Hash-driven tab tracking only applies to the uncontrolled mode. Only
|
|
190
|
-
// react to hashes that name a top-level tab. Section-level hashes
|
|
191
|
-
// (e.g. `#llm`, `#secrets`) are consumed by the inner panels, so leave
|
|
192
|
-
// the active tab untouched to avoid bouncing back to General.
|
|
193
225
|
if (isControlled)
|
|
194
226
|
return;
|
|
195
|
-
const
|
|
196
|
-
const
|
|
197
|
-
if (
|
|
198
|
-
setInternalTab(
|
|
199
|
-
|
|
227
|
+
const syncLocation = () => {
|
|
228
|
+
const fromPath = activeTabFromLocation(tabs, fallbackTab);
|
|
229
|
+
if (fromPath)
|
|
230
|
+
setInternalTab(fromPath);
|
|
231
|
+
if (window.location.pathname.startsWith("/settings/"))
|
|
232
|
+
return;
|
|
233
|
+
const hashValue = window.location.hash.replace(/^#/, "");
|
|
234
|
+
const fromHash = resolveTabId(tabs, hashValue);
|
|
235
|
+
if (!fromHash || !hashValue)
|
|
236
|
+
return;
|
|
237
|
+
const isTabHash = fromHash === hashValue;
|
|
238
|
+
updateRouteForTab(fromHash, isTabHash ? undefined : hashValue);
|
|
239
|
+
};
|
|
240
|
+
syncLocation();
|
|
241
|
+
window.addEventListener("hashchange", syncLocation);
|
|
242
|
+
window.addEventListener("popstate", syncLocation);
|
|
243
|
+
return () => {
|
|
244
|
+
window.removeEventListener("hashchange", syncLocation);
|
|
245
|
+
window.removeEventListener("popstate", syncLocation);
|
|
200
246
|
};
|
|
201
|
-
|
|
202
|
-
return () => window.removeEventListener("hashchange", handleHashChange);
|
|
203
|
-
}, [isControlled, tabs]);
|
|
247
|
+
}, [fallbackTab, isControlled, tabs]);
|
|
204
248
|
useEffect(() => {
|
|
205
|
-
// Controlled pages retain ownership of their active state, but shared
|
|
206
|
-
// organization navigation uses a hash deep link. Report only recognized
|
|
207
|
-
// top-level tab hashes; section hashes remain available to inner panels.
|
|
208
249
|
if (!isControlled)
|
|
209
250
|
return;
|
|
210
|
-
const
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
251
|
+
const syncControlledLocation = () => {
|
|
252
|
+
const fromPath = window.location.pathname.startsWith("/settings/")
|
|
253
|
+
? activeTabFromLocation(tabs, defaultTab)
|
|
254
|
+
: null;
|
|
255
|
+
const hashValue = window.location.hash.replace(/^#/, "");
|
|
256
|
+
const fromHash = hashValue ? resolveTabId(tabs, hashValue) : null;
|
|
257
|
+
const next = fromPath ?? fromHash;
|
|
258
|
+
const key = `${window.location.pathname}${window.location.hash}`;
|
|
259
|
+
if (!next || next === value || controlledHashRef.current === key) {
|
|
260
|
+
controlledHashRef.current = key;
|
|
214
261
|
return;
|
|
215
|
-
|
|
216
|
-
|
|
262
|
+
}
|
|
263
|
+
controlledHashRef.current = key;
|
|
264
|
+
onValueChange?.(next);
|
|
265
|
+
};
|
|
266
|
+
syncControlledLocation();
|
|
267
|
+
window.addEventListener("hashchange", syncControlledLocation);
|
|
268
|
+
window.addEventListener("popstate", syncControlledLocation);
|
|
269
|
+
return () => {
|
|
270
|
+
window.removeEventListener("hashchange", syncControlledLocation);
|
|
271
|
+
window.removeEventListener("popstate", syncControlledLocation);
|
|
217
272
|
};
|
|
218
|
-
|
|
219
|
-
window.addEventListener("hashchange", syncControlledHash);
|
|
220
|
-
return () => window.removeEventListener("hashchange", syncControlledHash);
|
|
221
|
-
}, [isControlled, onValueChange, tabs, value]);
|
|
273
|
+
}, [defaultTab, isControlled, onValueChange, tabs, value]);
|
|
222
274
|
useEffect(() => {
|
|
223
275
|
if (!enableSearch || autoFocusedSearchRef.current)
|
|
224
276
|
return;
|
|
@@ -306,24 +358,24 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
306
358
|
setQuery("");
|
|
307
359
|
if (typeof window === "undefined")
|
|
308
360
|
return;
|
|
309
|
-
const
|
|
310
|
-
if (
|
|
311
|
-
|
|
312
|
-
window.history.pushState(null, "", `${pathname}${search}#${hash}`);
|
|
361
|
+
const section = entry.hash?.replace(/^#/, "");
|
|
362
|
+
if (section) {
|
|
363
|
+
updateRouteForTab(entry.tabId, section);
|
|
313
364
|
// Let the inner panels open + scroll to their section.
|
|
365
|
+
window.dispatchEvent(new Event("popstate"));
|
|
314
366
|
window.dispatchEvent(new Event("hashchange"));
|
|
315
367
|
window.requestAnimationFrame(() => {
|
|
316
368
|
document
|
|
317
|
-
.getElementById(
|
|
369
|
+
.getElementById(section)
|
|
318
370
|
?.scrollIntoView({ block: "start", behavior: "smooth" });
|
|
319
371
|
});
|
|
320
372
|
}
|
|
321
373
|
else if (!isControlled) {
|
|
322
|
-
|
|
374
|
+
updateRouteForTab(entry.tabId);
|
|
323
375
|
}
|
|
324
376
|
};
|
|
325
377
|
const searching = enableSearch && trimmedQuery.length > 0;
|
|
326
|
-
return (_jsxs("div", { ref: rootRef, className: cn("flex h-full min-h-0 w-full flex-col overflow-hidden bg-background sm:flex-row", className), children: [_jsxs("div", { className: cn("flex shrink-0 flex-col gap-2 bg-background p-2 sm:min-h-0 sm:w-60 sm:overflow-y-auto sm:p-4", navClassName), children: [
|
|
378
|
+
return (_jsxs("div", { ref: rootRef, className: cn("flex h-full min-h-0 w-full flex-col overflow-hidden bg-background sm:flex-row", className), children: [_jsxs("div", { className: cn("flex shrink-0 flex-col gap-2 bg-background p-2 sm:min-h-0 sm:w-60 sm:overflow-y-auto sm:p-4", navClassName), children: [enableSearch ? (_jsxs("div", { className: "relative sm:mb-2", children: [_jsx(IconSearch, { className: "pointer-events-none absolute start-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { ref: searchInputRef, type: "search", value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: (event) => {
|
|
327
379
|
if (event.key === "Escape")
|
|
328
380
|
setQuery("");
|
|
329
381
|
if (event.key === "Enter" && results[0]) {
|
|
@@ -333,11 +385,12 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
333
385
|
}, placeholder: searchPlaceholder, "aria-label": searchPlaceholder, 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" }), query ? (_jsx("button", { type: "button", onClick: () => setQuery(""), "aria-label": "Clear search", 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", children: _jsx(IconX, { className: "size-3.5" }) })) : null] })) : null, searching ? (_jsx("div", { role: "listbox", "aria-label": "Settings search results", className: "flex flex-col gap-0.5", children: results.length === 0 ? (_jsx("p", { className: "px-2 py-6 text-center text-[12px] text-muted-foreground", children: "No matching settings" })) : (results.map((entry) => {
|
|
334
386
|
const Icon = entry.icon;
|
|
335
387
|
const tab = tabs.find((candidate) => candidate.id === entry.tabId);
|
|
388
|
+
const entryHash = entry.hash?.replace(/^#/, "");
|
|
336
389
|
const resultHref = tab?.href
|
|
337
|
-
?
|
|
338
|
-
?
|
|
390
|
+
? entryHash
|
|
391
|
+
? buildSettingsEntryRoute(entry.tabId, entryHash)
|
|
339
392
|
: tab.href
|
|
340
|
-
:
|
|
393
|
+
: buildSettingsEntryRoute(entry.tabId, entryHash);
|
|
341
394
|
const result = (_jsxs(_Fragment, { children: [Icon ? (_jsx(Icon, { className: "mt-0.5 size-4 shrink-0 text-muted-foreground" })) : null, _jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "truncate font-medium", children: entry.label }), _jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: entry.description ?? entry.tabLabel })] })] }));
|
|
342
395
|
return resultHref ? (_jsx(Link, { to: resultHref, role: "option", "aria-selected": false, 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", children: result }, entry.id)) : (_jsx("button", { type: "button", role: "option", "aria-selected": false, onClick: () => selectEntry(entry), 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", children: result }, entry.id));
|
|
343
396
|
})) })) : hasCustomTabs ? (_jsx(Tabs, { items: tabs.map((tab) => ({
|
|
@@ -351,7 +404,7 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
351
404
|
const nextTab = String(tabId);
|
|
352
405
|
changeTab(nextTab);
|
|
353
406
|
if (!isControlled)
|
|
354
|
-
|
|
407
|
+
updateRouteForTab(nextTab);
|
|
355
408
|
}, orientation: "vertical", "aria-label": ariaLabel, className: "flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible" })) : (_jsx("nav", { "aria-label": ariaLabel, role: "tablist", className: "flex gap-1 overflow-x-auto sm:flex-col sm:overflow-x-visible", children: tabGroups.map((group, groupIndex) => (_jsx("div", { "data-settings-tab-group": group.id, className: cn("contents sm:block", groupIndex > 0 && "sm:mt-3 sm:pt-1"), children: _jsxs("div", { className: "contents sm:flex sm:flex-col sm:gap-1", children: [_jsx("div", { className: "hidden px-3 pb-1 pt-1 text-[11px] font-medium text-muted-foreground sm:block", children: tabGroupLabels[group.id] ?? group.id }), group.tabs.map((tab) => {
|
|
356
409
|
const Icon = tab.icon;
|
|
357
410
|
const selected = tab.id === selectedTab?.id;
|
|
@@ -366,7 +419,7 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
366
419
|
return (_jsx("button", { type: "button", role: "tab", "aria-selected": selected, "aria-controls": `settings-tabpanel-${tab.id}`, id: `settings-tab-${tab.id}`, onClick: () => {
|
|
367
420
|
changeTab(tab.id);
|
|
368
421
|
if (!isControlled)
|
|
369
|
-
|
|
422
|
+
updateRouteForTab(tab.id);
|
|
370
423
|
}, className: cn("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", selected
|
|
371
424
|
? "bg-accent text-foreground"
|
|
372
425
|
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground"), children: tabContent }, tab.id));
|
|
@@ -13,6 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
13
13
|
import { Picker, Switch } from "@agent-native/toolkit/design-system";
|
|
14
14
|
import { IconAlertCircle, IconCheck, IconChevronDown, IconChevronRight, IconExternalLink, IconLoader2, IconLockOpen, } from "@tabler/icons-react";
|
|
15
15
|
import { useCallback, useEffect, useState } from "react";
|
|
16
|
+
import { buildSettingsRoute } from "../../navigation/index.js";
|
|
16
17
|
import { agentNativePath } from "../api-path.js";
|
|
17
18
|
import { SettingsRow } from "./SettingsRow.js";
|
|
18
19
|
import { openBuilderConnectPopup, useBuilderStatus, } from "./useBuilderStatus.js";
|
|
@@ -221,7 +222,8 @@ export function VoiceTranscriptionSection({ compact = false, } = {}) {
|
|
|
221
222
|
const focusKey = (key) => {
|
|
222
223
|
if (typeof window === "undefined")
|
|
223
224
|
return;
|
|
224
|
-
window.
|
|
225
|
+
window.history.pushState(null, "", buildSettingsRoute(`integrations:secrets:${key}`));
|
|
226
|
+
window.dispatchEvent(new Event("popstate"));
|
|
225
227
|
};
|
|
226
228
|
const chooseSource = (next) => {
|
|
227
229
|
if (next === transcriptionMode)
|
|
@@ -266,6 +268,9 @@ export function VoiceTranscriptionSection({ compact = false, } = {}) {
|
|
|
266
268
|
}
|
|
267
269
|
};
|
|
268
270
|
if (transcriptionMode === null) {
|
|
271
|
+
if (compact) {
|
|
272
|
+
return (_jsx(SettingsRow, { label: "Voice transcription", description: "Choose how voice input is transcribed.", control: _jsx("div", { className: "h-9 w-44 animate-pulse rounded-md border border-border bg-muted-foreground/10", "aria-label": "Loading voice transcription" }) }));
|
|
273
|
+
}
|
|
269
274
|
return (_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [_jsx(IconLoader2, { size: 10, className: "animate-spin" }), "Loading\u2026"] }));
|
|
270
275
|
}
|
|
271
276
|
if (compact) {
|
|
@@ -34,13 +34,35 @@ function firstVisibleSection(sections) {
|
|
|
34
34
|
return "llm";
|
|
35
35
|
return sections[0] ?? "llm";
|
|
36
36
|
}
|
|
37
|
+
function settingsPathParts() {
|
|
38
|
+
if (typeof window === "undefined")
|
|
39
|
+
return [];
|
|
40
|
+
const pathParts = window.location.pathname.split("/").filter(Boolean);
|
|
41
|
+
const settingsIndex = pathParts.indexOf("settings");
|
|
42
|
+
return settingsIndex === -1 ? [] : pathParts.slice(settingsIndex + 1);
|
|
43
|
+
}
|
|
44
|
+
function secretKeyFromPath(pathParts) {
|
|
45
|
+
const secretsIndex = pathParts.findIndex((part) => part.toLowerCase() === "secrets");
|
|
46
|
+
if (secretsIndex === -1)
|
|
47
|
+
return undefined;
|
|
48
|
+
const key = pathParts.slice(secretsIndex + 1).join("/");
|
|
49
|
+
return key || undefined;
|
|
50
|
+
}
|
|
37
51
|
function initialOpenSection(sections) {
|
|
38
52
|
const hashSection = typeof window === "undefined"
|
|
39
53
|
? null
|
|
40
54
|
: normalizeSettingsSection(window.location.hash);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
if (hashSection && sections.includes(hashSection))
|
|
56
|
+
return hashSection;
|
|
57
|
+
if (typeof window !== "undefined") {
|
|
58
|
+
const routeParts = settingsPathParts();
|
|
59
|
+
for (let index = routeParts.length - 1; index >= 0; index -= 1) {
|
|
60
|
+
const pathSection = normalizeSettingsSection(routeParts[index]);
|
|
61
|
+
if (pathSection && sections.includes(pathSection))
|
|
62
|
+
return pathSection;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return firstVisibleSection(sections);
|
|
44
66
|
}
|
|
45
67
|
export function useSettingsPanelController({ sections = ALL_SETTINGS_SECTIONS, initialSection, sectionRequestKey, onScrollToSection, } = {}) {
|
|
46
68
|
const visibleSections = useMemo(() => new Set(sections), [sections]);
|
|
@@ -72,23 +94,40 @@ export function useSettingsPanelController({ sections = ALL_SETTINGS_SECTIONS, i
|
|
|
72
94
|
useEffect(() => {
|
|
73
95
|
if (typeof window === "undefined")
|
|
74
96
|
return;
|
|
75
|
-
const
|
|
97
|
+
const handleLocationChange = () => {
|
|
76
98
|
const hash = window.location.hash?.replace(/^#/, "") ?? "";
|
|
77
|
-
|
|
99
|
+
let section = normalizeSettingsSection(hash);
|
|
100
|
+
const pathParts = settingsPathParts();
|
|
101
|
+
if (!section) {
|
|
102
|
+
for (let index = pathParts.length - 1; index >= 0; index -= 1) {
|
|
103
|
+
const pathSection = normalizeSettingsSection(pathParts[index]);
|
|
104
|
+
if (pathSection) {
|
|
105
|
+
section = pathSection;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
78
110
|
if (!section || !isSectionVisible(section))
|
|
79
111
|
return;
|
|
80
112
|
if (hash.startsWith("secrets:") || hash === "secrets") {
|
|
81
113
|
const key = hash.slice("secrets:".length);
|
|
82
114
|
setFocusSecretKey(key || undefined);
|
|
83
115
|
}
|
|
116
|
+
else if (section === "secrets") {
|
|
117
|
+
setFocusSecretKey(secretKeyFromPath(pathParts));
|
|
118
|
+
}
|
|
84
119
|
else {
|
|
85
120
|
setFocusSecretKey(undefined);
|
|
86
121
|
}
|
|
87
122
|
openSettingsSection(section, { scroll: true });
|
|
88
123
|
};
|
|
89
|
-
|
|
90
|
-
window.addEventListener("hashchange",
|
|
91
|
-
|
|
124
|
+
handleLocationChange();
|
|
125
|
+
window.addEventListener("hashchange", handleLocationChange);
|
|
126
|
+
window.addEventListener("popstate", handleLocationChange);
|
|
127
|
+
return () => {
|
|
128
|
+
window.removeEventListener("hashchange", handleLocationChange);
|
|
129
|
+
window.removeEventListener("popstate", handleLocationChange);
|
|
130
|
+
};
|
|
92
131
|
}, [isSectionVisible, openSettingsSection]);
|
|
93
132
|
return {
|
|
94
133
|
sections,
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
error: string;
|
|
30
29
|
ok?: undefined;
|
|
30
|
+
error: string;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
package/dist/db/client.d.ts
CHANGED
|
@@ -183,6 +183,15 @@ export declare function isServerlessRuntime(): boolean;
|
|
|
183
183
|
* leave room for concurrency.
|
|
184
184
|
*/
|
|
185
185
|
export declare function pgPoolOptions(url: string): Record<string, unknown>;
|
|
186
|
+
/**
|
|
187
|
+
* Shared options for every Neon serverless pool. The startup parameter is
|
|
188
|
+
* applied by Postgres before the first transaction, so a killed function
|
|
189
|
+
* cannot return a connection that remains idle in transaction indefinitely.
|
|
190
|
+
*/
|
|
191
|
+
export declare function neonPoolOptions(): {
|
|
192
|
+
max: number;
|
|
193
|
+
idle_in_transaction_session_timeout?: number;
|
|
194
|
+
};
|
|
186
195
|
/**
|
|
187
196
|
* Connection cap for the @neondatabase/serverless `Pool`.
|
|
188
197
|
*
|
package/dist/db/client.js
CHANGED
|
@@ -778,15 +778,35 @@ export function pgPoolOptions(url) {
|
|
|
778
778
|
const serverless = isServerlessRuntime();
|
|
779
779
|
return {
|
|
780
780
|
onnotice: () => { },
|
|
781
|
-
max: serverless ?
|
|
781
|
+
max: serverless ? serverlessPoolMax() : 20,
|
|
782
782
|
idle_timeout: serverless ? 20 : 240,
|
|
783
783
|
max_lifetime: 60 * 30,
|
|
784
784
|
connect_timeout: 10,
|
|
785
|
+
...(serverless
|
|
786
|
+
? {
|
|
787
|
+
connection: {
|
|
788
|
+
idle_in_transaction_session_timeout: 30_000,
|
|
789
|
+
},
|
|
790
|
+
}
|
|
791
|
+
: {}),
|
|
785
792
|
// Supabase's connection pooler (Transaction mode) requires prepare:false.
|
|
786
793
|
// Only disable for Supabase URLs to avoid degrading other deployments.
|
|
787
794
|
...(url.includes("supabase") ? { prepare: false } : {}),
|
|
788
795
|
};
|
|
789
796
|
}
|
|
797
|
+
/**
|
|
798
|
+
* Shared options for every Neon serverless pool. The startup parameter is
|
|
799
|
+
* applied by Postgres before the first transaction, so a killed function
|
|
800
|
+
* cannot return a connection that remains idle in transaction indefinitely.
|
|
801
|
+
*/
|
|
802
|
+
export function neonPoolOptions() {
|
|
803
|
+
return {
|
|
804
|
+
max: neonPoolMax(),
|
|
805
|
+
...(isServerlessRuntime()
|
|
806
|
+
? { idle_in_transaction_session_timeout: 30_000 }
|
|
807
|
+
: {}),
|
|
808
|
+
};
|
|
809
|
+
}
|
|
790
810
|
/**
|
|
791
811
|
* Connection cap for the @neondatabase/serverless `Pool`.
|
|
792
812
|
*
|
|
@@ -804,20 +824,27 @@ export function pgPoolOptions(url) {
|
|
|
804
824
|
export function neonPoolMax() {
|
|
805
825
|
if (!isServerlessRuntime())
|
|
806
826
|
return 20;
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
//
|
|
811
|
-
//
|
|
812
|
-
//
|
|
813
|
-
//
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
//
|
|
817
|
-
//
|
|
827
|
+
return serverlessPoolMax();
|
|
828
|
+
}
|
|
829
|
+
function serverlessPoolMax() {
|
|
830
|
+
// Scheduled Analytics workers run independently and may overlap across
|
|
831
|
+
// invocations. They process work sequentially, so one connection prevents
|
|
832
|
+
// a slow sweep from multiplying Neon connections while foreground requests
|
|
833
|
+
// retain two slots for their concurrent reads.
|
|
834
|
+
if (isLowConnectionBackgroundRuntime())
|
|
835
|
+
return 1;
|
|
836
|
+
// Netlify can run several background workers concurrently. Keep their four
|
|
837
|
+
// slots: the agent pre-send setup fires ~6 concurrent DB reads, and two
|
|
838
|
+
// connections previously froze the worker before it could claim. Foreground
|
|
839
|
+
// requests use two slots instead, leaving more headroom across warm
|
|
840
|
+
// instances where the user-facing routes are the pressure source.
|
|
818
841
|
if (isBackgroundFunctionPoolContext())
|
|
819
842
|
return 4;
|
|
820
|
-
return
|
|
843
|
+
return 2;
|
|
844
|
+
}
|
|
845
|
+
function isLowConnectionBackgroundRuntime() {
|
|
846
|
+
return (globalThis
|
|
847
|
+
.__AGENT_NATIVE_LOW_CONNECTION_BACKGROUND_RUNTIME__ === true);
|
|
821
848
|
}
|
|
822
849
|
/**
|
|
823
850
|
* Inline mirror of `isInBackgroundFunctionRuntime()`
|
|
@@ -1085,7 +1112,7 @@ async function createDbExecInternal(config = {}, trackSingletonResources = false
|
|
|
1085
1112
|
// connections, so its direct executions use stateless Neon HTTP instead.
|
|
1086
1113
|
// The foreground and transaction surface keep the WebSocket pool.
|
|
1087
1114
|
const bgHttp = isBackgroundFunctionPoolContext();
|
|
1088
|
-
const makePool = () => new Pool({ connectionString: url,
|
|
1115
|
+
const makePool = () => new Pool({ connectionString: url, ...neonPoolOptions() });
|
|
1089
1116
|
// The singleton exec shares the process pool; `createDbExec()` callers own
|
|
1090
1117
|
// a `close()` and so must not be handed it.
|
|
1091
1118
|
const pool = trackSingletonResources
|
|
@@ -1250,8 +1277,16 @@ async function createDbExecInternal(config = {}, trackSingletonResources = false
|
|
|
1250
1277
|
return result;
|
|
1251
1278
|
}
|
|
1252
1279
|
catch (err) {
|
|
1253
|
-
|
|
1254
|
-
|
|
1280
|
+
let rollbackFailed = false;
|
|
1281
|
+
try {
|
|
1282
|
+
await queryNeonClient(client, "ROLLBACK");
|
|
1283
|
+
}
|
|
1284
|
+
catch {
|
|
1285
|
+
rollbackFailed = true;
|
|
1286
|
+
}
|
|
1287
|
+
// A failed rollback can leave the backend inside the transaction.
|
|
1288
|
+
// Do not return that client to PgBouncer as if it were clean.
|
|
1289
|
+
releaseClient(isConnectionError(err) || rollbackFailed ? true : undefined);
|
|
1255
1290
|
throw err;
|
|
1256
1291
|
}
|
|
1257
1292
|
}, 1);
|
package/dist/db/create-get-db.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { drizzle as drizzleD1 } from "drizzle-orm/d1";
|
|
3
|
-
import { getDialect, getCloudflareD1Binding, getDatabaseUrl, getDatabaseAuthToken, isLocalSqliteUrl, isPgliteUrl, isConnectionError, getPgliteClient, loadPgliteDrizzle, prepareLocalSqliteUrl, sqliteFilenameFromUrl, pgPoolOptions,
|
|
3
|
+
import { getDialect, getCloudflareD1Binding, getDatabaseUrl, getDatabaseAuthToken, isLocalSqliteUrl, isPgliteUrl, isConnectionError, getPgliteClient, loadPgliteDrizzle, prepareLocalSqliteUrl, sqliteFilenameFromUrl, pgPoolOptions, neonPoolOptions, attachNeonPoolErrorLogger, withDbTimeout, retryOnConnectionError, dbOpTimeoutMs, sharedDbPool, onSharedDbPoolsClosed, onSharedDbPoolReplaced, } from "./client.js";
|
|
4
4
|
// Lazy driver loaders — cached promises so dynamic import only runs once.
|
|
5
5
|
let _pgDrizzle;
|
|
6
6
|
function getPgDrizzle() {
|
|
@@ -407,7 +407,7 @@ export function createGetDb(schema) {
|
|
|
407
407
|
// `createGetDb` store: one connect per process instead of one per
|
|
408
408
|
// schema module. See `sharedDbPool` in client.ts.
|
|
409
409
|
resetOnPoolClose("neon", url);
|
|
410
|
-
const rawPool = sharedDbPool("neon", url, () => new Pool({ connectionString: url,
|
|
410
|
+
const rawPool = sharedDbPool("neon", url, () => new Pool({ connectionString: url, ...neonPoolOptions() }));
|
|
411
411
|
attachNeonPoolErrorLogger(rawPool);
|
|
412
412
|
// Wrap the pool with the resilience layer so Drizzle queries get the
|
|
413
413
|
// same withDbTimeout + retryOnConnectionError protection as the raw
|
package/dist/db/ddl-guard.d.ts
CHANGED
|
@@ -32,33 +32,33 @@ import { type DbExec } from "./client.js";
|
|
|
32
32
|
/**
|
|
33
33
|
* True when running against Postgres AND the given table already exists in the
|
|
34
34
|
* `public` schema. Returns `false` on SQLite (callers gate their own behaviour
|
|
35
|
-
* there), for invalid identifiers,
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* there), for invalid identifiers, and `undefined` when `information_schema`
|
|
36
|
+
* is unreadable. Unknown must stay distinct from absent: treating a timed-out
|
|
37
|
+
* probe as missing starts a DDL lock storm on a busy serverless database.
|
|
38
38
|
*
|
|
39
39
|
* This is a plain read (no lock), so it never blocks on an `ACCESS EXCLUSIVE`
|
|
40
40
|
* lock the way `CREATE`/`ALTER` would.
|
|
41
41
|
*/
|
|
42
|
-
export declare function pgTableExists(table: string, injectedClient?: DbExec, dialectIsPostgres?: boolean): Promise<boolean>;
|
|
42
|
+
export declare function pgTableExists(table: string, injectedClient?: DbExec, dialectIsPostgres?: boolean): Promise<boolean | undefined>;
|
|
43
43
|
/**
|
|
44
44
|
* True when running against Postgres AND the given column already exists on the
|
|
45
45
|
* given table in the `public` schema. Returns `false` on SQLite, for invalid
|
|
46
|
-
* identifiers,
|
|
46
|
+
* identifiers, and `undefined` when `information_schema` is unreadable.
|
|
47
47
|
*
|
|
48
48
|
* Plain read — no lock taken.
|
|
49
49
|
*/
|
|
50
|
-
export declare function pgColumnExists(table: string, column: string, injectedClient?: DbExec): Promise<boolean>;
|
|
50
|
+
export declare function pgColumnExists(table: string, column: string, injectedClient?: DbExec): Promise<boolean | undefined>;
|
|
51
51
|
/**
|
|
52
52
|
* True when running against Postgres AND an index with the given name already
|
|
53
53
|
* exists in the `public` schema. Returns `false` on SQLite, for invalid
|
|
54
|
-
* identifiers,
|
|
54
|
+
* identifiers, and `undefined` when `pg_indexes` is unreadable.
|
|
55
55
|
*
|
|
56
56
|
* `CREATE INDEX` (without CONCURRENTLY) takes a `SHARE` lock that blocks
|
|
57
57
|
* writes, so on a fresh background-worker process behind a concurrent
|
|
58
58
|
* connection this can hang just like a `CREATE`/`ALTER` would; checking first
|
|
59
59
|
* skips the lock on the already-migrated hot path.
|
|
60
60
|
*/
|
|
61
|
-
export declare function pgIndexExists(indexName: string, injectedClient?: DbExec, dialectIsPostgres?: boolean): Promise<boolean>;
|
|
61
|
+
export declare function pgIndexExists(indexName: string, injectedClient?: DbExec, dialectIsPostgres?: boolean): Promise<boolean | undefined>;
|
|
62
62
|
/**
|
|
63
63
|
* Probe → guarded-DDL → re-probe sequence for one piece of on-demand schema.
|
|
64
64
|
*
|
|
@@ -86,8 +86,8 @@ export declare function pgIndexExists(indexName: string, injectedClient?: DbExec
|
|
|
86
86
|
* `false` only when it already existed up front (no DDL issued).
|
|
87
87
|
*/
|
|
88
88
|
export declare function ensureSchemaObject(options: {
|
|
89
|
-
/** Lock-free existence check; `true` ⇒
|
|
90
|
-
probe: () => Promise<boolean>;
|
|
89
|
+
/** Lock-free existence check; `true` ⇒ present, `undefined` ⇒ unreadable. */
|
|
90
|
+
probe: () => Promise<boolean | undefined>;
|
|
91
91
|
/** DDL to run only when `probe()` reports the object missing. */
|
|
92
92
|
ddl: string;
|
|
93
93
|
/** Human-readable name of what's being ensured, for the error message. */
|
|
@@ -150,6 +150,7 @@ export declare function isLockTimeoutError(err: unknown): boolean;
|
|
|
150
150
|
*/
|
|
151
151
|
export declare function runGuardedDdl(ddl: string, options?: {
|
|
152
152
|
lockTimeout?: string;
|
|
153
|
+
idleInTransactionTimeout?: string;
|
|
153
154
|
injectedClient?: DbExec;
|
|
154
155
|
dialectIsPostgres?: boolean;
|
|
155
156
|
}): Promise<boolean>;
|