@agent-native/core 0.145.5 → 0.145.7
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 +1 -1
- package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +17 -1
- package/corpus/templates/analytics/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +22 -3
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/analytics/AGENTS.md +2 -1
- package/corpus/templates/analytics/actions/account-deep-dive.ts +83 -47
- package/corpus/templates/analytics/actions/create-dashboard-folder.ts +27 -0
- package/corpus/templates/analytics/actions/gong-calls.ts +3 -3
- package/corpus/templates/analytics/actions/list-dashboard-folders.ts +26 -0
- package/corpus/templates/analytics/actions/list-sql-dashboards.ts +1 -0
- package/corpus/templates/analytics/actions/set-dashboard-folder.ts +26 -0
- package/corpus/templates/analytics/app/components/ProviderCorpusJobNotifier.tsx +18 -3
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +6 -4
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +12 -2
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +35 -20
- package/corpus/templates/analytics/app/global.css +17 -0
- package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +29 -15
- package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +15 -3
- package/corpus/templates/analytics/app/i18n-data.ts +296 -0
- package/corpus/templates/analytics/app/lib/prefetch-keys.ts +23 -2
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +642 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +66 -31
- package/corpus/templates/analytics/app/root.tsx +4 -0
- package/corpus/templates/analytics/app/routes/dashboards._index.tsx +5 -1
- package/corpus/templates/analytics/changelog/2026-08-07-added-a-dashboards-overview-with-personal-and-shared-folders.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-analytics-no-longer-stalls-under-bursts-of-event-ingest-key-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-analytics-tracking-and-chat-startup-no-longer-emit-avoidable.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-dashboard-panels-now-load-custom-api-data-programs-reliably.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-gong-searches-conserve-api-quota-and-report-incomplete-coverage.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-searchable-dashboards-make-personal-and-shared-folders-easie.md +6 -0
- package/corpus/templates/analytics/netlify.toml +3 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +112 -0
- package/corpus/templates/analytics/server/db/index.ts +12 -0
- package/corpus/templates/analytics/server/db/schema.ts +14 -0
- package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +4 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +85 -15
- package/corpus/templates/analytics/server/lib/dashboard-folders-store.ts +168 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +9 -4
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +116 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +4 -8
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +65 -10
- package/corpus/templates/analytics/server/lib/gong.ts +139 -78
- package/corpus/templates/analytics/server/lib/session-replay.ts +5 -5
- package/corpus/templates/analytics/server/plugins/db.ts +55 -15
- package/corpus/templates/analytics/server/plugins/session-replay-retention-jobs.ts +6 -2
- package/corpus/templates/analytics/server/routes/api/session-replay/retention.post.ts +65 -0
- package/corpus/templates/assets/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/assets/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/brain/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/calendar/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/chat/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/chat/.env.example +3 -0
- package/corpus/templates/chat/AGENTS.md +4 -0
- package/corpus/templates/clips/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/clips/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +4 -0
- package/corpus/templates/clips/actions/request-transcript.ts +52 -3
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -10
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
- package/corpus/templates/clips/changelog/2026-08-07-screen-recordings-now-capture-tab-and-system-audio-even-when.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-07-transcription-now-retries-transient-cloud-failures-automatic.md +6 -0
- package/corpus/templates/clips/server/db/schema.ts +7 -0
- package/corpus/templates/clips/server/plugins/db.ts +8 -0
- package/corpus/templates/clips/shared/recording-capture.ts +38 -0
- package/corpus/templates/clips/shared/transcript-failure.ts +89 -0
- package/corpus/templates/content/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/content/.env.example +9 -3
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -0
- package/corpus/templates/content/changelog/2026-08-07-collapsed-sidebar-utility-buttons-stay-anchored-at-the-botto.md +6 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/design/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/design/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/dispatch/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/factory/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +279 -0
- package/corpus/templates/factory/actions/get-factory-automation-health.ts +23 -4
- package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +1 -1
- package/corpus/templates/factory/app/routes/factory.tsx +21 -3
- package/corpus/templates/factory/changelog/2026-08-07-factory-can-keep-builder-bot-pull-requests-moving-by-request.md +6 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +1 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +4 -1
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +81 -12
- package/corpus/templates/factory/server/triage/github-client.ts +31 -0
- package/corpus/templates/factory/server/triage/pr-babysit.ts +75 -1
- package/corpus/templates/forms/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/forms/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/mail/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/mail/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/plan/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -1
- package/corpus/templates/plan/changelog/2026-08-07-inline-help-icons-now-stay-visually-balanced-with-nearby-tex.md +6 -0
- package/corpus/templates/slides/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/slides/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/slides/.env.example +5 -0
- package/corpus/templates/slides/changelog/2026-08-07-fixed-generated-slides-briefly-disappearing-while-they-are-b.md +6 -0
- package/corpus/templates/slides/server/plugins/collab.ts +20 -8
- package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +18 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/corpus/templates/tasks/.env.example +3 -0
- package/dist/agent/production-agent.js +24 -3
- package/dist/client/AgentPanel.d.ts +6 -0
- package/dist/client/AgentPanel.js +176 -30
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.js +4 -1
- package/dist/client/ConnectBuilderCard.js +6 -11
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/RuntimeConfigNotice.d.ts +1 -0
- package/dist/client/RuntimeConfigNotice.js +94 -0
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/agent-chat-adapter.js +85 -4
- package/dist/client/agent-page/AgentTabsPage.js +1 -1
- package/dist/client/agent-sidebar-state.d.ts +6 -0
- package/dist/client/agent-sidebar-state.js +25 -0
- package/dist/client/app-providers.js +2 -1
- package/dist/client/assistant-ui-recovery.js +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/markdown-renderer.d.ts +2 -1
- package/dist/client/chat/markdown-renderer.js +48 -2
- package/dist/client/chat/message-components.d.ts +6 -0
- package/dist/client/chat/message-components.js +182 -53
- package/dist/client/chat/tool-call-display.d.ts +16 -4
- package/dist/client/chat/tool-call-display.js +225 -18
- package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
- package/dist/client/frame-protocol.d.ts +4 -0
- package/dist/client/i18n.js +9 -0
- package/dist/client/integrations/IntegrationsPanel.js +2 -5
- package/dist/client/onboarding/FirstRunOnboarding.js +2 -3
- package/dist/client/org/TeamPage.js +49 -6
- package/dist/client/org/hooks.d.ts +7 -2
- package/dist/client/org/hooks.js +11 -4
- package/dist/client/resources/McpConnectionSuggestion.js +2 -3
- package/dist/client/resources/McpIntegrationDialog.js +2 -16
- package/dist/client/resources/McpIntegrationLogo.d.ts +11 -0
- package/dist/client/resources/McpIntegrationLogo.js +14 -0
- package/dist/client/resources/ResourceTree.js +1 -1
- package/dist/client/resources/mcp-integration-logos.d.ts +1 -0
- package/dist/client/resources/mcp-integration-logos.js +47 -18
- package/dist/client/settings/useBuilderStatus.js +6 -0
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/client/use-db-sync.js +4 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/config.d.ts +26 -3
- package/dist/config.js +106 -14
- package/dist/db/ddl-guard.d.ts +15 -2
- package/dist/db/ddl-guard.js +53 -5
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/scheduler.js +7 -0
- package/dist/localization/default-messages.d.ts +17 -0
- package/dist/localization/default-messages.js +17 -0
- package/dist/mcp/oauth-client-metadata.js +5 -1
- package/dist/mcp/oauth-route.d.ts +5 -4
- package/dist/mcp/oauth-route.js +25 -9
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +9 -10
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -0
- package/dist/org/handlers.js +17 -2
- package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +12 -2
- package/dist/provider-api/corpus-jobs.js +31 -1
- package/dist/provider-api/index.d.ts +2 -0
- package/dist/provider-api/index.js +7 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +1 -1
- package/dist/server/agent-chat/recurring-jobs-runtime.js +14 -2
- package/dist/server/agent-chat/script-entries.js +12 -1
- package/dist/server/agent-chat-plugin.js +2 -2
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +85 -1
- package/dist/server/better-auth-instance.d.ts +9 -0
- package/dist/server/better-auth-instance.js +25 -11
- package/dist/server/core-routes-plugin.d.ts +7 -0
- package/dist/server/core-routes-plugin.js +51 -5
- package/dist/server/create-server.js +23 -2
- package/dist/server/db-pressure.d.ts +38 -0
- package/dist/server/db-pressure.js +147 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/legacy-auth-migration.d.ts +10 -0
- package/dist/server/legacy-auth-migration.js +37 -0
- package/dist/server/onboarding-html.js +206 -2
- package/dist/server/poll.d.ts +26 -0
- package/dist/server/poll.js +108 -13
- package/dist/server/ssr-handler.js +4 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/runtime-config.d.ts +44 -0
- package/dist/shared/runtime-config.js +284 -0
- package/dist/styles/agent-native.css +48 -1
- package/dist/templates/chat/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/chat/.env.example +3 -0
- package/dist/templates/chat/AGENTS.md +4 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/default/AGENTS.md +6 -1
- package/dist/templates/default/app/i18n/ar-SA.ts +6 -0
- package/dist/templates/default/app/i18n/de-DE.ts +6 -0
- package/dist/templates/default/app/i18n/en-US.ts +6 -0
- package/dist/templates/default/app/i18n/es-ES.ts +6 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +6 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +6 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +6 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +6 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +6 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +6 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +6 -0
- package/dist/templates/headless/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
- package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
- package/dist/templates/workspace-core/AGENTS.md +7 -2
- package/dist/templates/workspace-root/AGENTS.md +5 -0
- package/dist/vite/client.d.ts +3 -3
- package/dist/vite/client.js +47 -1
- package/dist/vite/index.d.ts +1 -1
- package/docs/content/agent-native-config.mdx +240 -139
- package/docs/content/authentication.mdx +17 -0
- package/docs/content/deployment.mdx +19 -14
- package/docs/content/drop-in-agent.mdx +19 -2
- package/docs/content/environment-variables.mdx +63 -38
- package/docs/content/getting-started-actions.mdx +15 -6
- package/docs/content/getting-started-database.mdx +14 -10
- package/docs/content/getting-started-pages.mdx +32 -35
- package/docs/content/getting-started.mdx +7 -6
- package/package.json +1 -1
- package/src/templates/chat/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/chat/.env.example +3 -0
- package/src/templates/chat/AGENTS.md +4 -0
- package/src/templates/default/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/default/AGENTS.md +6 -1
- package/src/templates/default/app/i18n/ar-SA.ts +6 -0
- package/src/templates/default/app/i18n/de-DE.ts +6 -0
- package/src/templates/default/app/i18n/en-US.ts +6 -0
- package/src/templates/default/app/i18n/es-ES.ts +6 -0
- package/src/templates/default/app/i18n/fr-FR.ts +6 -0
- package/src/templates/default/app/i18n/hi-IN.ts +6 -0
- package/src/templates/default/app/i18n/ja-JP.ts +6 -0
- package/src/templates/default/app/i18n/ko-KR.ts +6 -0
- package/src/templates/default/app/i18n/pt-BR.ts +6 -0
- package/src/templates/default/app/i18n/zh-CN.ts +6 -0
- package/src/templates/default/app/i18n/zh-TW.ts +6 -0
- package/src/templates/headless/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
- package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
- package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
- package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
- package/src/templates/workspace-core/AGENTS.md +7 -2
- package/src/templates/workspace-root/AGENTS.md +5 -0
- package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +0 -1
- package/corpus/templates/dispatch/app/routes/admin.apps.tsx +0 -1
|
@@ -97,6 +97,12 @@ const EN_AUTH_COPY = {
|
|
|
97
97
|
backToSignIn: "Back to sign in",
|
|
98
98
|
localNotePrefix: "Your account is stored in this app's own DB",
|
|
99
99
|
localNoteSuffix: ", not a third-party service.",
|
|
100
|
+
localDevButton: "Continue as local dev",
|
|
101
|
+
localDevDescription: "Only works in local development on this computer.",
|
|
102
|
+
localDevHelp: "Learn about local development sign-in",
|
|
103
|
+
localDevSigningIn: "Signing in locally…",
|
|
104
|
+
localDevFailed: "Local development sign-in is unavailable.",
|
|
105
|
+
localDevFullOptions: "Show full sign in options",
|
|
100
106
|
runLocally: "Run Locally",
|
|
101
107
|
runLocallySentence: "Run locally",
|
|
102
108
|
openSource: "100% free and open source",
|
|
@@ -193,6 +199,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
193
199
|
backToSignIn: "返回登录",
|
|
194
200
|
localNotePrefix: "你的账户存储在此应用自己的数据库中",
|
|
195
201
|
localNoteSuffix: ",而不是第三方服务。",
|
|
202
|
+
localDevButton: "以本地开发身份继续",
|
|
203
|
+
localDevDescription: "仅在此计算机的本地开发环境中有效。",
|
|
204
|
+
localDevHelp: "了解本地开发登录",
|
|
205
|
+
localDevSigningIn: "正在本地登录…",
|
|
206
|
+
localDevFailed: "本地开发登录不可用。",
|
|
207
|
+
localDevFullOptions: "显示完整登录选项",
|
|
196
208
|
runLocally: "本地运行",
|
|
197
209
|
runLocallySentence: "本地运行",
|
|
198
210
|
openSource: "100% 免费且开源",
|
|
@@ -287,6 +299,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
287
299
|
backToSignIn: "返回登入",
|
|
288
300
|
localNotePrefix: "你的帳號儲存在此應用程式自己的資料庫中",
|
|
289
301
|
localNoteSuffix: ",而不是第三方服務。",
|
|
302
|
+
localDevButton: "以本機開發身分繼續",
|
|
303
|
+
localDevDescription: "僅在這台電腦的本機開發環境中有效。",
|
|
304
|
+
localDevHelp: "了解本機開發登入",
|
|
305
|
+
localDevSigningIn: "正在本機登入…",
|
|
306
|
+
localDevFailed: "本機開發登入無法使用。",
|
|
307
|
+
localDevFullOptions: "顯示完整登入選項",
|
|
290
308
|
runLocally: "在本機執行",
|
|
291
309
|
runLocallySentence: "在本機執行",
|
|
292
310
|
openSource: "100% 免費且開源",
|
|
@@ -381,6 +399,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
381
399
|
backToSignIn: "Volver a iniciar sesión",
|
|
382
400
|
localNotePrefix: "Tu cuenta se almacena en la propia base de datos de esta app",
|
|
383
401
|
localNoteSuffix: ", no en un servicio de terceros.",
|
|
402
|
+
localDevButton: "Continuar como desarrollador local",
|
|
403
|
+
localDevDescription: "Solo funciona en el desarrollo local de este equipo.",
|
|
404
|
+
localDevHelp: "Más información sobre el inicio de sesión local",
|
|
405
|
+
localDevSigningIn: "Iniciando sesión localmente…",
|
|
406
|
+
localDevFailed: "El inicio de sesión de desarrollo local no está disponible.",
|
|
407
|
+
localDevFullOptions: "Mostrar todas las opciones de inicio de sesión",
|
|
384
408
|
runLocally: "Ejecutar localmente",
|
|
385
409
|
runLocallySentence: "Ejecutar localmente",
|
|
386
410
|
openSource: "100% gratis y de código abierto",
|
|
@@ -475,6 +499,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
475
499
|
backToSignIn: "Retour à la connexion",
|
|
476
500
|
localNotePrefix: "Votre compte est stocké dans la base de données propre à cette app",
|
|
477
501
|
localNoteSuffix: ", pas dans un service tiers.",
|
|
502
|
+
localDevButton: "Continuer comme développeur local",
|
|
503
|
+
localDevDescription: "Fonctionne uniquement en développement local sur cet ordinateur.",
|
|
504
|
+
localDevHelp: "En savoir plus sur la connexion locale",
|
|
505
|
+
localDevSigningIn: "Connexion locale…",
|
|
506
|
+
localDevFailed: "La connexion de développement local est indisponible.",
|
|
507
|
+
localDevFullOptions: "Afficher toutes les options de connexion",
|
|
478
508
|
runLocally: "Exécuter localement",
|
|
479
509
|
runLocallySentence: "Exécuter localement",
|
|
480
510
|
openSource: "100 % gratuit et open source",
|
|
@@ -569,6 +599,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
569
599
|
backToSignIn: "Zurück zur Anmeldung",
|
|
570
600
|
localNotePrefix: "Dein Konto wird in der eigenen Datenbank dieser App gespeichert",
|
|
571
601
|
localNoteSuffix: ", nicht bei einem Drittanbieter.",
|
|
602
|
+
localDevButton: "Als lokale Entwicklung fortfahren",
|
|
603
|
+
localDevDescription: "Funktioniert nur in der lokalen Entwicklung auf diesem Computer.",
|
|
604
|
+
localDevHelp: "Mehr über die lokale Anmeldung erfahren",
|
|
605
|
+
localDevSigningIn: "Lokale Anmeldung…",
|
|
606
|
+
localDevFailed: "Die lokale Entwicklungsanmeldung ist nicht verfügbar.",
|
|
607
|
+
localDevFullOptions: "Alle Anmeldeoptionen anzeigen",
|
|
572
608
|
runLocally: "Lokal ausführen",
|
|
573
609
|
runLocallySentence: "Lokal ausführen",
|
|
574
610
|
openSource: "100 % kostenlos und Open Source",
|
|
@@ -663,6 +699,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
663
699
|
backToSignIn: "サインインに戻る",
|
|
664
700
|
localNotePrefix: "アカウントはこのアプリ自身の DB に保存されます",
|
|
665
701
|
localNoteSuffix: "。サードパーティサービスには保存されません。",
|
|
702
|
+
localDevButton: "ローカル開発として続行",
|
|
703
|
+
localDevDescription: "このコンピューターのローカル開発でのみ利用できます。",
|
|
704
|
+
localDevHelp: "ローカル開発サインインについて詳しく見る",
|
|
705
|
+
localDevSigningIn: "ローカルでサインイン中…",
|
|
706
|
+
localDevFailed: "ローカル開発のサインインは利用できません。",
|
|
707
|
+
localDevFullOptions: "完全なサインイン オプションを表示",
|
|
666
708
|
runLocally: "ローカルで実行",
|
|
667
709
|
runLocallySentence: "ローカルで実行",
|
|
668
710
|
openSource: "100% 無料でオープンソース",
|
|
@@ -757,6 +799,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
757
799
|
backToSignIn: "로그인으로 돌아가기",
|
|
758
800
|
localNotePrefix: "계정은 이 앱의 자체 DB에 저장됩니다",
|
|
759
801
|
localNoteSuffix: ", 타사 서비스가 아닙니다.",
|
|
802
|
+
localDevButton: "로컬 개발자로 계속",
|
|
803
|
+
localDevDescription: "이 컴퓨터의 로컬 개발 환경에서만 작동합니다.",
|
|
804
|
+
localDevHelp: "로컬 개발 로그인 자세히 보기",
|
|
805
|
+
localDevSigningIn: "로컬로 로그인하는 중…",
|
|
806
|
+
localDevFailed: "로컬 개발 로그인을 사용할 수 없습니다.",
|
|
807
|
+
localDevFullOptions: "전체 로그인 옵션 보기",
|
|
760
808
|
runLocally: "로컬에서 실행",
|
|
761
809
|
runLocallySentence: "로컬에서 실행",
|
|
762
810
|
openSource: "100% 무료 오픈 소스",
|
|
@@ -851,6 +899,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
851
899
|
backToSignIn: "Voltar para entrar",
|
|
852
900
|
localNotePrefix: "Sua conta fica armazenada no banco de dados próprio deste app",
|
|
853
901
|
localNoteSuffix: ", não em um serviço de terceiros.",
|
|
902
|
+
localDevButton: "Continuar como desenvolvedor local",
|
|
903
|
+
localDevDescription: "Funciona apenas no desenvolvimento local deste computador.",
|
|
904
|
+
localDevHelp: "Saiba mais sobre o login de desenvolvimento local",
|
|
905
|
+
localDevSigningIn: "Entrando localmente…",
|
|
906
|
+
localDevFailed: "O login de desenvolvimento local não está disponível.",
|
|
907
|
+
localDevFullOptions: "Mostrar todas as opções de login",
|
|
854
908
|
runLocally: "Executar localmente",
|
|
855
909
|
runLocallySentence: "Executar localmente",
|
|
856
910
|
openSource: "100% grátis e open source",
|
|
@@ -945,6 +999,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
945
999
|
backToSignIn: "साइन इन पर वापस जाएं",
|
|
946
1000
|
localNotePrefix: "आपका खाता इस ऐप के अपने DB में संग्रहीत है",
|
|
947
1001
|
localNoteSuffix: ", किसी third-party सेवा में नहीं।",
|
|
1002
|
+
localDevButton: "स्थानीय डेवलपर के रूप में जारी रखें",
|
|
1003
|
+
localDevDescription: "यह केवल इस कंप्यूटर के स्थानीय विकास में काम करता है।",
|
|
1004
|
+
localDevHelp: "स्थानीय विकास साइन-इन के बारे में जानें",
|
|
1005
|
+
localDevSigningIn: "स्थानीय रूप से साइन इन हो रहा है…",
|
|
1006
|
+
localDevFailed: "स्थानीय विकास साइन-इन उपलब्ध नहीं है।",
|
|
1007
|
+
localDevFullOptions: "साइन-इन के सभी विकल्प दिखाएं",
|
|
948
1008
|
runLocally: "लोकल चलाएं",
|
|
949
1009
|
runLocallySentence: "लोकल चलाएं",
|
|
950
1010
|
openSource: "100% मुफ्त और open source",
|
|
@@ -1039,6 +1099,12 @@ const AUTH_LOCALE_COPY = {
|
|
|
1039
1099
|
backToSignIn: "العودة إلى تسجيل الدخول",
|
|
1040
1100
|
localNotePrefix: "يتم تخزين حسابك في قاعدة بيانات هذا التطبيق",
|
|
1041
1101
|
localNoteSuffix: "، وليس في خدمة خارجية.",
|
|
1102
|
+
localDevButton: "المتابعة كمطور محلي",
|
|
1103
|
+
localDevDescription: "يعمل فقط أثناء التطوير المحلي على هذا الكمبيوتر.",
|
|
1104
|
+
localDevHelp: "تعرف على تسجيل دخول التطوير المحلي",
|
|
1105
|
+
localDevSigningIn: "جارٍ تسجيل الدخول محليًا…",
|
|
1106
|
+
localDevFailed: "تسجيل دخول التطوير المحلي غير متاح.",
|
|
1107
|
+
localDevFullOptions: "عرض خيارات تسجيل الدخول الكاملة",
|
|
1042
1108
|
runLocally: "تشغيل محليًا",
|
|
1043
1109
|
runLocallySentence: "تشغيل محليًا",
|
|
1044
1110
|
openSource: "مجاني ومفتوح المصدر 100%",
|
|
@@ -1380,6 +1446,16 @@ ${googleNoticeRunLocalPanelHtml}
|
|
|
1380
1446
|
</div>`
|
|
1381
1447
|
: "";
|
|
1382
1448
|
const identitySsoHtml = identitySsoLoginButtonHtml();
|
|
1449
|
+
const localDevHtml = `
|
|
1450
|
+
<div class="local-dev-signin" id="local-dev-signin" hidden>
|
|
1451
|
+
<button type="button" class="btn-local-dev btn-primary" id="local-dev-btn" title="${esc(t("localDevDescription"))}"${i18nAttr("localDevButton")} data-i18n-title="localDevDescription" aria-describedby="local-dev-description">${esc(t("localDevButton"))}</button>
|
|
1452
|
+
<p class="local-dev-description" id="local-dev-description">
|
|
1453
|
+
<span${i18nAttr("localDevDescription")}>${esc(t("localDevDescription"))}</span>
|
|
1454
|
+
<a class="local-dev-help" id="local-dev-help" href="https://www.agent-native.com/docs/authentication#local-development-sign-in" target="_blank" rel="noreferrer" aria-label="${esc(t("localDevHelp"))}" title="${esc(t("localDevHelp"))}" data-i18n-title="localDevHelp"${i18nAriaAttr("localDevHelp")}><span class="local-dev-help-glyph" aria-hidden="true">?</span></a>
|
|
1455
|
+
</p>
|
|
1456
|
+
<button type="button" class="local-dev-full-options" id="local-dev-full-options" hidden${i18nAttr("localDevFullOptions")}>${esc(t("localDevFullOptions"))}</button>
|
|
1457
|
+
<p class="msg error" id="local-dev-msg" role="status" aria-live="polite"></p>
|
|
1458
|
+
</div>`;
|
|
1383
1459
|
const identitySsoMagicLinkSelector = identitySsoHtml
|
|
1384
1460
|
? " .card.magic-link-complete #identity-sso-btn,\n"
|
|
1385
1461
|
: "";
|
|
@@ -1993,6 +2069,70 @@ ${hasMarketing
|
|
|
1993
2069
|
cursor: pointer;
|
|
1994
2070
|
}
|
|
1995
2071
|
.btn-secondary:hover { color: #bbb; border-color: rgba(255,255,255,0.2); }
|
|
2072
|
+
.local-dev-signin {
|
|
2073
|
+
margin: 1.25rem 0 0.25rem;
|
|
2074
|
+
padding-top: 1rem;
|
|
2075
|
+
border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
|
|
2076
|
+
}
|
|
2077
|
+
.btn-local-dev {
|
|
2078
|
+
margin-top: 0.25rem;
|
|
2079
|
+
}
|
|
2080
|
+
.btn-local-dev:disabled { opacity: 0.5; cursor: wait; }
|
|
2081
|
+
.local-dev-description {
|
|
2082
|
+
display: flex;
|
|
2083
|
+
align-items: center;
|
|
2084
|
+
justify-content: center;
|
|
2085
|
+
gap: 0.35rem;
|
|
2086
|
+
margin: 0.5rem 0 0;
|
|
2087
|
+
color: color-mix(in srgb, currentColor 50%, transparent);
|
|
2088
|
+
font-size: 0.6875rem;
|
|
2089
|
+
line-height: 1.45;
|
|
2090
|
+
text-align: center;
|
|
2091
|
+
}
|
|
2092
|
+
.local-dev-help {
|
|
2093
|
+
display: inline-flex;
|
|
2094
|
+
align-items: center;
|
|
2095
|
+
justify-content: center;
|
|
2096
|
+
flex: 0 0 auto;
|
|
2097
|
+
width: 1.5rem;
|
|
2098
|
+
height: 1.5rem;
|
|
2099
|
+
margin: -0.375rem;
|
|
2100
|
+
color: inherit;
|
|
2101
|
+
text-decoration: none;
|
|
2102
|
+
}
|
|
2103
|
+
.local-dev-help-glyph {
|
|
2104
|
+
display: inline-flex;
|
|
2105
|
+
align-items: center;
|
|
2106
|
+
justify-content: center;
|
|
2107
|
+
width: 0.625rem;
|
|
2108
|
+
height: 0.625rem;
|
|
2109
|
+
border: 1px solid currentColor;
|
|
2110
|
+
border-radius: 50%;
|
|
2111
|
+
font-size: 0.4375rem;
|
|
2112
|
+
font-weight: 600;
|
|
2113
|
+
line-height: 1;
|
|
2114
|
+
}
|
|
2115
|
+
.local-dev-help:hover { color: currentColor; }
|
|
2116
|
+
.local-dev-help:focus-visible {
|
|
2117
|
+
outline: 2px solid currentColor;
|
|
2118
|
+
outline-offset: 2px;
|
|
2119
|
+
}
|
|
2120
|
+
.local-dev-full-options {
|
|
2121
|
+
display: block;
|
|
2122
|
+
margin: 0.75rem auto 0;
|
|
2123
|
+
padding: 0;
|
|
2124
|
+
background: transparent;
|
|
2125
|
+
border: 0;
|
|
2126
|
+
color: color-mix(in srgb, currentColor 62%, transparent);
|
|
2127
|
+
font-size: 0.75rem;
|
|
2128
|
+
cursor: pointer;
|
|
2129
|
+
text-decoration: underline;
|
|
2130
|
+
text-underline-offset: 2px;
|
|
2131
|
+
}
|
|
2132
|
+
.local-dev-full-options:hover { color: currentColor; }
|
|
2133
|
+
.local-dev-full-options[hidden] { display: none; }
|
|
2134
|
+
.full-auth-options { margin-top: 1rem; }
|
|
2135
|
+
.full-auth-options[hidden] { display: none; }
|
|
1996
2136
|
.legal-note {
|
|
1997
2137
|
margin-top: 0.375rem;
|
|
1998
2138
|
margin-bottom: 0.875rem;
|
|
@@ -2393,6 +2533,8 @@ ${marketingPanelHtml}
|
|
|
2393
2533
|
${i18nDataAttr("data-upgrade-copy", "upgradeCopy").trim()}
|
|
2394
2534
|
></p>
|
|
2395
2535
|
${identitySsoHtml}
|
|
2536
|
+
${localDevHtml}
|
|
2537
|
+
<div id="full-auth-options" class="full-auth-options">
|
|
2396
2538
|
${renderGoogleButton
|
|
2397
2539
|
? `
|
|
2398
2540
|
<div class="google-signin" id="google-signin">
|
|
@@ -2469,6 +2611,7 @@ ${signupLocalModeNoteHtml}
|
|
|
2469
2611
|
</p>
|
|
2470
2612
|
</form>`}
|
|
2471
2613
|
</div>
|
|
2614
|
+
</div>
|
|
2472
2615
|
<p class="local-note" id="local-note">
|
|
2473
2616
|
<span${i18nAttr("localNotePrefix")}>${esc(t("localNotePrefix"))}</span> (<strong>${getConnectionLabel()}</strong>)<span${i18nAttr("localNoteSuffix")}>${esc(t("localNoteSuffix"))}</span>
|
|
2474
2617
|
</p>${marketingCloseHtml}
|
|
@@ -2810,6 +2953,66 @@ ${signInJourneyInlineScript()}
|
|
|
2810
2953
|
return false;
|
|
2811
2954
|
});
|
|
2812
2955
|
}
|
|
2956
|
+
function __anIsLoopbackHostname() {
|
|
2957
|
+
var hostname = (window.location.hostname || '').toLowerCase();
|
|
2958
|
+
return hostname === 'localhost' || hostname === '::1' || hostname === '127.0.0.1' || hostname.indexOf('127.') === 0;
|
|
2959
|
+
}
|
|
2960
|
+
function __anShouldStartWithLocalDev() {
|
|
2961
|
+
if (!__anIsLoopbackHostname()) return false;
|
|
2962
|
+
var params = new URLSearchParams(window.location.search);
|
|
2963
|
+
var explicitTab = params.get('tab');
|
|
2964
|
+
var verifiedRedirect = typeof __anIsVerifiedRedirectSuccess === 'function' && __anIsVerifiedRedirectSuccess();
|
|
2965
|
+
return explicitTab !== 'login' && explicitTab !== 'signup' && !verifiedRedirect;
|
|
2966
|
+
}
|
|
2967
|
+
function __anSetFullAuthOptionsVisible(visible) {
|
|
2968
|
+
var options = document.getElementById('full-auth-options');
|
|
2969
|
+
var toggle = document.getElementById('local-dev-full-options');
|
|
2970
|
+
if (!options) return;
|
|
2971
|
+
if (visible) {
|
|
2972
|
+
options.removeAttribute('hidden');
|
|
2973
|
+
if (toggle) toggle.setAttribute('hidden', '');
|
|
2974
|
+
} else {
|
|
2975
|
+
options.setAttribute('hidden', '');
|
|
2976
|
+
if (toggle) toggle.removeAttribute('hidden');
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
(function __anPrepareLocalDevButton() {
|
|
2980
|
+
var container = document.getElementById('local-dev-signin');
|
|
2981
|
+
var button = document.getElementById('local-dev-btn');
|
|
2982
|
+
var fullOptionsButton = document.getElementById('local-dev-full-options');
|
|
2983
|
+
var message = document.getElementById('local-dev-msg');
|
|
2984
|
+
if (!container || !button || !__anIsLoopbackHostname()) return;
|
|
2985
|
+
container.hidden = false;
|
|
2986
|
+
var startWithLocalDev = __anShouldStartWithLocalDev();
|
|
2987
|
+
__anSetFullAuthOptionsVisible(!startWithLocalDev);
|
|
2988
|
+
if (startWithLocalDev) button.focus();
|
|
2989
|
+
if (fullOptionsButton) fullOptionsButton.addEventListener('click', function() {
|
|
2990
|
+
__anSetFullAuthOptionsVisible(true);
|
|
2991
|
+
var firstInput = document.querySelector('#full-auth-options input, #full-auth-options button, #full-auth-options a');
|
|
2992
|
+
if (firstInput) firstInput.focus();
|
|
2993
|
+
});
|
|
2994
|
+
button.addEventListener('click', function() {
|
|
2995
|
+
button.disabled = true;
|
|
2996
|
+
button.textContent = __anT('localDevSigningIn');
|
|
2997
|
+
fetch(__anPath('/_agent-native/auth/local-dev'), {
|
|
2998
|
+
method: 'POST',
|
|
2999
|
+
credentials: 'include',
|
|
3000
|
+
headers: { 'Accept': 'application/json' },
|
|
3001
|
+
}).then(function(response) {
|
|
3002
|
+
if (!response.ok) throw new Error('local-dev-auth-failed');
|
|
3003
|
+
}).then(function() {
|
|
3004
|
+
__anRedirectToSignedInApp(__anResumeHref());
|
|
3005
|
+
}).catch(function() {
|
|
3006
|
+
button.disabled = false;
|
|
3007
|
+
button.textContent = __anT('localDevButton');
|
|
3008
|
+
__anSetFullAuthOptionsVisible(true);
|
|
3009
|
+
if (message) {
|
|
3010
|
+
message.textContent = __anT('localDevFailed');
|
|
3011
|
+
message.classList.add('show');
|
|
3012
|
+
}
|
|
3013
|
+
});
|
|
3014
|
+
});
|
|
3015
|
+
})();
|
|
2813
3016
|
${identitySsoScript}
|
|
2814
3017
|
(function __anRedirectIfAlreadySignedIn() {
|
|
2815
3018
|
__anMaybeRedirectSignedIn();
|
|
@@ -3498,7 +3701,7 @@ ${googleOnly
|
|
|
3498
3701
|
}
|
|
3499
3702
|
}
|
|
3500
3703
|
(function initActiveTab() {
|
|
3501
|
-
var initial = 'signup';
|
|
3704
|
+
var initial = __AN_AUTH_MODE === 'magic-link' ? 'magicLink' : 'signup';
|
|
3502
3705
|
try {
|
|
3503
3706
|
var params = new URLSearchParams(location.search);
|
|
3504
3707
|
var qp = params.get('tab');
|
|
@@ -3517,7 +3720,8 @@ ${googleOnly
|
|
|
3517
3720
|
if (stored === 'login' || stored === 'signup') initial = stored;
|
|
3518
3721
|
}
|
|
3519
3722
|
} catch (e) {}
|
|
3520
|
-
|
|
3723
|
+
if (initial === 'magicLink') showMagicLinkForm();
|
|
3724
|
+
else setActiveTab(initial, { persist: false });
|
|
3521
3725
|
try {
|
|
3522
3726
|
if (__anIsVerifiedRedirectSuccess()) {
|
|
3523
3727
|
var rememberedEmail = readRememberedPendingSignupEmail();
|
package/dist/server/poll.d.ts
CHANGED
|
@@ -147,6 +147,7 @@ export declare class AppSyncState {
|
|
|
147
147
|
private readonly pollEmitter;
|
|
148
148
|
private syncEventsInitPromise;
|
|
149
149
|
private lastDurablePrune;
|
|
150
|
+
private durablePruneFailures;
|
|
150
151
|
/**
|
|
151
152
|
* Whether we've seeded `version` from the DB. In serverless (Netlify,
|
|
152
153
|
* Vercel, etc.) each invocation starts fresh — without seeding, `version`
|
|
@@ -212,6 +213,31 @@ export declare class AppSyncState {
|
|
|
212
213
|
*/
|
|
213
214
|
wireLocalEmitters(): void;
|
|
214
215
|
ensureSyncEventsTable(): Promise<boolean>;
|
|
216
|
+
/**
|
|
217
|
+
* Drop events past the retention window, in bounded batches.
|
|
218
|
+
*
|
|
219
|
+
* Three things here are load-bearing, all of them learned from a 47 GB
|
|
220
|
+
* `sync_events` table on a live app:
|
|
221
|
+
*
|
|
222
|
+
* - Prune by `created_at`, the actual retention timestamp, with the
|
|
223
|
+
* additive `(created_at, id)` index created above. A version can move
|
|
224
|
+
* ahead of the clock under bursty writes, so it is not a retention
|
|
225
|
+
* timestamp and cannot define a 24-hour boundary safely.
|
|
226
|
+
* - Batch it. One statement deleting an unbounded slice is a long
|
|
227
|
+
* transaction, and a long transaction killed mid-flight by a serverless
|
|
228
|
+
* worker shutdown is what leaves connections `idle in transaction`
|
|
229
|
+
* holding locks — the shape of the 2026-08-06 outage.
|
|
230
|
+
* - `ORDER BY version` inside the subquery. Without it the planner
|
|
231
|
+
* prefers a sequential scan even with a LIMIT; with it, the existing
|
|
232
|
+
* `sync_events_version_idx` drives the batch and the delete is a
|
|
233
|
+
* bounded index range scan.
|
|
234
|
+
*
|
|
235
|
+
* The `lastDurablePrune` throttle below is per-process, so every serverless
|
|
236
|
+
* worker prunes on its first poll. That was survivable only once the work
|
|
237
|
+
* itself became bounded and indexed; if concurrency is still a problem,
|
|
238
|
+
* the next step is a `pg_try_advisory_xact_lock` so one worker prunes at a
|
|
239
|
+
* time. Deliberately not done yet — measure before adding a lock.
|
|
240
|
+
*/
|
|
215
241
|
private pruneDurableEvents;
|
|
216
242
|
persistSyncEvent(event: ChangeEvent, dedupeKey?: string, presetId?: string): Promise<void>;
|
|
217
243
|
/**
|
package/dist/server/poll.js
CHANGED
|
@@ -25,7 +25,7 @@ import { defineEventHandler, getQuery, setResponseStatus } from "h3";
|
|
|
25
25
|
import { ACTION_CHANGE_MARKER_KEY, parseActionChangeMarker, } from "../action-change-marker.js";
|
|
26
26
|
import { getAppStateEmitter } from "../application-state/emitter.js";
|
|
27
27
|
import { getDbExec, isPostgres } from "../db/client.js";
|
|
28
|
-
import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
|
|
28
|
+
import { ensureIndexExists, ensureIndexExistsConcurrently, ensureTableExists, } from "../db/ddl-guard.js";
|
|
29
29
|
import { EXTENSION_CHANGE_MARKER_KEY, parseExtensionChangeMarker, } from "../extensions/change-marker.js";
|
|
30
30
|
import { getSettingsEmitter } from "../settings/store.js";
|
|
31
31
|
import { getSession } from "./auth.js";
|
|
@@ -34,6 +34,21 @@ import { getSession } from "./auth.js";
|
|
|
34
34
|
const MAX_BUFFER = 200;
|
|
35
35
|
const DURABLE_READ_LIMIT = 1000;
|
|
36
36
|
const DURABLE_RETENTION_MS = 24 * 60 * 60 * 1000;
|
|
37
|
+
/**
|
|
38
|
+
* Rows per prune statement, and the ceiling on statements per prune call.
|
|
39
|
+
* The product (400k) leaves headroom over one app's documented production of
|
|
40
|
+
* ~1k events/sec over the five-minute throttle, so a healthy app catches up;
|
|
41
|
+
* the cap still bounds how long a single call can run.
|
|
42
|
+
*/
|
|
43
|
+
const DURABLE_PRUNE_BATCH = 10_000;
|
|
44
|
+
const DURABLE_PRUNE_MAX_BATCHES = 40;
|
|
45
|
+
/**
|
|
46
|
+
* How far back a cold-started process replays durable action markers.
|
|
47
|
+
* Covers the gap between a separate action process writing its marker and this
|
|
48
|
+
* process's first poll — seconds in practice. Anything older is history, and
|
|
49
|
+
* replaying history is what produced 1,169 sync events/sec on one app.
|
|
50
|
+
*/
|
|
51
|
+
const ACTION_MARKER_REPLAY_WINDOW_MS = 60_000;
|
|
37
52
|
const LEGACY_DB_CHECK_INTERVAL_MS = 1000;
|
|
38
53
|
export const DURABLE_LEGACY_DB_CHECK_INTERVAL_MS = 30_000;
|
|
39
54
|
export const POLL_CHANGE_EVENT = "poll-change";
|
|
@@ -243,6 +258,7 @@ export class AppSyncState {
|
|
|
243
258
|
pollEmitter = new EventEmitter();
|
|
244
259
|
syncEventsInitPromise;
|
|
245
260
|
lastDurablePrune = 0;
|
|
261
|
+
durablePruneFailures = 0;
|
|
246
262
|
/**
|
|
247
263
|
* Whether we've seeded `version` from the DB. In serverless (Netlify,
|
|
248
264
|
* Vercel, etc.) each invocation starts fresh — without seeding, `version`
|
|
@@ -388,6 +404,7 @@ export class AppSyncState {
|
|
|
388
404
|
await ensureIndexExists("sync_events_version_idx", "CREATE INDEX IF NOT EXISTS sync_events_version_idx ON sync_events (version)", guardOptions);
|
|
389
405
|
await ensureIndexExists("sync_events_owner_version_idx", "CREATE INDEX IF NOT EXISTS sync_events_owner_version_idx ON sync_events (owner, version)", guardOptions);
|
|
390
406
|
await ensureIndexExists("sync_events_org_version_idx", "CREATE INDEX IF NOT EXISTS sync_events_org_version_idx ON sync_events (org_id, version)", guardOptions);
|
|
407
|
+
await ensureIndexExistsConcurrently("sync_events_created_at_id_idx", "CREATE INDEX CONCURRENTLY IF NOT EXISTS sync_events_created_at_id_idx ON sync_events (created_at, id)", guardOptions);
|
|
391
408
|
if (this.dbAssignedVersions) {
|
|
392
409
|
await ensureTableExists("sync_version", "CREATE TABLE IF NOT EXISTS sync_version (id INT PRIMARY KEY, v BIGINT NOT NULL)", guardOptions);
|
|
393
410
|
// Seed at/above both the existing durable max and wall clock, so
|
|
@@ -401,6 +418,7 @@ export class AppSyncState {
|
|
|
401
418
|
"CREATE INDEX IF NOT EXISTS sync_events_version_idx ON sync_events (version)",
|
|
402
419
|
"CREATE INDEX IF NOT EXISTS sync_events_owner_version_idx ON sync_events (owner, version)",
|
|
403
420
|
"CREATE INDEX IF NOT EXISTS sync_events_org_version_idx ON sync_events (org_id, version)",
|
|
421
|
+
"CREATE INDEX IF NOT EXISTS sync_events_created_at_id_idx ON sync_events (created_at, id)",
|
|
404
422
|
]) {
|
|
405
423
|
try {
|
|
406
424
|
await client.execute(ddl);
|
|
@@ -417,17 +435,66 @@ export class AppSyncState {
|
|
|
417
435
|
}
|
|
418
436
|
return this.syncEventsInitPromise;
|
|
419
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* Drop events past the retention window, in bounded batches.
|
|
440
|
+
*
|
|
441
|
+
* Three things here are load-bearing, all of them learned from a 47 GB
|
|
442
|
+
* `sync_events` table on a live app:
|
|
443
|
+
*
|
|
444
|
+
* - Prune by `created_at`, the actual retention timestamp, with the
|
|
445
|
+
* additive `(created_at, id)` index created above. A version can move
|
|
446
|
+
* ahead of the clock under bursty writes, so it is not a retention
|
|
447
|
+
* timestamp and cannot define a 24-hour boundary safely.
|
|
448
|
+
* - Batch it. One statement deleting an unbounded slice is a long
|
|
449
|
+
* transaction, and a long transaction killed mid-flight by a serverless
|
|
450
|
+
* worker shutdown is what leaves connections `idle in transaction`
|
|
451
|
+
* holding locks — the shape of the 2026-08-06 outage.
|
|
452
|
+
* - `ORDER BY version` inside the subquery. Without it the planner
|
|
453
|
+
* prefers a sequential scan even with a LIMIT; with it, the existing
|
|
454
|
+
* `sync_events_version_idx` drives the batch and the delete is a
|
|
455
|
+
* bounded index range scan.
|
|
456
|
+
*
|
|
457
|
+
* The `lastDurablePrune` throttle below is per-process, so every serverless
|
|
458
|
+
* worker prunes on its first poll. That was survivable only once the work
|
|
459
|
+
* itself became bounded and indexed; if concurrency is still a problem,
|
|
460
|
+
* the next step is a `pg_try_advisory_xact_lock` so one worker prunes at a
|
|
461
|
+
* time. Deliberately not done yet — measure before adding a lock.
|
|
462
|
+
*/
|
|
420
463
|
async pruneDurableEvents(client) {
|
|
421
464
|
const now = Date.now();
|
|
422
465
|
if (now - this.lastDurablePrune < 5 * 60 * 1000)
|
|
423
466
|
return;
|
|
424
467
|
this.lastDurablePrune = now;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
468
|
+
const cutoff = now - DURABLE_RETENTION_MS;
|
|
469
|
+
let deleted = 0;
|
|
470
|
+
try {
|
|
471
|
+
for (let batch = 0; batch < DURABLE_PRUNE_MAX_BATCHES; batch++) {
|
|
472
|
+
const result = await client.execute({
|
|
473
|
+
// `id IN (...)` rather than ctid/rowid: both are dialect-specific,
|
|
474
|
+
// and the primary key is indexed on every dialect we ship.
|
|
475
|
+
sql: `DELETE FROM sync_events WHERE id IN (
|
|
476
|
+
SELECT id FROM sync_events WHERE created_at < ?
|
|
477
|
+
ORDER BY created_at, id LIMIT ?
|
|
478
|
+
)`,
|
|
479
|
+
args: [cutoff, DURABLE_PRUNE_BATCH],
|
|
480
|
+
});
|
|
481
|
+
deleted += result.rowsAffected;
|
|
482
|
+
if (result.rowsAffected < DURABLE_PRUNE_BATCH)
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
this.durablePruneFailures = 0;
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
// This used to be `.catch(() => {})`. A prune that silently never
|
|
489
|
+
// succeeded is indistinguishable from one that had nothing to do, which
|
|
490
|
+
// is how the table reached 47 GB without anyone finding out. Warn once
|
|
491
|
+
// per failure streak so a persistently broken prune is visible without
|
|
492
|
+
// repeating every five minutes.
|
|
493
|
+
this.durablePruneFailures++;
|
|
494
|
+
if (this.durablePruneFailures === 1) {
|
|
495
|
+
console.warn(`[agent-native] sync_events prune failed after deleting ${deleted} row(s); the table will grow until this succeeds:`, err instanceof Error ? err.message : String(err));
|
|
496
|
+
}
|
|
497
|
+
}
|
|
431
498
|
}
|
|
432
499
|
async persistSyncEvent(event, dedupeKey, presetId) {
|
|
433
500
|
if (!(await this.ensureSyncEventsTable()))
|
|
@@ -1025,7 +1092,17 @@ export class AppSyncState {
|
|
|
1025
1092
|
// Action markers are durable specifically so a web server can observe work
|
|
1026
1093
|
// performed by a separate action process. Do not baseline past an existing
|
|
1027
1094
|
// marker on cold start, or the first poll after the action will miss it.
|
|
1028
|
-
|
|
1095
|
+
//
|
|
1096
|
+
// Bounded to a replay window rather than rewound to 0. At 0 the filter
|
|
1097
|
+
// below (`updated_at > lastActionMarkerTs`) passes EVERY row, and the
|
|
1098
|
+
// marker table is one never-pruned row per identity that has ever run a
|
|
1099
|
+
// mutating action — so every cold start re-emitted the entire history.
|
|
1100
|
+
// On one production app that was 2,188 rows replayed ~32 times a minute:
|
|
1101
|
+
// 1,169 sync events/sec, none of it real traffic, against ~1.7/sec that
|
|
1102
|
+
// was. A `> 0` first-run guard like the sibling detectors use would be
|
|
1103
|
+
// wrong here — it would discard the cross-process wakeup this rewind
|
|
1104
|
+
// exists for. Bounding the window keeps that and drops the history.
|
|
1105
|
+
this.lastActionMarkerTs = Math.max(0, actionMarkerTs - ACTION_MARKER_REPLAY_WINDOW_MS);
|
|
1029
1106
|
this.replayActionMarkerOnce = actionMarkerTs > 0;
|
|
1030
1107
|
this.lastScreenRefreshTs = refreshTs;
|
|
1031
1108
|
this.lastScreenRefreshTsBySession.clear();
|
|
@@ -1151,14 +1228,25 @@ export class AppSyncState {
|
|
|
1151
1228
|
// serverless action invocations wake the web server's SSE/poll loop as a
|
|
1152
1229
|
// first-class source:"action" event rather than a generic app-state bump.
|
|
1153
1230
|
if (actionMarkerTs > this.lastActionMarkerTs) {
|
|
1231
|
+
// Bounded by the same watermark the filter below applies, so a cold
|
|
1232
|
+
// start reads its replay window instead of every marker ever written.
|
|
1154
1233
|
const actionMarkerResult = await db.execute({
|
|
1155
|
-
sql: "SELECT session_id, value, updated_at FROM application_state WHERE key = ? ORDER BY updated_at ASC",
|
|
1156
|
-
args: [ACTION_CHANGE_MARKER_KEY],
|
|
1234
|
+
sql: "SELECT session_id, value, updated_at FROM application_state WHERE key = ? AND updated_at > ? ORDER BY updated_at ASC",
|
|
1235
|
+
args: [ACTION_CHANGE_MARKER_KEY, this.lastActionMarkerTs],
|
|
1157
1236
|
});
|
|
1158
1237
|
const changedActionMarkers = actionMarkerResult.rows.filter((row) => timestampValue(row.updated_at) > this.lastActionMarkerTs);
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1238
|
+
for (const row of changedActionMarkers) {
|
|
1239
|
+
const target = parseActionChangeMarker(row.session_id, row.value);
|
|
1240
|
+
if (!target)
|
|
1241
|
+
continue;
|
|
1242
|
+
// Keyed on the ROW's own timestamp, not the table-wide max: every
|
|
1243
|
+
// process replaying the same marker must produce the same id so
|
|
1244
|
+
// `ON CONFLICT (id) DO NOTHING` collapses them. Keyed on the max,
|
|
1245
|
+
// two processes booting a moment apart hash the same row
|
|
1246
|
+
// differently and each writes its own copy. Matches the extension
|
|
1247
|
+
// marker path.
|
|
1248
|
+
this.recordActionChanges([target], `action|${timestampValue(row.updated_at)}`);
|
|
1249
|
+
}
|
|
1162
1250
|
this.lastActionMarkerTs = actionMarkerTs;
|
|
1163
1251
|
}
|
|
1164
1252
|
// Check for screen-refresh requests from the agent. The `refresh-screen`
|
|
@@ -1290,6 +1378,13 @@ export function getDefaultAppSyncState() {
|
|
|
1290
1378
|
if (!_defaultState) {
|
|
1291
1379
|
_defaultState = new AppSyncState({
|
|
1292
1380
|
dbAssignedVersions: hostedRealtimeTransportEnabled(),
|
|
1381
|
+
// Only the out-of-band detectors (action markers, extensions, app-state)
|
|
1382
|
+
// pass a dedupeKey, so this changes nothing for ordinary writes — they
|
|
1383
|
+
// keep unique ids. It exists so N processes detecting the SAME external
|
|
1384
|
+
// write collapse to one row via `ON CONFLICT (id) DO NOTHING`. Left off,
|
|
1385
|
+
// it never once executed in production: every dedupeKey threaded through
|
|
1386
|
+
// this file was inert, and each cold start wrote its own duplicate set.
|
|
1387
|
+
deterministicEventIds: true,
|
|
1293
1388
|
});
|
|
1294
1389
|
}
|
|
1295
1390
|
return _defaultState;
|
|
@@ -18,7 +18,7 @@ import { defineEventHandler } from "h3";
|
|
|
18
18
|
*/
|
|
19
19
|
import { createRequestHandler } from "react-router";
|
|
20
20
|
import { isMcpPublicPath } from "../mcp/route-paths.js";
|
|
21
|
-
import { DEFAULT_SPECULATION_RULES_PATH, resolveSsrCacheHeaders, } from "../shared/cache-control.js";
|
|
21
|
+
import { DEFAULT_SPECULATION_RULES_PATH, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, } from "../shared/cache-control.js";
|
|
22
22
|
import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, withAgentNativeSocialImageCacheBuster, } from "../shared/social-meta.js";
|
|
23
23
|
import { getAppBasePathFromViteEnv, stripAppBasePath as canonicalStripAppBasePath, } from "./app-base-path.js";
|
|
24
24
|
import { captureError } from "./capture-error.js";
|
|
@@ -225,6 +225,9 @@ function applyDefaultSsrCacheHeader(headers, status, pathname) {
|
|
|
225
225
|
for (const [name, value] of Object.entries(resolveSsrCacheHeaders())) {
|
|
226
226
|
headers.set(name, value);
|
|
227
227
|
}
|
|
228
|
+
for (const [name, value] of Object.entries(resolveSsrCacheKeyHeaders())) {
|
|
229
|
+
headers.set(name, value);
|
|
230
|
+
}
|
|
228
231
|
}
|
|
229
232
|
function applyDefaultSpeculationRulesHeader(headers, status, basePath) {
|
|
230
233
|
if (status < 200 || status >= 400)
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { SIGN_IN_CONTINUATION_MAX_LENGTH, SIGN_IN_CONTINUATION_PARAM, SIGN_IN_EN
|
|
|
5
5
|
export { truncate } from "./truncate.js";
|
|
6
6
|
export { injectDocumentMarkup } from "./html-document.js";
|
|
7
7
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
8
|
+
export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, type RuntimeConfigEnvironment, type RuntimeConfigIssue, type RuntimeConfigIssueCode, type RuntimeConfigIssueSeverity, type RuntimeConfigPhase, type RuntimeConfigReport, type RuntimeConfigRequirements, } from "./runtime-config.js";
|
|
8
9
|
export { llmConnectionTrackingProperties, normalizeLlmConnection, type LlmConnectionStatus, } from "./llm-connection.js";
|
|
9
10
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, } from "./workspace-app-id.js";
|
|
10
11
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, type WorkspaceAppRouteAccess, type WorkspaceAppRouteAccessFromConfig, type WorkspaceAppAudience, } from "./workspace-app-audience.js";
|
package/dist/shared/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { SIGN_IN_CONTINUATION_MAX_LENGTH, SIGN_IN_CONTINUATION_PARAM, SIGN_IN_EN
|
|
|
5
5
|
export { truncate } from "./truncate.js";
|
|
6
6
|
export { injectDocumentMarkup } from "./html-document.js";
|
|
7
7
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
8
|
+
export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, } from "./runtime-config.js";
|
|
8
9
|
export { llmConnectionTrackingProperties, normalizeLlmConnection, } from "./llm-connection.js";
|
|
9
10
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, } from "./workspace-app-id.js";
|
|
10
11
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "./workspace-app-audience.js";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production configuration diagnostics.
|
|
3
|
+
*
|
|
4
|
+
* This module deliberately accepts an env-like record instead of reading
|
|
5
|
+
* process.env so the same rules can run during a Vite build, on the server,
|
|
6
|
+
* and in focused tests without ever exposing secret values to the browser.
|
|
7
|
+
*/
|
|
8
|
+
export type RuntimeConfigEnvironment = "development" | "production";
|
|
9
|
+
export type RuntimeConfigPhase = "build" | "runtime";
|
|
10
|
+
export type RuntimeConfigIssueSeverity = "warning" | "error";
|
|
11
|
+
export type RuntimeConfigIssueCode = "auth-disabled-in-production" | "missing-auth-secret" | "weak-auth-secret" | "missing-a2a-secret" | "weak-a2a-secret" | "invalid-auth-url" | "missing-database-url" | "local-database-in-production" | "missing-required-env";
|
|
12
|
+
export interface RuntimeConfigRequirements {
|
|
13
|
+
/** Whether the app's default or custom auth layer is expected to run. */
|
|
14
|
+
authEnabled?: boolean;
|
|
15
|
+
/** Whether the app needs a persistent database outside local development. */
|
|
16
|
+
databaseRequired?: boolean;
|
|
17
|
+
/** Additional non-secret keys the app declares as required. */
|
|
18
|
+
requiredEnv?: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
export interface RuntimeConfigIssue {
|
|
21
|
+
code: RuntimeConfigIssueCode;
|
|
22
|
+
severity: RuntimeConfigIssueSeverity;
|
|
23
|
+
title: string;
|
|
24
|
+
message: string;
|
|
25
|
+
envKeys: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface RuntimeConfigReport {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
status: "ok" | "warning" | "error";
|
|
30
|
+
environment: RuntimeConfigEnvironment;
|
|
31
|
+
phase: RuntimeConfigPhase;
|
|
32
|
+
issues: RuntimeConfigIssue[];
|
|
33
|
+
prompt: string;
|
|
34
|
+
}
|
|
35
|
+
export interface RuntimeConfigReportOptions {
|
|
36
|
+
environment?: RuntimeConfigEnvironment;
|
|
37
|
+
phase?: RuntimeConfigPhase;
|
|
38
|
+
appName?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function runtimeConfigRequirementsFromSearchParams(searchParams: URLSearchParams): RuntimeConfigRequirements;
|
|
41
|
+
export declare function buildRuntimeConfigPrompt(report: Pick<RuntimeConfigReport, "environment" | "phase" | "issues">, appName?: string): string;
|
|
42
|
+
export declare function getRuntimeConfigReport(env: Record<string, string | undefined>, requirements?: RuntimeConfigRequirements, options?: RuntimeConfigReportOptions): RuntimeConfigReport;
|
|
43
|
+
export declare function formatRuntimeConfigReport(report: RuntimeConfigReport): string;
|
|
44
|
+
export declare function parseRuntimeConfigReport(value: unknown): RuntimeConfigReport | null;
|