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