@useatlas/create 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. package/README.md +231 -0
  2. package/index.ts +829 -0
  3. package/package.json +38 -0
  4. package/templates/docker/.env.example +67 -0
  5. package/templates/docker/Dockerfile +52 -0
  6. package/templates/docker/bin/__tests__/benchmark.test.ts +598 -0
  7. package/templates/docker/bin/__tests__/duckdb-ingest.test.ts +171 -0
  8. package/templates/docker/bin/__tests__/eval.test.ts +434 -0
  9. package/templates/docker/bin/__tests__/matview-partition.test.ts +615 -0
  10. package/templates/docker/bin/__tests__/multi-source.test.ts +113 -0
  11. package/templates/docker/bin/__tests__/plugin-cli.test.ts +322 -0
  12. package/templates/docker/bin/__tests__/profiler-heuristics.test.ts +608 -0
  13. package/templates/docker/bin/__tests__/query.test.ts +240 -0
  14. package/templates/docker/bin/__tests__/schema-drift.test.ts +542 -0
  15. package/templates/docker/bin/__tests__/view-yaml-generation.test.ts +146 -0
  16. package/templates/docker/bin/atlas.ts +5044 -0
  17. package/templates/docker/bin/benchmark.ts +695 -0
  18. package/templates/docker/bin/enrich.ts +559 -0
  19. package/templates/docker/bin/eval.ts +770 -0
  20. package/templates/docker/bin/smoke.ts +438 -0
  21. package/templates/docker/data/.gitkeep +0 -0
  22. package/templates/docker/data/cybersec.sql +1961 -0
  23. package/templates/docker/data/demo-semantic/catalog.yml +40 -0
  24. package/templates/docker/data/demo-semantic/entities/accounts.yml +170 -0
  25. package/templates/docker/data/demo-semantic/entities/companies.yml +207 -0
  26. package/templates/docker/data/demo-semantic/entities/people.yml +145 -0
  27. package/templates/docker/data/demo-semantic/glossary.yml +22 -0
  28. package/templates/docker/data/demo-semantic/metrics/accounts.yml +38 -0
  29. package/templates/docker/data/demo-semantic/metrics/companies.yml +89 -0
  30. package/templates/docker/data/demo.sql +373 -0
  31. package/templates/docker/data/ecommerce.sql +1690 -0
  32. package/templates/docker/data/init-demo-db.sql +8 -0
  33. package/templates/docker/docker-compose.yml +34 -0
  34. package/templates/docker/docs/deploy.md +390 -0
  35. package/templates/docker/eslint.config.mjs +18 -0
  36. package/templates/docker/gitignore +5 -0
  37. package/templates/docker/next.config.ts +9 -0
  38. package/templates/docker/package.json +59 -0
  39. package/templates/docker/postcss.config.mjs +8 -0
  40. package/templates/docker/public/.gitkeep +0 -0
  41. package/templates/docker/public/favicon.svg +4 -0
  42. package/templates/docker/railway.json +13 -0
  43. package/templates/docker/render.yaml +34 -0
  44. package/templates/docker/semantic/catalog.yml +5 -0
  45. package/templates/docker/semantic/entities/.gitkeep +0 -0
  46. package/templates/docker/semantic/glossary.yml +6 -0
  47. package/templates/docker/semantic/metrics/.gitkeep +0 -0
  48. package/templates/docker/sidecar/Dockerfile +28 -0
  49. package/templates/docker/sidecar/railway.json +14 -0
  50. package/templates/docker/sidecar/server.ts +188 -0
  51. package/templates/docker/src/api/__tests__/actions.test.ts +683 -0
  52. package/templates/docker/src/api/__tests__/admin.test.ts +820 -0
  53. package/templates/docker/src/api/__tests__/auth.test.ts +165 -0
  54. package/templates/docker/src/api/__tests__/chat.test.ts +376 -0
  55. package/templates/docker/src/api/__tests__/conversations.test.ts +555 -0
  56. package/templates/docker/src/api/__tests__/cors.test.ts +135 -0
  57. package/templates/docker/src/api/__tests__/health-plugin.test.ts +169 -0
  58. package/templates/docker/src/api/__tests__/health.test.ts +261 -0
  59. package/templates/docker/src/api/__tests__/query.test.ts +891 -0
  60. package/templates/docker/src/api/__tests__/scheduled-tasks.test.ts +601 -0
  61. package/templates/docker/src/api/__tests__/slack.test.ts +847 -0
  62. package/templates/docker/src/api/index.ts +117 -0
  63. package/templates/docker/src/api/routes/actions.ts +274 -0
  64. package/templates/docker/src/api/routes/admin.ts +757 -0
  65. package/templates/docker/src/api/routes/auth.ts +48 -0
  66. package/templates/docker/src/api/routes/chat.ts +465 -0
  67. package/templates/docker/src/api/routes/conversations.ts +266 -0
  68. package/templates/docker/src/api/routes/health.ts +287 -0
  69. package/templates/docker/src/api/routes/openapi.ts +390 -0
  70. package/templates/docker/src/api/routes/query.ts +318 -0
  71. package/templates/docker/src/api/routes/scheduled-tasks.ts +467 -0
  72. package/templates/docker/src/api/routes/slack.ts +611 -0
  73. package/templates/docker/src/api/server.ts +226 -0
  74. package/templates/docker/src/app/api/[...route]/route.ts +33 -0
  75. package/templates/docker/src/app/error.tsx +24 -0
  76. package/templates/docker/src/app/globals.css +126 -0
  77. package/templates/docker/src/app/layout.tsx +19 -0
  78. package/templates/docker/src/app/page.tsx +14 -0
  79. package/templates/docker/src/global.d.ts +1 -0
  80. package/templates/docker/src/lib/__tests__/agent-cache.test.ts +437 -0
  81. package/templates/docker/src/lib/__tests__/agent-dialect.test.ts +114 -0
  82. package/templates/docker/src/lib/__tests__/agent-health-annotations.test.ts +164 -0
  83. package/templates/docker/src/lib/__tests__/agent-integration.test.ts +514 -0
  84. package/templates/docker/src/lib/__tests__/config-actions.test.ts +166 -0
  85. package/templates/docker/src/lib/__tests__/config.test.ts +1063 -0
  86. package/templates/docker/src/lib/__tests__/conversations.test.ts +589 -0
  87. package/templates/docker/src/lib/__tests__/errors.test.ts +256 -0
  88. package/templates/docker/src/lib/__tests__/logger.test.ts +200 -0
  89. package/templates/docker/src/lib/__tests__/providers.test.ts +99 -0
  90. package/templates/docker/src/lib/__tests__/rls.test.ts +435 -0
  91. package/templates/docker/src/lib/__tests__/scheduled-task-types.test.ts +124 -0
  92. package/templates/docker/src/lib/__tests__/scheduled-tasks.test.ts +550 -0
  93. package/templates/docker/src/lib/__tests__/semantic-index.test.ts +547 -0
  94. package/templates/docker/src/lib/__tests__/semantic-multisource.test.ts +544 -0
  95. package/templates/docker/src/lib/__tests__/semantic.test.ts +363 -0
  96. package/templates/docker/src/lib/__tests__/startup-actions.test.ts +452 -0
  97. package/templates/docker/src/lib/__tests__/startup.test.ts +465 -0
  98. package/templates/docker/src/lib/__tests__/tracing.test.ts +28 -0
  99. package/templates/docker/src/lib/action-types.ts +95 -0
  100. package/templates/docker/src/lib/agent-query.ts +178 -0
  101. package/templates/docker/src/lib/agent.ts +505 -0
  102. package/templates/docker/src/lib/api-url.ts +2 -0
  103. package/templates/docker/src/lib/auth/__tests__/audit.test.ts +418 -0
  104. package/templates/docker/src/lib/auth/__tests__/byot-integration.test.ts +222 -0
  105. package/templates/docker/src/lib/auth/__tests__/byot.test.ts +366 -0
  106. package/templates/docker/src/lib/auth/__tests__/detect.test.ts +190 -0
  107. package/templates/docker/src/lib/auth/__tests__/managed.test.ts +173 -0
  108. package/templates/docker/src/lib/auth/__tests__/middleware.test.ts +456 -0
  109. package/templates/docker/src/lib/auth/__tests__/migrate.test.ts +201 -0
  110. package/templates/docker/src/lib/auth/__tests__/permissions.test.ts +225 -0
  111. package/templates/docker/src/lib/auth/__tests__/server.test.ts +34 -0
  112. package/templates/docker/src/lib/auth/__tests__/simple-key.test.ts +176 -0
  113. package/templates/docker/src/lib/auth/__tests__/types.test.ts +44 -0
  114. package/templates/docker/src/lib/auth/audit.ts +89 -0
  115. package/templates/docker/src/lib/auth/byot.ts +158 -0
  116. package/templates/docker/src/lib/auth/client.ts +35 -0
  117. package/templates/docker/src/lib/auth/detect.ts +83 -0
  118. package/templates/docker/src/lib/auth/managed.ts +73 -0
  119. package/templates/docker/src/lib/auth/middleware.ts +208 -0
  120. package/templates/docker/src/lib/auth/migrate.ts +111 -0
  121. package/templates/docker/src/lib/auth/permissions.ts +156 -0
  122. package/templates/docker/src/lib/auth/server.ts +142 -0
  123. package/templates/docker/src/lib/auth/simple-key.ts +92 -0
  124. package/templates/docker/src/lib/auth/types.ts +49 -0
  125. package/templates/docker/src/lib/config.ts +704 -0
  126. package/templates/docker/src/lib/conversation-types.ts +29 -0
  127. package/templates/docker/src/lib/conversations.ts +270 -0
  128. package/templates/docker/src/lib/db/__tests__/connection.test.ts +69 -0
  129. package/templates/docker/src/lib/db/__tests__/duckdb.test.ts +141 -0
  130. package/templates/docker/src/lib/db/__tests__/internal.test.ts +387 -0
  131. package/templates/docker/src/lib/db/__tests__/registry-health.test.ts +207 -0
  132. package/templates/docker/src/lib/db/__tests__/registry-pool-limits.test.ts +156 -0
  133. package/templates/docker/src/lib/db/__tests__/registry.test.ts +595 -0
  134. package/templates/docker/src/lib/db/__tests__/salesforce.test.ts +339 -0
  135. package/templates/docker/src/lib/db/__tests__/snowflake.test.ts +217 -0
  136. package/templates/docker/src/lib/db/__tests__/source-rate-limit.test.ts +130 -0
  137. package/templates/docker/src/lib/db/connection.ts +753 -0
  138. package/templates/docker/src/lib/db/duckdb.ts +122 -0
  139. package/templates/docker/src/lib/db/internal.ts +273 -0
  140. package/templates/docker/src/lib/db/salesforce.ts +342 -0
  141. package/templates/docker/src/lib/db/source-rate-limit.ts +191 -0
  142. package/templates/docker/src/lib/errors.ts +154 -0
  143. package/templates/docker/src/lib/logger.ts +98 -0
  144. package/templates/docker/src/lib/plugins/__tests__/hooks-integration.test.ts +202 -0
  145. package/templates/docker/src/lib/plugins/__tests__/hooks.test.ts +529 -0
  146. package/templates/docker/src/lib/plugins/__tests__/migrate.test.ts +521 -0
  147. package/templates/docker/src/lib/plugins/__tests__/registry.test.ts +346 -0
  148. package/templates/docker/src/lib/plugins/__tests__/tools.test.ts +49 -0
  149. package/templates/docker/src/lib/plugins/__tests__/wiring.test.ts +585 -0
  150. package/templates/docker/src/lib/plugins/hooks.ts +162 -0
  151. package/templates/docker/src/lib/plugins/index.ts +9 -0
  152. package/templates/docker/src/lib/plugins/migrate.ts +309 -0
  153. package/templates/docker/src/lib/plugins/registry.ts +231 -0
  154. package/templates/docker/src/lib/plugins/tools.ts +39 -0
  155. package/templates/docker/src/lib/plugins/wiring.ts +291 -0
  156. package/templates/docker/src/lib/providers.ts +102 -0
  157. package/templates/docker/src/lib/rls.ts +321 -0
  158. package/templates/docker/src/lib/scheduled-task-types.ts +132 -0
  159. package/templates/docker/src/lib/scheduled-tasks.ts +475 -0
  160. package/templates/docker/src/lib/scheduler/__tests__/delivery.test.ts +192 -0
  161. package/templates/docker/src/lib/scheduler/__tests__/engine.test.ts +248 -0
  162. package/templates/docker/src/lib/scheduler/__tests__/format-email.test.ts +96 -0
  163. package/templates/docker/src/lib/scheduler/__tests__/format-slack.test.ts +78 -0
  164. package/templates/docker/src/lib/scheduler/__tests__/format-webhook.test.ts +78 -0
  165. package/templates/docker/src/lib/scheduler/delivery.ts +248 -0
  166. package/templates/docker/src/lib/scheduler/engine.ts +317 -0
  167. package/templates/docker/src/lib/scheduler/executor.ts +73 -0
  168. package/templates/docker/src/lib/scheduler/format-email.ts +109 -0
  169. package/templates/docker/src/lib/scheduler/format-slack.ts +35 -0
  170. package/templates/docker/src/lib/scheduler/format-webhook.ts +37 -0
  171. package/templates/docker/src/lib/scheduler/index.ts +7 -0
  172. package/templates/docker/src/lib/security.ts +11 -0
  173. package/templates/docker/src/lib/semantic-index.ts +503 -0
  174. package/templates/docker/src/lib/semantic.ts +387 -0
  175. package/templates/docker/src/lib/sidecar-types.ts +16 -0
  176. package/templates/docker/src/lib/slack/__tests__/api.test.ts +160 -0
  177. package/templates/docker/src/lib/slack/__tests__/format.test.ts +237 -0
  178. package/templates/docker/src/lib/slack/__tests__/store.test.ts +188 -0
  179. package/templates/docker/src/lib/slack/__tests__/threads.test.ts +112 -0
  180. package/templates/docker/src/lib/slack/__tests__/verify.test.ts +111 -0
  181. package/templates/docker/src/lib/slack/api.ts +102 -0
  182. package/templates/docker/src/lib/slack/format.ts +209 -0
  183. package/templates/docker/src/lib/slack/store.ts +107 -0
  184. package/templates/docker/src/lib/slack/threads.ts +64 -0
  185. package/templates/docker/src/lib/slack/verify.ts +71 -0
  186. package/templates/docker/src/lib/startup.ts +730 -0
  187. package/templates/docker/src/lib/tools/__tests__/action-permissions.test.ts +594 -0
  188. package/templates/docker/src/lib/tools/__tests__/custom-validation.test.ts +238 -0
  189. package/templates/docker/src/lib/tools/__tests__/explore-backend.test.ts +267 -0
  190. package/templates/docker/src/lib/tools/__tests__/explore-nsjail.test.ts +492 -0
  191. package/templates/docker/src/lib/tools/__tests__/explore-plugin.test.ts +374 -0
  192. package/templates/docker/src/lib/tools/__tests__/explore-sdk-compat.test.ts +82 -0
  193. package/templates/docker/src/lib/tools/__tests__/explore-sidecar.test.ts +208 -0
  194. package/templates/docker/src/lib/tools/__tests__/registry-actions.test.ts +144 -0
  195. package/templates/docker/src/lib/tools/__tests__/registry.test.ts +235 -0
  196. package/templates/docker/src/lib/tools/__tests__/salesforce-tool.test.ts +154 -0
  197. package/templates/docker/src/lib/tools/__tests__/soql-validation.test.ts +303 -0
  198. package/templates/docker/src/lib/tools/__tests__/sql-audit.test.ts +225 -0
  199. package/templates/docker/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +98 -0
  200. package/templates/docker/src/lib/tools/__tests__/sql-duckdb.test.ts +233 -0
  201. package/templates/docker/src/lib/tools/__tests__/sql-ratelimit.test.ts +225 -0
  202. package/templates/docker/src/lib/tools/__tests__/sql.test.ts +1012 -0
  203. package/templates/docker/src/lib/tools/actions/__tests__/audit.test.ts +211 -0
  204. package/templates/docker/src/lib/tools/actions/__tests__/email.test.ts +378 -0
  205. package/templates/docker/src/lib/tools/actions/__tests__/handler.test.ts +681 -0
  206. package/templates/docker/src/lib/tools/actions/__tests__/jira.test.ts +427 -0
  207. package/templates/docker/src/lib/tools/actions/audit.ts +47 -0
  208. package/templates/docker/src/lib/tools/actions/email.ts +191 -0
  209. package/templates/docker/src/lib/tools/actions/handler.ts +591 -0
  210. package/templates/docker/src/lib/tools/actions/index.ts +23 -0
  211. package/templates/docker/src/lib/tools/actions/jira.ts +220 -0
  212. package/templates/docker/src/lib/tools/explore-nsjail.ts +343 -0
  213. package/templates/docker/src/lib/tools/explore-sandbox.ts +264 -0
  214. package/templates/docker/src/lib/tools/explore-sidecar.ts +163 -0
  215. package/templates/docker/src/lib/tools/explore.ts +379 -0
  216. package/templates/docker/src/lib/tools/registry.ts +221 -0
  217. package/templates/docker/src/lib/tools/salesforce.ts +138 -0
  218. package/templates/docker/src/lib/tools/soql-validation.ts +172 -0
  219. package/templates/docker/src/lib/tools/sql.ts +680 -0
  220. package/templates/docker/src/lib/tracing.ts +40 -0
  221. package/templates/docker/src/lib/utils.ts +6 -0
  222. package/templates/docker/src/test-setup.ts +38 -0
  223. package/templates/docker/src/types/vercel-sandbox.d.ts +54 -0
  224. package/templates/docker/src/ui/components/actions/action-approval-card.tsx +295 -0
  225. package/templates/docker/src/ui/components/actions/action-status-badge.tsx +50 -0
  226. package/templates/docker/src/ui/components/admin/admin-layout.tsx +26 -0
  227. package/templates/docker/src/ui/components/admin/admin-sidebar.tsx +96 -0
  228. package/templates/docker/src/ui/components/admin/empty-state.tsx +24 -0
  229. package/templates/docker/src/ui/components/admin/entity-detail.tsx +233 -0
  230. package/templates/docker/src/ui/components/admin/entity-list.tsx +96 -0
  231. package/templates/docker/src/ui/components/admin/error-banner.tsx +22 -0
  232. package/templates/docker/src/ui/components/admin/feature-disabled.tsx +44 -0
  233. package/templates/docker/src/ui/components/admin/health-badge.tsx +30 -0
  234. package/templates/docker/src/ui/components/admin/loading-state.tsx +14 -0
  235. package/templates/docker/src/ui/components/admin/stat-card.tsx +32 -0
  236. package/templates/docker/src/ui/components/atlas-chat.tsx +370 -0
  237. package/templates/docker/src/ui/components/chart/chart-detection.ts +261 -0
  238. package/templates/docker/src/ui/components/chart/result-chart.tsx +375 -0
  239. package/templates/docker/src/ui/components/chat/api-key-bar.tsx +66 -0
  240. package/templates/docker/src/ui/components/chat/copy-button.tsx +25 -0
  241. package/templates/docker/src/ui/components/chat/data-table.tsx +102 -0
  242. package/templates/docker/src/ui/components/chat/error-banner.tsx +32 -0
  243. package/templates/docker/src/ui/components/chat/explore-card.tsx +41 -0
  244. package/templates/docker/src/ui/components/chat/loading-card.tsx +10 -0
  245. package/templates/docker/src/ui/components/chat/managed-auth-card.tsx +116 -0
  246. package/templates/docker/src/ui/components/chat/markdown.tsx +72 -0
  247. package/templates/docker/src/ui/components/chat/sql-block.tsx +30 -0
  248. package/templates/docker/src/ui/components/chat/sql-result-card.tsx +144 -0
  249. package/templates/docker/src/ui/components/chat/starter-prompts.ts +6 -0
  250. package/templates/docker/src/ui/components/chat/tool-part.tsx +40 -0
  251. package/templates/docker/src/ui/components/chat/typing-indicator.tsx +19 -0
  252. package/templates/docker/src/ui/components/conversations/conversation-item.tsx +120 -0
  253. package/templates/docker/src/ui/components/conversations/conversation-list.tsx +66 -0
  254. package/templates/docker/src/ui/components/conversations/conversation-sidebar.tsx +78 -0
  255. package/templates/docker/src/ui/components/conversations/delete-confirmation.tsx +27 -0
  256. package/templates/docker/src/ui/context.tsx +78 -0
  257. package/templates/docker/src/ui/hooks/use-admin-fetch.ts +104 -0
  258. package/templates/docker/src/ui/hooks/use-conversations.ts +184 -0
  259. package/templates/docker/src/ui/hooks/use-dark-mode.ts +17 -0
  260. package/templates/docker/src/ui/lib/action-types.ts +63 -0
  261. package/templates/docker/src/ui/lib/helpers.ts +104 -0
  262. package/templates/docker/src/ui/lib/types.ts +145 -0
  263. package/templates/docker/tsconfig.json +41 -0
  264. package/templates/docker/vercel.json +3 -0
  265. package/templates/nextjs-standalone/.env.example +68 -0
  266. package/templates/nextjs-standalone/bin/__tests__/benchmark.test.ts +598 -0
  267. package/templates/nextjs-standalone/bin/__tests__/duckdb-ingest.test.ts +171 -0
  268. package/templates/nextjs-standalone/bin/__tests__/eval.test.ts +434 -0
  269. package/templates/nextjs-standalone/bin/__tests__/matview-partition.test.ts +615 -0
  270. package/templates/nextjs-standalone/bin/__tests__/multi-source.test.ts +113 -0
  271. package/templates/nextjs-standalone/bin/__tests__/plugin-cli.test.ts +322 -0
  272. package/templates/nextjs-standalone/bin/__tests__/profiler-heuristics.test.ts +608 -0
  273. package/templates/nextjs-standalone/bin/__tests__/query.test.ts +240 -0
  274. package/templates/nextjs-standalone/bin/__tests__/schema-drift.test.ts +542 -0
  275. package/templates/nextjs-standalone/bin/__tests__/view-yaml-generation.test.ts +146 -0
  276. package/templates/nextjs-standalone/bin/atlas.ts +5044 -0
  277. package/templates/nextjs-standalone/bin/benchmark.ts +695 -0
  278. package/templates/nextjs-standalone/bin/enrich.ts +559 -0
  279. package/templates/nextjs-standalone/bin/eval.ts +770 -0
  280. package/templates/nextjs-standalone/bin/smoke.ts +438 -0
  281. package/templates/nextjs-standalone/data/.gitkeep +0 -0
  282. package/templates/nextjs-standalone/data/cybersec.sql +1961 -0
  283. package/templates/nextjs-standalone/data/demo-semantic/catalog.yml +40 -0
  284. package/templates/nextjs-standalone/data/demo-semantic/entities/accounts.yml +170 -0
  285. package/templates/nextjs-standalone/data/demo-semantic/entities/companies.yml +207 -0
  286. package/templates/nextjs-standalone/data/demo-semantic/entities/people.yml +145 -0
  287. package/templates/nextjs-standalone/data/demo-semantic/glossary.yml +22 -0
  288. package/templates/nextjs-standalone/data/demo-semantic/metrics/accounts.yml +38 -0
  289. package/templates/nextjs-standalone/data/demo-semantic/metrics/companies.yml +89 -0
  290. package/templates/nextjs-standalone/data/demo.sql +373 -0
  291. package/templates/nextjs-standalone/data/ecommerce.sql +1690 -0
  292. package/templates/nextjs-standalone/data/init-demo-db.sql +8 -0
  293. package/templates/nextjs-standalone/docs/deploy.md +390 -0
  294. package/templates/nextjs-standalone/eslint.config.mjs +18 -0
  295. package/templates/nextjs-standalone/gitignore +5 -0
  296. package/templates/nextjs-standalone/next.config.ts +10 -0
  297. package/templates/nextjs-standalone/package.json +63 -0
  298. package/templates/nextjs-standalone/postcss.config.mjs +8 -0
  299. package/templates/nextjs-standalone/semantic/catalog.yml +5 -0
  300. package/templates/nextjs-standalone/semantic/entities/.gitkeep +0 -0
  301. package/templates/nextjs-standalone/semantic/glossary.yml +6 -0
  302. package/templates/nextjs-standalone/semantic/metrics/.gitkeep +0 -0
  303. package/templates/nextjs-standalone/src/api/__tests__/actions.test.ts +683 -0
  304. package/templates/nextjs-standalone/src/api/__tests__/admin.test.ts +820 -0
  305. package/templates/nextjs-standalone/src/api/__tests__/auth.test.ts +165 -0
  306. package/templates/nextjs-standalone/src/api/__tests__/chat.test.ts +376 -0
  307. package/templates/nextjs-standalone/src/api/__tests__/conversations.test.ts +555 -0
  308. package/templates/nextjs-standalone/src/api/__tests__/cors.test.ts +135 -0
  309. package/templates/nextjs-standalone/src/api/__tests__/health-plugin.test.ts +169 -0
  310. package/templates/nextjs-standalone/src/api/__tests__/health.test.ts +261 -0
  311. package/templates/nextjs-standalone/src/api/__tests__/query.test.ts +891 -0
  312. package/templates/nextjs-standalone/src/api/__tests__/scheduled-tasks.test.ts +601 -0
  313. package/templates/nextjs-standalone/src/api/__tests__/slack.test.ts +847 -0
  314. package/templates/nextjs-standalone/src/api/index.ts +117 -0
  315. package/templates/nextjs-standalone/src/api/routes/actions.ts +274 -0
  316. package/templates/nextjs-standalone/src/api/routes/admin.ts +757 -0
  317. package/templates/nextjs-standalone/src/api/routes/auth.ts +48 -0
  318. package/templates/nextjs-standalone/src/api/routes/chat.ts +465 -0
  319. package/templates/nextjs-standalone/src/api/routes/conversations.ts +266 -0
  320. package/templates/nextjs-standalone/src/api/routes/health.ts +287 -0
  321. package/templates/nextjs-standalone/src/api/routes/openapi.ts +390 -0
  322. package/templates/nextjs-standalone/src/api/routes/query.ts +318 -0
  323. package/templates/nextjs-standalone/src/api/routes/scheduled-tasks.ts +467 -0
  324. package/templates/nextjs-standalone/src/api/routes/slack.ts +611 -0
  325. package/templates/nextjs-standalone/src/api/server.ts +226 -0
  326. package/templates/nextjs-standalone/src/app/api/[...route]/route.ts +33 -0
  327. package/templates/nextjs-standalone/src/app/error.tsx +24 -0
  328. package/templates/nextjs-standalone/src/app/global-error.tsx +68 -0
  329. package/templates/nextjs-standalone/src/app/globals.css +126 -0
  330. package/templates/nextjs-standalone/src/app/layout.tsx +19 -0
  331. package/templates/nextjs-standalone/src/app/page.tsx +14 -0
  332. package/templates/nextjs-standalone/src/lib/__tests__/agent-cache.test.ts +437 -0
  333. package/templates/nextjs-standalone/src/lib/__tests__/agent-dialect.test.ts +114 -0
  334. package/templates/nextjs-standalone/src/lib/__tests__/agent-health-annotations.test.ts +164 -0
  335. package/templates/nextjs-standalone/src/lib/__tests__/agent-integration.test.ts +514 -0
  336. package/templates/nextjs-standalone/src/lib/__tests__/config-actions.test.ts +166 -0
  337. package/templates/nextjs-standalone/src/lib/__tests__/config.test.ts +1063 -0
  338. package/templates/nextjs-standalone/src/lib/__tests__/conversations.test.ts +589 -0
  339. package/templates/nextjs-standalone/src/lib/__tests__/errors.test.ts +256 -0
  340. package/templates/nextjs-standalone/src/lib/__tests__/logger.test.ts +200 -0
  341. package/templates/nextjs-standalone/src/lib/__tests__/providers.test.ts +99 -0
  342. package/templates/nextjs-standalone/src/lib/__tests__/rls.test.ts +435 -0
  343. package/templates/nextjs-standalone/src/lib/__tests__/scheduled-task-types.test.ts +124 -0
  344. package/templates/nextjs-standalone/src/lib/__tests__/scheduled-tasks.test.ts +550 -0
  345. package/templates/nextjs-standalone/src/lib/__tests__/semantic-index.test.ts +547 -0
  346. package/templates/nextjs-standalone/src/lib/__tests__/semantic-multisource.test.ts +544 -0
  347. package/templates/nextjs-standalone/src/lib/__tests__/semantic.test.ts +363 -0
  348. package/templates/nextjs-standalone/src/lib/__tests__/startup-actions.test.ts +452 -0
  349. package/templates/nextjs-standalone/src/lib/__tests__/startup.test.ts +465 -0
  350. package/templates/nextjs-standalone/src/lib/__tests__/tracing.test.ts +28 -0
  351. package/templates/nextjs-standalone/src/lib/action-types.ts +95 -0
  352. package/templates/nextjs-standalone/src/lib/agent-query.ts +178 -0
  353. package/templates/nextjs-standalone/src/lib/agent.ts +505 -0
  354. package/templates/nextjs-standalone/src/lib/api-url.ts +3 -0
  355. package/templates/nextjs-standalone/src/lib/auth/__tests__/audit.test.ts +418 -0
  356. package/templates/nextjs-standalone/src/lib/auth/__tests__/byot-integration.test.ts +222 -0
  357. package/templates/nextjs-standalone/src/lib/auth/__tests__/byot.test.ts +366 -0
  358. package/templates/nextjs-standalone/src/lib/auth/__tests__/detect.test.ts +190 -0
  359. package/templates/nextjs-standalone/src/lib/auth/__tests__/managed.test.ts +173 -0
  360. package/templates/nextjs-standalone/src/lib/auth/__tests__/middleware.test.ts +456 -0
  361. package/templates/nextjs-standalone/src/lib/auth/__tests__/migrate.test.ts +201 -0
  362. package/templates/nextjs-standalone/src/lib/auth/__tests__/permissions.test.ts +225 -0
  363. package/templates/nextjs-standalone/src/lib/auth/__tests__/server.test.ts +34 -0
  364. package/templates/nextjs-standalone/src/lib/auth/__tests__/simple-key.test.ts +176 -0
  365. package/templates/nextjs-standalone/src/lib/auth/__tests__/types.test.ts +44 -0
  366. package/templates/nextjs-standalone/src/lib/auth/audit.ts +89 -0
  367. package/templates/nextjs-standalone/src/lib/auth/byot.ts +158 -0
  368. package/templates/nextjs-standalone/src/lib/auth/client.ts +23 -0
  369. package/templates/nextjs-standalone/src/lib/auth/detect.ts +83 -0
  370. package/templates/nextjs-standalone/src/lib/auth/managed.ts +73 -0
  371. package/templates/nextjs-standalone/src/lib/auth/middleware.ts +208 -0
  372. package/templates/nextjs-standalone/src/lib/auth/migrate.ts +111 -0
  373. package/templates/nextjs-standalone/src/lib/auth/permissions.ts +156 -0
  374. package/templates/nextjs-standalone/src/lib/auth/server.ts +142 -0
  375. package/templates/nextjs-standalone/src/lib/auth/simple-key.ts +92 -0
  376. package/templates/nextjs-standalone/src/lib/auth/types.ts +49 -0
  377. package/templates/nextjs-standalone/src/lib/config.ts +704 -0
  378. package/templates/nextjs-standalone/src/lib/conversation-types.ts +29 -0
  379. package/templates/nextjs-standalone/src/lib/conversations.ts +270 -0
  380. package/templates/nextjs-standalone/src/lib/db/__tests__/connection.test.ts +69 -0
  381. package/templates/nextjs-standalone/src/lib/db/__tests__/duckdb.test.ts +141 -0
  382. package/templates/nextjs-standalone/src/lib/db/__tests__/internal.test.ts +387 -0
  383. package/templates/nextjs-standalone/src/lib/db/__tests__/registry-health.test.ts +207 -0
  384. package/templates/nextjs-standalone/src/lib/db/__tests__/registry-pool-limits.test.ts +156 -0
  385. package/templates/nextjs-standalone/src/lib/db/__tests__/registry.test.ts +595 -0
  386. package/templates/nextjs-standalone/src/lib/db/__tests__/salesforce.test.ts +339 -0
  387. package/templates/nextjs-standalone/src/lib/db/__tests__/snowflake.test.ts +217 -0
  388. package/templates/nextjs-standalone/src/lib/db/__tests__/source-rate-limit.test.ts +130 -0
  389. package/templates/nextjs-standalone/src/lib/db/connection.ts +753 -0
  390. package/templates/nextjs-standalone/src/lib/db/duckdb.ts +122 -0
  391. package/templates/nextjs-standalone/src/lib/db/internal.ts +273 -0
  392. package/templates/nextjs-standalone/src/lib/db/salesforce.ts +342 -0
  393. package/templates/nextjs-standalone/src/lib/db/source-rate-limit.ts +191 -0
  394. package/templates/nextjs-standalone/src/lib/errors.ts +154 -0
  395. package/templates/nextjs-standalone/src/lib/logger.ts +98 -0
  396. package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks-integration.test.ts +202 -0
  397. package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks.test.ts +529 -0
  398. package/templates/nextjs-standalone/src/lib/plugins/__tests__/migrate.test.ts +521 -0
  399. package/templates/nextjs-standalone/src/lib/plugins/__tests__/registry.test.ts +346 -0
  400. package/templates/nextjs-standalone/src/lib/plugins/__tests__/tools.test.ts +49 -0
  401. package/templates/nextjs-standalone/src/lib/plugins/__tests__/wiring.test.ts +585 -0
  402. package/templates/nextjs-standalone/src/lib/plugins/hooks.ts +162 -0
  403. package/templates/nextjs-standalone/src/lib/plugins/index.ts +9 -0
  404. package/templates/nextjs-standalone/src/lib/plugins/migrate.ts +309 -0
  405. package/templates/nextjs-standalone/src/lib/plugins/registry.ts +231 -0
  406. package/templates/nextjs-standalone/src/lib/plugins/tools.ts +39 -0
  407. package/templates/nextjs-standalone/src/lib/plugins/wiring.ts +291 -0
  408. package/templates/nextjs-standalone/src/lib/providers.ts +102 -0
  409. package/templates/nextjs-standalone/src/lib/rls.ts +321 -0
  410. package/templates/nextjs-standalone/src/lib/scheduled-task-types.ts +132 -0
  411. package/templates/nextjs-standalone/src/lib/scheduled-tasks.ts +475 -0
  412. package/templates/nextjs-standalone/src/lib/scheduler/__tests__/delivery.test.ts +192 -0
  413. package/templates/nextjs-standalone/src/lib/scheduler/__tests__/engine.test.ts +248 -0
  414. package/templates/nextjs-standalone/src/lib/scheduler/__tests__/format-email.test.ts +96 -0
  415. package/templates/nextjs-standalone/src/lib/scheduler/__tests__/format-slack.test.ts +78 -0
  416. package/templates/nextjs-standalone/src/lib/scheduler/__tests__/format-webhook.test.ts +78 -0
  417. package/templates/nextjs-standalone/src/lib/scheduler/delivery.ts +248 -0
  418. package/templates/nextjs-standalone/src/lib/scheduler/engine.ts +317 -0
  419. package/templates/nextjs-standalone/src/lib/scheduler/executor.ts +73 -0
  420. package/templates/nextjs-standalone/src/lib/scheduler/format-email.ts +109 -0
  421. package/templates/nextjs-standalone/src/lib/scheduler/format-slack.ts +35 -0
  422. package/templates/nextjs-standalone/src/lib/scheduler/format-webhook.ts +37 -0
  423. package/templates/nextjs-standalone/src/lib/scheduler/index.ts +7 -0
  424. package/templates/nextjs-standalone/src/lib/security.ts +11 -0
  425. package/templates/nextjs-standalone/src/lib/semantic-index.ts +503 -0
  426. package/templates/nextjs-standalone/src/lib/semantic.ts +387 -0
  427. package/templates/nextjs-standalone/src/lib/sidecar-types.ts +16 -0
  428. package/templates/nextjs-standalone/src/lib/slack/__tests__/api.test.ts +160 -0
  429. package/templates/nextjs-standalone/src/lib/slack/__tests__/format.test.ts +237 -0
  430. package/templates/nextjs-standalone/src/lib/slack/__tests__/store.test.ts +188 -0
  431. package/templates/nextjs-standalone/src/lib/slack/__tests__/threads.test.ts +112 -0
  432. package/templates/nextjs-standalone/src/lib/slack/__tests__/verify.test.ts +111 -0
  433. package/templates/nextjs-standalone/src/lib/slack/api.ts +102 -0
  434. package/templates/nextjs-standalone/src/lib/slack/format.ts +209 -0
  435. package/templates/nextjs-standalone/src/lib/slack/store.ts +107 -0
  436. package/templates/nextjs-standalone/src/lib/slack/threads.ts +64 -0
  437. package/templates/nextjs-standalone/src/lib/slack/verify.ts +71 -0
  438. package/templates/nextjs-standalone/src/lib/startup.ts +730 -0
  439. package/templates/nextjs-standalone/src/lib/tools/__tests__/action-permissions.test.ts +594 -0
  440. package/templates/nextjs-standalone/src/lib/tools/__tests__/custom-validation.test.ts +238 -0
  441. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-backend.test.ts +267 -0
  442. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-nsjail.test.ts +492 -0
  443. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-plugin.test.ts +374 -0
  444. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sdk-compat.test.ts +82 -0
  445. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sidecar.test.ts +208 -0
  446. package/templates/nextjs-standalone/src/lib/tools/__tests__/registry-actions.test.ts +144 -0
  447. package/templates/nextjs-standalone/src/lib/tools/__tests__/registry.test.ts +235 -0
  448. package/templates/nextjs-standalone/src/lib/tools/__tests__/salesforce-tool.test.ts +154 -0
  449. package/templates/nextjs-standalone/src/lib/tools/__tests__/soql-validation.test.ts +303 -0
  450. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-audit.test.ts +225 -0
  451. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +98 -0
  452. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-duckdb.test.ts +233 -0
  453. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-ratelimit.test.ts +225 -0
  454. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql.test.ts +1012 -0
  455. package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/audit.test.ts +211 -0
  456. package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/email.test.ts +378 -0
  457. package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/handler.test.ts +681 -0
  458. package/templates/nextjs-standalone/src/lib/tools/actions/__tests__/jira.test.ts +427 -0
  459. package/templates/nextjs-standalone/src/lib/tools/actions/audit.ts +47 -0
  460. package/templates/nextjs-standalone/src/lib/tools/actions/email.ts +191 -0
  461. package/templates/nextjs-standalone/src/lib/tools/actions/handler.ts +591 -0
  462. package/templates/nextjs-standalone/src/lib/tools/actions/index.ts +23 -0
  463. package/templates/nextjs-standalone/src/lib/tools/actions/jira.ts +220 -0
  464. package/templates/nextjs-standalone/src/lib/tools/explore-nsjail.ts +343 -0
  465. package/templates/nextjs-standalone/src/lib/tools/explore-sandbox.ts +264 -0
  466. package/templates/nextjs-standalone/src/lib/tools/explore-sidecar.ts +163 -0
  467. package/templates/nextjs-standalone/src/lib/tools/explore.ts +379 -0
  468. package/templates/nextjs-standalone/src/lib/tools/registry.ts +221 -0
  469. package/templates/nextjs-standalone/src/lib/tools/salesforce.ts +138 -0
  470. package/templates/nextjs-standalone/src/lib/tools/soql-validation.ts +172 -0
  471. package/templates/nextjs-standalone/src/lib/tools/sql.ts +680 -0
  472. package/templates/nextjs-standalone/src/lib/tracing.ts +40 -0
  473. package/templates/nextjs-standalone/src/lib/utils.ts +6 -0
  474. package/templates/nextjs-standalone/src/test-setup.ts +38 -0
  475. package/templates/nextjs-standalone/src/ui/components/actions/action-approval-card.tsx +295 -0
  476. package/templates/nextjs-standalone/src/ui/components/actions/action-status-badge.tsx +50 -0
  477. package/templates/nextjs-standalone/src/ui/components/admin/admin-layout.tsx +26 -0
  478. package/templates/nextjs-standalone/src/ui/components/admin/admin-sidebar.tsx +96 -0
  479. package/templates/nextjs-standalone/src/ui/components/admin/empty-state.tsx +24 -0
  480. package/templates/nextjs-standalone/src/ui/components/admin/entity-detail.tsx +233 -0
  481. package/templates/nextjs-standalone/src/ui/components/admin/entity-list.tsx +96 -0
  482. package/templates/nextjs-standalone/src/ui/components/admin/error-banner.tsx +22 -0
  483. package/templates/nextjs-standalone/src/ui/components/admin/feature-disabled.tsx +44 -0
  484. package/templates/nextjs-standalone/src/ui/components/admin/health-badge.tsx +30 -0
  485. package/templates/nextjs-standalone/src/ui/components/admin/loading-state.tsx +14 -0
  486. package/templates/nextjs-standalone/src/ui/components/admin/stat-card.tsx +32 -0
  487. package/templates/nextjs-standalone/src/ui/components/atlas-chat.tsx +370 -0
  488. package/templates/nextjs-standalone/src/ui/components/chart/chart-detection.ts +261 -0
  489. package/templates/nextjs-standalone/src/ui/components/chart/result-chart.tsx +375 -0
  490. package/templates/nextjs-standalone/src/ui/components/chat/api-key-bar.tsx +66 -0
  491. package/templates/nextjs-standalone/src/ui/components/chat/copy-button.tsx +25 -0
  492. package/templates/nextjs-standalone/src/ui/components/chat/data-table.tsx +102 -0
  493. package/templates/nextjs-standalone/src/ui/components/chat/error-banner.tsx +32 -0
  494. package/templates/nextjs-standalone/src/ui/components/chat/explore-card.tsx +41 -0
  495. package/templates/nextjs-standalone/src/ui/components/chat/loading-card.tsx +10 -0
  496. package/templates/nextjs-standalone/src/ui/components/chat/managed-auth-card.tsx +116 -0
  497. package/templates/nextjs-standalone/src/ui/components/chat/markdown.tsx +72 -0
  498. package/templates/nextjs-standalone/src/ui/components/chat/sql-block.tsx +30 -0
  499. package/templates/nextjs-standalone/src/ui/components/chat/sql-result-card.tsx +144 -0
  500. package/templates/nextjs-standalone/src/ui/components/chat/starter-prompts.ts +6 -0
  501. package/templates/nextjs-standalone/src/ui/components/chat/tool-part.tsx +40 -0
  502. package/templates/nextjs-standalone/src/ui/components/chat/typing-indicator.tsx +19 -0
  503. package/templates/nextjs-standalone/src/ui/components/conversations/conversation-item.tsx +120 -0
  504. package/templates/nextjs-standalone/src/ui/components/conversations/conversation-list.tsx +66 -0
  505. package/templates/nextjs-standalone/src/ui/components/conversations/conversation-sidebar.tsx +78 -0
  506. package/templates/nextjs-standalone/src/ui/components/conversations/delete-confirmation.tsx +27 -0
  507. package/templates/nextjs-standalone/src/ui/context.tsx +78 -0
  508. package/templates/nextjs-standalone/src/ui/hooks/use-admin-fetch.ts +104 -0
  509. package/templates/nextjs-standalone/src/ui/hooks/use-conversations.ts +184 -0
  510. package/templates/nextjs-standalone/src/ui/hooks/use-dark-mode.ts +17 -0
  511. package/templates/nextjs-standalone/src/ui/lib/action-types.ts +63 -0
  512. package/templates/nextjs-standalone/src/ui/lib/helpers.ts +104 -0
  513. package/templates/nextjs-standalone/src/ui/lib/types.ts +145 -0
  514. package/templates/nextjs-standalone/tsconfig.json +32 -0
  515. package/templates/nextjs-standalone/vercel.json +4 -0
@@ -0,0 +1,465 @@
1
+ import { describe, it, expect, beforeEach, afterEach, mock, type Mock } from "bun:test";
2
+ import { resetAuthModeCache } from "@atlas/api/lib/auth/detect";
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Mock heavy I/O modules so validateEnvironment() skips DB/filesystem checks
6
+ // and we can focus on auth diagnostics.
7
+ // ---------------------------------------------------------------------------
8
+
9
+ // Mock fs — semantic layer check passes, container detection skipped
10
+ mock.module("fs", () => ({
11
+ existsSync: () => false,
12
+ readdirSync: () => ["orders.yml"],
13
+ }));
14
+
15
+ // Mock db/connection — avoid real DB imports
16
+ mock.module("@atlas/api/lib/db/connection", () => ({
17
+ detectDBType: () => "postgres",
18
+ }));
19
+
20
+ // Mock explore-nsjail — controllable sandbox capability check
21
+ let mockNsjailBinaryPath: string | null = null;
22
+ let mockCapabilityResult: { ok: boolean; error?: string } = { ok: true };
23
+
24
+ mock.module("@atlas/api/lib/tools/explore-nsjail", () => ({
25
+ findNsjailBinary: () => mockNsjailBinaryPath,
26
+ testNsjailCapabilities: async () => mockCapabilityResult,
27
+ isNsjailAvailable: () => mockNsjailBinaryPath !== null,
28
+ }));
29
+
30
+ // Mock explore — track markNsjailFailed and markSidecarFailed calls
31
+ let mockMarkNsjailFailedCalled = false;
32
+ let mockMarkSidecarFailedCalled = false;
33
+
34
+ mock.module("@atlas/api/lib/tools/explore", () => ({
35
+ markNsjailFailed: () => { mockMarkNsjailFailedCalled = true; },
36
+ markSidecarFailed: () => { mockMarkSidecarFailedCalled = true; },
37
+ getExploreBackendType: () => "just-bash",
38
+ getActiveSandboxPluginId: () => null,
39
+ invalidateExploreBackend: () => {},
40
+ }));
41
+
42
+ const { validateEnvironment, getStartupWarnings, resetStartupCache } =
43
+ await import("@atlas/api/lib/startup");
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Env snapshot — capture/restore only the vars this test touches
47
+ // ---------------------------------------------------------------------------
48
+
49
+ const MANAGED_VARS = [
50
+ "ATLAS_DATASOURCE_URL",
51
+ "DATABASE_URL",
52
+ "ATLAS_API_KEY",
53
+ "ATLAS_PROVIDER",
54
+ "BETTER_AUTH_SECRET",
55
+ "BETTER_AUTH_URL",
56
+ "BETTER_AUTH_TRUSTED_ORIGINS",
57
+ "ATLAS_AUTH_JWKS_URL",
58
+ "ATLAS_AUTH_ISSUER",
59
+ "ATLAS_AUTH_AUDIENCE",
60
+ "ATLAS_SANDBOX",
61
+ "ATLAS_SANDBOX_URL",
62
+ "ATLAS_RUNTIME",
63
+ "VERCEL",
64
+ ] as const;
65
+
66
+ const saved: Record<string, string | undefined> = {};
67
+
68
+ beforeEach(() => {
69
+ for (const key of MANAGED_VARS) {
70
+ saved[key] = process.env[key];
71
+ }
72
+ resetStartupCache();
73
+ resetAuthModeCache();
74
+
75
+ // Set the minimum env so the first 5 checks pass (datasource, API key,
76
+ // semantic layer, DB connectivity, internal DB). We only test auth checks.
77
+ // ATLAS_DATASOURCE_URL unset → just a warning, not an error
78
+ delete process.env.ATLAS_DATASOURCE_URL;
79
+ delete process.env.DATABASE_URL;
80
+ delete process.env.ATLAS_API_KEY;
81
+ delete process.env.BETTER_AUTH_SECRET;
82
+ delete process.env.BETTER_AUTH_URL;
83
+ delete process.env.BETTER_AUTH_TRUSTED_ORIGINS;
84
+ delete process.env.ATLAS_AUTH_JWKS_URL;
85
+ delete process.env.ATLAS_AUTH_ISSUER;
86
+ delete process.env.ATLAS_AUTH_AUDIENCE;
87
+ delete process.env.ATLAS_SANDBOX;
88
+ delete process.env.ATLAS_SANDBOX_URL;
89
+ delete process.env.ATLAS_RUNTIME;
90
+ delete process.env.VERCEL;
91
+ process.env.ATLAS_PROVIDER = "ollama"; // No API key required
92
+
93
+ // Reset sandbox mock defaults
94
+ mockNsjailBinaryPath = null;
95
+ mockCapabilityResult = { ok: true };
96
+ mockMarkNsjailFailedCalled = false;
97
+ mockMarkSidecarFailedCalled = false;
98
+ });
99
+
100
+ afterEach(() => {
101
+ for (const key of MANAGED_VARS) {
102
+ if (saved[key] !== undefined) process.env[key] = saved[key];
103
+ else delete process.env[key];
104
+ }
105
+ resetStartupCache();
106
+ resetAuthModeCache();
107
+ });
108
+
109
+ // ---------------------------------------------------------------------------
110
+ // Auth mode: none — no auth-specific diagnostics
111
+ // ---------------------------------------------------------------------------
112
+
113
+ describe("auth diagnostics — mode none", () => {
114
+ it("produces no auth errors when no auth env vars are set", async () => {
115
+ delete process.env.ATLAS_API_KEY;
116
+ delete process.env.BETTER_AUTH_SECRET;
117
+ delete process.env.ATLAS_AUTH_JWKS_URL;
118
+ delete process.env.ATLAS_AUTH_ISSUER;
119
+
120
+ const errors = await validateEnvironment();
121
+ const authCodes = errors
122
+ .map((e) => e.code)
123
+ .filter((c) =>
124
+ ["WEAK_AUTH_SECRET", "INVALID_JWKS_URL", "MISSING_AUTH_ISSUER"].includes(c),
125
+ );
126
+ expect(authCodes).toEqual([]);
127
+ });
128
+ });
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // Auth mode: simple-key — no auth-specific diagnostics
132
+ // ---------------------------------------------------------------------------
133
+
134
+ describe("auth diagnostics — mode simple-key", () => {
135
+ it("produces no auth errors when ATLAS_API_KEY is set", async () => {
136
+ process.env.ATLAS_API_KEY = "test-key-123";
137
+
138
+ const errors = await validateEnvironment();
139
+ const authCodes = errors
140
+ .map((e) => e.code)
141
+ .filter((c) =>
142
+ ["WEAK_AUTH_SECRET", "INVALID_JWKS_URL", "MISSING_AUTH_ISSUER"].includes(c),
143
+ );
144
+ expect(authCodes).toEqual([]);
145
+ });
146
+ });
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Auth mode: managed — BETTER_AUTH_SECRET checks
150
+ // ---------------------------------------------------------------------------
151
+
152
+ describe("auth diagnostics — mode managed", () => {
153
+ beforeEach(() => {
154
+ delete process.env.ATLAS_API_KEY;
155
+ delete process.env.ATLAS_AUTH_JWKS_URL;
156
+ delete process.env.ATLAS_AUTH_ISSUER;
157
+ });
158
+
159
+ it("reports WEAK_AUTH_SECRET when secret is shorter than 32 chars", async () => {
160
+ process.env.BETTER_AUTH_SECRET = "too-short";
161
+
162
+ const errors = await validateEnvironment();
163
+ const weak = errors.find((e) => e.code === "WEAK_AUTH_SECRET");
164
+ expect(weak).toBeDefined();
165
+ expect(weak!.message).toContain("32 characters");
166
+ });
167
+
168
+ it("reports WEAK_AUTH_SECRET when secret is exactly 31 chars", async () => {
169
+ process.env.BETTER_AUTH_SECRET = "a".repeat(31);
170
+
171
+ const errors = await validateEnvironment();
172
+ expect(errors.some((e) => e.code === "WEAK_AUTH_SECRET")).toBe(true);
173
+ });
174
+
175
+ it("no WEAK_AUTH_SECRET when secret is exactly 32 chars", async () => {
176
+ process.env.BETTER_AUTH_SECRET = "a".repeat(32);
177
+
178
+ const errors = await validateEnvironment();
179
+ expect(errors.some((e) => e.code === "WEAK_AUTH_SECRET")).toBe(false);
180
+ });
181
+
182
+ it("no WEAK_AUTH_SECRET when secret is longer than 32 chars", async () => {
183
+ process.env.BETTER_AUTH_SECRET = "a".repeat(64);
184
+
185
+ const errors = await validateEnvironment();
186
+ expect(errors.some((e) => e.code === "WEAK_AUTH_SECRET")).toBe(false);
187
+ });
188
+
189
+ it("adds MISSING_AUTH_URL warning when BETTER_AUTH_URL not set", async () => {
190
+ process.env.BETTER_AUTH_SECRET = "a".repeat(32);
191
+ delete process.env.BETTER_AUTH_URL;
192
+
193
+ await validateEnvironment();
194
+ const warnings = getStartupWarnings();
195
+ expect(warnings.some((w) => w.includes("BETTER_AUTH_URL"))).toBe(true);
196
+ });
197
+
198
+ it("no MISSING_AUTH_URL warning when BETTER_AUTH_URL is set", async () => {
199
+ process.env.BETTER_AUTH_SECRET = "a".repeat(32);
200
+ process.env.BETTER_AUTH_URL = "https://atlas.example.com";
201
+
202
+ await validateEnvironment();
203
+ const warnings = getStartupWarnings();
204
+ expect(warnings.some((w) => w.includes("BETTER_AUTH_URL"))).toBe(false);
205
+ });
206
+
207
+ it("reports INTERNAL_DB_UNREACHABLE when DATABASE_URL is not set", async () => {
208
+ process.env.BETTER_AUTH_SECRET = "a".repeat(32);
209
+ delete process.env.DATABASE_URL;
210
+
211
+ const errors = await validateEnvironment();
212
+ const dbErr = errors.find((e) => e.code === "INTERNAL_DB_UNREACHABLE");
213
+ expect(dbErr).toBeDefined();
214
+ expect(dbErr!.message).toContain("session storage");
215
+ });
216
+ });
217
+
218
+ // ---------------------------------------------------------------------------
219
+ // Auth mode: byot — JWKS + issuer checks
220
+ // ---------------------------------------------------------------------------
221
+
222
+ describe("auth diagnostics — mode byot", () => {
223
+ beforeEach(() => {
224
+ delete process.env.ATLAS_API_KEY;
225
+ delete process.env.BETTER_AUTH_SECRET;
226
+ });
227
+
228
+ it("reports INVALID_JWKS_URL when URL is not valid", async () => {
229
+ process.env.ATLAS_AUTH_JWKS_URL = "not-a-url";
230
+ process.env.ATLAS_AUTH_ISSUER = "https://idp.example.com/";
231
+
232
+ const errors = await validateEnvironment();
233
+ const invalid = errors.find((e) => e.code === "INVALID_JWKS_URL");
234
+ expect(invalid).toBeDefined();
235
+ expect(invalid!.message).toContain("not a valid URL");
236
+ });
237
+
238
+ it("no INVALID_JWKS_URL when URL is valid", async () => {
239
+ process.env.ATLAS_AUTH_JWKS_URL = "https://idp.example.com/.well-known/jwks.json";
240
+ process.env.ATLAS_AUTH_ISSUER = "https://idp.example.com/";
241
+
242
+ const errors = await validateEnvironment();
243
+ expect(errors.some((e) => e.code === "INVALID_JWKS_URL")).toBe(false);
244
+ });
245
+
246
+ it("reports MISSING_AUTH_ISSUER when ATLAS_AUTH_ISSUER not set", async () => {
247
+ process.env.ATLAS_AUTH_JWKS_URL = "https://idp.example.com/.well-known/jwks.json";
248
+ delete process.env.ATLAS_AUTH_ISSUER;
249
+
250
+ const errors = await validateEnvironment();
251
+ const missing = errors.find((e) => e.code === "MISSING_AUTH_ISSUER");
252
+ expect(missing).toBeDefined();
253
+ expect(missing!.message).toContain("ATLAS_AUTH_ISSUER");
254
+ });
255
+
256
+ it("no MISSING_AUTH_ISSUER when ATLAS_AUTH_ISSUER is set", async () => {
257
+ process.env.ATLAS_AUTH_JWKS_URL = "https://idp.example.com/.well-known/jwks.json";
258
+ process.env.ATLAS_AUTH_ISSUER = "https://idp.example.com/";
259
+
260
+ const errors = await validateEnvironment();
261
+ expect(errors.some((e) => e.code === "MISSING_AUTH_ISSUER")).toBe(false);
262
+ });
263
+
264
+ it("reports both INVALID_JWKS_URL and MISSING_AUTH_ISSUER when both are wrong", async () => {
265
+ process.env.ATLAS_AUTH_JWKS_URL = "not-a-url";
266
+ delete process.env.ATLAS_AUTH_ISSUER;
267
+
268
+ const errors = await validateEnvironment();
269
+ const codes = errors.map((e) => e.code);
270
+ expect(codes).toContain("INVALID_JWKS_URL");
271
+ expect(codes).toContain("MISSING_AUTH_ISSUER");
272
+ });
273
+ });
274
+
275
+ // ---------------------------------------------------------------------------
276
+ // Orphaned auth env var warnings
277
+ // ---------------------------------------------------------------------------
278
+
279
+ describe("auth diagnostics — orphaned env var warnings", () => {
280
+ beforeEach(() => {
281
+ delete process.env.ATLAS_API_KEY;
282
+ delete process.env.BETTER_AUTH_SECRET;
283
+ delete process.env.ATLAS_AUTH_JWKS_URL;
284
+ delete process.env.ATLAS_AUTH_ISSUER;
285
+ delete process.env.BETTER_AUTH_URL;
286
+ delete process.env.BETTER_AUTH_TRUSTED_ORIGINS;
287
+ });
288
+
289
+ it("warns about orphaned ATLAS_AUTH_ISSUER when BYOT not active", async () => {
290
+ process.env.ATLAS_AUTH_ISSUER = "https://idp.example.com/";
291
+ // ATLAS_AUTH_JWKS_URL not set → auth mode is "none", not "byot"
292
+
293
+ await validateEnvironment();
294
+ const warnings = getStartupWarnings();
295
+ expect(warnings.some((w) => w.includes("BYOT auth mode is not active"))).toBe(true);
296
+ });
297
+
298
+ it("warns about orphaned BETTER_AUTH_URL when managed not active", async () => {
299
+ process.env.BETTER_AUTH_URL = "https://atlas.example.com";
300
+ // BETTER_AUTH_SECRET not set → auth mode is "none", not "managed"
301
+
302
+ await validateEnvironment();
303
+ const warnings = getStartupWarnings();
304
+ expect(warnings.some((w) => w.includes("managed auth mode is not active"))).toBe(true);
305
+ });
306
+ });
307
+
308
+ // ---------------------------------------------------------------------------
309
+ // Sandbox pre-flight diagnostics
310
+ // ---------------------------------------------------------------------------
311
+
312
+ describe("sandbox diagnostics", () => {
313
+ beforeEach(() => {
314
+ delete process.env.ATLAS_SANDBOX;
315
+ delete process.env.ATLAS_RUNTIME;
316
+ delete process.env.VERCEL;
317
+ });
318
+
319
+ it("no sandbox warning when nsjail found and capabilities pass", async () => {
320
+ mockNsjailBinaryPath = "/usr/local/bin/nsjail";
321
+ mockCapabilityResult = { ok: true };
322
+
323
+ await validateEnvironment();
324
+ const warnings = getStartupWarnings();
325
+ expect(warnings.some((w) => w.includes("nsjail"))).toBe(false);
326
+ expect(warnings.some((w) => w.includes("just-bash"))).toBe(false);
327
+ expect(mockMarkNsjailFailedCalled).toBe(false);
328
+ });
329
+
330
+ it("warns when nsjail available but capabilities fail (auto-detected)", async () => {
331
+ mockNsjailBinaryPath = "/usr/local/bin/nsjail";
332
+ mockCapabilityResult = { ok: false, error: "clone failed: EPERM" };
333
+
334
+ await validateEnvironment();
335
+ const warnings = getStartupWarnings();
336
+ expect(
337
+ warnings.some((w) => w.includes("namespace creation failed") && w.includes("falling back to just-bash")),
338
+ ).toBe(true);
339
+ expect(mockMarkNsjailFailedCalled).toBe(true);
340
+ });
341
+
342
+ it("warns with explicit message when ATLAS_SANDBOX=nsjail and capabilities fail", async () => {
343
+ process.env.ATLAS_SANDBOX = "nsjail";
344
+ mockNsjailBinaryPath = "/usr/local/bin/nsjail";
345
+ mockCapabilityResult = { ok: false, error: "clone failed: EPERM" };
346
+
347
+ await validateEnvironment();
348
+ const warnings = getStartupWarnings();
349
+ expect(
350
+ warnings.some((w) => w.includes("nsjail explicitly requested") && w.includes("ATLAS_SANDBOX=")),
351
+ ).toBe(true);
352
+ expect(mockMarkNsjailFailedCalled).toBe(true);
353
+ });
354
+
355
+ it("warns when ATLAS_SANDBOX=nsjail but binary not found", async () => {
356
+ process.env.ATLAS_SANDBOX = "nsjail";
357
+ mockNsjailBinaryPath = null;
358
+
359
+ await validateEnvironment();
360
+ const warnings = getStartupWarnings();
361
+ expect(
362
+ warnings.some((w) => w.includes("nsjail binary was not found")),
363
+ ).toBe(true);
364
+ });
365
+
366
+ it("no sandbox warning on Vercel runtime", async () => {
367
+ process.env.VERCEL = "1";
368
+ mockNsjailBinaryPath = null; // no nsjail on Vercel
369
+
370
+ await validateEnvironment();
371
+ const warnings = getStartupWarnings();
372
+ expect(warnings.some((w) => w.includes("nsjail"))).toBe(false);
373
+ expect(warnings.some((w) => w.includes("just-bash"))).toBe(false);
374
+ });
375
+ });
376
+
377
+ // ---------------------------------------------------------------------------
378
+ // Sidecar diagnostics
379
+ // ---------------------------------------------------------------------------
380
+
381
+ describe("sidecar diagnostics", () => {
382
+ const originalFetch = globalThis.fetch;
383
+ let mockFetch: Mock<typeof globalThis.fetch>;
384
+
385
+ beforeEach(() => {
386
+ delete process.env.ATLAS_SANDBOX;
387
+ delete process.env.ATLAS_SANDBOX_URL;
388
+ delete process.env.ATLAS_RUNTIME;
389
+ delete process.env.VERCEL;
390
+ // nsjail not available — sidecar path is reachable
391
+ mockNsjailBinaryPath = null;
392
+
393
+ mockFetch = mock() as unknown as Mock<typeof globalThis.fetch>;
394
+ globalThis.fetch = mockFetch as unknown as typeof globalThis.fetch;
395
+ });
396
+
397
+ afterEach(() => {
398
+ globalThis.fetch = originalFetch;
399
+ });
400
+
401
+ it("no sidecar warning when ATLAS_SANDBOX_URL set and sidecar healthy", async () => {
402
+ process.env.ATLAS_SANDBOX_URL = "http://sandbox-sidecar:8080";
403
+ mockFetch.mockResolvedValue(
404
+ new Response(JSON.stringify({ status: "ok" }), { status: 200 }),
405
+ );
406
+
407
+ await validateEnvironment();
408
+ const warnings = getStartupWarnings();
409
+ expect(warnings.some((w) => w.includes("Sidecar"))).toBe(false);
410
+ expect(mockMarkSidecarFailedCalled).toBe(false);
411
+ });
412
+
413
+ it("warns when ATLAS_SANDBOX_URL set and sidecar returns HTTP 500", async () => {
414
+ process.env.ATLAS_SANDBOX_URL = "http://sandbox-sidecar:8080";
415
+ mockFetch.mockResolvedValue(
416
+ new Response("Internal Server Error", { status: 500 }),
417
+ );
418
+
419
+ await validateEnvironment();
420
+ const warnings = getStartupWarnings();
421
+ expect(
422
+ warnings.some((w) => w.includes("Sidecar health check returned HTTP 500")),
423
+ ).toBe(true);
424
+ expect(mockMarkSidecarFailedCalled).toBe(true);
425
+ });
426
+
427
+ it("warns when ATLAS_SANDBOX_URL set and sidecar unreachable", async () => {
428
+ process.env.ATLAS_SANDBOX_URL = "http://sandbox-sidecar:8080";
429
+ mockFetch.mockRejectedValue(new Error("connect ECONNREFUSED 127.0.0.1:8080"));
430
+
431
+ await validateEnvironment();
432
+ const warnings = getStartupWarnings();
433
+ expect(
434
+ warnings.some((w) => w.includes("Sidecar unreachable") && w.includes("ECONNREFUSED")),
435
+ ).toBe(true);
436
+ expect(mockMarkSidecarFailedCalled).toBe(true);
437
+ });
438
+
439
+ it("skips nsjail probe when ATLAS_SANDBOX_URL is set (no namespace warnings)", async () => {
440
+ process.env.ATLAS_SANDBOX_URL = "http://sandbox-sidecar:8080";
441
+ // nsjail binary is "available" — but should never be probed
442
+ mockNsjailBinaryPath = "/usr/local/bin/nsjail";
443
+ mockCapabilityResult = { ok: false, error: "clone failed: EPERM" };
444
+ mockFetch.mockResolvedValue(
445
+ new Response(JSON.stringify({ status: "ok" }), { status: 200 }),
446
+ );
447
+
448
+ await validateEnvironment();
449
+ const warnings = getStartupWarnings();
450
+ // No nsjail warnings — sidecar path was taken, nsjail was never probed
451
+ expect(warnings.some((w) => w.includes("nsjail"))).toBe(false);
452
+ expect(warnings.some((w) => w.includes("namespace"))).toBe(false);
453
+ expect(mockMarkNsjailFailedCalled).toBe(false);
454
+ expect(mockMarkSidecarFailedCalled).toBe(false);
455
+ });
456
+
457
+ it("does not attempt sidecar health check when ATLAS_SANDBOX_URL not set", async () => {
458
+ delete process.env.ATLAS_SANDBOX_URL;
459
+
460
+ await validateEnvironment();
461
+ // fetch should not have been called for a sidecar health check
462
+ expect(mockFetch).not.toHaveBeenCalled();
463
+ expect(mockMarkSidecarFailedCalled).toBe(false);
464
+ });
465
+ });
@@ -0,0 +1,28 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { withSpan } from "../tracing";
3
+
4
+ describe("tracing", () => {
5
+ test("withSpan runs fn and returns result when OTel not initialized", async () => {
6
+ const result = await withSpan("test.span", { key: "value" }, async () => {
7
+ return 42;
8
+ });
9
+ expect(result).toBe(42);
10
+ });
11
+
12
+ test("withSpan propagates thrown errors", async () => {
13
+ const error = new Error("test error");
14
+ await expect(
15
+ withSpan("test.error", {}, async () => {
16
+ throw error;
17
+ }),
18
+ ).rejects.toThrow("test error");
19
+ });
20
+
21
+ test("withSpan works with async functions", async () => {
22
+ const result = await withSpan("test.async", {}, async () => {
23
+ await new Promise((resolve) => setTimeout(resolve, 1));
24
+ return "async-result";
25
+ });
26
+ expect(result).toBe("async-result");
27
+ });
28
+ });
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Action types for Atlas.
3
+ *
4
+ * ActionApprovalMode determines how an action request is handled.
5
+ * ActionStatus tracks the lifecycle of an action request.
6
+ * ActionRequest and ActionToolResult provide the tool-level interface.
7
+ * AtlasAction extends the structural tool interface with action metadata.
8
+ * ActionLogEntry represents the persisted audit row.
9
+ */
10
+
11
+ export const ACTION_APPROVAL_MODES = ["auto", "manual", "admin-only"] as const;
12
+ export type ActionApprovalMode = (typeof ACTION_APPROVAL_MODES)[number];
13
+
14
+ export const ACTION_STATUSES = [
15
+ "pending",
16
+ "approved",
17
+ "denied",
18
+ "executed",
19
+ "failed",
20
+ "timed_out", // Reserved — not yet implemented
21
+ "auto_approved",
22
+ ] as const;
23
+ export type ActionStatus = (typeof ACTION_STATUSES)[number];
24
+
25
+ /** Describes the action the agent wants to perform. */
26
+ export interface ActionRequest {
27
+ id: string;
28
+ actionType: string;
29
+ target: string;
30
+ summary: string;
31
+ payload: Record<string, unknown>;
32
+ reversible: boolean;
33
+ }
34
+
35
+ /** Information needed to undo an executed action. */
36
+ export interface RollbackInfo {
37
+ method: string;
38
+ params: Record<string, unknown>;
39
+ }
40
+
41
+ /** Discriminated union returned by action tools to the agent loop. */
42
+ export type ActionToolResult =
43
+ | { status: "pending_approval"; actionId: string; summary: string }
44
+ | { status: "executed"; actionId: string; result: unknown }
45
+ | { status: "denied"; actionId: string; reason?: string }
46
+ | { status: "auto_approved"; actionId: string; result: unknown }
47
+ | { status: "error"; actionId?: string; error: string };
48
+
49
+ /**
50
+ * Structural superset of AtlasTool with action-specific metadata.
51
+ *
52
+ * Uses `tool: unknown` because action-types cannot import `ToolSet`
53
+ * from the `ai` package. Structural typing ensures compatibility when
54
+ * registered in ToolRegistry.
55
+ */
56
+ export interface AtlasAction {
57
+ readonly name: string;
58
+ readonly description: string;
59
+ readonly tool: unknown;
60
+ readonly actionType: string;
61
+ readonly reversible: boolean;
62
+ readonly defaultApproval: ActionApprovalMode;
63
+ readonly requiredCredentials: string[];
64
+ }
65
+
66
+ /** Type guard: returns true if the tool has action metadata. */
67
+ export function isAction(tool: { readonly name: string }): tool is AtlasAction {
68
+ return (
69
+ "actionType" in tool &&
70
+ "reversible" in tool &&
71
+ "defaultApproval" in tool &&
72
+ "requiredCredentials" in tool
73
+ );
74
+ }
75
+
76
+ /** Database row shape for the action_log table. */
77
+ export interface ActionLogEntry {
78
+ id: string;
79
+ requested_at: string;
80
+ resolved_at: string | null;
81
+ executed_at: string | null;
82
+ requested_by: string | null;
83
+ approved_by: string | null;
84
+ auth_mode: string;
85
+ action_type: string;
86
+ target: string;
87
+ summary: string;
88
+ payload: Record<string, unknown>;
89
+ status: ActionStatus;
90
+ result: unknown;
91
+ error: string | null;
92
+ rollback_info: RollbackInfo | null;
93
+ conversation_id: string | null;
94
+ request_id: string | null;
95
+ }