@mantajs/cli 0.2.0-beta.0

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 (282) hide show
  1. package/bin/manta.mjs +20 -0
  2. package/bin/manta.ts +13 -0
  3. package/dist/admin/generate-admin-config.d.ts +8 -0
  4. package/dist/admin/generate-admin-config.d.ts.map +1 -0
  5. package/dist/admin/generate-admin-config.js +127 -0
  6. package/dist/admin/generate-admin-config.js.map +1 -0
  7. package/dist/ai/chat-handler.d.ts +10 -0
  8. package/dist/ai/chat-handler.d.ts.map +1 -0
  9. package/dist/ai/chat-handler.js +1353 -0
  10. package/dist/ai/chat-handler.js.map +1 -0
  11. package/dist/bootstrap/boot.d.ts +25 -0
  12. package/dist/bootstrap/boot.d.ts.map +1 -0
  13. package/dist/bootstrap/boot.js +344 -0
  14. package/dist/bootstrap/boot.js.map +1 -0
  15. package/dist/bootstrap/bootstrap-app.d.ts +71 -0
  16. package/dist/bootstrap/bootstrap-app.d.ts.map +1 -0
  17. package/dist/bootstrap/bootstrap-app.js +308 -0
  18. package/dist/bootstrap/bootstrap-app.js.map +1 -0
  19. package/dist/bootstrap/bootstrap-context.d.ts +76 -0
  20. package/dist/bootstrap/bootstrap-context.d.ts.map +1 -0
  21. package/dist/bootstrap/bootstrap-context.js +4 -0
  22. package/dist/bootstrap/bootstrap-context.js.map +1 -0
  23. package/dist/bootstrap/bootstrap-helpers.d.ts +71 -0
  24. package/dist/bootstrap/bootstrap-helpers.d.ts.map +1 -0
  25. package/dist/bootstrap/bootstrap-helpers.js +373 -0
  26. package/dist/bootstrap/bootstrap-helpers.js.map +1 -0
  27. package/dist/bootstrap/generate-types.d.ts +7 -0
  28. package/dist/bootstrap/generate-types.d.ts.map +1 -0
  29. package/dist/bootstrap/generate-types.js +832 -0
  30. package/dist/bootstrap/generate-types.js.map +1 -0
  31. package/dist/bootstrap/phases/assemble/index.d.ts +5 -0
  32. package/dist/bootstrap/phases/assemble/index.d.ts.map +1 -0
  33. package/dist/bootstrap/phases/assemble/index.js +5 -0
  34. package/dist/bootstrap/phases/assemble/index.js.map +1 -0
  35. package/dist/bootstrap/phases/assemble/load-links.d.ts +3 -0
  36. package/dist/bootstrap/phases/assemble/load-links.d.ts.map +1 -0
  37. package/dist/bootstrap/phases/assemble/load-links.js +160 -0
  38. package/dist/bootstrap/phases/assemble/load-links.js.map +1 -0
  39. package/dist/bootstrap/phases/assemble/load-modules.d.ts +3 -0
  40. package/dist/bootstrap/phases/assemble/load-modules.d.ts.map +1 -0
  41. package/dist/bootstrap/phases/assemble/load-modules.js +163 -0
  42. package/dist/bootstrap/phases/assemble/load-modules.js.map +1 -0
  43. package/dist/bootstrap/phases/assemble/load-resources.d.ts +3 -0
  44. package/dist/bootstrap/phases/assemble/load-resources.d.ts.map +1 -0
  45. package/dist/bootstrap/phases/assemble/load-resources.js +270 -0
  46. package/dist/bootstrap/phases/assemble/load-resources.js.map +1 -0
  47. package/dist/bootstrap/phases/assemble/wire-commands.d.ts +3 -0
  48. package/dist/bootstrap/phases/assemble/wire-commands.d.ts.map +1 -0
  49. package/dist/bootstrap/phases/assemble/wire-commands.js +408 -0
  50. package/dist/bootstrap/phases/assemble/wire-commands.js.map +1 -0
  51. package/dist/bootstrap/phases/assemble-modules.d.ts +3 -0
  52. package/dist/bootstrap/phases/assemble-modules.d.ts.map +1 -0
  53. package/dist/bootstrap/phases/assemble-modules.js +14 -0
  54. package/dist/bootstrap/phases/assemble-modules.js.map +1 -0
  55. package/dist/bootstrap/phases/build-app.d.ts +3 -0
  56. package/dist/bootstrap/phases/build-app.d.ts.map +1 -0
  57. package/dist/bootstrap/phases/build-app.js +15 -0
  58. package/dist/bootstrap/phases/build-app.js.map +1 -0
  59. package/dist/bootstrap/phases/discover-resources.d.ts +3 -0
  60. package/dist/bootstrap/phases/discover-resources.d.ts.map +1 -0
  61. package/dist/bootstrap/phases/discover-resources.js +60 -0
  62. package/dist/bootstrap/phases/discover-resources.js.map +1 -0
  63. package/dist/bootstrap/phases/index.d.ts +7 -0
  64. package/dist/bootstrap/phases/index.d.ts.map +1 -0
  65. package/dist/bootstrap/phases/index.js +7 -0
  66. package/dist/bootstrap/phases/index.js.map +1 -0
  67. package/dist/bootstrap/phases/init-infra.d.ts +3 -0
  68. package/dist/bootstrap/phases/init-infra.d.ts.map +1 -0
  69. package/dist/bootstrap/phases/init-infra.js +193 -0
  70. package/dist/bootstrap/phases/init-infra.js.map +1 -0
  71. package/dist/bootstrap/phases/seed-dev-users.d.ts +3 -0
  72. package/dist/bootstrap/phases/seed-dev-users.d.ts.map +1 -0
  73. package/dist/bootstrap/phases/seed-dev-users.js +93 -0
  74. package/dist/bootstrap/phases/seed-dev-users.js.map +1 -0
  75. package/dist/bootstrap/phases/wire/auth-helpers.d.ts +12 -0
  76. package/dist/bootstrap/phases/wire/auth-helpers.d.ts.map +1 -0
  77. package/dist/bootstrap/phases/wire/auth-helpers.js +25 -0
  78. package/dist/bootstrap/phases/wire/auth-helpers.js.map +1 -0
  79. package/dist/bootstrap/phases/wire/contexts/context-registry.d.ts +4 -0
  80. package/dist/bootstrap/phases/wire/contexts/context-registry.d.ts.map +1 -0
  81. package/dist/bootstrap/phases/wire/contexts/context-registry.js +96 -0
  82. package/dist/bootstrap/phases/wire/contexts/context-registry.js.map +1 -0
  83. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.d.ts +3 -0
  84. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.d.ts.map +1 -0
  85. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.js +138 -0
  86. package/dist/bootstrap/phases/wire/contexts/cqrs-routes.js.map +1 -0
  87. package/dist/bootstrap/phases/wire/contexts/index.d.ts +6 -0
  88. package/dist/bootstrap/phases/wire/contexts/index.d.ts.map +1 -0
  89. package/dist/bootstrap/phases/wire/contexts/index.js +6 -0
  90. package/dist/bootstrap/phases/wire/contexts/index.js.map +1 -0
  91. package/dist/bootstrap/phases/wire/contexts/query-endpoints.d.ts +3 -0
  92. package/dist/bootstrap/phases/wire/contexts/query-endpoints.d.ts.map +1 -0
  93. package/dist/bootstrap/phases/wire/contexts/query-endpoints.js +116 -0
  94. package/dist/bootstrap/phases/wire/contexts/query-endpoints.js.map +1 -0
  95. package/dist/bootstrap/phases/wire/contexts/spa-warnings.d.ts +3 -0
  96. package/dist/bootstrap/phases/wire/contexts/spa-warnings.d.ts.map +1 -0
  97. package/dist/bootstrap/phases/wire/contexts/spa-warnings.js +17 -0
  98. package/dist/bootstrap/phases/wire/contexts/spa-warnings.js.map +1 -0
  99. package/dist/bootstrap/phases/wire/contexts/user-routes.d.ts +3 -0
  100. package/dist/bootstrap/phases/wire/contexts/user-routes.d.ts.map +1 -0
  101. package/dist/bootstrap/phases/wire/contexts/user-routes.js +83 -0
  102. package/dist/bootstrap/phases/wire/contexts/user-routes.js.map +1 -0
  103. package/dist/bootstrap/phases/wire/index.d.ts +5 -0
  104. package/dist/bootstrap/phases/wire/index.d.ts.map +1 -0
  105. package/dist/bootstrap/phases/wire/index.js +5 -0
  106. package/dist/bootstrap/phases/wire/index.js.map +1 -0
  107. package/dist/bootstrap/phases/wire/wire-adapter.d.ts +12 -0
  108. package/dist/bootstrap/phases/wire/wire-adapter.d.ts.map +1 -0
  109. package/dist/bootstrap/phases/wire/wire-adapter.js +156 -0
  110. package/dist/bootstrap/phases/wire/wire-adapter.js.map +1 -0
  111. package/dist/bootstrap/phases/wire/wire-auth.d.ts +3 -0
  112. package/dist/bootstrap/phases/wire/wire-auth.d.ts.map +1 -0
  113. package/dist/bootstrap/phases/wire/wire-auth.js +46 -0
  114. package/dist/bootstrap/phases/wire/wire-auth.js.map +1 -0
  115. package/dist/bootstrap/phases/wire/wire-contexts.d.ts +3 -0
  116. package/dist/bootstrap/phases/wire/wire-contexts.d.ts.map +1 -0
  117. package/dist/bootstrap/phases/wire/wire-contexts.js +15 -0
  118. package/dist/bootstrap/phases/wire/wire-contexts.js.map +1 -0
  119. package/dist/bootstrap/phases/wire/wire-cron-routes.d.ts +3 -0
  120. package/dist/bootstrap/phases/wire/wire-cron-routes.d.ts.map +1 -0
  121. package/dist/bootstrap/phases/wire/wire-cron-routes.js +102 -0
  122. package/dist/bootstrap/phases/wire/wire-cron-routes.js.map +1 -0
  123. package/dist/bootstrap/phases/wire/wire-extras.d.ts +3 -0
  124. package/dist/bootstrap/phases/wire/wire-extras.d.ts.map +1 -0
  125. package/dist/bootstrap/phases/wire/wire-extras.js +305 -0
  126. package/dist/bootstrap/phases/wire/wire-extras.js.map +1 -0
  127. package/dist/bootstrap/phases/wire/wire-workflow-routes.d.ts +3 -0
  128. package/dist/bootstrap/phases/wire/wire-workflow-routes.d.ts.map +1 -0
  129. package/dist/bootstrap/phases/wire/wire-workflow-routes.js +212 -0
  130. package/dist/bootstrap/phases/wire/wire-workflow-routes.js.map +1 -0
  131. package/dist/bootstrap/phases/wire-http.d.ts +3 -0
  132. package/dist/bootstrap/phases/wire-http.d.ts.map +1 -0
  133. package/dist/bootstrap/phases/wire-http.js +10 -0
  134. package/dist/bootstrap/phases/wire-http.js.map +1 -0
  135. package/dist/bootstrap/validate-generated-ts.d.ts +6 -0
  136. package/dist/bootstrap/validate-generated-ts.d.ts.map +1 -0
  137. package/dist/bootstrap/validate-generated-ts.js +26 -0
  138. package/dist/bootstrap/validate-generated-ts.js.map +1 -0
  139. package/dist/build/generate-manifest.d.ts +10 -0
  140. package/dist/build/generate-manifest.d.ts.map +1 -0
  141. package/dist/build/generate-manifest.js +138 -0
  142. package/dist/build/generate-manifest.js.map +1 -0
  143. package/dist/cli.d.ts +3 -0
  144. package/dist/cli.d.ts.map +1 -0
  145. package/dist/cli.js +421 -0
  146. package/dist/cli.js.map +1 -0
  147. package/dist/commands/build.d.ts +21 -0
  148. package/dist/commands/build.d.ts.map +1 -0
  149. package/dist/commands/build.js +399 -0
  150. package/dist/commands/build.js.map +1 -0
  151. package/dist/commands/db/create.d.ts +17 -0
  152. package/dist/commands/db/create.d.ts.map +1 -0
  153. package/dist/commands/db/create.js +94 -0
  154. package/dist/commands/db/create.js.map +1 -0
  155. package/dist/commands/db/diff.d.ts +39 -0
  156. package/dist/commands/db/diff.d.ts.map +1 -0
  157. package/dist/commands/db/diff.js +81 -0
  158. package/dist/commands/db/diff.js.map +1 -0
  159. package/dist/commands/db/generate.d.ts +58 -0
  160. package/dist/commands/db/generate.d.ts.map +1 -0
  161. package/dist/commands/db/generate.js +138 -0
  162. package/dist/commands/db/generate.js.map +1 -0
  163. package/dist/commands/db/migrate.d.ts +29 -0
  164. package/dist/commands/db/migrate.d.ts.map +1 -0
  165. package/dist/commands/db/migrate.js +118 -0
  166. package/dist/commands/db/migrate.js.map +1 -0
  167. package/dist/commands/db/pg-deps.d.ts +30 -0
  168. package/dist/commands/db/pg-deps.d.ts.map +1 -0
  169. package/dist/commands/db/pg-deps.js +178 -0
  170. package/dist/commands/db/pg-deps.js.map +1 -0
  171. package/dist/commands/db/rollback.d.ts +21 -0
  172. package/dist/commands/db/rollback.d.ts.map +1 -0
  173. package/dist/commands/db/rollback.js +85 -0
  174. package/dist/commands/db/rollback.js.map +1 -0
  175. package/dist/commands/db/types.d.ts +113 -0
  176. package/dist/commands/db/types.d.ts.map +1 -0
  177. package/dist/commands/db/types.js +4 -0
  178. package/dist/commands/db/types.js.map +1 -0
  179. package/dist/commands/dev.d.ts +12 -0
  180. package/dist/commands/dev.d.ts.map +1 -0
  181. package/dist/commands/dev.js +79 -0
  182. package/dist/commands/dev.js.map +1 -0
  183. package/dist/commands/exec.d.ts +21 -0
  184. package/dist/commands/exec.d.ts.map +1 -0
  185. package/dist/commands/exec.js +148 -0
  186. package/dist/commands/exec.js.map +1 -0
  187. package/dist/commands/generate.d.ts +11 -0
  188. package/dist/commands/generate.d.ts.map +1 -0
  189. package/dist/commands/generate.js +19 -0
  190. package/dist/commands/generate.js.map +1 -0
  191. package/dist/commands/init.d.ts +14 -0
  192. package/dist/commands/init.d.ts.map +1 -0
  193. package/dist/commands/init.js +476 -0
  194. package/dist/commands/init.js.map +1 -0
  195. package/dist/commands/start.d.ts +15 -0
  196. package/dist/commands/start.d.ts.map +1 -0
  197. package/dist/commands/start.js +121 -0
  198. package/dist/commands/start.js.map +1 -0
  199. package/dist/commands/user.d.ts +19 -0
  200. package/dist/commands/user.d.ts.map +1 -0
  201. package/dist/commands/user.js +125 -0
  202. package/dist/commands/user.js.map +1 -0
  203. package/dist/config/load-config.d.ts +23 -0
  204. package/dist/config/load-config.d.ts.map +1 -0
  205. package/dist/config/load-config.js +105 -0
  206. package/dist/config/load-config.js.map +1 -0
  207. package/dist/config/load-env.d.ts +11 -0
  208. package/dist/config/load-env.d.ts.map +1 -0
  209. package/dist/config/load-env.js +61 -0
  210. package/dist/config/load-env.js.map +1 -0
  211. package/dist/config/resolve-adapters.d.ts +23 -0
  212. package/dist/config/resolve-adapters.d.ts.map +1 -0
  213. package/dist/config/resolve-adapters.js +96 -0
  214. package/dist/config/resolve-adapters.js.map +1 -0
  215. package/dist/index.d.ts +18 -0
  216. package/dist/index.d.ts.map +1 -0
  217. package/dist/index.js +19 -0
  218. package/dist/index.js.map +1 -0
  219. package/dist/jiti.d.ts +2 -0
  220. package/dist/jiti.d.ts.map +1 -0
  221. package/dist/jiti.js +2 -0
  222. package/dist/jiti.js.map +1 -0
  223. package/dist/openapi/generate-spec.d.ts +56 -0
  224. package/dist/openapi/generate-spec.d.ts.map +1 -0
  225. package/dist/openapi/generate-spec.js +491 -0
  226. package/dist/openapi/generate-spec.js.map +1 -0
  227. package/dist/openapi/index.d.ts +4 -0
  228. package/dist/openapi/index.d.ts.map +1 -0
  229. package/dist/openapi/index.js +3 -0
  230. package/dist/openapi/index.js.map +1 -0
  231. package/dist/openapi/swagger-html.d.ts +2 -0
  232. package/dist/openapi/swagger-html.d.ts.map +1 -0
  233. package/dist/openapi/swagger-html.js +29 -0
  234. package/dist/openapi/swagger-html.js.map +1 -0
  235. package/dist/plugins/merge-resources.d.ts +18 -0
  236. package/dist/plugins/merge-resources.d.ts.map +1 -0
  237. package/dist/plugins/merge-resources.js +76 -0
  238. package/dist/plugins/merge-resources.js.map +1 -0
  239. package/dist/plugins/resolve-plugins.d.ts +14 -0
  240. package/dist/plugins/resolve-plugins.d.ts.map +1 -0
  241. package/dist/plugins/resolve-plugins.js +73 -0
  242. package/dist/plugins/resolve-plugins.js.map +1 -0
  243. package/dist/resource-loader.d.ts +151 -0
  244. package/dist/resource-loader.d.ts.map +1 -0
  245. package/dist/resource-loader.js +456 -0
  246. package/dist/resource-loader.js.map +1 -0
  247. package/dist/route-discovery.d.ts +33 -0
  248. package/dist/route-discovery.d.ts.map +1 -0
  249. package/dist/route-discovery.js +69 -0
  250. package/dist/route-discovery.js.map +1 -0
  251. package/dist/server-bootstrap.d.ts +38 -0
  252. package/dist/server-bootstrap.d.ts.map +1 -0
  253. package/dist/server-bootstrap.js +21 -0
  254. package/dist/server-bootstrap.js.map +1 -0
  255. package/dist/spa/generate-spa.d.ts +15 -0
  256. package/dist/spa/generate-spa.d.ts.map +1 -0
  257. package/dist/spa/generate-spa.js +357 -0
  258. package/dist/spa/generate-spa.js.map +1 -0
  259. package/dist/templates/agent/nextjs.md +129 -0
  260. package/dist/templates/agent/nuxt.md +98 -0
  261. package/dist/templates/agent/standalone.md +498 -0
  262. package/dist/types.d.ts +145 -0
  263. package/dist/types.d.ts.map +1 -0
  264. package/dist/types.js +3 -0
  265. package/dist/types.js.map +1 -0
  266. package/dist/utils/colors.d.ts +7 -0
  267. package/dist/utils/colors.d.ts.map +1 -0
  268. package/dist/utils/colors.js +8 -0
  269. package/dist/utils/colors.js.map +1 -0
  270. package/dist/utils/logger.d.ts +10 -0
  271. package/dist/utils/logger.d.ts.map +1 -0
  272. package/dist/utils/logger.js +27 -0
  273. package/dist/utils/logger.js.map +1 -0
  274. package/dist/utils/prompts.d.ts +6 -0
  275. package/dist/utils/prompts.d.ts.map +1 -0
  276. package/dist/utils/prompts.js +28 -0
  277. package/dist/utils/prompts.js.map +1 -0
  278. package/dist/utils/spinner.d.ts +7 -0
  279. package/dist/utils/spinner.d.ts.map +1 -0
  280. package/dist/utils/spinner.js +20 -0
  281. package/dist/utils/spinner.js.map +1 -0
  282. package/package.json +80 -0
@@ -0,0 +1,15 @@
1
+ import type { DiscoveredSpa } from '../resource-loader';
2
+ export interface SpaGenerateOptions {
3
+ cwd: string;
4
+ spa: DiscoveredSpa;
5
+ dashboard?: string;
6
+ preset?: string;
7
+ /** Backend server port (from PORT env or default 3000) */
8
+ port?: number;
9
+ }
10
+ /**
11
+ * Generate all build artifacts for a SPA.
12
+ * Returns the path to the generated vite.config.ts.
13
+ */
14
+ export declare function generateSpaArtifacts(options: SpaGenerateOptions): string;
15
+ //# sourceMappingURL=generate-spa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-spa.d.ts","sourceRoot":"","sources":["../../src/spa/generate-spa.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,aAAa,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAmBxE"}
@@ -0,0 +1,357 @@
1
+ // SPA entry point generator — generates .manta/spa/{name}/ with:
2
+ // - index.html (auto-generated)
3
+ // - entry.tsx (imports dashboard shell + routes)
4
+ // - routes.ts (filesystem-derived routing)
5
+ // - vite.config.ts (Vite build config)
6
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
7
+ import { dirname, join, relative, resolve } from 'node:path';
8
+ /**
9
+ * Generate all build artifacts for a SPA.
10
+ * Returns the path to the generated vite.config.ts.
11
+ */
12
+ export function generateSpaArtifacts(options) {
13
+ const { cwd, spa, dashboard, preset, port = 3000 } = options;
14
+ const outDir = resolve(cwd, '.manta', 'spa', spa.name);
15
+ mkdirSync(outDir, { recursive: true });
16
+ // Generate routes.ts
17
+ writeFileSync(join(outDir, 'routes.ts'), generateRoutes(spa, cwd));
18
+ // Generate entry.tsx
19
+ writeFileSync(join(outDir, 'entry.tsx'), generateEntry(spa, cwd, outDir, dashboard, preset));
20
+ // Generate index.html
21
+ writeFileSync(join(outDir, 'index.html'), generateHtml(spa));
22
+ // Generate vite.config.ts
23
+ const viteConfigPath = join(outDir, 'vite.config.ts');
24
+ writeFileSync(viteConfigPath, generateViteConfig(spa, cwd, outDir, dashboard, preset, port));
25
+ return viteConfigPath;
26
+ }
27
+ function generateRoutes(spa, cwd) {
28
+ const lines = [
29
+ '// Auto-generated — do not edit',
30
+ `// Pages discovered from src/spa/${spa.name}/`,
31
+ '',
32
+ "import { lazy } from 'react'",
33
+ '',
34
+ ];
35
+ // Config import (defineSpa)
36
+ if (spa.configPath) {
37
+ const relPath = relative(resolve(cwd, '.manta', 'spa', spa.name), spa.configPath).replace(/\.ts$/, '');
38
+ lines.push(`import spaConfig from '${relPath}'`);
39
+ lines.push('');
40
+ }
41
+ const imports = [];
42
+ const routeDefs = [];
43
+ const specImports = [];
44
+ const specDefs = [];
45
+ for (const page of spa.pages) {
46
+ const varName = routeToVarName(page.route);
47
+ const relPath = relative(resolve(cwd, '.manta', 'spa', spa.name), page.path).replace(/\.tsx?$/, '');
48
+ const isSpec = page.path.endsWith('.ts') && !page.path.endsWith('.tsx');
49
+ if (isSpec) {
50
+ // Spec page (definePage/defineForm) — static import
51
+ specImports.push(`import ${varName}Spec from '${relPath}'`);
52
+ specDefs.push(` { route: '${page.route}', spec: ${varName}Spec },`);
53
+ }
54
+ else {
55
+ // React page — lazy import
56
+ imports.push(`const ${varName} = lazy(() => import('${relPath}'))`);
57
+ routeDefs.push(` { path: '${page.route}', component: ${varName} },`);
58
+ }
59
+ }
60
+ // Block imports
61
+ const blockImports = [];
62
+ const blockDefs = [];
63
+ for (const block of spa.blocks) {
64
+ const relPath = relative(resolve(cwd, '.manta', 'spa', spa.name), block.path).replace(/\.tsx?$/, '');
65
+ blockImports.push(`import ${block.type} from '${relPath}'`);
66
+ blockDefs.push(` '${block.type}': ${block.type},`);
67
+ }
68
+ lines.push(...specImports);
69
+ lines.push(...imports);
70
+ if (blockImports.length > 0) {
71
+ lines.push('');
72
+ lines.push(...blockImports);
73
+ }
74
+ lines.push('');
75
+ // Export React routes (legacy)
76
+ lines.push('export const routes = [');
77
+ lines.push(...routeDefs);
78
+ lines.push(']');
79
+ lines.push('');
80
+ // Export spec pages (definePage/defineForm)
81
+ lines.push('export const pageSpecs = [');
82
+ lines.push(...specDefs);
83
+ lines.push(']');
84
+ lines.push('');
85
+ // Export custom blocks
86
+ if (blockDefs.length > 0) {
87
+ lines.push('export const customBlocks = {');
88
+ lines.push(...blockDefs);
89
+ lines.push('}');
90
+ }
91
+ else {
92
+ lines.push('export const customBlocks = {}');
93
+ }
94
+ lines.push('');
95
+ // Export SPA config
96
+ if (spa.configPath) {
97
+ lines.push('export { spaConfig }');
98
+ }
99
+ else {
100
+ lines.push('export const spaConfig = null');
101
+ }
102
+ lines.push('');
103
+ // Export command schemas (for form validation)
104
+ const schemasPath = relative(resolve(cwd, '.manta', 'spa', spa.name), resolve(cwd, '.manta', 'command-schemas')).replace(/\\/g, '/');
105
+ lines.push(`export { commandSchemas } from '${schemasPath}'`);
106
+ lines.push('');
107
+ return lines.join('\n');
108
+ }
109
+ function generateEntry(spa, cwd, _outDir, dashboard, preset) {
110
+ // When @mantajs/dashboard is the dashboard shell, generate an entry that uses MantaDashboard
111
+ // which provides the full admin shell (sidebar, auth, registry, etc.)
112
+ if (dashboard === '@mantajs/dashboard') {
113
+ // Resolve the CSS path relative to the generated entry file
114
+ let cssImport = '// @mantajs/dashboard CSS not found';
115
+ try {
116
+ const pkgDir = dirname(require.resolve('@mantajs/dashboard/package.json', { paths: [cwd] }));
117
+ const distCss = join(pkgDir, 'dist', 'index.css');
118
+ const cssPath = (existsSync(distCss) ? distCss : join(pkgDir, 'src', 'index.css')).replace(/\\/g, '/');
119
+ cssImport = `import '${cssPath}'`;
120
+ }
121
+ catch {
122
+ /* not found */
123
+ }
124
+ const lines = [
125
+ '// Auto-generated — do not edit',
126
+ "import { Suspense } from 'react'",
127
+ "import { createRoot } from 'react-dom/client'",
128
+ "import { MantaDashboard } from '@mantajs/dashboard'",
129
+ "import { routes, pageSpecs, customBlocks, spaConfig, commandSchemas } from './routes'",
130
+ cssImport,
131
+ '',
132
+ 'const apiUrl = window.location.origin',
133
+ '',
134
+ '// Convert filesystem routes to React Router route objects (wrapped in Suspense for lazy loading)',
135
+ 'const customRoutes = routes.map((r) => ({',
136
+ " path: r.path === '/' ? undefined : r.path.replace(/^\\//, ''),",
137
+ ' element: <Suspense fallback={null}><r.component /></Suspense>,',
138
+ '}))',
139
+ '',
140
+ "createRoot(document.getElementById('root')!).render(",
141
+ ` <MantaDashboard apiUrl={apiUrl} basename="/${spa.name}" customRoutes={customRoutes} pageSpecs={pageSpecs} customBlocks={customBlocks} spaConfig={spaConfig} commandSchemas={commandSchemas} />,`,
142
+ ')',
143
+ '',
144
+ ];
145
+ return lines.join('\n');
146
+ }
147
+ // Fallback: bare BrowserRouter for custom SPAs without a dashboard shell
148
+ const lines = [
149
+ '// Auto-generated — do not edit',
150
+ "import React, { Suspense } from 'react'",
151
+ "import { createRoot } from 'react-dom/client'",
152
+ "import { BrowserRouter, Routes, Route } from 'react-router-dom'",
153
+ "import { routes } from './routes'",
154
+ ];
155
+ if (preset && preset !== '@mantajs/ui') {
156
+ lines.push(`import '${preset}/styles.css'`);
157
+ }
158
+ lines.push('');
159
+ lines.push('function App() {');
160
+ lines.push(` return (
161
+ <BrowserRouter basename="/${spa.name}">
162
+ <Suspense fallback={<div>Loading...</div>}>
163
+ <Routes>
164
+ {routes.map((r) => (
165
+ <Route key={r.path} path={r.path} element={<r.component />} />
166
+ ))}
167
+ </Routes>
168
+ </Suspense>
169
+ </BrowserRouter>
170
+ )`);
171
+ lines.push('}');
172
+ lines.push('');
173
+ lines.push("createRoot(document.getElementById('root')!).render(<App />)");
174
+ lines.push('');
175
+ return lines.join('\n');
176
+ }
177
+ function generateHtml(spa) {
178
+ return `<!DOCTYPE html>
179
+ <html lang="en">
180
+ <head>
181
+ <meta charset="UTF-8" />
182
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
183
+ <title>${spa.name.charAt(0).toUpperCase() + spa.name.slice(1)}</title>
184
+ </head>
185
+ <body>
186
+ <div id="root"></div>
187
+ <script type="module" src="./entry.tsx"></script>
188
+ </body>
189
+ </html>
190
+ `;
191
+ }
192
+ function generateViteConfig(spa, cwd, outDir, dashboard, _preset, port = 3000) {
193
+ const lines = [
194
+ `import { defineConfig } from 'vite'`,
195
+ `import react from '@vitejs/plugin-react'`,
196
+ `import tailwindcss from '@tailwindcss/vite'`,
197
+ '',
198
+ `export default defineConfig({`,
199
+ ` root: '${outDir.replace(/\\/g, '/')}',`,
200
+ ` base: '/${spa.name}/',`,
201
+ ` appType: 'spa',`,
202
+ ` plugins: [`,
203
+ ` react(),`,
204
+ ` tailwindcss(),`,
205
+ ` {`,
206
+ ` name: 'manta-trailing-slash',`,
207
+ ` configureServer(server) {`,
208
+ ` server.middlewares.use((req, _res, next) => {`,
209
+ ` if (req.url === '/${spa.name}') req.url = '/${spa.name}/'`,
210
+ ` next()`,
211
+ ` })`,
212
+ ` },`,
213
+ ` },`,
214
+ ` ],`,
215
+ ` server: {`,
216
+ ` hmr: true,`,
217
+ ` strictPort: true,`,
218
+ ` proxy: {`,
219
+ ` '/api': {`,
220
+ ` target: 'http://localhost:${port}',`,
221
+ ` changeOrigin: true,`,
222
+ ` },`,
223
+ ` },`,
224
+ ` },`,
225
+ ` build: {`,
226
+ ` outDir: '${resolve(cwd, 'public', spa.name).replace(/\\/g, '/')}',`,
227
+ ` emptyOutDir: true,`,
228
+ ` },`,
229
+ ` resolve: {`,
230
+ ` preserveSymlinks: true,`,
231
+ ` alias: {`,
232
+ ` '~spa': '${spa.path.replace(/\\/g, '/')}',`,
233
+ ];
234
+ // Deduplicate React — monorepo packages may resolve different copies
235
+ // Point to the package directory so sub-path imports (react/jsx-runtime) still work
236
+ for (const reactPkg of ['react', 'react-dom']) {
237
+ try {
238
+ const pkgDir = dirname(require.resolve(`${reactPkg}/package.json`, { paths: [cwd] })).replace(/\\/g, '/');
239
+ lines.push(` '${reactPkg}': '${pkgDir}',`);
240
+ }
241
+ catch {
242
+ /* not found */
243
+ }
244
+ }
245
+ // App pages often import peer UI deps directly. In a pnpm workspace those
246
+ // deps may live under a Manta package node_modules rather than the app root.
247
+ const depResolvePaths = [cwd];
248
+ const addDepResolvePath = (path) => {
249
+ if (!depResolvePaths.includes(path))
250
+ depResolvePaths.push(path);
251
+ };
252
+ try {
253
+ addDepResolvePath(dirname(require.resolve('@mantajs/dashboard/package.json', { paths: [cwd] })));
254
+ }
255
+ catch {
256
+ /* not found */
257
+ }
258
+ try {
259
+ const uiDir = dirname(require.resolve('@mantajs/ui/package.json', { paths: [cwd] }));
260
+ addDepResolvePath(uiDir);
261
+ addDepResolvePath(resolve(dirname(require.resolve('radix-ui', { paths: [uiDir] })), '..'));
262
+ }
263
+ catch {
264
+ /* not found */
265
+ }
266
+ const directPeerDeps = [
267
+ '@ai-sdk/react',
268
+ '@date-fns/tz',
269
+ '@hookform/resolvers',
270
+ '@tanstack/react-query',
271
+ '@tanstack/react-table',
272
+ 'lucide-react',
273
+ 'zod',
274
+ 'react-router-dom',
275
+ 'recharts',
276
+ 'react-hook-form',
277
+ 'react-helmet-async',
278
+ 'motion',
279
+ 'motion/react',
280
+ 'radix-ui',
281
+ 'react-day-picker',
282
+ 'date-fns',
283
+ 'cmdk',
284
+ 'class-variance-authority',
285
+ 'clsx',
286
+ 'tailwind-merge',
287
+ 'sonner',
288
+ '@radix-ui/react-slot',
289
+ '@radix-ui/react-checkbox',
290
+ '@radix-ui/react-dialog',
291
+ '@radix-ui/react-popover',
292
+ '@radix-ui/react-progress',
293
+ '@radix-ui/react-radio-group',
294
+ '@radix-ui/react-scroll-area',
295
+ '@radix-ui/react-select',
296
+ '@radix-ui/react-switch',
297
+ '@radix-ui/react-tabs',
298
+ ];
299
+ for (const depPkg of directPeerDeps) {
300
+ try {
301
+ let resolved = '';
302
+ let packageDir = '';
303
+ try {
304
+ packageDir = dirname(require.resolve(`${depPkg}/package.json`, { paths: depResolvePaths }));
305
+ resolved = packageDir;
306
+ }
307
+ catch {
308
+ resolved = require.resolve(depPkg, { paths: depResolvePaths });
309
+ packageDir = dirname(resolved);
310
+ }
311
+ addDepResolvePath(packageDir);
312
+ lines.push(` '${depPkg}': '${resolved.replace(/\\/g, '/')}',`);
313
+ }
314
+ catch {
315
+ /* not found */
316
+ }
317
+ }
318
+ // Resolve Manta packages for Vite alias
319
+ const pkgsToResolve = ['@mantajs/sdk', '@mantajs/ui'];
320
+ if (dashboard)
321
+ pkgsToResolve.push(dashboard);
322
+ for (const pkg of pkgsToResolve) {
323
+ try {
324
+ const pkgDir = dirname(require.resolve(`${pkg}/package.json`, { paths: [cwd] }));
325
+ const distDir = join(pkgDir, 'dist');
326
+ const sourceDir = existsSync(distDir) ? distDir : join(pkgDir, 'src');
327
+ const hasDist = sourceDir === distDir;
328
+ const hasTsx = existsSync(join(pkgDir, 'src', 'index.tsx'));
329
+ const entryFile = hasDist ? 'dist/index.js' : hasTsx ? 'src/index.tsx' : 'src/index.ts';
330
+ // Exact import → entry file, sub-path imports (e.g. /index.css) → package source/build directory
331
+ lines.push(` '${pkg}': '${join(pkgDir, entryFile).replace(/\\/g, '/')}',`);
332
+ lines.push(` '${pkg}/': '${sourceDir.replace(/\\/g, '/')}/',`);
333
+ }
334
+ catch {
335
+ // Not resolved — let Vite handle it
336
+ }
337
+ }
338
+ lines.push(` },`);
339
+ lines.push(` },`);
340
+ lines.push(`})`);
341
+ return lines.join('\n');
342
+ }
343
+ function routeToVarName(route) {
344
+ if (route === '/')
345
+ return 'PageHome';
346
+ return ('Page' +
347
+ route
348
+ .split('/')
349
+ .filter(Boolean)
350
+ .map((s) => s
351
+ .replace(/^:/, '')
352
+ .split('-')
353
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
354
+ .join(''))
355
+ .join(''));
356
+ }
357
+ //# sourceMappingURL=generate-spa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-spa.js","sourceRoot":"","sources":["../../src/spa/generate-spa.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ # Manta + Next.js — AI Agent Instructions
2
+
3
+ You are working in a **Next.js App Router project with Manta mounted inline**. The frontend is Next.js (React 19, App Router, TypeScript). The backend is Manta — a filesystem-first framework with integrated database, CQRS, auth, and admin dashboard. **They run in the same process**: Next owns the HTTP server; Manta lives inside a catch-all route handler.
4
+
5
+ ## Stack
6
+
7
+ - **Runtime**: Next.js 15 App Router
8
+ - **Backend**: Manta (auto-discovered from `src/modules/`, `src/commands/`, `src/queries/`, …)
9
+ - **Database**: PostgreSQL (managed by Manta through its adapters)
10
+ - **API**: Auto-generated from Manta commands, queries, auth, and the query graph
11
+ - **Admin**: `@mantajs/dashboard` mounted as a Next client component (no separate Vite server)
12
+
13
+ ## How they are wired together
14
+
15
+ The entire integration is 3 files in the Next project:
16
+
17
+ ```typescript
18
+ // next.config.ts
19
+ import { withManta } from '@mantajs/adapter-nextjs'
20
+ export default withManta({})
21
+ ```
22
+
23
+ ```typescript
24
+ // app/api/[...manta]/route.ts
25
+ export { GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD } from '@mantajs/adapter-nextjs/handler'
26
+ ```
27
+
28
+ ```typescript
29
+ // app/admin/[[...slug]]/page.tsx
30
+ export { default } from '@mantajs/adapter-nextjs/admin'
31
+ ```
32
+
33
+ - The API catch-all forwards every `/api/*` request to Manta's internal HTTP pipeline. All Manta-generated routes (commands, queries, graph, auth, openapi) are reachable this way.
34
+ - The admin catch-all mounts the Manta dashboard as a client component. Next bundles `@mantajs/dashboard` itself via `transpilePackages` (configured by `withManta`). `react-router-dom` inside the dashboard handles sub-routes.
35
+ - `withManta()` sets `transpilePackages` + `serverExternalPackages` so the raw-TS `@mantajs/*` workspace packages and native deps (postgres, pino, drizzle-orm) play nice with Next.
36
+
37
+ ## Project layout
38
+
39
+ ```
40
+ my-app/
41
+ ├── app/ Next.js App Router (frontend + API mount points)
42
+ │ ├── layout.tsx
43
+ │ ├── page.tsx your public home
44
+ │ ├── api/[...manta]/route.ts 1 line: re-export from @mantajs/adapter-nextjs/handler
45
+ │ ├── admin/[[...slug]]/page.tsx 1 line: re-export from @mantajs/adapter-nextjs/admin
46
+ │ └── (your other Next pages)
47
+
48
+ ├── lib/ shared client-side code (hooks, utilities, types)
49
+
50
+ ├── src/ Manta backend (filesystem-first, auto-discovered)
51
+ │ ├── modules/{mod}/entities/{entity}/{model,service}.ts
52
+ │ ├── commands/{context}/{name}.ts
53
+ │ ├── queries/{context}/{name,graph}.ts
54
+ │ ├── subscribers/{name}.ts
55
+ │ ├── jobs/{name}.ts
56
+ │ ├── links/{name}.ts
57
+ │ ├── agents/{name}.ts
58
+ │ └── middleware/{context}.ts
59
+
60
+ ├── manta.config.ts defineConfig — database, ports, presets
61
+ ├── next.config.ts withManta({})
62
+ ├── tsconfig.json
63
+ └── AGENT.md this file
64
+ ```
65
+
66
+ ## Development workflow
67
+
68
+ ```bash
69
+ pnpm dev # runs next dev — that's it. No separate Manta process.
70
+ pnpm generate # regenerate .manta/generated.d.ts (types for defineModel, field, etc.)
71
+ pnpm db:generate # create SQL migration from model changes
72
+ pnpm db:migrate # apply migrations to the database
73
+ ```
74
+
75
+ Manta boots lazily inside the Next.js server on the first API request (singleton pattern in `@mantajs/adapter-nextjs/bootstrap`). Subsequent requests reuse the cached app. Hot reload works normally — Next reloads on file changes, and Manta re-boots on module edits.
76
+
77
+ ## Consuming Manta from Next
78
+
79
+ ### From client components (most common)
80
+
81
+ Use `@mantajs/sdk` hooks — they call the relative `/api/*` endpoints via `fetch`:
82
+
83
+ ```typescript
84
+ 'use client'
85
+ import { useQuery, useCommand, useGraphQuery } from '@mantajs/sdk'
86
+
87
+ const { data } = useQuery('list-products', { status: 'active' })
88
+ const createProduct = useCommand('create-product')
89
+ const { data: products } = useGraphQuery({ entity: 'product', relations: ['inventory_item'] })
90
+ ```
91
+
92
+ ### From React Server Components
93
+
94
+ Two options:
95
+
96
+ 1. **HTTP round-trip** (simplest): `fetch('/api/public/my-query', ...)` from the RSC. Works everywhere, no singleton coupling.
97
+ 2. **Direct app access** (zero-latency): import `getMantaApp` from `@mantajs/adapter-nextjs` and call `app.queryService.graph(...)` / `app.commandRegistry.execute(...)` directly. Bypasses HTTP entirely. Use when you need sub-millisecond latency for SSR.
98
+
99
+ ```typescript
100
+ // app/products/page.tsx — RSC
101
+ import { getMantaApp } from '@mantajs/adapter-nextjs'
102
+
103
+ export default async function ProductsPage() {
104
+ const app = await getMantaApp()
105
+ const products = await app.queryService.graph({ entity: 'product', pagination: { take: 20 } })
106
+ return <ProductList products={products} />
107
+ }
108
+ ```
109
+
110
+ ### From Next API routes (for frontend-specific endpoints)
111
+
112
+ Don't. If you need a new endpoint, create a `defineCommand` or `defineQuery` in `src/`. The only Next API route you should own is the `[...manta]` catch-all. This keeps auth, validation, and auto-docs uniform.
113
+
114
+ ## Critical rules
115
+
116
+ 1. **No Next API routes beyond the catch-all** — Commands and queries ARE the API. Every endpoint goes through `src/commands/` or `src/queries/`. The `/api/[...manta]` catch-all covers everything.
117
+ 2. **`app/` is for pages only** (including RSC and client components). Backend logic lives in `src/`.
118
+ 3. **`src/spa/admin/pages/` is NOT used in the Next preset** — unlike the Nitro preset, where it feeds a Vite-built SPA. Custom admin pages in Next are inserted via `<MantaDashboard pageSpecs={...} customBlocks={...}>` props if you need them. For most projects the auto-generated dashboard is enough.
119
+ 4. **Always use `@mantajs/sdk` hooks in client components** — never hand-roll `fetch('/api/...')`. The SDK handles auth tokens, error normalisation, and React Query integration.
120
+ 5. **RSC → `getMantaApp()` path is optional** — prefer it for SSR data fetching, but `fetch('/api/...')` also works and is simpler for static rendering.
121
+ 6. **Manta rules still apply** — the 14 primitives below (`defineModel`, `defineCommand`, `defineQuery`, `defineWorkflow`, …) govern the backend exactly as in a standalone Manta project. Entity names PascalCase, 1 entity = 1 service, compensation automatic, etc.
122
+
123
+ ## Deployment
124
+
125
+ Manta-on-Next is a normal Next app. Deploy to Vercel, Node servers, or any runtime that supports Next 15 + server functions. Make sure `DATABASE_URL` is set in the environment. Manta's cold-start overhead is ~100-200ms on first request (singleton bootstrap).
126
+
127
+ ---
128
+
129
+ _The sections below are the canonical Manta primitives reference. Everything after this line is identical to the standalone Manta AGENT.md and applies to the `src/` backend in this project._
@@ -0,0 +1,98 @@
1
+ # Manta + Nuxt — AI Agent Instructions
2
+
3
+ You are working in a **Nuxt project with Manta backend**. The frontend is Nuxt (Vue, auto-imports). The backend is Manta — a tool-first runtime for AI agents with an integrated database.
4
+
5
+ ## Stack
6
+
7
+ - **Frontend**: Nuxt 3 (Vue 3, auto-imports, Nitro server)
8
+ - **Backend**: Manta (CQRS commands, DML models, compensable workflows)
9
+ - **Database**: PostgreSQL (managed by Manta)
10
+ - **API**: Auto-generated from Manta commands and contexts
11
+
12
+ ## How they connect
13
+
14
+ Nuxt calls Manta's auto-generated API endpoints via `$fetch` or `useFetch`:
15
+
16
+ ```typescript
17
+ // In a Nuxt page or composable:
18
+ const { data: posts } = await useFetch('http://localhost:9000/api/store/query/blog', {
19
+ method: 'POST',
20
+ body: { filters: { status: 'published' }, limit: 10 },
21
+ })
22
+
23
+ // Execute a command:
24
+ const result = await $fetch('http://localhost:9000/api/admin/command/create-post', {
25
+ method: 'POST',
26
+ headers: { Authorization: `Bearer ${token}` },
27
+ body: { title: 'Hello World', slug: 'hello-world', content: '...' },
28
+ })
29
+ ```
30
+
31
+ ## Manta backend structure
32
+
33
+ The Manta backend lives alongside Nuxt:
34
+
35
+ ```
36
+ my-app/
37
+ ├── pages/ # Nuxt pages (frontend)
38
+ ├── components/ # Nuxt components
39
+ ├── composables/ # Nuxt composables
40
+ ├── server/ # Nuxt server routes (if needed)
41
+ ├── src/ # Manta backend
42
+ │ ├── modules/
43
+ │ │ └── blog/
44
+ │ │ ├── entities/
45
+ │ │ │ └── post/
46
+ │ │ │ ├── model.ts
47
+ │ │ │ └── service.ts
48
+ │ │ └── index.ts
49
+ │ ├── commands/
50
+ │ ├── subscribers/
51
+ │ ├── jobs/
52
+ │ ├── links/
53
+ │ └── contexts/
54
+ ├── manta.config.ts # Manta configuration
55
+ ├── nuxt.config.ts # Nuxt configuration
56
+ └── AGENT.md # This file
57
+ ```
58
+
59
+ ## Manta backend rules
60
+
61
+ Same rules as standalone Manta. See documentation links below.
62
+
63
+ ### The 8 primitives
64
+
65
+ | Function | Purpose | Location |
66
+ |----------|---------|----------|
67
+ | `defineModel()` | Data entity schema | `src/modules/{mod}/entities/{entity}/model.ts` |
68
+ | `defineService()` | Mutations with compensation | `src/modules/{mod}/entities/{entity}/service.ts` |
69
+ | `defineCommand()` | Workflow entry point | `src/commands/{name}.ts` |
70
+ | `defineSubscriber()` | Event reaction | `src/subscribers/{name}.ts` |
71
+ | `defineJob()` | Cron task | `src/jobs/{name}.ts` |
72
+ | `defineLink()` | Cross-module relation | `src/links/{name}.ts` |
73
+ | `defineContext()` | API surface | `src/contexts/{name}.ts` |
74
+ | `defineConfig()` | Configuration | `manta.config.ts` |
75
+
76
+ ### Critical rules
77
+
78
+ 1. **No API routes in Manta** — Commands are the API. Use Nuxt `server/` routes only for frontend-specific needs.
79
+ 2. **1 entity = 1 service** — `model.ts` + `service.ts` per entity.
80
+ 3. **Compensation is mandatory** in `service.method()`.
81
+ 4. **Use `step.service.*` in commands**.
82
+ 5. **Entity names are PascalCase**.
83
+
84
+ ## Running both
85
+
86
+ ```bash
87
+ # Terminal 1: Manta backend
88
+ manta dev
89
+
90
+ # Terminal 2: Nuxt frontend
91
+ nuxt dev
92
+ ```
93
+
94
+ ## Documentation
95
+
96
+ Complete Manta documentation in `node_modules/@mantajs/core/docs/` — see [00-overview.md](node_modules/@mantajs/core/docs/00-overview.md) to start.
97
+
98
+ **Read the relevant doc BEFORE writing Manta backend code.**