@useatlas/create 0.0.6 → 0.0.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/LICENSE +21 -0
- package/README.md +1 -1
- package/index.ts +253 -36
- package/package.json +4 -4
- package/templates/docker/Dockerfile +1 -1
- package/templates/docker/Dockerfile.sidecar +1 -1
- package/templates/docker/bin/__tests__/duckdb-ingest.test.ts +17 -14
- package/templates/docker/bin/__tests__/failure-threshold.test.ts +148 -0
- package/templates/docker/bin/__tests__/fatal-error-propagation.test.ts +267 -0
- package/templates/docker/bin/__tests__/profiler-heuristics.test.ts +5 -5
- package/templates/docker/bin/__tests__/schema-drift.test.ts +39 -0
- package/templates/docker/bin/atlas.ts +981 -1819
- package/templates/docker/bin/benchmark.ts +14 -16
- package/templates/docker/bin/enrich.ts +7 -2
- package/templates/docker/brand.css +13 -0
- package/templates/docker/data/cybersec-semantic/catalog.yml +222 -0
- package/templates/docker/data/cybersec-semantic/entities/alerts.yml +195 -0
- package/templates/docker/data/cybersec-semantic/entities/assets.yml +191 -0
- package/templates/docker/data/cybersec-semantic/entities/compliance_assessments.yml +170 -0
- package/templates/docker/data/cybersec-semantic/entities/incidents.yml +219 -0
- package/templates/docker/data/cybersec-semantic/entities/organizations.yml +136 -0
- package/templates/docker/data/cybersec-semantic/entities/plans.yml +114 -0
- package/templates/docker/data/cybersec-semantic/entities/remediation_actions.yml +212 -0
- package/templates/docker/data/cybersec-semantic/entities/scan_results.yml +215 -0
- package/templates/docker/data/cybersec-semantic/entities/scans.yml +180 -0
- package/templates/docker/data/cybersec-semantic/entities/subscriptions.yml +184 -0
- package/templates/docker/data/cybersec-semantic/entities/users.yml +140 -0
- package/templates/docker/data/cybersec-semantic/entities/vulnerabilities.yml +154 -0
- package/templates/docker/data/cybersec-semantic/glossary.yml +207 -0
- package/templates/docker/data/cybersec-semantic/metrics/business.yml +148 -0
- package/templates/docker/data/cybersec-semantic/metrics/compliance.yml +138 -0
- package/templates/docker/data/cybersec-semantic/metrics/security.yml +181 -0
- package/templates/docker/data/cybersec.sql +8 -8
- package/templates/docker/data/demo.sql +3 -0
- package/templates/docker/data/ecommerce-semantic/catalog.yml +221 -0
- package/templates/docker/data/ecommerce-semantic/entities/categories.yml +91 -0
- package/templates/docker/data/ecommerce-semantic/entities/customers.yml +133 -0
- package/templates/docker/data/ecommerce-semantic/entities/email_campaigns.yml +119 -0
- package/templates/docker/data/ecommerce-semantic/entities/inventory_levels.yml +153 -0
- package/templates/docker/data/ecommerce-semantic/entities/order_items.yml +159 -0
- package/templates/docker/data/ecommerce-semantic/entities/orders.yml +199 -0
- package/templates/docker/data/ecommerce-semantic/entities/payments.yml +140 -0
- package/templates/docker/data/ecommerce-semantic/entities/product_reviews.yml +155 -0
- package/templates/docker/data/ecommerce-semantic/entities/products.yml +178 -0
- package/templates/docker/data/ecommerce-semantic/entities/promotions.yml +171 -0
- package/templates/docker/data/ecommerce-semantic/entities/returns.yml +144 -0
- package/templates/docker/data/ecommerce-semantic/entities/sellers.yml +124 -0
- package/templates/docker/data/ecommerce-semantic/entities/shipments.yml +159 -0
- package/templates/docker/data/ecommerce-semantic/glossary.yml +193 -0
- package/templates/docker/data/ecommerce-semantic/metrics/customers.yml +116 -0
- package/templates/docker/data/ecommerce-semantic/metrics/operations.yml +131 -0
- package/templates/docker/data/ecommerce-semantic/metrics/revenue.yml +120 -0
- package/templates/docker/docs/deploy.md +2 -1
- package/templates/docker/ee/src/__mocks__/internal.ts +170 -0
- package/templates/docker/ee/src/audit/purge-scheduler.ts +113 -0
- package/templates/docker/ee/src/audit/retention.ts +467 -0
- package/templates/docker/ee/src/auth/ip-allowlist.ts +367 -0
- package/templates/docker/ee/src/auth/roles.ts +562 -0
- package/templates/docker/ee/src/auth/scim.ts +343 -0
- package/templates/docker/ee/src/auth/sso.ts +538 -0
- package/templates/docker/ee/src/backups/engine.ts +355 -0
- package/templates/docker/ee/src/backups/index.ts +26 -0
- package/templates/docker/ee/src/backups/restore.ts +169 -0
- package/templates/docker/ee/src/backups/scheduler.ts +153 -0
- package/templates/docker/ee/src/backups/verify.ts +124 -0
- package/templates/docker/ee/src/branding/white-label.ts +228 -0
- package/templates/docker/ee/src/compliance/masking.ts +477 -0
- package/templates/docker/ee/src/compliance/patterns.ts +16 -0
- package/templates/docker/ee/src/compliance/pii-detection.ts +217 -0
- package/templates/docker/ee/src/compliance/reports.ts +402 -0
- package/templates/docker/ee/src/deploy-mode.ts +37 -0
- package/templates/docker/ee/src/governance/approval.ts +699 -0
- package/templates/docker/ee/src/index.ts +74 -0
- package/templates/docker/ee/src/platform/domains.ts +562 -0
- package/templates/docker/ee/src/platform/model-routing.ts +382 -0
- package/templates/docker/ee/src/platform/residency.ts +265 -0
- package/templates/docker/ee/src/sla/alerting.ts +382 -0
- package/templates/docker/ee/src/sla/index.ts +12 -0
- package/templates/docker/ee/src/sla/metrics.ts +275 -0
- package/templates/docker/ee/src/test-setup.ts +1 -0
- package/templates/docker/next.config.ts +4 -1
- package/templates/docker/package.json +49 -29
- package/templates/docker/sidecar/Dockerfile +1 -1
- package/templates/docker/src/api/index.ts +336 -24
- package/templates/docker/src/api/routes/actions.ts +443 -176
- package/templates/docker/src/api/routes/admin-abuse.ts +219 -0
- package/templates/docker/src/api/routes/admin-approval.ts +418 -0
- package/templates/docker/src/api/routes/admin-audit-retention.ts +405 -0
- package/templates/docker/src/api/routes/admin-auth.ts +122 -0
- package/templates/docker/src/api/routes/admin-branding.ts +252 -0
- package/templates/docker/src/api/routes/admin-compliance.ts +352 -0
- package/templates/docker/src/api/routes/admin-domains.ts +334 -0
- package/templates/docker/src/api/routes/admin-integrations.ts +2667 -0
- package/templates/docker/src/api/routes/admin-ip-allowlist.ts +261 -0
- package/templates/docker/src/api/routes/admin-learned-patterns.ts +525 -0
- package/templates/docker/src/api/routes/admin-model-config.ts +252 -0
- package/templates/docker/src/api/routes/admin-onboarding-emails.ts +145 -0
- package/templates/docker/src/api/routes/admin-orgs.ts +710 -0
- package/templates/docker/src/api/routes/admin-prompts.ts +694 -0
- package/templates/docker/src/api/routes/admin-residency.ts +570 -0
- package/templates/docker/src/api/routes/admin-roles.ts +296 -0
- package/templates/docker/src/api/routes/admin-router.ts +120 -0
- package/templates/docker/src/api/routes/admin-sandbox.ts +417 -0
- package/templates/docker/src/api/routes/admin-scim.ts +262 -0
- package/templates/docker/src/api/routes/admin-sso.ts +545 -0
- package/templates/docker/src/api/routes/admin-suggestions.ts +176 -0
- package/templates/docker/src/api/routes/admin-usage.ts +310 -0
- package/templates/docker/src/api/routes/admin.ts +4156 -898
- package/templates/docker/src/api/routes/auth-preamble.ts +105 -0
- package/templates/docker/src/api/routes/billing.ts +397 -0
- package/templates/docker/src/api/routes/chat.ts +597 -334
- package/templates/docker/src/api/routes/conversations.ts +987 -132
- package/templates/docker/src/api/routes/demo.ts +673 -0
- package/templates/docker/src/api/routes/discord.ts +274 -0
- package/templates/docker/src/api/routes/ee-error-handler.ts +32 -0
- package/templates/docker/src/api/routes/health.ts +129 -14
- package/templates/docker/src/api/routes/middleware.ts +244 -0
- package/templates/docker/src/api/routes/onboarding-emails.ts +134 -0
- package/templates/docker/src/api/routes/onboarding.ts +1109 -0
- package/templates/docker/src/api/routes/openapi.ts +184 -1597
- package/templates/docker/src/api/routes/platform-admin.ts +760 -0
- package/templates/docker/src/api/routes/platform-backups.ts +436 -0
- package/templates/docker/src/api/routes/platform-domains.ts +235 -0
- package/templates/docker/src/api/routes/platform-residency.ts +257 -0
- package/templates/docker/src/api/routes/platform-sla.ts +379 -0
- package/templates/docker/src/api/routes/prompts.ts +221 -0
- package/templates/docker/src/api/routes/public-branding.ts +106 -0
- package/templates/docker/src/api/routes/query.ts +330 -219
- package/templates/docker/src/api/routes/scheduled-tasks.ts +393 -297
- package/templates/docker/src/api/routes/semantic.ts +179 -0
- package/templates/docker/src/api/routes/sessions.ts +210 -0
- package/templates/docker/src/api/routes/shared-domains.ts +98 -0
- package/templates/docker/src/api/routes/shared-schemas.ts +139 -0
- package/templates/docker/src/api/routes/slack.ts +209 -52
- package/templates/docker/src/api/routes/suggestions.ts +233 -0
- package/templates/docker/src/api/routes/tables.ts +67 -0
- package/templates/docker/src/api/routes/teams.ts +222 -0
- package/templates/docker/src/api/routes/validate-sql.ts +188 -0
- package/templates/docker/src/api/routes/validation-hook.ts +62 -0
- package/templates/docker/src/api/routes/widget-loader.ts +356 -0
- package/templates/docker/src/api/routes/widget.ts +428 -0
- package/templates/docker/src/api/routes/wizard.ts +852 -0
- package/templates/docker/src/api/server.ts +187 -69
- package/templates/docker/src/app/error.tsx +5 -2
- package/templates/docker/src/app/globals.css +1 -1
- package/templates/docker/src/app/layout.tsx +7 -2
- package/templates/docker/src/app/page.tsx +39 -5
- package/templates/docker/src/components/data-table/data-table-column-header.tsx +99 -0
- package/templates/docker/src/components/data-table/data-table-date-filter.tsx +225 -0
- package/templates/docker/src/components/data-table/data-table-expandable.tsx +125 -0
- package/templates/docker/src/components/data-table/data-table-faceted-filter.tsx +189 -0
- package/templates/docker/src/components/data-table/data-table-pagination.tsx +112 -0
- package/templates/docker/src/components/data-table/data-table-range-filter.tsx +122 -0
- package/templates/docker/src/components/data-table/data-table-slider-filter.tsx +256 -0
- package/templates/docker/src/components/data-table/data-table-sort-list.tsx +407 -0
- package/templates/docker/src/components/data-table/data-table-toolbar.tsx +149 -0
- package/templates/docker/src/components/data-table/data-table-view-options.tsx +89 -0
- package/templates/docker/src/components/data-table/data-table.tsx +105 -0
- package/templates/docker/src/components/form-dialog.tsx +135 -0
- package/templates/docker/src/components/ui/accordion.tsx +66 -0
- package/templates/docker/src/components/ui/calendar.tsx +220 -0
- package/templates/docker/src/components/ui/checkbox.tsx +32 -0
- package/templates/docker/src/components/ui/faceted.tsx +283 -0
- package/templates/docker/src/components/ui/form.tsx +167 -0
- package/templates/docker/src/components/ui/label.tsx +24 -0
- package/templates/docker/src/components/ui/popover.tsx +89 -0
- package/templates/docker/src/components/ui/progress.tsx +31 -0
- package/templates/docker/src/components/ui/scroll-area.tsx +6 -2
- package/templates/docker/src/components/ui/slider.tsx +63 -0
- package/templates/docker/src/components/ui/sortable.tsx +581 -0
- package/templates/docker/src/components/ui/switch.tsx +35 -0
- package/templates/docker/src/components/ui/textarea.tsx +18 -0
- package/templates/docker/src/config/data-table.ts +82 -0
- package/templates/docker/src/env-check.ts +74 -0
- package/templates/docker/src/hooks/use-callback-ref.ts +27 -0
- package/templates/docker/src/hooks/use-data-table.ts +316 -0
- package/templates/docker/src/hooks/use-debounced-callback.ts +28 -0
- package/templates/docker/src/lib/action-types.ts +7 -41
- package/templates/docker/src/lib/agent-query.ts +4 -2
- package/templates/docker/src/lib/agent.ts +363 -31
- package/templates/docker/src/lib/auth/admin-permissions.ts +38 -0
- package/templates/docker/src/lib/auth/audit.ts +19 -4
- package/templates/docker/src/lib/auth/byot.ts +3 -3
- package/templates/docker/src/lib/auth/client.ts +33 -3
- package/templates/docker/src/lib/auth/detect.ts +29 -8
- package/templates/docker/src/lib/auth/managed.ts +104 -14
- package/templates/docker/src/lib/auth/middleware.ts +53 -6
- package/templates/docker/src/lib/auth/migrate.ts +140 -15
- package/templates/docker/src/lib/auth/oauth-state.ts +123 -0
- package/templates/docker/src/lib/auth/org-permissions.ts +55 -0
- package/templates/docker/src/lib/auth/permissions.ts +26 -19
- package/templates/docker/src/lib/auth/server.ts +355 -9
- package/templates/docker/src/lib/auth/simple-key.ts +3 -3
- package/templates/docker/src/lib/auth/types.ts +15 -21
- package/templates/docker/src/lib/billing/enforcement.ts +368 -0
- package/templates/docker/src/lib/billing/plans.ts +155 -0
- package/templates/docker/src/lib/cache/index.ts +92 -0
- package/templates/docker/src/lib/cache/keys.ts +30 -0
- package/templates/docker/src/lib/cache/lru.ts +79 -0
- package/templates/docker/src/lib/cache/types.ts +31 -0
- package/templates/docker/src/lib/compose-refs.ts +62 -0
- package/templates/docker/src/lib/config.ts +563 -11
- package/templates/docker/src/lib/connection-types.ts +9 -0
- package/templates/docker/src/lib/conversation-types.ts +1 -25
- package/templates/docker/src/lib/conversations.ts +345 -14
- package/templates/docker/src/lib/data-table.ts +61 -0
- package/templates/docker/src/lib/db/connection.ts +793 -39
- package/templates/docker/src/lib/db/internal.ts +985 -139
- package/templates/docker/src/lib/db/migrate.ts +295 -0
- package/templates/docker/src/lib/db/migrations/0000_baseline.sql +703 -0
- package/templates/docker/src/lib/db/migrations/0001_teams_installations.sql +14 -0
- package/templates/docker/src/lib/db/migrations/0002_discord_installations.sql +14 -0
- package/templates/docker/src/lib/db/migrations/0003_telegram_installations.sql +15 -0
- package/templates/docker/src/lib/db/migrations/0004_sandbox_credentials.sql +18 -0
- package/templates/docker/src/lib/db/migrations/0005_oauth_state.sql +16 -0
- package/templates/docker/src/lib/db/migrations/0006_byot_credentials.sql +14 -0
- package/templates/docker/src/lib/db/migrations/0007_gchat_installations.sql +15 -0
- package/templates/docker/src/lib/db/migrations/0008_github_installations.sql +14 -0
- package/templates/docker/src/lib/db/migrations/0009_linear_installations.sql +15 -0
- package/templates/docker/src/lib/db/migrations/0010_whatsapp_installations.sql +14 -0
- package/templates/docker/src/lib/db/migrations/0011_email_installations.sql +16 -0
- package/templates/docker/src/lib/db/migrations/0012_region_migrations.sql +25 -0
- package/templates/docker/src/lib/db/schema.ts +1120 -0
- package/templates/docker/src/lib/db/source-rate-limit.ts +89 -139
- package/templates/docker/src/lib/demo.ts +308 -0
- package/templates/docker/src/lib/discord/store.ts +225 -0
- package/templates/docker/src/lib/effect/ai.ts +243 -0
- package/templates/docker/src/lib/effect/errors.ts +234 -0
- package/templates/docker/src/lib/effect/hono.ts +454 -0
- package/templates/docker/src/lib/effect/index.ts +137 -0
- package/templates/docker/src/lib/effect/layers.ts +496 -0
- package/templates/docker/src/lib/effect/services.ts +776 -0
- package/templates/docker/src/lib/effect/sql.ts +178 -0
- package/templates/docker/src/lib/effect/toolkit.ts +123 -0
- package/templates/docker/src/lib/email/delivery.ts +232 -0
- package/templates/docker/src/lib/email/engine.ts +349 -0
- package/templates/docker/src/lib/email/hooks.ts +107 -0
- package/templates/docker/src/lib/email/index.ts +16 -0
- package/templates/docker/src/lib/email/scheduler.ts +72 -0
- package/templates/docker/src/lib/email/sequence.ts +73 -0
- package/templates/docker/src/lib/email/store.ts +163 -0
- package/templates/docker/src/lib/email/templates.ts +215 -0
- package/templates/docker/src/lib/format.ts +67 -0
- package/templates/docker/src/lib/gchat/store.ts +202 -0
- package/templates/docker/src/lib/github/store.ts +197 -0
- package/templates/docker/src/lib/id.ts +29 -0
- package/templates/docker/src/lib/integrations/types.ts +166 -0
- package/templates/docker/src/lib/learn/pattern-analyzer.ts +224 -0
- package/templates/docker/src/lib/learn/pattern-cache.ts +229 -0
- package/templates/docker/src/lib/learn/pattern-proposer.ts +87 -0
- package/templates/docker/src/lib/learn/suggestion-helpers.ts +34 -0
- package/templates/docker/src/lib/learn/suggestions.ts +139 -0
- package/templates/docker/src/lib/linear/store.ts +200 -0
- package/templates/docker/src/lib/logger.ts +35 -3
- package/templates/docker/src/lib/metering.ts +272 -0
- package/templates/docker/src/lib/parsers.ts +99 -0
- package/templates/docker/src/lib/plugins/hooks.ts +13 -11
- package/templates/docker/src/lib/plugins/index.ts +3 -1
- package/templates/docker/src/lib/plugins/registry.ts +58 -6
- package/templates/docker/src/lib/plugins/settings.ts +147 -0
- package/templates/docker/src/lib/plugins/wiring.ts +6 -9
- package/templates/docker/src/lib/profiler.ts +1665 -0
- package/templates/docker/src/lib/providers.ts +188 -13
- package/templates/docker/src/lib/rls.ts +172 -60
- package/templates/docker/src/lib/sandbox/credentials.ts +206 -0
- package/templates/docker/src/lib/sandbox/validate.ts +179 -0
- package/templates/docker/src/lib/scheduled-task-types.ts +26 -94
- package/templates/docker/src/lib/scheduled-tasks.ts +174 -34
- package/templates/docker/src/lib/scheduler/delivery.ts +248 -150
- package/templates/docker/src/lib/scheduler/engine.ts +190 -154
- package/templates/docker/src/lib/scheduler/executor.ts +74 -23
- package/templates/docker/src/lib/scheduler/preview.ts +72 -0
- package/templates/docker/src/lib/security/abuse.ts +463 -0
- package/templates/docker/src/lib/semantic/diff.ts +267 -0
- package/templates/docker/src/lib/semantic/entities.ts +167 -0
- package/templates/docker/src/lib/semantic/files.ts +283 -0
- package/templates/docker/src/lib/semantic/index.ts +27 -0
- package/templates/docker/src/lib/{semantic-index.ts → semantic/search.ts} +80 -9
- package/templates/docker/src/lib/semantic/sync.ts +581 -0
- package/templates/docker/src/lib/{semantic.ts → semantic/whitelist.ts} +189 -3
- package/templates/docker/src/lib/settings.ts +817 -0
- package/templates/docker/src/lib/sidecar-types.ts +13 -0
- package/templates/docker/src/lib/slack/store.ts +134 -25
- package/templates/docker/src/lib/startup.ts +528 -362
- package/templates/docker/src/lib/teams/store.ts +216 -0
- package/templates/docker/src/lib/telegram/store.ts +202 -0
- package/templates/docker/src/lib/telemetry.ts +40 -0
- package/templates/docker/src/lib/tools/actions/audit.ts +8 -5
- package/templates/docker/src/lib/tools/actions/email.ts +3 -1
- package/templates/docker/src/lib/tools/actions/handler.ts +276 -93
- package/templates/docker/src/lib/tools/actions/jira.ts +2 -2
- package/templates/docker/src/lib/tools/backends/detect.ts +16 -0
- package/templates/docker/src/lib/tools/backends/index.ts +11 -0
- package/templates/docker/src/lib/tools/backends/nsjail.ts +213 -0
- package/templates/docker/src/lib/tools/backends/shared.ts +103 -0
- package/templates/docker/src/lib/tools/backends/types.ts +26 -0
- package/templates/docker/src/lib/tools/explore-nsjail.ts +7 -228
- package/templates/docker/src/lib/tools/explore-sandbox.ts +4 -29
- package/templates/docker/src/lib/tools/explore-sidecar.ts +18 -2
- package/templates/docker/src/lib/tools/explore.ts +246 -54
- package/templates/docker/src/lib/tools/index.ts +17 -0
- package/templates/docker/src/lib/tools/python-nsjail.ts +11 -139
- package/templates/docker/src/lib/tools/python-sandbox.ts +9 -132
- package/templates/docker/src/lib/tools/python-sidecar.ts +184 -3
- package/templates/docker/src/lib/tools/python-stream.ts +33 -0
- package/templates/docker/src/lib/tools/python-wrapper.ts +129 -0
- package/templates/docker/src/lib/tools/python.ts +115 -15
- package/templates/docker/src/lib/tools/registry.ts +14 -2
- package/templates/docker/src/lib/tools/sql.ts +778 -362
- package/templates/docker/src/lib/tracing.ts +16 -0
- package/templates/docker/src/lib/whatsapp/store.ts +198 -0
- package/templates/docker/src/lib/workspace.ts +89 -0
- package/templates/docker/src/progress.ts +121 -0
- package/templates/docker/src/types/data-table.ts +48 -0
- package/templates/docker/src/ui/atlas-chat-reexport.ts +3 -0
- package/templates/docker/src/ui/components/actions/action-approval-card.tsx +26 -19
- package/templates/docker/src/ui/components/actions/action-status-badge.tsx +3 -3
- package/templates/docker/src/ui/components/admin/admin-layout.tsx +57 -39
- package/templates/docker/src/ui/components/admin/admin-sidebar.tsx +213 -35
- package/templates/docker/src/ui/components/admin/delivery-status-badge.tsx +53 -0
- package/templates/docker/src/ui/components/admin/empty-state.tsx +27 -6
- package/templates/docker/src/ui/components/admin/entity-detail.tsx +3 -52
- package/templates/docker/src/ui/components/admin/error-banner.tsx +2 -2
- package/templates/docker/src/ui/components/admin/feature-disabled.tsx +28 -5
- package/templates/docker/src/ui/components/admin-content-wrapper.tsx +87 -0
- package/templates/docker/src/ui/components/atlas-chat.tsx +449 -166
- package/templates/docker/src/ui/components/branding-head.tsx +41 -0
- package/templates/docker/src/ui/components/chart/chart-detection.ts +62 -5
- package/templates/docker/src/ui/components/chart/result-chart.tsx +316 -125
- package/templates/docker/src/ui/components/chat/api-key-bar.tsx +4 -4
- package/templates/docker/src/ui/components/chat/data-table.tsx +45 -4
- package/templates/docker/src/ui/components/chat/error-banner.tsx +86 -5
- package/templates/docker/src/ui/components/chat/follow-up-chips.tsx +29 -0
- package/templates/docker/src/ui/components/chat/markdown.tsx +24 -0
- package/templates/docker/src/ui/components/chat/prompt-library.tsx +206 -0
- package/templates/docker/src/ui/components/chat/python-result-card.tsx +106 -78
- package/templates/docker/src/ui/components/chat/result-card-base.tsx +101 -0
- package/templates/docker/src/ui/components/chat/share-dialog.tsx +377 -0
- package/templates/docker/src/ui/components/chat/sql-result-card.tsx +94 -73
- package/templates/docker/src/ui/components/chat/suggestion-chips.tsx +46 -0
- package/templates/docker/src/ui/components/chat/tool-part.tsx +16 -4
- package/templates/docker/src/ui/components/conversations/conversation-item.tsx +48 -17
- package/templates/docker/src/ui/components/conversations/conversation-list.tsx +38 -24
- package/templates/docker/src/ui/components/conversations/conversation-sidebar.tsx +66 -7
- package/templates/docker/src/ui/components/conversations/delete-confirmation.tsx +9 -2
- package/templates/docker/src/ui/components/error-boundary.tsx +66 -0
- package/templates/docker/src/ui/components/notebook/delete-cell-dialog.tsx +48 -0
- package/templates/docker/src/ui/components/notebook/fork-branch-selector.tsx +68 -0
- package/templates/docker/src/ui/components/notebook/notebook-cell-input.tsx +76 -0
- package/templates/docker/src/ui/components/notebook/notebook-cell-output.tsx +58 -0
- package/templates/docker/src/ui/components/notebook/notebook-cell-toolbar.tsx +91 -0
- package/templates/docker/src/ui/components/notebook/notebook-cell.tsx +119 -0
- package/templates/docker/src/ui/components/notebook/notebook-empty-state.tsx +19 -0
- package/templates/docker/src/ui/components/notebook/notebook-export.ts +287 -0
- package/templates/docker/src/ui/components/notebook/notebook-input-bar.tsx +49 -0
- package/templates/docker/src/ui/components/notebook/notebook-shell.tsx +266 -0
- package/templates/docker/src/ui/components/notebook/notebook-text-cell.tsx +152 -0
- package/templates/docker/src/ui/components/notebook/types.ts +39 -0
- package/templates/docker/src/ui/components/notebook/use-keyboard-nav.ts +109 -0
- package/templates/docker/src/ui/components/notebook/use-notebook.ts +684 -0
- package/templates/docker/src/ui/components/org-switcher.tsx +111 -0
- package/templates/docker/src/ui/components/region-picker.tsx +103 -0
- package/templates/docker/src/ui/components/schema-explorer/schema-explorer.tsx +522 -0
- package/templates/docker/src/ui/components/social-icons.tsx +26 -0
- package/templates/docker/src/ui/components/tour/guided-tour.tsx +81 -0
- package/templates/docker/src/ui/components/tour/index.ts +5 -0
- package/templates/docker/src/ui/components/tour/nav-bar.tsx +100 -0
- package/templates/docker/src/ui/components/tour/tour-overlay.tsx +298 -0
- package/templates/docker/src/ui/components/tour/tour-steps.ts +43 -0
- package/templates/docker/src/ui/components/tour/types.ts +21 -0
- package/templates/docker/src/ui/components/tour/use-tour.ts +193 -0
- package/templates/docker/src/ui/context-reexport.ts +3 -0
- package/templates/docker/src/ui/hooks/theme-init-script.ts +17 -0
- package/templates/docker/src/ui/hooks/use-admin-fetch.ts +38 -30
- package/templates/docker/src/ui/hooks/use-admin-mutation.ts +188 -0
- package/templates/docker/src/ui/hooks/use-atlas-transport.ts +225 -0
- package/templates/docker/src/ui/hooks/use-branding.ts +68 -0
- package/templates/docker/src/ui/hooks/use-conversations.ts +106 -83
- package/templates/docker/src/ui/hooks/use-dark-mode.ts +134 -10
- package/templates/docker/src/ui/hooks/use-deploy-mode.ts +36 -0
- package/templates/docker/src/ui/hooks/use-platform-admin-guard.ts +49 -0
- package/templates/docker/src/ui/lib/action-types.ts +11 -63
- package/templates/docker/src/ui/lib/admin-schemas.ts +744 -0
- package/templates/docker/src/ui/lib/fetch-client.ts +84 -0
- package/templates/docker/src/ui/lib/fetch-error.ts +54 -0
- package/templates/docker/src/ui/lib/helpers.ts +94 -1
- package/templates/docker/src/ui/lib/types.ts +149 -140
- package/templates/docker/tsconfig.json +4 -2
- package/templates/nextjs-standalone/bin/__tests__/duckdb-ingest.test.ts +17 -14
- package/templates/nextjs-standalone/bin/__tests__/failure-threshold.test.ts +148 -0
- package/templates/nextjs-standalone/bin/__tests__/fatal-error-propagation.test.ts +267 -0
- package/templates/nextjs-standalone/bin/__tests__/profiler-heuristics.test.ts +5 -5
- package/templates/nextjs-standalone/bin/__tests__/schema-drift.test.ts +39 -0
- package/templates/nextjs-standalone/bin/atlas.ts +981 -1819
- package/templates/nextjs-standalone/bin/benchmark.ts +14 -16
- package/templates/nextjs-standalone/bin/enrich.ts +7 -2
- package/templates/nextjs-standalone/brand.css +13 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/catalog.yml +222 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/alerts.yml +195 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/assets.yml +191 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/compliance_assessments.yml +170 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/incidents.yml +219 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/organizations.yml +136 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/plans.yml +114 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/remediation_actions.yml +212 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/scan_results.yml +215 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/scans.yml +180 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/subscriptions.yml +184 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/users.yml +140 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/entities/vulnerabilities.yml +154 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/glossary.yml +207 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/metrics/business.yml +148 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/metrics/compliance.yml +138 -0
- package/templates/nextjs-standalone/data/cybersec-semantic/metrics/security.yml +181 -0
- package/templates/nextjs-standalone/data/cybersec.sql +8 -8
- package/templates/nextjs-standalone/data/demo.sql +3 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/catalog.yml +221 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/categories.yml +91 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/customers.yml +133 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/email_campaigns.yml +119 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/inventory_levels.yml +153 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/order_items.yml +159 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/orders.yml +199 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/payments.yml +140 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/product_reviews.yml +155 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/products.yml +178 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/promotions.yml +171 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/returns.yml +144 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/sellers.yml +124 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/entities/shipments.yml +159 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/glossary.yml +193 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/metrics/customers.yml +116 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/metrics/operations.yml +131 -0
- package/templates/nextjs-standalone/data/ecommerce-semantic/metrics/revenue.yml +120 -0
- package/templates/nextjs-standalone/docs/deploy.md +2 -1
- package/templates/nextjs-standalone/ee/src/__mocks__/internal.ts +170 -0
- package/templates/nextjs-standalone/ee/src/audit/purge-scheduler.ts +113 -0
- package/templates/nextjs-standalone/ee/src/audit/retention.ts +467 -0
- package/templates/nextjs-standalone/ee/src/auth/ip-allowlist.ts +367 -0
- package/templates/nextjs-standalone/ee/src/auth/roles.ts +562 -0
- package/templates/nextjs-standalone/ee/src/auth/scim.ts +343 -0
- package/templates/nextjs-standalone/ee/src/auth/sso.ts +538 -0
- package/templates/nextjs-standalone/ee/src/backups/engine.ts +355 -0
- package/templates/nextjs-standalone/ee/src/backups/index.ts +26 -0
- package/templates/nextjs-standalone/ee/src/backups/restore.ts +169 -0
- package/templates/nextjs-standalone/ee/src/backups/scheduler.ts +153 -0
- package/templates/nextjs-standalone/ee/src/backups/verify.ts +124 -0
- package/templates/nextjs-standalone/ee/src/branding/white-label.ts +228 -0
- package/templates/nextjs-standalone/ee/src/compliance/masking.ts +477 -0
- package/templates/nextjs-standalone/ee/src/compliance/patterns.ts +16 -0
- package/templates/nextjs-standalone/ee/src/compliance/pii-detection.ts +217 -0
- package/templates/nextjs-standalone/ee/src/compliance/reports.ts +402 -0
- package/templates/nextjs-standalone/ee/src/deploy-mode.ts +37 -0
- package/templates/nextjs-standalone/ee/src/governance/approval.ts +699 -0
- package/templates/nextjs-standalone/ee/src/index.ts +74 -0
- package/templates/nextjs-standalone/ee/src/platform/domains.ts +562 -0
- package/templates/nextjs-standalone/ee/src/platform/model-routing.ts +382 -0
- package/templates/nextjs-standalone/ee/src/platform/residency.ts +265 -0
- package/templates/nextjs-standalone/ee/src/sla/alerting.ts +382 -0
- package/templates/nextjs-standalone/ee/src/sla/index.ts +12 -0
- package/templates/nextjs-standalone/ee/src/sla/metrics.ts +275 -0
- package/templates/nextjs-standalone/ee/src/test-setup.ts +1 -0
- package/templates/nextjs-standalone/next.config.ts +1 -1
- package/templates/nextjs-standalone/package.json +50 -30
- package/templates/nextjs-standalone/src/api/index.ts +336 -24
- package/templates/nextjs-standalone/src/api/routes/actions.ts +443 -176
- package/templates/nextjs-standalone/src/api/routes/admin-abuse.ts +219 -0
- package/templates/nextjs-standalone/src/api/routes/admin-approval.ts +418 -0
- package/templates/nextjs-standalone/src/api/routes/admin-audit-retention.ts +405 -0
- package/templates/nextjs-standalone/src/api/routes/admin-auth.ts +122 -0
- package/templates/nextjs-standalone/src/api/routes/admin-branding.ts +252 -0
- package/templates/nextjs-standalone/src/api/routes/admin-compliance.ts +352 -0
- package/templates/nextjs-standalone/src/api/routes/admin-domains.ts +334 -0
- package/templates/nextjs-standalone/src/api/routes/admin-integrations.ts +2667 -0
- package/templates/nextjs-standalone/src/api/routes/admin-ip-allowlist.ts +261 -0
- package/templates/nextjs-standalone/src/api/routes/admin-learned-patterns.ts +525 -0
- package/templates/nextjs-standalone/src/api/routes/admin-model-config.ts +252 -0
- package/templates/nextjs-standalone/src/api/routes/admin-onboarding-emails.ts +145 -0
- package/templates/nextjs-standalone/src/api/routes/admin-orgs.ts +710 -0
- package/templates/nextjs-standalone/src/api/routes/admin-prompts.ts +694 -0
- package/templates/nextjs-standalone/src/api/routes/admin-residency.ts +570 -0
- package/templates/nextjs-standalone/src/api/routes/admin-roles.ts +296 -0
- package/templates/nextjs-standalone/src/api/routes/admin-router.ts +120 -0
- package/templates/nextjs-standalone/src/api/routes/admin-sandbox.ts +417 -0
- package/templates/nextjs-standalone/src/api/routes/admin-scim.ts +262 -0
- package/templates/nextjs-standalone/src/api/routes/admin-sso.ts +545 -0
- package/templates/nextjs-standalone/src/api/routes/admin-suggestions.ts +176 -0
- package/templates/nextjs-standalone/src/api/routes/admin-usage.ts +310 -0
- package/templates/nextjs-standalone/src/api/routes/admin.ts +4156 -898
- package/templates/nextjs-standalone/src/api/routes/auth-preamble.ts +105 -0
- package/templates/nextjs-standalone/src/api/routes/billing.ts +397 -0
- package/templates/nextjs-standalone/src/api/routes/chat.ts +597 -334
- package/templates/nextjs-standalone/src/api/routes/conversations.ts +987 -132
- package/templates/nextjs-standalone/src/api/routes/demo.ts +673 -0
- package/templates/nextjs-standalone/src/api/routes/discord.ts +274 -0
- package/templates/nextjs-standalone/src/api/routes/ee-error-handler.ts +32 -0
- package/templates/nextjs-standalone/src/api/routes/health.ts +129 -14
- package/templates/nextjs-standalone/src/api/routes/middleware.ts +244 -0
- package/templates/nextjs-standalone/src/api/routes/onboarding-emails.ts +134 -0
- package/templates/nextjs-standalone/src/api/routes/onboarding.ts +1109 -0
- package/templates/nextjs-standalone/src/api/routes/openapi.ts +184 -1597
- package/templates/nextjs-standalone/src/api/routes/platform-admin.ts +760 -0
- package/templates/nextjs-standalone/src/api/routes/platform-backups.ts +436 -0
- package/templates/nextjs-standalone/src/api/routes/platform-domains.ts +235 -0
- package/templates/nextjs-standalone/src/api/routes/platform-residency.ts +257 -0
- package/templates/nextjs-standalone/src/api/routes/platform-sla.ts +379 -0
- package/templates/nextjs-standalone/src/api/routes/prompts.ts +221 -0
- package/templates/nextjs-standalone/src/api/routes/public-branding.ts +106 -0
- package/templates/nextjs-standalone/src/api/routes/query.ts +330 -219
- package/templates/nextjs-standalone/src/api/routes/scheduled-tasks.ts +393 -297
- package/templates/nextjs-standalone/src/api/routes/semantic.ts +179 -0
- package/templates/nextjs-standalone/src/api/routes/sessions.ts +210 -0
- package/templates/nextjs-standalone/src/api/routes/shared-domains.ts +98 -0
- package/templates/nextjs-standalone/src/api/routes/shared-schemas.ts +139 -0
- package/templates/nextjs-standalone/src/api/routes/slack.ts +209 -52
- package/templates/nextjs-standalone/src/api/routes/suggestions.ts +233 -0
- package/templates/nextjs-standalone/src/api/routes/tables.ts +67 -0
- package/templates/nextjs-standalone/src/api/routes/teams.ts +222 -0
- package/templates/nextjs-standalone/src/api/routes/validate-sql.ts +188 -0
- package/templates/nextjs-standalone/src/api/routes/validation-hook.ts +62 -0
- package/templates/nextjs-standalone/src/api/routes/widget-loader.ts +356 -0
- package/templates/nextjs-standalone/src/api/routes/widget.ts +428 -0
- package/templates/nextjs-standalone/src/api/routes/wizard.ts +852 -0
- package/templates/nextjs-standalone/src/api/server.ts +187 -69
- package/templates/nextjs-standalone/src/app/error.tsx +5 -2
- package/templates/nextjs-standalone/src/app/globals.css +1 -1
- package/templates/nextjs-standalone/src/app/layout.tsx +7 -2
- package/templates/nextjs-standalone/src/app/page.tsx +39 -5
- package/templates/nextjs-standalone/src/components/data-table/data-table-column-header.tsx +99 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-date-filter.tsx +225 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-expandable.tsx +125 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-faceted-filter.tsx +189 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-pagination.tsx +112 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-range-filter.tsx +122 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-slider-filter.tsx +256 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-sort-list.tsx +407 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-toolbar.tsx +149 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table-view-options.tsx +89 -0
- package/templates/nextjs-standalone/src/components/data-table/data-table.tsx +105 -0
- package/templates/nextjs-standalone/src/components/form-dialog.tsx +135 -0
- package/templates/nextjs-standalone/src/components/ui/accordion.tsx +66 -0
- package/templates/nextjs-standalone/src/components/ui/calendar.tsx +220 -0
- package/templates/nextjs-standalone/src/components/ui/checkbox.tsx +32 -0
- package/templates/nextjs-standalone/src/components/ui/faceted.tsx +283 -0
- package/templates/nextjs-standalone/src/components/ui/form.tsx +167 -0
- package/templates/nextjs-standalone/src/components/ui/label.tsx +24 -0
- package/templates/nextjs-standalone/src/components/ui/popover.tsx +89 -0
- package/templates/nextjs-standalone/src/components/ui/progress.tsx +31 -0
- package/templates/nextjs-standalone/src/components/ui/scroll-area.tsx +6 -2
- package/templates/nextjs-standalone/src/components/ui/slider.tsx +63 -0
- package/templates/nextjs-standalone/src/components/ui/sortable.tsx +581 -0
- package/templates/nextjs-standalone/src/components/ui/switch.tsx +35 -0
- package/templates/nextjs-standalone/src/components/ui/textarea.tsx +18 -0
- package/templates/nextjs-standalone/src/config/data-table.ts +82 -0
- package/templates/nextjs-standalone/src/env-check.ts +74 -0
- package/templates/nextjs-standalone/src/hooks/use-callback-ref.ts +27 -0
- package/templates/nextjs-standalone/src/hooks/use-data-table.ts +316 -0
- package/templates/nextjs-standalone/src/hooks/use-debounced-callback.ts +28 -0
- package/templates/nextjs-standalone/src/lib/action-types.ts +7 -41
- package/templates/nextjs-standalone/src/lib/agent-query.ts +4 -2
- package/templates/nextjs-standalone/src/lib/agent.ts +363 -31
- package/templates/nextjs-standalone/src/lib/api-url.ts +2 -3
- package/templates/nextjs-standalone/src/lib/auth/admin-permissions.ts +38 -0
- package/templates/nextjs-standalone/src/lib/auth/audit.ts +19 -4
- package/templates/nextjs-standalone/src/lib/auth/byot.ts +3 -3
- package/templates/nextjs-standalone/src/lib/auth/detect.ts +29 -8
- package/templates/nextjs-standalone/src/lib/auth/managed.ts +104 -14
- package/templates/nextjs-standalone/src/lib/auth/middleware.ts +53 -6
- package/templates/nextjs-standalone/src/lib/auth/migrate.ts +140 -15
- package/templates/nextjs-standalone/src/lib/auth/oauth-state.ts +123 -0
- package/templates/nextjs-standalone/src/lib/auth/org-permissions.ts +55 -0
- package/templates/nextjs-standalone/src/lib/auth/permissions.ts +26 -19
- package/templates/nextjs-standalone/src/lib/auth/server.ts +355 -9
- package/templates/nextjs-standalone/src/lib/auth/simple-key.ts +3 -3
- package/templates/nextjs-standalone/src/lib/auth/types.ts +15 -21
- package/templates/nextjs-standalone/src/lib/billing/enforcement.ts +368 -0
- package/templates/nextjs-standalone/src/lib/billing/plans.ts +155 -0
- package/templates/nextjs-standalone/src/lib/cache/index.ts +92 -0
- package/templates/nextjs-standalone/src/lib/cache/keys.ts +30 -0
- package/templates/nextjs-standalone/src/lib/cache/lru.ts +79 -0
- package/templates/nextjs-standalone/src/lib/cache/types.ts +31 -0
- package/templates/nextjs-standalone/src/lib/compose-refs.ts +62 -0
- package/templates/nextjs-standalone/src/lib/config.ts +563 -11
- package/templates/nextjs-standalone/src/lib/connection-types.ts +9 -0
- package/templates/nextjs-standalone/src/lib/conversation-types.ts +1 -25
- package/templates/nextjs-standalone/src/lib/conversations.ts +345 -14
- package/templates/nextjs-standalone/src/lib/data-table.ts +61 -0
- package/templates/nextjs-standalone/src/lib/db/connection.ts +793 -39
- package/templates/nextjs-standalone/src/lib/db/internal.ts +985 -139
- package/templates/nextjs-standalone/src/lib/db/migrate.ts +295 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0000_baseline.sql +703 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0001_teams_installations.sql +14 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0002_discord_installations.sql +14 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0003_telegram_installations.sql +15 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0004_sandbox_credentials.sql +18 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0005_oauth_state.sql +16 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0006_byot_credentials.sql +14 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0007_gchat_installations.sql +15 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0008_github_installations.sql +14 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0009_linear_installations.sql +15 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0010_whatsapp_installations.sql +14 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0011_email_installations.sql +16 -0
- package/templates/nextjs-standalone/src/lib/db/migrations/0012_region_migrations.sql +25 -0
- package/templates/nextjs-standalone/src/lib/db/schema.ts +1120 -0
- package/templates/nextjs-standalone/src/lib/db/source-rate-limit.ts +89 -139
- package/templates/nextjs-standalone/src/lib/demo.ts +308 -0
- package/templates/nextjs-standalone/src/lib/discord/store.ts +225 -0
- package/templates/nextjs-standalone/src/lib/effect/ai.ts +243 -0
- package/templates/nextjs-standalone/src/lib/effect/errors.ts +234 -0
- package/templates/nextjs-standalone/src/lib/effect/hono.ts +454 -0
- package/templates/nextjs-standalone/src/lib/effect/index.ts +137 -0
- package/templates/nextjs-standalone/src/lib/effect/layers.ts +496 -0
- package/templates/nextjs-standalone/src/lib/effect/services.ts +776 -0
- package/templates/nextjs-standalone/src/lib/effect/sql.ts +178 -0
- package/templates/nextjs-standalone/src/lib/effect/toolkit.ts +123 -0
- package/templates/nextjs-standalone/src/lib/email/delivery.ts +232 -0
- package/templates/nextjs-standalone/src/lib/email/engine.ts +349 -0
- package/templates/nextjs-standalone/src/lib/email/hooks.ts +107 -0
- package/templates/nextjs-standalone/src/lib/email/index.ts +16 -0
- package/templates/nextjs-standalone/src/lib/email/scheduler.ts +72 -0
- package/templates/nextjs-standalone/src/lib/email/sequence.ts +73 -0
- package/templates/nextjs-standalone/src/lib/email/store.ts +163 -0
- package/templates/nextjs-standalone/src/lib/email/templates.ts +215 -0
- package/templates/nextjs-standalone/src/lib/format.test.ts +117 -0
- package/templates/nextjs-standalone/src/lib/format.ts +67 -0
- package/templates/nextjs-standalone/src/lib/gchat/store.ts +202 -0
- package/templates/nextjs-standalone/src/lib/github/store.ts +197 -0
- package/templates/nextjs-standalone/src/lib/id.ts +29 -0
- package/templates/nextjs-standalone/src/lib/integrations/types.ts +166 -0
- package/templates/nextjs-standalone/src/lib/learn/pattern-analyzer.ts +224 -0
- package/templates/nextjs-standalone/src/lib/learn/pattern-cache.ts +229 -0
- package/templates/nextjs-standalone/src/lib/learn/pattern-proposer.ts +87 -0
- package/templates/nextjs-standalone/src/lib/learn/suggestion-helpers.ts +34 -0
- package/templates/nextjs-standalone/src/lib/learn/suggestions.ts +139 -0
- package/templates/nextjs-standalone/src/lib/linear/store.ts +200 -0
- package/templates/nextjs-standalone/src/lib/logger.ts +35 -3
- package/templates/nextjs-standalone/src/lib/metering.ts +272 -0
- package/templates/nextjs-standalone/src/lib/parsers.ts +99 -0
- package/templates/nextjs-standalone/src/lib/plugins/hooks.ts +13 -11
- package/templates/nextjs-standalone/src/lib/plugins/index.ts +3 -1
- package/templates/nextjs-standalone/src/lib/plugins/registry.ts +58 -6
- package/templates/nextjs-standalone/src/lib/plugins/settings.ts +147 -0
- package/templates/nextjs-standalone/src/lib/plugins/wiring.ts +6 -9
- package/templates/nextjs-standalone/src/lib/profiler.ts +1665 -0
- package/templates/nextjs-standalone/src/lib/providers.ts +188 -13
- package/templates/nextjs-standalone/src/lib/rls.ts +172 -60
- package/templates/nextjs-standalone/src/lib/sandbox/credentials.ts +206 -0
- package/templates/nextjs-standalone/src/lib/sandbox/validate.ts +179 -0
- package/templates/nextjs-standalone/src/lib/scheduled-task-types.ts +26 -94
- package/templates/nextjs-standalone/src/lib/scheduled-tasks.ts +174 -34
- package/templates/nextjs-standalone/src/lib/scheduler/delivery.ts +248 -150
- package/templates/nextjs-standalone/src/lib/scheduler/engine.ts +190 -154
- package/templates/nextjs-standalone/src/lib/scheduler/executor.ts +74 -23
- package/templates/nextjs-standalone/src/lib/scheduler/preview.ts +72 -0
- package/templates/nextjs-standalone/src/lib/security/abuse.ts +463 -0
- package/templates/nextjs-standalone/src/lib/semantic/diff.ts +267 -0
- package/templates/nextjs-standalone/src/lib/semantic/entities.ts +167 -0
- package/templates/nextjs-standalone/src/lib/semantic/files.ts +283 -0
- package/templates/nextjs-standalone/src/lib/semantic/index.ts +27 -0
- package/templates/nextjs-standalone/src/lib/{semantic-index.ts → semantic/search.ts} +80 -9
- package/templates/nextjs-standalone/src/lib/semantic/sync.ts +581 -0
- package/templates/nextjs-standalone/src/lib/{semantic.ts → semantic/whitelist.ts} +189 -3
- package/templates/nextjs-standalone/src/lib/settings.ts +817 -0
- package/templates/nextjs-standalone/src/lib/sidecar-types.ts +13 -0
- package/templates/nextjs-standalone/src/lib/slack/store.ts +134 -25
- package/templates/nextjs-standalone/src/lib/startup.ts +528 -362
- package/templates/nextjs-standalone/src/lib/teams/store.ts +216 -0
- package/templates/nextjs-standalone/src/lib/telegram/store.ts +202 -0
- package/templates/nextjs-standalone/src/lib/telemetry.ts +40 -0
- package/templates/nextjs-standalone/src/lib/tools/actions/audit.ts +8 -5
- package/templates/nextjs-standalone/src/lib/tools/actions/email.ts +3 -1
- package/templates/nextjs-standalone/src/lib/tools/actions/handler.ts +276 -93
- package/templates/nextjs-standalone/src/lib/tools/actions/jira.ts +2 -2
- package/templates/nextjs-standalone/src/lib/tools/backends/detect.ts +16 -0
- package/templates/nextjs-standalone/src/lib/tools/backends/index.ts +11 -0
- package/templates/nextjs-standalone/src/lib/tools/backends/nsjail.ts +213 -0
- package/templates/nextjs-standalone/src/lib/tools/backends/shared.ts +103 -0
- package/templates/nextjs-standalone/src/lib/tools/backends/types.ts +26 -0
- package/templates/nextjs-standalone/src/lib/tools/explore-nsjail.ts +7 -228
- package/templates/nextjs-standalone/src/lib/tools/explore-sandbox.ts +4 -29
- package/templates/nextjs-standalone/src/lib/tools/explore-sidecar.ts +18 -2
- package/templates/nextjs-standalone/src/lib/tools/explore.ts +246 -54
- package/templates/nextjs-standalone/src/lib/tools/index.ts +17 -0
- package/templates/nextjs-standalone/src/lib/tools/python-nsjail.ts +11 -139
- package/templates/nextjs-standalone/src/lib/tools/python-sandbox.ts +9 -132
- package/templates/nextjs-standalone/src/lib/tools/python-sidecar.ts +184 -3
- package/templates/nextjs-standalone/src/lib/tools/python-stream.ts +33 -0
- package/templates/nextjs-standalone/src/lib/tools/python-wrapper.ts +129 -0
- package/templates/nextjs-standalone/src/lib/tools/python.ts +115 -15
- package/templates/nextjs-standalone/src/lib/tools/registry.ts +14 -2
- package/templates/nextjs-standalone/src/lib/tools/sql.ts +778 -362
- package/templates/nextjs-standalone/src/lib/tracing.ts +16 -0
- package/templates/nextjs-standalone/src/lib/whatsapp/store.ts +198 -0
- package/templates/nextjs-standalone/src/lib/workspace.ts +89 -0
- package/templates/nextjs-standalone/src/progress.ts +121 -0
- package/templates/nextjs-standalone/src/types/data-table.ts +48 -0
- package/templates/nextjs-standalone/src/ui/atlas-chat-reexport.ts +3 -0
- package/templates/nextjs-standalone/src/ui/components/actions/action-approval-card.tsx +26 -19
- package/templates/nextjs-standalone/src/ui/components/actions/action-status-badge.tsx +3 -3
- package/templates/nextjs-standalone/src/ui/components/admin/admin-layout.tsx +57 -39
- package/templates/nextjs-standalone/src/ui/components/admin/admin-sidebar.tsx +213 -35
- package/templates/nextjs-standalone/src/ui/components/admin/delivery-status-badge.tsx +53 -0
- package/templates/nextjs-standalone/src/ui/components/admin/empty-state.tsx +27 -6
- package/templates/nextjs-standalone/src/ui/components/admin/entity-detail.tsx +3 -52
- package/templates/nextjs-standalone/src/ui/components/admin/error-banner.tsx +2 -2
- package/templates/nextjs-standalone/src/ui/components/admin/feature-disabled.tsx +28 -5
- package/templates/nextjs-standalone/src/ui/components/admin-content-wrapper.tsx +87 -0
- package/templates/nextjs-standalone/src/ui/components/atlas-chat.tsx +449 -166
- package/templates/nextjs-standalone/src/ui/components/branding-head.tsx +41 -0
- package/templates/nextjs-standalone/src/ui/components/chart/chart-detection.ts +62 -5
- package/templates/nextjs-standalone/src/ui/components/chart/result-chart.tsx +316 -125
- package/templates/nextjs-standalone/src/ui/components/chat/api-key-bar.tsx +4 -4
- package/templates/nextjs-standalone/src/ui/components/chat/data-table.tsx +45 -4
- package/templates/nextjs-standalone/src/ui/components/chat/error-banner.tsx +86 -5
- package/templates/nextjs-standalone/src/ui/components/chat/follow-up-chips.tsx +29 -0
- package/templates/nextjs-standalone/src/ui/components/chat/markdown.tsx +24 -0
- package/templates/nextjs-standalone/src/ui/components/chat/prompt-library.tsx +206 -0
- package/templates/nextjs-standalone/src/ui/components/chat/python-result-card.tsx +106 -78
- package/templates/nextjs-standalone/src/ui/components/chat/result-card-base.tsx +101 -0
- package/templates/nextjs-standalone/src/ui/components/chat/share-dialog.tsx +377 -0
- package/templates/nextjs-standalone/src/ui/components/chat/sql-result-card.tsx +94 -73
- package/templates/nextjs-standalone/src/ui/components/chat/suggestion-chips.tsx +46 -0
- package/templates/nextjs-standalone/src/ui/components/chat/tool-part.tsx +16 -4
- package/templates/nextjs-standalone/src/ui/components/conversations/conversation-item.tsx +48 -17
- package/templates/nextjs-standalone/src/ui/components/conversations/conversation-list.tsx +38 -24
- package/templates/nextjs-standalone/src/ui/components/conversations/conversation-sidebar.tsx +66 -7
- package/templates/nextjs-standalone/src/ui/components/conversations/delete-confirmation.tsx +9 -2
- package/templates/nextjs-standalone/src/ui/components/error-boundary.tsx +66 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/delete-cell-dialog.tsx +48 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/fork-branch-selector.tsx +68 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-cell-input.tsx +76 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-cell-output.tsx +58 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-cell-toolbar.tsx +91 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-cell.tsx +119 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-empty-state.tsx +19 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-export.ts +287 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-input-bar.tsx +49 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-shell.tsx +266 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/notebook-text-cell.tsx +152 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/types.ts +39 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/use-keyboard-nav.ts +109 -0
- package/templates/nextjs-standalone/src/ui/components/notebook/use-notebook.ts +684 -0
- package/templates/nextjs-standalone/src/ui/components/org-switcher.tsx +111 -0
- package/templates/nextjs-standalone/src/ui/components/region-picker.tsx +103 -0
- package/templates/nextjs-standalone/src/ui/components/schema-explorer/schema-explorer.tsx +522 -0
- package/templates/nextjs-standalone/src/ui/components/social-icons.tsx +26 -0
- package/templates/nextjs-standalone/src/ui/components/tour/guided-tour.tsx +81 -0
- package/templates/nextjs-standalone/src/ui/components/tour/index.ts +5 -0
- package/templates/nextjs-standalone/src/ui/components/tour/nav-bar.tsx +100 -0
- package/templates/nextjs-standalone/src/ui/components/tour/tour-overlay.tsx +298 -0
- package/templates/nextjs-standalone/src/ui/components/tour/tour-steps.ts +43 -0
- package/templates/nextjs-standalone/src/ui/components/tour/types.ts +21 -0
- package/templates/nextjs-standalone/src/ui/components/tour/use-tour.ts +193 -0
- package/templates/nextjs-standalone/src/ui/context-reexport.ts +3 -0
- package/templates/nextjs-standalone/src/ui/hooks/theme-init-script.ts +17 -0
- package/templates/nextjs-standalone/src/ui/hooks/use-admin-fetch.ts +38 -30
- package/templates/nextjs-standalone/src/ui/hooks/use-admin-mutation.ts +188 -0
- package/templates/nextjs-standalone/src/ui/hooks/use-atlas-transport.ts +225 -0
- package/templates/nextjs-standalone/src/ui/hooks/use-branding.ts +68 -0
- package/templates/nextjs-standalone/src/ui/hooks/use-conversations.ts +106 -83
- package/templates/nextjs-standalone/src/ui/hooks/use-dark-mode.ts +134 -10
- package/templates/nextjs-standalone/src/ui/hooks/use-deploy-mode.ts +36 -0
- package/templates/nextjs-standalone/src/ui/hooks/use-platform-admin-guard.ts +49 -0
- package/templates/nextjs-standalone/src/ui/lib/action-types.ts +11 -63
- package/templates/nextjs-standalone/src/ui/lib/admin-schemas.ts +744 -0
- package/templates/nextjs-standalone/src/ui/lib/fetch-client.ts +84 -0
- package/templates/nextjs-standalone/src/ui/lib/fetch-error.ts +54 -0
- package/templates/nextjs-standalone/src/ui/lib/helpers.ts +94 -1
- package/templates/nextjs-standalone/src/ui/lib/types.ts +149 -140
- package/templates/nextjs-standalone/tsconfig.json +3 -2
- package/templates/docker/src/api/__tests__/actions.test.ts +0 -683
- package/templates/docker/src/api/__tests__/admin.test.ts +0 -820
- package/templates/docker/src/api/__tests__/auth.test.ts +0 -165
- package/templates/docker/src/api/__tests__/chat.test.ts +0 -376
- package/templates/docker/src/api/__tests__/conversations.test.ts +0 -555
- package/templates/docker/src/api/__tests__/cors.test.ts +0 -135
- package/templates/docker/src/api/__tests__/health-plugin.test.ts +0 -176
- package/templates/docker/src/api/__tests__/health.test.ts +0 -283
- package/templates/docker/src/api/__tests__/query.test.ts +0 -891
- package/templates/docker/src/api/__tests__/scheduled-tasks.test.ts +0 -601
- package/templates/docker/src/api/__tests__/slack.test.ts +0 -847
- package/templates/docker/src/lib/__tests__/agent-cache.test.ts +0 -439
- package/templates/docker/src/lib/__tests__/agent-dialect.test.ts +0 -131
- package/templates/docker/src/lib/__tests__/agent-health-annotations.test.ts +0 -166
- package/templates/docker/src/lib/__tests__/agent-integration.test.ts +0 -516
- package/templates/docker/src/lib/__tests__/config-actions.test.ts +0 -166
- package/templates/docker/src/lib/__tests__/config.test.ts +0 -1113
- package/templates/docker/src/lib/__tests__/conversations.test.ts +0 -589
- package/templates/docker/src/lib/__tests__/errors.test.ts +0 -256
- package/templates/docker/src/lib/__tests__/logger.test.ts +0 -200
- package/templates/docker/src/lib/__tests__/plugin-aware-validation.test.ts +0 -321
- package/templates/docker/src/lib/__tests__/providers.test.ts +0 -130
- package/templates/docker/src/lib/__tests__/rls.test.ts +0 -435
- package/templates/docker/src/lib/__tests__/scheduled-task-types.test.ts +0 -124
- package/templates/docker/src/lib/__tests__/scheduled-tasks.test.ts +0 -550
- package/templates/docker/src/lib/__tests__/semantic-index.test.ts +0 -547
- package/templates/docker/src/lib/__tests__/semantic-multisource.test.ts +0 -544
- package/templates/docker/src/lib/__tests__/semantic.test.ts +0 -363
- package/templates/docker/src/lib/__tests__/startup-actions.test.ts +0 -461
- package/templates/docker/src/lib/__tests__/startup-first-run.test.ts +0 -429
- package/templates/docker/src/lib/__tests__/startup.test.ts +0 -470
- package/templates/docker/src/lib/__tests__/tracing.test.ts +0 -28
- package/templates/docker/src/lib/auth/__tests__/audit.test.ts +0 -418
- package/templates/docker/src/lib/auth/__tests__/byot-integration.test.ts +0 -222
- package/templates/docker/src/lib/auth/__tests__/byot.test.ts +0 -366
- package/templates/docker/src/lib/auth/__tests__/detect.test.ts +0 -190
- package/templates/docker/src/lib/auth/__tests__/managed.test.ts +0 -173
- package/templates/docker/src/lib/auth/__tests__/middleware.test.ts +0 -456
- package/templates/docker/src/lib/auth/__tests__/migrate.test.ts +0 -203
- package/templates/docker/src/lib/auth/__tests__/permissions.test.ts +0 -225
- package/templates/docker/src/lib/auth/__tests__/server.test.ts +0 -34
- package/templates/docker/src/lib/auth/__tests__/simple-key.test.ts +0 -176
- package/templates/docker/src/lib/auth/__tests__/types.test.ts +0 -44
- package/templates/docker/src/lib/db/__tests__/connection.test.ts +0 -144
- package/templates/docker/src/lib/db/__tests__/internal.test.ts +0 -387
- package/templates/docker/src/lib/db/__tests__/registry-health.test.ts +0 -190
- package/templates/docker/src/lib/db/__tests__/registry-pool-limits.test.ts +0 -137
- package/templates/docker/src/lib/db/__tests__/registry.test.ts +0 -398
- package/templates/docker/src/lib/db/__tests__/source-rate-limit.test.ts +0 -130
- package/templates/docker/src/lib/errors.ts +0 -154
- package/templates/docker/src/lib/plugins/__tests__/hooks-integration.test.ts +0 -204
- package/templates/docker/src/lib/plugins/__tests__/hooks.test.ts +0 -529
- package/templates/docker/src/lib/plugins/__tests__/migrate.test.ts +0 -875
- package/templates/docker/src/lib/plugins/__tests__/registry.test.ts +0 -373
- package/templates/docker/src/lib/plugins/__tests__/tools.test.ts +0 -49
- package/templates/docker/src/lib/plugins/__tests__/wiring.test.ts +0 -799
- package/templates/docker/src/lib/scheduler/__tests__/delivery.test.ts +0 -192
- package/templates/docker/src/lib/scheduler/__tests__/engine.test.ts +0 -248
- package/templates/docker/src/lib/scheduler/__tests__/format-email.test.ts +0 -96
- package/templates/docker/src/lib/scheduler/__tests__/format-slack.test.ts +0 -78
- package/templates/docker/src/lib/scheduler/__tests__/format-webhook.test.ts +0 -78
- package/templates/docker/src/lib/scheduler/index.ts +0 -7
- package/templates/docker/src/lib/slack/__tests__/api.test.ts +0 -160
- package/templates/docker/src/lib/slack/__tests__/format.test.ts +0 -237
- package/templates/docker/src/lib/slack/__tests__/store.test.ts +0 -188
- package/templates/docker/src/lib/slack/__tests__/threads.test.ts +0 -112
- package/templates/docker/src/lib/slack/__tests__/verify.test.ts +0 -111
- package/templates/docker/src/lib/tools/__tests__/action-permissions.test.ts +0 -594
- package/templates/docker/src/lib/tools/__tests__/custom-validation.test.ts +0 -240
- package/templates/docker/src/lib/tools/__tests__/explore-backend.test.ts +0 -267
- package/templates/docker/src/lib/tools/__tests__/explore-nsjail.test.ts +0 -506
- package/templates/docker/src/lib/tools/__tests__/explore-plugin.test.ts +0 -374
- package/templates/docker/src/lib/tools/__tests__/explore-sdk-compat.test.ts +0 -82
- package/templates/docker/src/lib/tools/__tests__/explore-sidecar.test.ts +0 -210
- package/templates/docker/src/lib/tools/__tests__/python-nsjail.test.ts +0 -515
- package/templates/docker/src/lib/tools/__tests__/python-sandbox.test.ts +0 -397
- package/templates/docker/src/lib/tools/__tests__/python-sidecar.test.ts +0 -365
- package/templates/docker/src/lib/tools/__tests__/python.test.ts +0 -331
- package/templates/docker/src/lib/tools/__tests__/registry-actions.test.ts +0 -132
- package/templates/docker/src/lib/tools/__tests__/registry.test.ts +0 -242
- package/templates/docker/src/lib/tools/__tests__/sql-audit.test.ts +0 -227
- package/templates/docker/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +0 -100
- package/templates/docker/src/lib/tools/__tests__/sql-ratelimit.test.ts +0 -227
- package/templates/docker/src/lib/tools/__tests__/sql.test.ts +0 -709
- package/templates/docker/src/lib/tools/actions/__tests__/audit.test.ts +0 -211
- package/templates/docker/src/lib/tools/actions/__tests__/email.test.ts +0 -378
- package/templates/docker/src/lib/tools/actions/__tests__/handler.test.ts +0 -681
- package/templates/docker/src/lib/tools/actions/__tests__/jira.test.ts +0 -427
- package/templates/docker/src/test-setup.ts +0 -38
- package/templates/docker/src/types/vercel-sandbox.d.ts +0 -61
- package/templates/docker/src/ui/components/chat/managed-auth-card.tsx +0 -116
- package/templates/nextjs-standalone/src/api/__tests__/actions.test.ts +0 -683
- package/templates/nextjs-standalone/src/api/__tests__/admin.test.ts +0 -820
- package/templates/nextjs-standalone/src/api/__tests__/auth.test.ts +0 -165
- package/templates/nextjs-standalone/src/api/__tests__/chat.test.ts +0 -376
- package/templates/nextjs-standalone/src/api/__tests__/conversations.test.ts +0 -555
- package/templates/nextjs-standalone/src/api/__tests__/cors.test.ts +0 -135
- package/templates/nextjs-standalone/src/api/__tests__/health-plugin.test.ts +0 -176
- package/templates/nextjs-standalone/src/api/__tests__/health.test.ts +0 -283
- package/templates/nextjs-standalone/src/api/__tests__/query.test.ts +0 -891
- package/templates/nextjs-standalone/src/api/__tests__/scheduled-tasks.test.ts +0 -601
- package/templates/nextjs-standalone/src/api/__tests__/slack.test.ts +0 -847
- package/templates/nextjs-standalone/src/app/global-error.tsx +0 -68
- package/templates/nextjs-standalone/src/lib/__tests__/agent-cache.test.ts +0 -439
- package/templates/nextjs-standalone/src/lib/__tests__/agent-dialect.test.ts +0 -131
- package/templates/nextjs-standalone/src/lib/__tests__/agent-health-annotations.test.ts +0 -166
- package/templates/nextjs-standalone/src/lib/__tests__/agent-integration.test.ts +0 -516
- package/templates/nextjs-standalone/src/lib/__tests__/config-actions.test.ts +0 -166
- package/templates/nextjs-standalone/src/lib/__tests__/config.test.ts +0 -1113
- package/templates/nextjs-standalone/src/lib/__tests__/conversations.test.ts +0 -589
- package/templates/nextjs-standalone/src/lib/__tests__/errors.test.ts +0 -256
- package/templates/nextjs-standalone/src/lib/__tests__/logger.test.ts +0 -200
- package/templates/nextjs-standalone/src/lib/__tests__/plugin-aware-validation.test.ts +0 -321
- package/templates/nextjs-standalone/src/lib/__tests__/providers.test.ts +0 -130
- package/templates/nextjs-standalone/src/lib/__tests__/rls.test.ts +0 -435
- package/templates/nextjs-standalone/src/lib/__tests__/scheduled-task-types.test.ts +0 -124
- package/templates/nextjs-standalone/src/lib/__tests__/scheduled-tasks.test.ts +0 -550
- package/templates/nextjs-standalone/src/lib/__tests__/semantic-index.test.ts +0 -547
- package/templates/nextjs-standalone/src/lib/__tests__/semantic-multisource.test.ts +0 -544
- package/templates/nextjs-standalone/src/lib/__tests__/semantic.test.ts +0 -363
- package/templates/nextjs-standalone/src/lib/__tests__/startup-actions.test.ts +0 -461
- package/templates/nextjs-standalone/src/lib/__tests__/startup-first-run.test.ts +0 -429
- package/templates/nextjs-standalone/src/lib/__tests__/startup.test.ts +0 -470
- package/templates/nextjs-standalone/src/lib/__tests__/tracing.test.ts +0 -28
- package/templates/nextjs-standalone/src/lib/auth/__tests__/audit.test.ts +0 -418
- package/templates/nextjs-standalone/src/lib/auth/__tests__/byot-integration.test.ts +0 -222
- package/templates/nextjs-standalone/src/lib/auth/__tests__/byot.test.ts +0 -366
- package/templates/nextjs-standalone/src/lib/auth/__tests__/detect.test.ts +0 -190
- package/templates/nextjs-standalone/src/lib/auth/__tests__/managed.test.ts +0 -173
- package/templates/nextjs-standalone/src/lib/auth/__tests__/middleware.test.ts +0 -456
- package/templates/nextjs-standalone/src/lib/auth/__tests__/migrate.test.ts +0 -203
- package/templates/nextjs-standalone/src/lib/auth/__tests__/permissions.test.ts +0 -225
- package/templates/nextjs-standalone/src/lib/auth/__tests__/server.test.ts +0 -34
- package/templates/nextjs-standalone/src/lib/auth/__tests__/simple-key.test.ts +0 -176
- package/templates/nextjs-standalone/src/lib/auth/__tests__/types.test.ts +0 -44
- package/templates/nextjs-standalone/src/lib/db/__tests__/connection.test.ts +0 -144
- package/templates/nextjs-standalone/src/lib/db/__tests__/internal.test.ts +0 -387
- package/templates/nextjs-standalone/src/lib/db/__tests__/registry-health.test.ts +0 -190
- package/templates/nextjs-standalone/src/lib/db/__tests__/registry-pool-limits.test.ts +0 -137
- package/templates/nextjs-standalone/src/lib/db/__tests__/registry.test.ts +0 -398
- package/templates/nextjs-standalone/src/lib/db/__tests__/source-rate-limit.test.ts +0 -130
- package/templates/nextjs-standalone/src/lib/errors.ts +0 -154
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks-integration.test.ts +0 -204
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks.test.ts +0 -529
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/migrate.test.ts +0 -875
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/registry.test.ts +0 -373
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/tools.test.ts +0 -49
- package/templates/nextjs-standalone/src/lib/plugins/__tests__/wiring.test.ts +0 -799
- package/templates/nextjs-standalone/src/lib/scheduler/__tests__/delivery.test.ts +0 -192
- package/templates/nextjs-standalone/src/lib/scheduler/__tests__/engine.test.ts +0 -248
- package/templates/nextjs-standalone/src/lib/scheduler/__tests__/format-email.test.ts +0 -96
- package/templates/nextjs-standalone/src/lib/scheduler/__tests__/format-slack.test.ts +0 -78
- package/templates/nextjs-standalone/src/lib/scheduler/__tests__/format-webhook.test.ts +0 -78
- package/templates/nextjs-standalone/src/lib/scheduler/index.ts +0 -7
- package/templates/nextjs-standalone/src/lib/slack/__tests__/api.test.ts +0 -160
- package/templates/nextjs-standalone/src/lib/slack/__tests__/format.test.ts +0 -237
- package/templates/nextjs-standalone/src/lib/slack/__tests__/store.test.ts +0 -188
- package/templates/nextjs-standalone/src/lib/slack/__tests__/threads.test.ts +0 -112
- package/templates/nextjs-standalone/src/lib/slack/__tests__/verify.test.ts +0 -111
- package/templates/nextjs-standalone/src/lib/tools/__tests__/action-permissions.test.ts +0 -594
- package/templates/nextjs-standalone/src/lib/tools/__tests__/custom-validation.test.ts +0 -240
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-backend.test.ts +0 -267
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-nsjail.test.ts +0 -506
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-plugin.test.ts +0 -374
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sdk-compat.test.ts +0 -82
- package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sidecar.test.ts +0 -210
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python-nsjail.test.ts +0 -515
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python-sandbox.test.ts +0 -397
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python-sidecar.test.ts +0 -365
- package/templates/nextjs-standalone/src/lib/tools/__tests__/python.test.ts +0 -331
- package/templates/nextjs-standalone/src/lib/tools/__tests__/registry-actions.test.ts +0 -132
- package/templates/nextjs-standalone/src/lib/tools/__tests__/registry.test.ts +0 -242
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-audit.test.ts +0 -227
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +0 -100
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-ratelimit.test.ts +0 -227
- package/templates/nextjs-standalone/src/lib/tools/__tests__/sql.test.ts +0 -709
- package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/audit.test.ts +0 -211
- package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/email.test.ts +0 -378
- package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/handler.test.ts +0 -681
- package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/jira.test.ts +0 -427
- package/templates/nextjs-standalone/src/test-setup.ts +0 -38
- package/templates/nextjs-standalone/src/ui/components/chat/managed-auth-card.tsx +0 -116
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
import * as fs from "fs";
|
|
9
9
|
import * as path from "path";
|
|
10
|
+
import { matchError } from "@useatlas/types";
|
|
10
11
|
import { detectDBType, resolveDatasourceUrl } from "./db/connection";
|
|
11
12
|
import { maskConnectionUrl } from "./security";
|
|
12
13
|
import { getDefaultProvider } from "./providers";
|
|
13
14
|
import { detectAuthMode, getAuthModeSource } from "./auth/detect";
|
|
14
15
|
import { createLogger } from "./logger";
|
|
16
|
+
import { getSemanticRoot as getDefaultSemanticRoot } from "./semantic/files";
|
|
15
17
|
|
|
16
18
|
const log = createLogger("startup");
|
|
17
19
|
|
|
@@ -76,8 +78,63 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
76
78
|
|
|
77
79
|
const errors: DiagnosticError[] = [];
|
|
78
80
|
|
|
79
|
-
// 1. Analytics datasource
|
|
81
|
+
// 1. Analytics datasource URL presence
|
|
80
82
|
const resolvedDatasourceUrl = resolveDatasourceUrl();
|
|
83
|
+
checkDatasourceUrlPresence(errors, resolvedDatasourceUrl);
|
|
84
|
+
|
|
85
|
+
// 2. API key for configured provider
|
|
86
|
+
checkProviderApiKey(errors);
|
|
87
|
+
|
|
88
|
+
// 3. Semantic layer presence
|
|
89
|
+
checkSemanticLayerPresence(errors);
|
|
90
|
+
|
|
91
|
+
// 4. Datasource connectivity (only if a datasource URL is resolved)
|
|
92
|
+
if (resolvedDatasourceUrl) {
|
|
93
|
+
await checkDatasourceConnectivity(errors, resolvedDatasourceUrl);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 5. Internal database (DATABASE_URL) — optional, for auth/audit/settings
|
|
97
|
+
await checkInternalDbConnectivity(errors);
|
|
98
|
+
|
|
99
|
+
// Check if boot-time migration reported errors
|
|
100
|
+
const { getMigrationError } = await import("@atlas/api/lib/auth/migrate");
|
|
101
|
+
const migrationErr = getMigrationError();
|
|
102
|
+
if (migrationErr) {
|
|
103
|
+
errors.push({ code: "INTERNAL_DB_UNREACHABLE", message: migrationErr });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 5.5. Config file validation (atlas.config.ts)
|
|
107
|
+
await checkConfigFile(errors);
|
|
108
|
+
|
|
109
|
+
// 6. Auth mode diagnostics + 6.5. encryption key check
|
|
110
|
+
const authMode = await checkAuthModeDiagnostics(errors);
|
|
111
|
+
|
|
112
|
+
// 7. Action framework diagnostics
|
|
113
|
+
if (process.env.ATLAS_ACTIONS_ENABLED === "true") {
|
|
114
|
+
await checkActionFramework(errors, authMode);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 8. Slack integration — optional, informational only
|
|
118
|
+
if (process.env.SLACK_SIGNING_SECRET) {
|
|
119
|
+
const slackMode = process.env.SLACK_CLIENT_ID ? "oauth" : "single-workspace";
|
|
120
|
+
log.info({ slackMode }, "Slack integration enabled");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 9. Sandbox plugins + 10. Sandbox pre-flight
|
|
124
|
+
await logSandboxPlugins();
|
|
125
|
+
await checkSandboxPreFlight();
|
|
126
|
+
|
|
127
|
+
_cached = errors;
|
|
128
|
+
_cachedAt = Date.now();
|
|
129
|
+
return errors;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ── Startup validation helpers ──────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
function checkDatasourceUrlPresence(
|
|
135
|
+
errors: DiagnosticError[],
|
|
136
|
+
resolvedDatasourceUrl: string | undefined,
|
|
137
|
+
): void {
|
|
81
138
|
if (!resolvedDatasourceUrl) {
|
|
82
139
|
if (process.env.ATLAS_DEMO_DATA === "true") {
|
|
83
140
|
const msg =
|
|
@@ -109,8 +166,9 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
109
166
|
const source = process.env.DATABASE_URL_UNPOOLED ? "DATABASE_URL_UNPOOLED" : "DATABASE_URL";
|
|
110
167
|
log.info("Demo mode: using %s as analytics datasource", source);
|
|
111
168
|
}
|
|
169
|
+
}
|
|
112
170
|
|
|
113
|
-
|
|
171
|
+
function checkProviderApiKey(errors: DiagnosticError[]): void {
|
|
114
172
|
const provider = process.env.ATLAS_PROVIDER ?? getDefaultProvider();
|
|
115
173
|
const requiredKey = PROVIDER_KEY_MAP[provider];
|
|
116
174
|
|
|
@@ -125,9 +183,10 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
125
183
|
}
|
|
126
184
|
errors.push({ code: "MISSING_API_KEY", message });
|
|
127
185
|
}
|
|
186
|
+
}
|
|
128
187
|
|
|
129
|
-
|
|
130
|
-
const semanticDir = path.
|
|
188
|
+
function checkSemanticLayerPresence(errors: DiagnosticError[]): void {
|
|
189
|
+
const semanticDir = path.join(getDefaultSemanticRoot(), "entities");
|
|
131
190
|
let hasEntities = false;
|
|
132
191
|
try {
|
|
133
192
|
const files = fs.readdirSync(semanticDir);
|
|
@@ -135,7 +194,6 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
135
194
|
} catch (err) {
|
|
136
195
|
const code = err instanceof Error && "code" in err ? (err as NodeJS.ErrnoException).code : undefined;
|
|
137
196
|
if (code !== "ENOENT") {
|
|
138
|
-
// Non-ENOENT errors (permissions, not a directory, etc.) — report the real problem
|
|
139
197
|
errors.push({
|
|
140
198
|
code: "MISSING_SEMANTIC_LAYER",
|
|
141
199
|
message: `Could not read semantic layer directory: ${err instanceof Error ? err.message : String(err)}. Check file permissions.`,
|
|
@@ -150,147 +208,210 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
150
208
|
"No semantic layer found. Run 'bun run atlas -- init' to generate one from your database, or 'bun run atlas -- init --demo' to load demo data.",
|
|
151
209
|
});
|
|
152
210
|
}
|
|
211
|
+
}
|
|
153
212
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
213
|
+
async function checkDatasourceConnectivity(
|
|
214
|
+
errors: DiagnosticError[],
|
|
215
|
+
resolvedDatasourceUrl: string,
|
|
216
|
+
): Promise<void> {
|
|
217
|
+
let dbType: ReturnType<typeof detectDBType> | null = null;
|
|
218
|
+
try {
|
|
219
|
+
dbType = detectDBType(resolvedDatasourceUrl);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
222
|
+
log.error({ err: detail }, "Unsupported datasource URL");
|
|
223
|
+
errors.push({ code: "DB_UNREACHABLE", message: detail });
|
|
224
|
+
}
|
|
164
225
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
226
|
+
if (dbType === "mysql") {
|
|
227
|
+
await checkMysqlConnectivity(errors, resolvedDatasourceUrl);
|
|
228
|
+
} else if (dbType === "postgres") {
|
|
229
|
+
await checkPostgresConnectivity(errors, resolvedDatasourceUrl);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Non-core database types are validated by their respective datasource plugins.
|
|
233
|
+
if (dbType && dbType !== "postgres" && dbType !== "mysql") {
|
|
234
|
+
log.info(
|
|
235
|
+
{ dbType },
|
|
236
|
+
"Non-core datasource type '%s' — connectivity validation deferred to plugin initialize()",
|
|
237
|
+
dbType,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function checkMysqlConnectivity(
|
|
243
|
+
errors: DiagnosticError[],
|
|
244
|
+
url: string,
|
|
245
|
+
): Promise<void> {
|
|
246
|
+
if (!isValidUrl(url)) {
|
|
247
|
+
errors.push({
|
|
248
|
+
code: "DB_UNREACHABLE",
|
|
249
|
+
message: "ATLAS_DATASOURCE_URL appears malformed. Expected format: mysql://user:pass@host:3306/dbname",
|
|
250
|
+
});
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
255
|
+
const mysql = require("mysql2/promise");
|
|
256
|
+
let pool;
|
|
257
|
+
try {
|
|
258
|
+
pool = mysql.createPool({
|
|
259
|
+
uri: url,
|
|
260
|
+
connectionLimit: 1,
|
|
261
|
+
connectTimeout: 5000,
|
|
262
|
+
});
|
|
263
|
+
const conn = await pool.getConnection();
|
|
264
|
+
conn.release();
|
|
265
|
+
} catch (err) {
|
|
266
|
+
const detail = err instanceof Error ? err.message : "";
|
|
267
|
+
log.error({ err: detail }, "MySQL connection check failed");
|
|
268
|
+
|
|
269
|
+
const maskedUrl = maskConnectionUrl(url);
|
|
270
|
+
const matched = matchError(err);
|
|
271
|
+
let message: string;
|
|
272
|
+
if (matched) {
|
|
273
|
+
message = `Cannot connect to ${maskedUrl}. ${matched.message}`;
|
|
274
|
+
} else if (/Access denied/i.test(detail) || /ER_ACCESS_DENIED/i.test(detail)) {
|
|
275
|
+
message = `Cannot connect to ${maskedUrl}. Authentication failed — check your username and password.`;
|
|
276
|
+
} else if (/ER_BAD_DB_ERROR/i.test(detail)) {
|
|
277
|
+
let dbHint = "";
|
|
278
|
+
try {
|
|
279
|
+
const noDatabaseUrl = url.replace(/\/[^/?#]+(?=[?#]|$)/, "/");
|
|
280
|
+
const listPool = mysql.createPool({
|
|
281
|
+
uri: noDatabaseUrl,
|
|
282
|
+
connectionLimit: 1,
|
|
283
|
+
connectTimeout: 5000,
|
|
171
284
|
});
|
|
172
|
-
} else {
|
|
173
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
174
|
-
const mysql = require("mysql2/promise");
|
|
175
|
-
let pool;
|
|
176
285
|
try {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
log.error({ err: detail }, "MySQL connection check failed");
|
|
187
|
-
|
|
188
|
-
let message = `Cannot connect to ${maskConnectionUrl(resolvedDatasourceUrl)}. Check the connection string and ensure the database is running.`;
|
|
189
|
-
|
|
190
|
-
if (/ECONNREFUSED/i.test(detail)) {
|
|
191
|
-
message += " The connection was refused — is the MySQL server running?";
|
|
192
|
-
} else if (/Access denied/i.test(detail) || /ER_ACCESS_DENIED/i.test(detail)) {
|
|
193
|
-
message += " Authentication failed — check your username and password.";
|
|
194
|
-
} else if (/ER_BAD_DB_ERROR/i.test(detail)) {
|
|
195
|
-
message += " The specified database does not exist.";
|
|
196
|
-
} else if (/timeout/i.test(detail)) {
|
|
197
|
-
message += " The connection timed out — check network/firewall settings.";
|
|
286
|
+
const listConn = await listPool.getConnection();
|
|
287
|
+
const [dbRows] = await listConn.query(
|
|
288
|
+
"SELECT schema_name FROM information_schema.schemata " +
|
|
289
|
+
"WHERE schema_name NOT IN ('mysql', 'sys', 'performance_schema', 'information_schema') " +
|
|
290
|
+
"ORDER BY schema_name"
|
|
291
|
+
);
|
|
292
|
+
const schemas = (dbRows as Array<{ schema_name: string }>).map(r => r.schema_name);
|
|
293
|
+
if (schemas.length > 0) {
|
|
294
|
+
dbHint = ` Available databases: ${schemas.join(", ")}.`;
|
|
198
295
|
}
|
|
199
|
-
|
|
200
|
-
errors.push({ code: "DB_UNREACHABLE", message });
|
|
296
|
+
listConn.release();
|
|
201
297
|
} finally {
|
|
202
|
-
|
|
203
|
-
await pool.end().catch((err: unknown) => {
|
|
204
|
-
log.warn({ err: err instanceof Error ? err.message : String(err) }, "Pool cleanup warning");
|
|
205
|
-
});
|
|
206
|
-
}
|
|
298
|
+
await listPool.end().catch(() => {});
|
|
207
299
|
}
|
|
300
|
+
} catch {
|
|
301
|
+
// Database listing failed — fall back to generic message
|
|
208
302
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
303
|
+
message = `Cannot connect to ${maskedUrl}. The specified database does not exist.${dbHint}`;
|
|
304
|
+
} else {
|
|
305
|
+
message = `Cannot connect to ${maskedUrl}. Check the connection string and ensure the database is running.`;
|
|
306
|
+
}
|
|
213
307
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
308
|
+
errors.push({ code: "DB_UNREACHABLE", message });
|
|
309
|
+
} finally {
|
|
310
|
+
if (pool) {
|
|
311
|
+
await pool.end().catch((err: unknown) => {
|
|
312
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "Pool cleanup warning");
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
221
317
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
229
|
-
const { Pool } = require("pg");
|
|
230
|
-
const pool = new Pool({
|
|
231
|
-
connectionString: resolvedDatasourceUrl,
|
|
232
|
-
max: 1,
|
|
233
|
-
connectionTimeoutMillis: 5000,
|
|
234
|
-
});
|
|
235
|
-
try {
|
|
236
|
-
const client = await pool.connect();
|
|
237
|
-
|
|
238
|
-
// Verify schema exists if ATLAS_SCHEMA is set and valid
|
|
239
|
-
if (atlasSchema && atlasSchema !== "public" && VALID_SQL_IDENTIFIER.test(atlasSchema)) {
|
|
240
|
-
try {
|
|
241
|
-
const result = await client.query(
|
|
242
|
-
"SELECT 1 FROM pg_namespace WHERE nspname = $1",
|
|
243
|
-
[atlasSchema]
|
|
244
|
-
);
|
|
245
|
-
if (result.rows.length === 0) {
|
|
246
|
-
errors.push({
|
|
247
|
-
code: "INVALID_SCHEMA",
|
|
248
|
-
message: `Schema "${atlasSchema}" does not exist in the database. Check ATLAS_SCHEMA in your .env file.`,
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
} catch (schemaErr) {
|
|
252
|
-
log.error({ err: schemaErr instanceof Error ? schemaErr.message : String(schemaErr) }, "Schema existence check failed");
|
|
253
|
-
errors.push({
|
|
254
|
-
code: "INVALID_SCHEMA",
|
|
255
|
-
message: `Could not verify schema "${atlasSchema}". Check ATLAS_SCHEMA and database permissions.`,
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
318
|
+
async function checkPostgresConnectivity(
|
|
319
|
+
errors: DiagnosticError[],
|
|
320
|
+
url: string,
|
|
321
|
+
): Promise<void> {
|
|
322
|
+
const atlasSchema = process.env.ATLAS_SCHEMA;
|
|
323
|
+
const VALID_SQL_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
259
324
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
325
|
+
// Validate ATLAS_SCHEMA format before attempting connection
|
|
326
|
+
if (atlasSchema && !VALID_SQL_IDENTIFIER.test(atlasSchema)) {
|
|
327
|
+
errors.push({
|
|
328
|
+
code: "INVALID_SCHEMA",
|
|
329
|
+
message: `Invalid ATLAS_SCHEMA "${atlasSchema}". Must be a valid SQL identifier (letters, digits, underscores).`,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
264
332
|
|
|
265
|
-
|
|
333
|
+
if (!isValidUrl(url)) {
|
|
334
|
+
errors.push({
|
|
335
|
+
code: "DB_UNREACHABLE",
|
|
336
|
+
message: "ATLAS_DATASOURCE_URL appears malformed. Expected format: postgresql://user:pass@host:5432/dbname",
|
|
337
|
+
});
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
266
340
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
341
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
342
|
+
const { Pool } = require("pg");
|
|
343
|
+
const pool = new Pool({
|
|
344
|
+
connectionString: url,
|
|
345
|
+
max: 1,
|
|
346
|
+
connectionTimeoutMillis: 5000,
|
|
347
|
+
});
|
|
348
|
+
try {
|
|
349
|
+
const client = await pool.connect();
|
|
274
350
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
351
|
+
// Verify schema exists if ATLAS_SCHEMA is set and valid
|
|
352
|
+
if (atlasSchema && atlasSchema !== "public" && VALID_SQL_IDENTIFIER.test(atlasSchema)) {
|
|
353
|
+
try {
|
|
354
|
+
const result = await client.query(
|
|
355
|
+
"SELECT 1 FROM pg_namespace WHERE nspname = $1",
|
|
356
|
+
[atlasSchema]
|
|
357
|
+
);
|
|
358
|
+
if (result.rows.length === 0) {
|
|
359
|
+
let schemaHint = "";
|
|
360
|
+
try {
|
|
361
|
+
const schemasResult = await client.query(
|
|
362
|
+
"SELECT schema_name FROM information_schema.schemata " +
|
|
363
|
+
"WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast') " +
|
|
364
|
+
"AND schema_name NOT LIKE 'pg_temp_%' AND schema_name NOT LIKE 'pg_toast_temp_%' " +
|
|
365
|
+
"ORDER BY schema_name"
|
|
366
|
+
);
|
|
367
|
+
const schemas = schemasResult.rows.map(
|
|
368
|
+
(r: { schema_name: string }) => r.schema_name
|
|
369
|
+
);
|
|
370
|
+
if (schemas.length > 0) {
|
|
371
|
+
schemaHint = ` Available schemas: ${schemas.join(", ")}.`;
|
|
372
|
+
}
|
|
373
|
+
} catch {
|
|
374
|
+
// Schema listing failed — fall back to generic message
|
|
375
|
+
}
|
|
376
|
+
errors.push({
|
|
377
|
+
code: "INVALID_SCHEMA",
|
|
378
|
+
message: `Schema "${atlasSchema}" does not exist in the database.${schemaHint} Check ATLAS_SCHEMA in your .env file.`,
|
|
279
379
|
});
|
|
280
380
|
}
|
|
381
|
+
} catch (schemaErr) {
|
|
382
|
+
log.error({ err: schemaErr instanceof Error ? schemaErr.message : String(schemaErr) }, "Schema existence check failed");
|
|
383
|
+
errors.push({
|
|
384
|
+
code: "INVALID_SCHEMA",
|
|
385
|
+
message: `Could not verify schema "${atlasSchema}". Check ATLAS_SCHEMA and database permissions.`,
|
|
386
|
+
});
|
|
281
387
|
}
|
|
282
388
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
389
|
+
|
|
390
|
+
client.release();
|
|
391
|
+
} catch (err) {
|
|
392
|
+
const detail = err instanceof Error ? err.message : "";
|
|
393
|
+
log.error({ err: detail }, "DB connection check failed");
|
|
394
|
+
|
|
395
|
+
const maskedUrl = maskConnectionUrl(url);
|
|
396
|
+
const matched = matchError(err);
|
|
397
|
+
let message: string;
|
|
398
|
+
if (matched) {
|
|
399
|
+
message = `Cannot connect to ${maskedUrl}. ${matched.message}`;
|
|
400
|
+
} else if (/authentication/i.test(detail) || /password/i.test(detail)) {
|
|
401
|
+
message = `Cannot connect to ${maskedUrl}. Authentication failed — check your username and password.`;
|
|
402
|
+
} else {
|
|
403
|
+
message = `Cannot connect to ${maskedUrl}. Check the connection string and ensure the database is running.`;
|
|
290
404
|
}
|
|
405
|
+
|
|
406
|
+
errors.push({ code: "DB_UNREACHABLE", message });
|
|
407
|
+
} finally {
|
|
408
|
+
await pool.end().catch((err: unknown) => {
|
|
409
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "Pool cleanup warning");
|
|
410
|
+
});
|
|
291
411
|
}
|
|
412
|
+
}
|
|
292
413
|
|
|
293
|
-
|
|
414
|
+
async function checkInternalDbConnectivity(errors: DiagnosticError[]): Promise<void> {
|
|
294
415
|
if (process.env.DATABASE_URL) {
|
|
295
416
|
if (!isValidUrl(process.env.DATABASE_URL)) {
|
|
296
417
|
errors.push({
|
|
@@ -312,13 +433,15 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
312
433
|
const detail = err instanceof Error ? err.message : "";
|
|
313
434
|
log.error({ err: detail }, "Internal DB connection check failed");
|
|
314
435
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
message
|
|
436
|
+
const maskedUrl = maskConnectionUrl(process.env.DATABASE_URL!);
|
|
437
|
+
const matched = matchError(err);
|
|
438
|
+
let message: string;
|
|
439
|
+
if (matched) {
|
|
440
|
+
message = `Cannot connect to internal database at ${maskedUrl}. ${matched.message}`;
|
|
320
441
|
} else if (/authentication/i.test(detail) || /password/i.test(detail)) {
|
|
321
|
-
message
|
|
442
|
+
message = `Cannot connect to internal database at ${maskedUrl}. Authentication failed — check your username and password.`;
|
|
443
|
+
} else {
|
|
444
|
+
message = `Cannot connect to internal database at ${maskedUrl}. Check the connection string and ensure the database is running.`;
|
|
322
445
|
}
|
|
323
446
|
|
|
324
447
|
errors.push({ code: "INTERNAL_DB_UNREACHABLE", message });
|
|
@@ -335,15 +458,9 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
335
458
|
}
|
|
336
459
|
log.warn(msg);
|
|
337
460
|
}
|
|
461
|
+
}
|
|
338
462
|
|
|
339
|
-
|
|
340
|
-
const { getMigrationError } = await import("@atlas/api/lib/auth/migrate");
|
|
341
|
-
const migrationErr = getMigrationError();
|
|
342
|
-
if (migrationErr) {
|
|
343
|
-
errors.push({ code: "INTERNAL_DB_UNREACHABLE", message: migrationErr });
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// 5.5. Config file validation (atlas.config.ts)
|
|
463
|
+
async function checkConfigFile(errors: DiagnosticError[]): Promise<void> {
|
|
347
464
|
try {
|
|
348
465
|
const configMod = await import("@atlas/api/lib/config");
|
|
349
466
|
if (typeof configMod.loadConfig === "function" && !configMod.getConfig()) {
|
|
@@ -354,27 +471,29 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
354
471
|
log.error({ err: detail }, "Config validation failed");
|
|
355
472
|
errors.push({ code: "INVALID_CONFIG", message: detail });
|
|
356
473
|
}
|
|
474
|
+
}
|
|
357
475
|
|
|
358
|
-
|
|
476
|
+
async function checkAuthModeDiagnostics(errors: DiagnosticError[]): Promise<string> {
|
|
359
477
|
const authMode = detectAuthMode();
|
|
360
478
|
const authSource = getAuthModeSource();
|
|
361
479
|
log.info({ authMode, source: authSource }, "Auth mode: %s (%s)", authMode, authSource);
|
|
362
480
|
|
|
363
|
-
// When mode is explicit, verify prerequisite env vars
|
|
364
|
-
if (authSource === "explicit") {
|
|
481
|
+
// When mode is pinned (explicit env var or config file), verify prerequisite env vars
|
|
482
|
+
if (authSource === "explicit" || authSource === "config") {
|
|
483
|
+
const source = authSource === "config" ? "atlas.config.ts" : "ATLAS_AUTH_MODE";
|
|
365
484
|
if (authMode === "simple-key" && !process.env.ATLAS_API_KEY) {
|
|
366
485
|
errors.push({
|
|
367
486
|
code: "MISSING_AUTH_PREREQ",
|
|
368
487
|
message:
|
|
369
|
-
|
|
370
|
-
"Set ATLAS_API_KEY to a shared secret, or
|
|
488
|
+
`Auth mode is 'api-key' (from ${source}) but ATLAS_API_KEY is not set. ` +
|
|
489
|
+
"Set ATLAS_API_KEY to a shared secret, or change auth to 'auto'.",
|
|
371
490
|
});
|
|
372
491
|
}
|
|
373
492
|
if (authMode === "managed" && !process.env.BETTER_AUTH_SECRET) {
|
|
374
493
|
errors.push({
|
|
375
494
|
code: "MISSING_AUTH_PREREQ",
|
|
376
495
|
message:
|
|
377
|
-
|
|
496
|
+
`Auth mode is 'managed' (from ${source}) but BETTER_AUTH_SECRET is not set. ` +
|
|
378
497
|
"Set BETTER_AUTH_SECRET to a random string of at least 32 characters.",
|
|
379
498
|
});
|
|
380
499
|
}
|
|
@@ -382,91 +501,115 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
382
501
|
errors.push({
|
|
383
502
|
code: "MISSING_AUTH_PREREQ",
|
|
384
503
|
message:
|
|
385
|
-
|
|
504
|
+
`Auth mode is 'byot' (from ${source}) but ATLAS_AUTH_JWKS_URL is not set. ` +
|
|
386
505
|
"Set ATLAS_AUTH_JWKS_URL to your identity provider's JWKS endpoint.",
|
|
387
506
|
});
|
|
388
507
|
}
|
|
389
508
|
}
|
|
390
509
|
|
|
391
510
|
if (authMode === "managed") {
|
|
392
|
-
|
|
393
|
-
errors.push({
|
|
394
|
-
code: "INTERNAL_DB_UNREACHABLE",
|
|
395
|
-
message:
|
|
396
|
-
"Managed auth mode requires DATABASE_URL for session storage. " +
|
|
397
|
-
"Set DATABASE_URL to a PostgreSQL connection string (postgresql://user:pass@host:5432/atlas).",
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
const secret = process.env.BETTER_AUTH_SECRET ?? "";
|
|
401
|
-
if (secret.length < 32) {
|
|
402
|
-
errors.push({
|
|
403
|
-
code: "WEAK_AUTH_SECRET",
|
|
404
|
-
message:
|
|
405
|
-
`BETTER_AUTH_SECRET must be at least 32 characters (currently ${secret.length}). ` +
|
|
406
|
-
"Generate one with: openssl rand -base64 32",
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
if (!process.env.BETTER_AUTH_URL) {
|
|
410
|
-
const msg =
|
|
411
|
-
"BETTER_AUTH_URL is not set. Better Auth will auto-detect from the request, " +
|
|
412
|
-
"but setting it explicitly is recommended for production.";
|
|
413
|
-
if (!_startupWarnings.includes(msg)) {
|
|
414
|
-
_startupWarnings.push(msg);
|
|
415
|
-
}
|
|
416
|
-
log.warn(msg);
|
|
417
|
-
}
|
|
511
|
+
checkManagedAuthMode(errors);
|
|
418
512
|
}
|
|
419
513
|
|
|
420
514
|
if (authMode === "byot") {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
515
|
+
await checkByotAuthMode(errors);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Warn about orphaned auth env vars that suggest misconfiguration
|
|
519
|
+
warnOrphanedAuthVars(authMode, authSource);
|
|
520
|
+
|
|
521
|
+
// 6.5. Connection encryption key check — only relevant when internal DB stores connection URLs
|
|
522
|
+
if (process.env.DATABASE_URL && !process.env.ATLAS_ENCRYPTION_KEY && !process.env.BETTER_AUTH_SECRET) {
|
|
523
|
+
const msg =
|
|
524
|
+
"No encryption key available for connection URLs. Set ATLAS_ENCRYPTION_KEY or BETTER_AUTH_SECRET " +
|
|
525
|
+
"to encrypt connection credentials at rest.";
|
|
526
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
527
|
+
log.warn(msg);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return authMode;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function checkManagedAuthMode(errors: DiagnosticError[]): void {
|
|
534
|
+
if (!process.env.DATABASE_URL) {
|
|
535
|
+
errors.push({
|
|
536
|
+
code: "INTERNAL_DB_UNREACHABLE",
|
|
537
|
+
message:
|
|
538
|
+
"Managed auth mode requires DATABASE_URL for session storage. " +
|
|
539
|
+
"Set DATABASE_URL to a PostgreSQL connection string (postgresql://user:pass@host:5432/atlas).",
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
const secret = process.env.BETTER_AUTH_SECRET ?? "";
|
|
543
|
+
if (secret.length < 32) {
|
|
544
|
+
errors.push({
|
|
545
|
+
code: "WEAK_AUTH_SECRET",
|
|
546
|
+
message:
|
|
547
|
+
`BETTER_AUTH_SECRET must be at least 32 characters (currently ${secret.length}). ` +
|
|
548
|
+
"Generate one with: openssl rand -base64 32",
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
if (!process.env.BETTER_AUTH_URL) {
|
|
552
|
+
const msg =
|
|
553
|
+
"BETTER_AUTH_URL is not set. Better Auth will auto-detect from the request, " +
|
|
554
|
+
"but setting it explicitly is recommended for production.";
|
|
555
|
+
if (!_startupWarnings.includes(msg)) {
|
|
556
|
+
_startupWarnings.push(msg);
|
|
432
557
|
}
|
|
558
|
+
log.warn(msg);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
433
561
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
562
|
+
async function checkByotAuthMode(errors: DiagnosticError[]): Promise<void> {
|
|
563
|
+
const jwksUrl = process.env.ATLAS_AUTH_JWKS_URL ?? "";
|
|
564
|
+
let jwksUrlValid = false;
|
|
565
|
+
try {
|
|
566
|
+
new URL(jwksUrl);
|
|
567
|
+
jwksUrlValid = true;
|
|
568
|
+
} catch (err) {
|
|
569
|
+
errors.push({
|
|
570
|
+
code: "INVALID_JWKS_URL",
|
|
571
|
+
message:
|
|
572
|
+
`ATLAS_AUTH_JWKS_URL is not a valid URL (${err instanceof Error ? err.message : "parse error"}). Expected format: https://your-idp.com/.well-known/jwks.json`,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Reachability check — non-blocking warning since the IdP might be temporarily down
|
|
577
|
+
if (jwksUrlValid) {
|
|
578
|
+
try {
|
|
579
|
+
const resp = await fetch(jwksUrl, { signal: AbortSignal.timeout(5000) });
|
|
580
|
+
if (!resp.ok) {
|
|
581
|
+
const msg = `JWKS endpoint returned HTTP ${resp.status}. Verify the URL is correct.`;
|
|
582
|
+
log.warn({ jwksUrl, status: resp.status }, msg);
|
|
583
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
445
584
|
}
|
|
585
|
+
} catch (err) {
|
|
586
|
+
log.warn({ err: err instanceof Error ? err.message : String(err), jwksUrl }, "JWKS endpoint unreachable during startup check");
|
|
446
587
|
}
|
|
588
|
+
}
|
|
447
589
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
590
|
+
if (!process.env.ATLAS_AUTH_ISSUER) {
|
|
591
|
+
errors.push({
|
|
592
|
+
code: "MISSING_AUTH_ISSUER",
|
|
593
|
+
message:
|
|
594
|
+
"ATLAS_AUTH_ISSUER is required for BYOT auth mode. Set it to your identity provider's issuer URL (e.g. https://your-idp.com/).",
|
|
595
|
+
});
|
|
596
|
+
}
|
|
455
597
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
598
|
+
if (process.env.ATLAS_AUTH_AUDIENCE === "") {
|
|
599
|
+
const msg =
|
|
600
|
+
"ATLAS_AUTH_AUDIENCE is set to an empty string — audience validation will be skipped. " +
|
|
601
|
+
"Remove the variable entirely if audience checking is not needed, or set it to a valid audience value.";
|
|
602
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
603
|
+
log.warn(msg);
|
|
463
604
|
}
|
|
605
|
+
}
|
|
464
606
|
|
|
465
|
-
|
|
607
|
+
function warnOrphanedAuthVars(authMode: string, authSource: string | null): void {
|
|
466
608
|
if (authMode !== "byot" && process.env.ATLAS_AUTH_ISSUER) {
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
609
|
+
const pinned = authSource === "explicit" || authSource === "config";
|
|
610
|
+
const msg = pinned
|
|
611
|
+
? `ATLAS_AUTH_ISSUER is set but auth mode is '${authMode}' (${authSource}). ` +
|
|
612
|
+
"Remove ATLAS_AUTH_ISSUER, or change auth to 'byot' to use it."
|
|
470
613
|
: "ATLAS_AUTH_ISSUER is set but ATLAS_AUTH_JWKS_URL is not — BYOT auth mode is not active. " +
|
|
471
614
|
"Set ATLAS_AUTH_JWKS_URL to enable BYOT, or remove ATLAS_AUTH_ISSUER.";
|
|
472
615
|
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
@@ -474,86 +617,81 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
474
617
|
}
|
|
475
618
|
|
|
476
619
|
if (authMode !== "managed" && (process.env.BETTER_AUTH_URL || process.env.BETTER_AUTH_TRUSTED_ORIGINS)) {
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
620
|
+
const pinned = authSource === "explicit" || authSource === "config";
|
|
621
|
+
const msg = pinned
|
|
622
|
+
? `BETTER_AUTH_URL or BETTER_AUTH_TRUSTED_ORIGINS is set but auth mode is '${authMode}' (${authSource}). ` +
|
|
623
|
+
"Remove these env vars, or change auth to 'managed' to use them."
|
|
480
624
|
: "BETTER_AUTH_URL or BETTER_AUTH_TRUSTED_ORIGINS is set but BETTER_AUTH_SECRET is not — " +
|
|
481
625
|
"managed auth mode is not active. Set BETTER_AUTH_SECRET to enable managed auth.";
|
|
482
626
|
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
483
627
|
log.warn(msg);
|
|
484
628
|
}
|
|
629
|
+
}
|
|
485
630
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
log.info("Action framework enabled");
|
|
631
|
+
async function checkActionFramework(errors: DiagnosticError[], authMode: string): Promise<void> {
|
|
632
|
+
log.info("Action framework enabled");
|
|
489
633
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
// Check required credentials for registered actions (warnings only —
|
|
500
|
-
// missing optional action credentials should not block chat queries)
|
|
501
|
-
try {
|
|
502
|
-
const { buildRegistry } = await import("@atlas/api/lib/tools/registry");
|
|
503
|
-
const actionRegistry = await buildRegistry({ includeActions: true });
|
|
504
|
-
const missingCreds = actionRegistry.validateActionCredentials();
|
|
505
|
-
for (const { action, missing } of missingCreds) {
|
|
506
|
-
const msg = `Action "${action}" missing credentials: ${missing.join(", ")}`;
|
|
507
|
-
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
508
|
-
log.warn(msg);
|
|
509
|
-
}
|
|
510
|
-
} catch (err) {
|
|
511
|
-
log.warn(
|
|
512
|
-
{ err: err instanceof Error ? err.message : String(err) },
|
|
513
|
-
"Could not validate action credentials at startup",
|
|
514
|
-
);
|
|
515
|
-
}
|
|
634
|
+
// Actions require authentication — reject "none" auth mode
|
|
635
|
+
if (authMode === "none") {
|
|
636
|
+
errors.push({
|
|
637
|
+
code: "ACTIONS_REQUIRE_AUTH",
|
|
638
|
+
message:
|
|
639
|
+
"Actions require authentication. Set ATLAS_API_KEY, BETTER_AUTH_SECRET, or ATLAS_AUTH_JWKS_URL to enable an auth mode.",
|
|
640
|
+
});
|
|
641
|
+
}
|
|
516
642
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
643
|
+
// Check required credentials for registered actions (warnings only —
|
|
644
|
+
// missing optional action credentials should not block chat queries)
|
|
645
|
+
try {
|
|
646
|
+
const { buildRegistry } = await import("@atlas/api/lib/tools/registry");
|
|
647
|
+
const { registry: actionRegistry } = await buildRegistry({ includeActions: true });
|
|
648
|
+
const missingCreds = actionRegistry.validateActionCredentials();
|
|
649
|
+
for (const { action, missing } of missingCreds) {
|
|
650
|
+
const msg = `Action "${action}" missing credentials: ${missing.join(", ")}`;
|
|
522
651
|
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
523
652
|
log.warn(msg);
|
|
524
653
|
}
|
|
654
|
+
} catch (err) {
|
|
655
|
+
log.warn(
|
|
656
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
657
|
+
"Could not validate action credentials at startup",
|
|
658
|
+
);
|
|
659
|
+
}
|
|
525
660
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
661
|
+
// Warn if no internal DB for persistent tracking
|
|
662
|
+
if (!process.env.DATABASE_URL) {
|
|
663
|
+
const msg =
|
|
664
|
+
"Action framework requires DATABASE_URL for persistent tracking. " +
|
|
665
|
+
"Actions will use in-memory storage only (lost on restart).";
|
|
666
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
667
|
+
log.warn(msg);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Warn about high-risk actions set to auto-approve
|
|
671
|
+
try {
|
|
672
|
+
const { getConfig } = await import("@atlas/api/lib/config");
|
|
673
|
+
const config = getConfig();
|
|
674
|
+
const actionsConfig = config?.actions;
|
|
675
|
+
if (actionsConfig) {
|
|
676
|
+
const highRiskActions = ["email:send", "jira:create", "salesforce:update", "salesforce:create"];
|
|
677
|
+
for (const actionType of highRiskActions) {
|
|
678
|
+
const perAction = actionsConfig[actionType] as { approval?: string } | undefined;
|
|
679
|
+
if (perAction?.approval === "auto") {
|
|
680
|
+
const msg = `${actionType} configured for auto-approve — ensure you understand the risk`;
|
|
681
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
682
|
+
log.warn(msg);
|
|
540
683
|
}
|
|
541
684
|
}
|
|
542
|
-
} catch (err) {
|
|
543
|
-
log.warn(
|
|
544
|
-
{ err: err instanceof Error ? err.message : String(err) },
|
|
545
|
-
"Could not validate action config at startup",
|
|
546
|
-
);
|
|
547
685
|
}
|
|
686
|
+
} catch (err) {
|
|
687
|
+
log.warn(
|
|
688
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
689
|
+
"Could not validate action config at startup",
|
|
690
|
+
);
|
|
548
691
|
}
|
|
692
|
+
}
|
|
549
693
|
|
|
550
|
-
|
|
551
|
-
if (process.env.SLACK_SIGNING_SECRET) {
|
|
552
|
-
const slackMode = process.env.SLACK_CLIENT_ID ? "oauth" : "single-workspace";
|
|
553
|
-
log.info({ slackMode }, "Slack integration enabled");
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// 9. Sandbox plugins — log any registered sandbox plugins before built-in pre-flight
|
|
694
|
+
async function logSandboxPlugins(): Promise<void> {
|
|
557
695
|
try {
|
|
558
696
|
const { plugins: pluginRegistry } = await import("@atlas/api/lib/plugins/registry");
|
|
559
697
|
try {
|
|
@@ -579,115 +717,143 @@ export async function validateEnvironment(): Promise<DiagnosticError[]> {
|
|
|
579
717
|
} catch {
|
|
580
718
|
// Plugin registry module not available — skip
|
|
581
719
|
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
async function checkSandboxPreFlight(): Promise<void> {
|
|
723
|
+
try {
|
|
724
|
+
const { getConfig: getAtlasConfig } = await import("@atlas/api/lib/config");
|
|
725
|
+
const sandboxPriority = getAtlasConfig()?.sandbox?.priority;
|
|
726
|
+
if (sandboxPriority) {
|
|
727
|
+
log.info(
|
|
728
|
+
{ priority: sandboxPriority },
|
|
729
|
+
"Custom sandbox priority configured: %s",
|
|
730
|
+
sandboxPriority.join(" > "),
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
} catch (err) {
|
|
734
|
+
const isModuleErr = err != null && typeof err === "object" && "code" in err
|
|
735
|
+
&& (err as NodeJS.ErrnoException).code === "MODULE_NOT_FOUND";
|
|
736
|
+
if (!isModuleErr) {
|
|
737
|
+
log.warn(
|
|
738
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
739
|
+
"Failed to read sandbox priority from config",
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
582
743
|
|
|
583
|
-
// 10. Sandbox pre-flight (explore tool isolation)
|
|
584
744
|
const isVercel = process.env.ATLAS_RUNTIME === "vercel" || !!process.env.VERCEL;
|
|
585
745
|
if (isVercel) {
|
|
586
746
|
log.info("Explore tool: Vercel sandbox active");
|
|
587
747
|
} else if (process.env.ATLAS_SANDBOX === "nsjail") {
|
|
588
|
-
|
|
589
|
-
try {
|
|
590
|
-
const { findNsjailBinary, testNsjailCapabilities } = await import(
|
|
591
|
-
"@atlas/api/lib/tools/explore-nsjail"
|
|
592
|
-
);
|
|
593
|
-
const { markNsjailFailed } = await import(
|
|
594
|
-
"@atlas/api/lib/tools/explore"
|
|
595
|
-
);
|
|
596
|
-
const nsjailPath = findNsjailBinary();
|
|
597
|
-
if (nsjailPath) {
|
|
598
|
-
const semanticRoot = path.resolve(process.cwd(), "semantic");
|
|
599
|
-
const capResult = await testNsjailCapabilities(nsjailPath, semanticRoot);
|
|
600
|
-
if (capResult.ok) {
|
|
601
|
-
log.info("Explore tool: nsjail sandbox active");
|
|
602
|
-
} else {
|
|
603
|
-
markNsjailFailed();
|
|
604
|
-
const msg =
|
|
605
|
-
`nsjail explicitly requested (ATLAS_SANDBOX=nsjail) but namespace creation failed: ${capResult.error}. ` +
|
|
606
|
-
"This platform may not support Linux namespaces. " +
|
|
607
|
-
"Set ATLAS_SANDBOX= (empty) to allow fallback to just-bash, or check platform documentation for namespace support.";
|
|
608
|
-
log.error(msg);
|
|
609
|
-
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
610
|
-
}
|
|
611
|
-
} else {
|
|
612
|
-
const msg =
|
|
613
|
-
"ATLAS_SANDBOX=nsjail is set but nsjail binary was not found. " +
|
|
614
|
-
"Install nsjail or set ATLAS_NSJAIL_PATH to the binary location.";
|
|
615
|
-
log.error(msg);
|
|
616
|
-
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
617
|
-
}
|
|
618
|
-
} catch (err) {
|
|
619
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
620
|
-
log.warn({ err: detail }, "Sandbox pre-flight check skipped");
|
|
621
|
-
}
|
|
748
|
+
await checkExplicitNsjail();
|
|
622
749
|
} else if (process.env.ATLAS_SANDBOX_URL) {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
750
|
+
await checkSidecarHealth();
|
|
751
|
+
} else {
|
|
752
|
+
await autoDetectNsjail();
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
async function checkExplicitNsjail(): Promise<void> {
|
|
757
|
+
try {
|
|
758
|
+
const { findNsjailBinary, testNsjailCapabilities } = await import(
|
|
759
|
+
"@atlas/api/lib/tools/explore-nsjail"
|
|
760
|
+
);
|
|
761
|
+
const { markNsjailFailed } = await import(
|
|
626
762
|
"@atlas/api/lib/tools/explore"
|
|
627
763
|
);
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
const
|
|
631
|
-
|
|
632
|
-
|
|
764
|
+
const nsjailPath = findNsjailBinary();
|
|
765
|
+
if (nsjailPath) {
|
|
766
|
+
const semanticRoot = getDefaultSemanticRoot();
|
|
767
|
+
const capResult = await testNsjailCapabilities(nsjailPath, semanticRoot);
|
|
768
|
+
if (capResult.ok) {
|
|
769
|
+
log.info("Explore tool: nsjail sandbox active");
|
|
633
770
|
} else {
|
|
634
|
-
|
|
771
|
+
markNsjailFailed();
|
|
635
772
|
const msg =
|
|
636
|
-
`
|
|
637
|
-
"
|
|
773
|
+
`nsjail explicitly requested (ATLAS_SANDBOX=nsjail) but namespace creation failed: ${capResult.error}. ` +
|
|
774
|
+
"This platform may not support Linux namespaces. " +
|
|
775
|
+
"Set ATLAS_SANDBOX= (empty) to allow fallback to just-bash, or check platform documentation for namespace support.";
|
|
638
776
|
log.error(msg);
|
|
639
777
|
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
640
778
|
}
|
|
641
|
-
}
|
|
642
|
-
markSidecarFailed();
|
|
643
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
779
|
+
} else {
|
|
644
780
|
const msg =
|
|
645
|
-
|
|
646
|
-
"
|
|
781
|
+
"ATLAS_SANDBOX=nsjail is set but nsjail binary was not found. " +
|
|
782
|
+
"Install nsjail or set ATLAS_NSJAIL_PATH to the binary location.";
|
|
647
783
|
log.error(msg);
|
|
648
784
|
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
649
785
|
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
} catch (err) {
|
|
677
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
678
|
-
log.warn({ err: detail }, "Sandbox pre-flight check skipped");
|
|
786
|
+
} catch (err) {
|
|
787
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
788
|
+
log.warn({ err: detail }, "Sandbox pre-flight check skipped");
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
async function checkSidecarHealth(): Promise<void> {
|
|
793
|
+
// Caller guarantees ATLAS_SANDBOX_URL is set
|
|
794
|
+
const sidecarUrl = process.env.ATLAS_SANDBOX_URL!;
|
|
795
|
+
const { markSidecarFailed } = await import(
|
|
796
|
+
"@atlas/api/lib/tools/explore"
|
|
797
|
+
);
|
|
798
|
+
try {
|
|
799
|
+
const healthUrl = new URL("/health", sidecarUrl).toString();
|
|
800
|
+
const resp = await fetch(healthUrl, { signal: AbortSignal.timeout(5000) });
|
|
801
|
+
if (resp.ok) {
|
|
802
|
+
log.info({ url: sidecarUrl }, "Explore tool: sidecar sandbox active");
|
|
803
|
+
} else {
|
|
804
|
+
markSidecarFailed();
|
|
805
|
+
const msg =
|
|
806
|
+
`Sidecar health check returned HTTP ${resp.status} at ${sidecarUrl}. ` +
|
|
807
|
+
"Check that the sandbox-sidecar service is running and healthy.";
|
|
808
|
+
log.error(msg);
|
|
809
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
679
810
|
}
|
|
811
|
+
} catch (err) {
|
|
812
|
+
markSidecarFailed();
|
|
813
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
814
|
+
const msg =
|
|
815
|
+
`Sidecar unreachable at ${sidecarUrl}: ${detail}. ` +
|
|
816
|
+
"The sidecar may not be running yet — explore will retry on first use.";
|
|
817
|
+
log.error(msg);
|
|
818
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
680
821
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
822
|
+
async function autoDetectNsjail(): Promise<void> {
|
|
823
|
+
let nsjailActive = false;
|
|
824
|
+
try {
|
|
825
|
+
const { findNsjailBinary, testNsjailCapabilities } = await import(
|
|
826
|
+
"@atlas/api/lib/tools/explore-nsjail"
|
|
827
|
+
);
|
|
828
|
+
const { markNsjailFailed } = await import(
|
|
829
|
+
"@atlas/api/lib/tools/explore"
|
|
830
|
+
);
|
|
831
|
+
const nsjailPath = findNsjailBinary();
|
|
832
|
+
if (nsjailPath) {
|
|
833
|
+
const semanticRoot = getDefaultSemanticRoot();
|
|
834
|
+
const capResult = await testNsjailCapabilities(nsjailPath, semanticRoot);
|
|
835
|
+
if (capResult.ok) {
|
|
836
|
+
log.info("Explore tool: nsjail sandbox active");
|
|
837
|
+
nsjailActive = true;
|
|
838
|
+
} else {
|
|
839
|
+
markNsjailFailed();
|
|
840
|
+
const msg =
|
|
841
|
+
`nsjail available but namespace creation failed: ${capResult.error} — ` +
|
|
842
|
+
"falling back to just-bash (no process isolation).";
|
|
843
|
+
log.warn(msg);
|
|
844
|
+
if (!_startupWarnings.includes(msg)) _startupWarnings.push(msg);
|
|
845
|
+
}
|
|
685
846
|
}
|
|
847
|
+
} catch (err) {
|
|
848
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
849
|
+
log.warn({ err: detail }, "Sandbox pre-flight check skipped");
|
|
686
850
|
}
|
|
687
851
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
852
|
+
if (!nsjailActive) {
|
|
853
|
+
log.info(
|
|
854
|
+
"Explore tool: just-bash (no process isolation). Install nsjail or configure ATLAS_SANDBOX_URL for sandboxed execution.",
|
|
855
|
+
);
|
|
856
|
+
}
|
|
691
857
|
}
|
|
692
858
|
|
|
693
859
|
function isValidUrl(url: string): boolean {
|