@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,40 @@
1
+ /**
2
+ * Lightweight tracing helper.
3
+ *
4
+ * Wraps async functions in OpenTelemetry spans. When the OTel SDK is not
5
+ * initialized (no OTEL_EXPORTER_OTLP_ENDPOINT), @opentelemetry/api returns
6
+ * a no-op tracer — zero overhead, no conditional imports needed.
7
+ */
8
+
9
+ import { trace, SpanStatusCode, type Attributes } from "@opentelemetry/api";
10
+
11
+ const tracer = trace.getTracer("atlas");
12
+
13
+ /**
14
+ * Execute `fn` inside an OTel span. Sets span status and records exceptions
15
+ * on failure. When OTel is not initialized the span is a no-op.
16
+ */
17
+ export async function withSpan<T>(
18
+ name: string,
19
+ attributes: Attributes,
20
+ fn: () => Promise<T>,
21
+ ): Promise<T> {
22
+ return tracer.startActiveSpan(name, { attributes }, async (span) => {
23
+ try {
24
+ const result = await fn();
25
+ span.setStatus({ code: SpanStatusCode.OK });
26
+ return result;
27
+ } catch (err) {
28
+ span.setStatus({
29
+ code: SpanStatusCode.ERROR,
30
+ message: err instanceof Error ? err.message : String(err),
31
+ });
32
+ span.recordException(
33
+ err instanceof Error ? err : new Error(String(err)),
34
+ );
35
+ throw err;
36
+ } finally {
37
+ span.end();
38
+ }
39
+ });
40
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Global test preload — strips ATLAS_*, BETTER_AUTH_*, DATABASE_URL, and
3
+ * provider API keys (ANTHROPIC_API_KEY, etc.) before any test file loads,
4
+ * preventing the developer's real .env from leaking into tests.
5
+ *
6
+ * Individual tests set the vars they need in beforeEach; this preload ensures a
7
+ * clean baseline. Original values are restored in a top-level afterAll so the
8
+ * process isn't permanently modified.
9
+ */
10
+
11
+ import { afterAll } from "bun:test";
12
+
13
+ const prefixes = ["ATLAS_", "BETTER_AUTH_"];
14
+ const exactVars = [
15
+ "DATABASE_URL",
16
+ "ANTHROPIC_API_KEY",
17
+ "OPENAI_API_KEY",
18
+ "AWS_ACCESS_KEY_ID",
19
+ "AWS_SECRET_ACCESS_KEY",
20
+ "AWS_SESSION_TOKEN",
21
+ ];
22
+
23
+ // Snapshot current values so we can restore them after the entire suite
24
+ const snapshot: Record<string, string> = {};
25
+
26
+ for (const key of Object.keys(process.env)) {
27
+ if (prefixes.some((p) => key.startsWith(p)) || exactVars.includes(key)) {
28
+ snapshot[key] = process.env[key]!;
29
+ delete process.env[key];
30
+ }
31
+ }
32
+
33
+ afterAll(() => {
34
+ // Restore snapshotted vars
35
+ for (const [key, value] of Object.entries(snapshot)) {
36
+ process.env[key] = value;
37
+ }
38
+ });
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Minimal type declarations for @vercel/sandbox ^1.x (optional dependency).
3
+ * These declarations provide type safety on environments where the optional
4
+ * package is not installed (e.g., self-hosted Docker deployments).
5
+ * When @vercel/sandbox is installed, its own types take precedence.
6
+ *
7
+ * Last synced with: @vercel/sandbox@1.x SDK reference
8
+ */
9
+ declare module "@vercel/sandbox" {
10
+ interface SandboxCreateOptions {
11
+ runtime?: string;
12
+ /**
13
+ * Network policy for the sandbox. Atlas MUST use "deny-all"
14
+ * to prevent the explore tool from making network requests.
15
+ * Actual SDK also accepts an object form for fine-grained rules.
16
+ */
17
+ networkPolicy?: "deny-all" | "allow-all" | (string & {});
18
+ ports?: number[];
19
+ timeout?: number;
20
+ }
21
+
22
+ interface WriteFileEntry {
23
+ path: string;
24
+ content: Buffer;
25
+ }
26
+
27
+ interface RunCommandParams {
28
+ cmd: string;
29
+ args?: string[];
30
+ cwd?: string;
31
+ env?: Record<string, string>;
32
+ sudo?: boolean;
33
+ }
34
+
35
+ /** Subset of actual CommandFinished class — see SDK docs for full API. */
36
+ interface CommandFinished {
37
+ exitCode: number;
38
+ stdout(): Promise<string>;
39
+ stderr(): Promise<string>;
40
+ }
41
+
42
+ class Sandbox {
43
+ static create(opts?: SandboxCreateOptions): Promise<Sandbox>;
44
+ mkDir(path: string): Promise<void>;
45
+ writeFiles(files: WriteFileEntry[]): Promise<void>;
46
+ runCommand(params: RunCommandParams): Promise<CommandFinished>;
47
+ runCommand(
48
+ command: string,
49
+ args?: string[],
50
+ opts?: { signal?: AbortSignal }
51
+ ): Promise<CommandFinished>;
52
+ stop(): Promise<Sandbox>;
53
+ }
54
+ }
@@ -0,0 +1,295 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { getToolArgs, getToolResult, isToolComplete } from "../../lib/helpers";
5
+ import {
6
+ isActionToolResult,
7
+ RESOLVED_STATUSES,
8
+ type ActionStatus,
9
+ type ResolvedStatus,
10
+ type ActionApprovalResponse,
11
+ type ActionToolResultShape,
12
+ } from "../../lib/action-types";
13
+ import { useAtlasConfig } from "../../context";
14
+ import { useActionAuth } from "../../context";
15
+ import { LoadingCard } from "../chat/loading-card";
16
+ import { ActionStatusBadge } from "./action-status-badge";
17
+
18
+ /* ------------------------------------------------------------------ */
19
+ /* Safe JSON.stringify helper */
20
+ /* ------------------------------------------------------------------ */
21
+
22
+ function safeStringify(value: unknown): string {
23
+ try {
24
+ return JSON.stringify(value, null, 2);
25
+ } catch {
26
+ return "[Unable to display]";
27
+ }
28
+ }
29
+
30
+ /* ------------------------------------------------------------------ */
31
+ /* Card state machine */
32
+ /* ------------------------------------------------------------------ */
33
+
34
+ type CardState =
35
+ | { phase: "idle" }
36
+ | { phase: "submitting"; action: "approve" | "deny" }
37
+ | { phase: "resolved"; status: ResolvedStatus; result?: unknown }
38
+ | { phase: "error"; message: string };
39
+
40
+ /* ------------------------------------------------------------------ */
41
+ /* Border color by status */
42
+ /* ------------------------------------------------------------------ */
43
+
44
+ function borderColor(status: ActionStatus): string {
45
+ switch (status) {
46
+ case "pending_approval":
47
+ return "border-yellow-300 dark:border-yellow-900/50";
48
+ case "approved":
49
+ case "executed":
50
+ case "auto_approved":
51
+ return "border-green-300 dark:border-green-900/50";
52
+ case "denied":
53
+ case "failed":
54
+ return "border-red-300 dark:border-red-900/50";
55
+ default:
56
+ return "border-zinc-200 dark:border-zinc-700";
57
+ }
58
+ }
59
+
60
+ /* ------------------------------------------------------------------ */
61
+ /* Component */
62
+ /* ------------------------------------------------------------------ */
63
+
64
+ export function ActionApprovalCard({ part }: { part: unknown }) {
65
+ const { apiUrl } = useAtlasConfig();
66
+ const actionAuth = useActionAuth();
67
+ const args = getToolArgs(part);
68
+ const rawResult = getToolResult(part);
69
+ const done = isToolComplete(part);
70
+
71
+ const [cardState, setCardState] = useState<CardState>({ phase: "idle" });
72
+ const [open, setOpen] = useState(false);
73
+ const [denyReason, setDenyReason] = useState("");
74
+ const [showDenyInput, setShowDenyInput] = useState(false);
75
+
76
+ if (!done) return <LoadingCard label="Requesting action approval..." />;
77
+
78
+ if (!isActionToolResult(rawResult)) {
79
+ return (
80
+ <div className="my-2 rounded-lg border border-yellow-300 bg-yellow-50 px-3 py-2 text-xs text-yellow-700 dark:border-yellow-900/50 dark:bg-yellow-950/20 dark:text-yellow-400">
81
+ Action result (unexpected format)
82
+ </div>
83
+ );
84
+ }
85
+
86
+ const toolResult: ActionToolResultShape = rawResult;
87
+
88
+ // Effective status: local optimistic update wins over server result
89
+ const effectiveStatus: ActionStatus =
90
+ cardState.phase === "resolved" ? cardState.status : toolResult.status;
91
+
92
+ const isPending = effectiveStatus === "pending_approval" && cardState.phase !== "submitting";
93
+ const isSubmitting = cardState.phase === "submitting";
94
+ const resolvedResult = cardState.phase === "resolved" ? cardState.result : toolResult.result;
95
+
96
+ /* ---------------------------------------------------------------- */
97
+ /* API helpers */
98
+ /* ---------------------------------------------------------------- */
99
+
100
+ async function callAction(endpoint: "approve" | "deny", body?: Record<string, unknown>) {
101
+ if (!actionAuth) {
102
+ console.warn("ActionApprovalCard: No ActionAuthProvider found. API calls will be sent without authentication.");
103
+ }
104
+
105
+ const headers: Record<string, string> = {
106
+ "Content-Type": "application/json",
107
+ ...(actionAuth?.getHeaders() ?? {}),
108
+ };
109
+ const credentials = actionAuth?.getCredentials() ?? "same-origin";
110
+
111
+ const res = await fetch(
112
+ `${apiUrl}/api/v1/actions/${toolResult.actionId}/${endpoint}`,
113
+ {
114
+ method: "POST",
115
+ headers,
116
+ credentials,
117
+ body: body ? JSON.stringify(body) : undefined,
118
+ },
119
+ );
120
+
121
+ if (res.status === 409) {
122
+ // Already resolved — read current status from response
123
+ let data: ActionApprovalResponse;
124
+ try {
125
+ data = (await res.json()) as ActionApprovalResponse;
126
+ } catch {
127
+ throw new Error("Action was already resolved, but the response could not be read. Refresh the page.");
128
+ }
129
+ const status = typeof data.status === "string" ? data.status as ResolvedStatus : "failed" as ResolvedStatus;
130
+ const label = status.replace(/_/g, " ");
131
+ throw new Error(`This action was already ${label} by another user or policy.`);
132
+ }
133
+
134
+ if (!res.ok) {
135
+ const text = await res.text().catch(() => "Unknown error");
136
+ throw new Error(`Server responded ${res.status}: ${text}`);
137
+ }
138
+
139
+ let data: ActionApprovalResponse;
140
+ try {
141
+ data = (await res.json()) as ActionApprovalResponse;
142
+ } catch {
143
+ throw new Error("Action succeeded, but the response could not be read. Refresh the page.");
144
+ }
145
+ if (typeof data.status !== "string") {
146
+ throw new Error("Action succeeded, but the server returned an invalid status. Refresh the page.");
147
+ }
148
+ setCardState({ phase: "resolved", status: data.status as ResolvedStatus, result: data.result });
149
+ }
150
+
151
+ async function handleApprove() {
152
+ setCardState({ phase: "submitting", action: "approve" });
153
+ try {
154
+ await callAction("approve");
155
+ } catch (err) {
156
+ console.error("Action approval failed:", err);
157
+ const message =
158
+ err instanceof TypeError
159
+ ? "Network error — could not reach the server."
160
+ : err instanceof Error
161
+ ? err.message
162
+ : String(err);
163
+ setCardState({ phase: "error", message });
164
+ }
165
+ }
166
+
167
+ async function handleDeny() {
168
+ setCardState({ phase: "submitting", action: "deny" });
169
+ try {
170
+ await callAction("deny", denyReason.trim() ? { reason: denyReason.trim() } : undefined);
171
+ } catch (err) {
172
+ console.error("Action approval failed:", err);
173
+ const message =
174
+ err instanceof TypeError
175
+ ? "Network error — could not reach the server."
176
+ : err instanceof Error
177
+ ? err.message
178
+ : String(err);
179
+ setCardState({ phase: "error", message });
180
+ }
181
+ }
182
+
183
+ /* ---------------------------------------------------------------- */
184
+ /* Render */
185
+ /* ---------------------------------------------------------------- */
186
+
187
+ return (
188
+ <div className={`my-2 overflow-hidden rounded-lg border ${borderColor(effectiveStatus)} bg-zinc-50 dark:bg-zinc-900`}>
189
+ {/* Header */}
190
+ <button
191
+ onClick={() => setOpen(!open)}
192
+ className="flex w-full items-center gap-2 px-3 py-2 text-left text-xs transition-colors hover:bg-zinc-100/60 dark:hover:bg-zinc-800/60"
193
+ >
194
+ <ActionStatusBadge status={effectiveStatus} />
195
+ <span className="flex-1 truncate text-zinc-500 dark:text-zinc-400">
196
+ {toolResult.summary ?? String(args.description ?? "Action")}
197
+ </span>
198
+ <span className="text-zinc-400 dark:text-zinc-600">{open ? "\u25BE" : "\u25B8"}</span>
199
+ </button>
200
+
201
+ {/* Expanded details */}
202
+ {open && (
203
+ <div className="border-t border-zinc-100 px-3 py-2 dark:border-zinc-800">
204
+ {toolResult.details && (
205
+ <pre className="mb-2 max-h-48 overflow-auto rounded bg-zinc-100 p-2 text-xs text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400">
206
+ {safeStringify(toolResult.details)}
207
+ </pre>
208
+ )}
209
+ {resolvedResult != null && (
210
+ <div className="mb-2 rounded bg-green-50 p-2 text-xs text-green-700 dark:bg-green-900/20 dark:text-green-400">
211
+ <span className="font-medium">Result: </span>
212
+ {typeof resolvedResult === "string"
213
+ ? resolvedResult
214
+ : safeStringify(resolvedResult)}
215
+ </div>
216
+ )}
217
+ {toolResult.error && (
218
+ <div className="mb-2 rounded bg-red-50 p-2 text-xs text-red-700 dark:bg-red-900/20 dark:text-red-400">
219
+ <span className="font-medium">Error: </span>
220
+ {toolResult.error}
221
+ </div>
222
+ )}
223
+ {toolResult.reason && RESOLVED_STATUSES.has(effectiveStatus) && (
224
+ <div className="mb-2 text-xs text-zinc-500 dark:text-zinc-400">
225
+ <span className="font-medium">Reason: </span>
226
+ {toolResult.reason}
227
+ </div>
228
+ )}
229
+ </div>
230
+ )}
231
+
232
+ {/* Approval buttons — only when pending */}
233
+ {(isPending || isSubmitting || cardState.phase === "error") && (
234
+ <div className="border-t border-zinc-100 px-3 py-2 dark:border-zinc-800">
235
+ {cardState.phase === "error" && (
236
+ <p className="mb-2 text-xs text-red-600 dark:text-red-400">{cardState.message}</p>
237
+ )}
238
+
239
+ <div className="flex items-center gap-2">
240
+ <button
241
+ onClick={handleApprove}
242
+ disabled={isSubmitting}
243
+ className="inline-flex items-center gap-1.5 rounded bg-blue-600 px-3 py-1.5 text-xs font-medium text-white transition-colors hover:bg-blue-500 disabled:opacity-40"
244
+ >
245
+ {isSubmitting && cardState.action === "approve" && (
246
+ <span className="inline-block h-3 w-3 animate-spin rounded-full border-2 border-white/30 border-t-white" />
247
+ )}
248
+ Approve
249
+ </button>
250
+
251
+ {!showDenyInput ? (
252
+ <button
253
+ onClick={() => setShowDenyInput(true)}
254
+ disabled={isSubmitting}
255
+ className="rounded border border-zinc-300 px-3 py-1.5 text-xs font-medium text-zinc-600 transition-colors hover:border-zinc-400 hover:text-zinc-800 disabled:opacity-40 dark:border-zinc-600 dark:text-zinc-400 dark:hover:border-zinc-500 dark:hover:text-zinc-200"
256
+ >
257
+ Deny
258
+ </button>
259
+ ) : (
260
+ <div className="flex flex-1 items-center gap-2">
261
+ <input
262
+ value={denyReason}
263
+ onChange={(e) => setDenyReason(e.target.value)}
264
+ placeholder="Reason (optional)"
265
+ className="flex-1 rounded border border-zinc-200 bg-white px-2 py-1 text-xs text-zinc-900 placeholder-zinc-400 outline-none focus:border-red-400 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100 dark:placeholder-zinc-600"
266
+ disabled={isSubmitting}
267
+ />
268
+ <button
269
+ onClick={handleDeny}
270
+ disabled={isSubmitting}
271
+ className="inline-flex items-center gap-1.5 rounded bg-red-600 px-3 py-1.5 text-xs font-medium text-white transition-colors hover:bg-red-500 disabled:opacity-40"
272
+ >
273
+ {isSubmitting && cardState.action === "deny" && (
274
+ <span className="inline-block h-3 w-3 animate-spin rounded-full border-2 border-white/30 border-t-white" />
275
+ )}
276
+ Confirm Deny
277
+ </button>
278
+ <button
279
+ onClick={() => {
280
+ setShowDenyInput(false);
281
+ setDenyReason("");
282
+ }}
283
+ disabled={isSubmitting}
284
+ className="text-xs text-zinc-400 hover:text-zinc-600 disabled:opacity-40 dark:hover:text-zinc-300"
285
+ >
286
+ Cancel
287
+ </button>
288
+ </div>
289
+ )}
290
+ </div>
291
+ </div>
292
+ )}
293
+ </div>
294
+ );
295
+ }
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import type { ActionStatus } from "../../lib/action-types";
4
+
5
+ const STATUS_CONFIG: Record<ActionStatus, { label: string; classes: string }> = {
6
+ pending_approval: {
7
+ label: "Pending Approval",
8
+ classes: "bg-yellow-100 text-yellow-700 dark:bg-yellow-600/20 dark:text-yellow-400",
9
+ },
10
+ approved: {
11
+ label: "Approved",
12
+ classes: "bg-green-100 text-green-700 dark:bg-green-600/20 dark:text-green-400",
13
+ },
14
+ executed: {
15
+ label: "Executed",
16
+ classes: "bg-green-100 text-green-700 dark:bg-green-600/20 dark:text-green-400",
17
+ },
18
+ auto_approved: {
19
+ label: "Auto-approved",
20
+ classes: "bg-green-100 text-green-700 dark:bg-green-600/20 dark:text-green-400",
21
+ },
22
+ denied: {
23
+ label: "Denied",
24
+ classes: "bg-red-100 text-red-700 dark:bg-red-600/20 dark:text-red-400",
25
+ },
26
+ failed: {
27
+ label: "Failed",
28
+ classes: "bg-red-100 text-red-700 dark:bg-red-600/20 dark:text-red-400",
29
+ },
30
+ rolled_back: {
31
+ label: "Rolled Back",
32
+ classes: "bg-zinc-100 text-zinc-700 dark:bg-zinc-600/20 dark:text-zinc-400",
33
+ },
34
+ timed_out: {
35
+ label: "Timed Out",
36
+ classes: "bg-zinc-100 text-zinc-700 dark:bg-zinc-600/20 dark:text-zinc-400",
37
+ },
38
+ };
39
+
40
+ export function ActionStatusBadge({ status }: { status: ActionStatus }) {
41
+ const config = STATUS_CONFIG[status] ?? {
42
+ label: status.replace(/_/g, " "),
43
+ classes: "bg-zinc-100 text-zinc-700 dark:bg-zinc-600/20 dark:text-zinc-400",
44
+ };
45
+ return (
46
+ <span className={`rounded px-1.5 py-0.5 text-xs font-medium ${config.classes}`}>
47
+ {config.label}
48
+ </span>
49
+ );
50
+ }
@@ -0,0 +1,26 @@
1
+ "use client";
2
+
3
+ import type { ReactNode } from "react";
4
+ import { SidebarProvider, SidebarInset, SidebarTrigger } from "@/components/ui/sidebar";
5
+ import { Separator } from "@/components/ui/separator";
6
+ import { AdminSidebar } from "./admin-sidebar";
7
+
8
+ // TODO: Add real role gating once admin API enforces auth.
9
+ // For now, all users can access the admin console — the admin API
10
+ // endpoints will reject unauthorized requests server-side.
11
+
12
+ export function AdminLayout({ children }: { children: ReactNode }) {
13
+ return (
14
+ <SidebarProvider>
15
+ <AdminSidebar />
16
+ <SidebarInset>
17
+ <header className="flex h-12 shrink-0 items-center gap-2 border-b px-4">
18
+ <SidebarTrigger className="-ml-1" />
19
+ <Separator orientation="vertical" className="mr-2 h-4" />
20
+ <span className="text-sm font-medium text-muted-foreground">Admin Console</span>
21
+ </header>
22
+ <div className="flex-1 overflow-auto">{children}</div>
23
+ </SidebarInset>
24
+ </SidebarProvider>
25
+ );
26
+ }
@@ -0,0 +1,96 @@
1
+ "use client";
2
+
3
+ import Link from "next/link";
4
+ import { usePathname } from "next/navigation";
5
+ import {
6
+ LayoutDashboard,
7
+ Database,
8
+ Cable,
9
+ ScrollText,
10
+ Puzzle,
11
+ CalendarClock,
12
+ Zap,
13
+ ArrowLeft,
14
+ } from "lucide-react";
15
+ import {
16
+ Sidebar,
17
+ SidebarContent,
18
+ SidebarGroup,
19
+ SidebarGroupContent,
20
+ SidebarGroupLabel,
21
+ SidebarHeader,
22
+ SidebarMenu,
23
+ SidebarMenuItem,
24
+ SidebarMenuButton,
25
+ SidebarFooter,
26
+ SidebarSeparator,
27
+ } from "@/components/ui/sidebar";
28
+
29
+ const navItems = [
30
+ { href: "/admin", label: "Overview", icon: LayoutDashboard, exact: true },
31
+ { href: "/admin/semantic", label: "Semantic Layer", icon: Database },
32
+ { href: "/admin/connections", label: "Connections", icon: Cable },
33
+ { href: "/admin/audit", label: "Audit", icon: ScrollText },
34
+ { href: "/admin/plugins", label: "Plugins", icon: Puzzle },
35
+ { href: "/admin/scheduled-tasks", label: "Scheduled Tasks", icon: CalendarClock },
36
+ { href: "/admin/actions", label: "Actions", icon: Zap },
37
+ ];
38
+
39
+ export function AdminSidebar() {
40
+ const pathname = usePathname();
41
+
42
+ function isActive(item: (typeof navItems)[number]) {
43
+ if (item.exact) return pathname === item.href;
44
+ return pathname.startsWith(item.href);
45
+ }
46
+
47
+ return (
48
+ <Sidebar>
49
+ <SidebarHeader className="px-3 pt-4 pb-2">
50
+ <div className="flex items-center gap-2.5">
51
+ <svg viewBox="0 0 256 256" fill="none" className="size-6 shrink-0" aria-hidden="true">
52
+ <path d="M128 24 L232 208 L24 208 Z" stroke="#23CE9E" strokeWidth="14" fill="none" strokeLinejoin="round" />
53
+ <circle cx="128" cy="28" r="16" fill="#23CE9E" />
54
+ </svg>
55
+ <div>
56
+ <p className="text-sm font-semibold leading-none tracking-tight">Atlas</p>
57
+ <p className="text-xs text-muted-foreground">Admin Console</p>
58
+ </div>
59
+ </div>
60
+ </SidebarHeader>
61
+ <SidebarSeparator />
62
+ <SidebarContent>
63
+ <SidebarGroup>
64
+ <SidebarGroupLabel>Navigation</SidebarGroupLabel>
65
+ <SidebarGroupContent>
66
+ <SidebarMenu>
67
+ {navItems.map((item) => (
68
+ <SidebarMenuItem key={item.href}>
69
+ <SidebarMenuButton asChild isActive={isActive(item)} tooltip={item.label}>
70
+ <Link href={item.href}>
71
+ <item.icon className="size-4" />
72
+ <span>{item.label}</span>
73
+ </Link>
74
+ </SidebarMenuButton>
75
+ </SidebarMenuItem>
76
+ ))}
77
+ </SidebarMenu>
78
+ </SidebarGroupContent>
79
+ </SidebarGroup>
80
+ </SidebarContent>
81
+ <SidebarFooter>
82
+ <SidebarSeparator />
83
+ <SidebarMenu>
84
+ <SidebarMenuItem>
85
+ <SidebarMenuButton asChild tooltip="Back to Chat">
86
+ <Link href="/">
87
+ <ArrowLeft className="size-4" />
88
+ <span>Back to Chat</span>
89
+ </Link>
90
+ </SidebarMenuButton>
91
+ </SidebarMenuItem>
92
+ </SidebarMenu>
93
+ </SidebarFooter>
94
+ </Sidebar>
95
+ );
96
+ }
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ import type { LucideIcon } from "lucide-react";
4
+ import type { ReactNode } from "react";
5
+
6
+ export function EmptyState({
7
+ icon: Icon,
8
+ message,
9
+ children,
10
+ }: {
11
+ icon: LucideIcon;
12
+ message: string;
13
+ children?: ReactNode;
14
+ }) {
15
+ return (
16
+ <div className="flex h-64 items-center justify-center text-muted-foreground">
17
+ <div className="text-center">
18
+ <Icon className="mx-auto size-10 opacity-50" />
19
+ <p className="mt-3 text-sm">{message}</p>
20
+ {children}
21
+ </div>
22
+ </div>
23
+ );
24
+ }