@squadbase/vantage 0.6.2-dev1.a7c4a3e → 0.6.2-dev1.ac99e02

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 (186) hide show
  1. package/dist/add-4GHF2TX2.js +6 -0
  2. package/dist/add-4GHF2TX2.js.map +1 -0
  3. package/dist/{build-JB4VOMUI.js → build-MFWRPYKW.js} +9 -9
  4. package/dist/{build-JB4VOMUI.js.map → build-MFWRPYKW.js.map} +1 -1
  5. package/dist/{check-ZJYK6RLG.js → check-ZBIH422T.js} +7 -7
  6. package/dist/{check-ZJYK6RLG.js.map → check-ZBIH422T.js.map} +1 -1
  7. package/dist/{chunk-BCE22JSM.js → chunk-7DZGJQ3P.js} +33 -14
  8. package/dist/chunk-7DZGJQ3P.js.map +1 -0
  9. package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
  10. package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
  11. package/dist/{chunk-MP3QSOXL.js → chunk-AG6RZ2RR.js} +992 -16
  12. package/dist/chunk-AG6RZ2RR.js.map +1 -0
  13. package/dist/{chunk-KLEIVDUV.js → chunk-CEXAQQ5W.js} +150 -11
  14. package/dist/chunk-CEXAQQ5W.js.map +1 -0
  15. package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
  16. package/dist/chunk-GNXCX4WE.js.map +1 -0
  17. package/dist/chunk-IBGOCWJB.js +1716 -0
  18. package/dist/chunk-IBGOCWJB.js.map +1 -0
  19. package/dist/{chunk-JGRMRXXZ.js → chunk-JKLLFVEU.js} +3 -3
  20. package/dist/{chunk-JGRMRXXZ.js.map → chunk-JKLLFVEU.js.map} +1 -1
  21. package/dist/{chunk-RPZAALCX.js → chunk-OB6UBJXF.js} +153 -153
  22. package/dist/{chunk-RPZAALCX.js.map → chunk-OB6UBJXF.js.map} +1 -1
  23. package/dist/{chunk-EP6JHXSR.js → chunk-QEWCYW3I.js} +44 -9
  24. package/dist/chunk-QEWCYW3I.js.map +1 -0
  25. package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
  26. package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
  27. package/dist/{chunk-PVTHHV7X.js → chunk-V3LF7BE7.js} +27 -5
  28. package/dist/chunk-V3LF7BE7.js.map +1 -0
  29. package/dist/{chunk-DTDVSFRY.js → chunk-XQUSGIDG.js} +17 -3
  30. package/dist/chunk-XQUSGIDG.js.map +1 -0
  31. package/dist/cli.js +12 -11
  32. package/dist/cli.js.map +1 -1
  33. package/dist/client/index.d.ts +32 -3
  34. package/dist/client/index.js +205 -12
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/components/index.d.ts +216 -1
  37. package/dist/components/index.js +2 -2
  38. package/dist/{dev-FCEC3UKQ.js → dev-DCTOHQ6W.js} +10 -10
  39. package/dist/dev-DCTOHQ6W.js.map +1 -0
  40. package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
  41. package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
  42. package/dist/{doctor-WHZXPERA.js → doctor-5E2VEZPK.js} +7 -7
  43. package/dist/{doctor-WHZXPERA.js.map → doctor-5E2VEZPK.js.map} +1 -1
  44. package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
  45. package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
  46. package/dist/query/index.d.ts +0 -11
  47. package/dist/query/index.js +2 -2
  48. package/dist/{routes-GTFO5PUF.js → routes-3SGAFDMC.js} +6 -6
  49. package/dist/{routes-GTFO5PUF.js.map → routes-3SGAFDMC.js.map} +1 -1
  50. package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
  51. package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
  52. package/dist/slide/index.js +47 -10
  53. package/dist/slide/index.js.map +1 -1
  54. package/dist/table/index.js +8 -7
  55. package/dist/table/index.js.map +1 -1
  56. package/dist/ui/index.d.ts +140 -10
  57. package/dist/ui/index.js +1405 -63
  58. package/dist/ui/index.js.map +1 -1
  59. package/dist/{upgrade-AL4KZZR4.js → upgrade-DBBE6GIR.js} +7 -7
  60. package/dist/{upgrade-AL4KZZR4.js.map → upgrade-DBBE6GIR.js.map} +1 -1
  61. package/dist/vite/index.d.ts +10 -0
  62. package/dist/vite/index.js +4 -4
  63. package/docs/index.json +291 -61
  64. package/docs/ja/changelog.md +26 -0
  65. package/docs/ja/components.md +33 -89
  66. package/docs/ja/page-types/csv.md +83 -0
  67. package/docs/ja/page-types/doc.md +83 -0
  68. package/docs/ja/page-types/excel.md +82 -0
  69. package/docs/ja/page-types/slide.md +132 -0
  70. package/docs/ja/page-types.md +47 -0
  71. package/docs/ja/parts/area-chart.md +61 -0
  72. package/docs/ja/parts/bar-chart.md +69 -0
  73. package/docs/ja/parts/bar-list.md +35 -0
  74. package/docs/ja/parts/category-bar.md +36 -0
  75. package/docs/ja/parts/donut-chart.md +47 -0
  76. package/docs/ja/parts/echart.md +3 -0
  77. package/docs/ja/parts/line-chart.md +58 -0
  78. package/docs/ja/parts/progress-circle.md +34 -0
  79. package/docs/ja/parts/sparkline.md +1 -1
  80. package/docs/ja/parts/tracker.md +32 -0
  81. package/docs/ja/routing.md +8 -86
  82. package/docs/ja/ui/alert-dialog.md +41 -0
  83. package/docs/ja/ui/avatar.md +31 -0
  84. package/docs/ja/ui/combobox.md +74 -0
  85. package/docs/ja/ui/drawer.md +41 -0
  86. package/docs/ja/ui/field.md +42 -0
  87. package/docs/ja/ui/hover-card.md +21 -0
  88. package/docs/ja/ui/kbd.md +16 -0
  89. package/docs/ja/ui/pagination.md +36 -0
  90. package/docs/ja/ui/radio-group.md +21 -0
  91. package/docs/ja/ui/toast.md +46 -0
  92. package/docs/ja/ui-and-theming.md +14 -7
  93. package/package.json +25 -13
  94. package/registry/ui/accordion.tsx +74 -0
  95. package/registry/ui/alert-dialog.tsx +189 -0
  96. package/registry/ui/alert.tsx +78 -0
  97. package/registry/ui/app-shell.tsx +281 -0
  98. package/registry/ui/area-chart.tsx +1015 -0
  99. package/registry/ui/avatar.tsx +110 -0
  100. package/registry/ui/badge.tsx +54 -0
  101. package/registry/ui/bar-chart.tsx +1013 -0
  102. package/registry/ui/bar-list.tsx +302 -0
  103. package/registry/ui/breadcrumb.tsx +126 -0
  104. package/registry/ui/button.tsx +60 -0
  105. package/registry/ui/calendar.tsx +221 -0
  106. package/registry/ui/card.tsx +105 -0
  107. package/registry/ui/category-bar.tsx +281 -0
  108. package/registry/ui/checkbox.tsx +28 -0
  109. package/registry/ui/collapsible.tsx +21 -0
  110. package/registry/ui/combobox.tsx +310 -0
  111. package/registry/ui/command.tsx +196 -0
  112. package/registry/ui/dashboard-card.tsx +174 -0
  113. package/registry/ui/data-table.tsx +16 -91
  114. package/registry/ui/date-range-picker.tsx +209 -0
  115. package/registry/ui/dialog.tsx +159 -0
  116. package/registry/ui/donut-chart.tsx +1004 -0
  117. package/registry/ui/drawer.tsx +229 -0
  118. package/registry/ui/dropdown-menu.tsx +272 -0
  119. package/registry/ui/echart.tsx +486 -0
  120. package/registry/ui/field.tsx +240 -0
  121. package/registry/ui/filter-bar.tsx +365 -0
  122. package/registry/ui/funnel-steps.tsx +274 -0
  123. package/registry/ui/hover-card.tsx +52 -0
  124. package/registry/ui/input-group.tsx +158 -0
  125. package/registry/ui/input.tsx +22 -0
  126. package/registry/ui/kbd.tsx +28 -0
  127. package/registry/ui/label.tsx +20 -0
  128. package/registry/ui/line-chart.tsx +1007 -0
  129. package/registry/ui/metric-value.tsx +54 -0
  130. package/registry/ui/multi-select.tsx +226 -0
  131. package/registry/ui/page-shell.tsx +227 -0
  132. package/registry/ui/pagination.tsx +138 -0
  133. package/registry/ui/placeholder.tsx +30 -0
  134. package/registry/ui/popover.tsx +90 -0
  135. package/registry/ui/progress-circle.tsx +272 -0
  136. package/registry/ui/progress.tsx +83 -0
  137. package/registry/ui/radio-group.tsx +39 -0
  138. package/registry/ui/scroll-area.tsx +55 -0
  139. package/registry/ui/searchable-select.tsx +209 -0
  140. package/registry/ui/section-header.tsx +41 -0
  141. package/registry/ui/segmented-control.tsx +71 -0
  142. package/registry/ui/select.tsx +253 -0
  143. package/registry/ui/separator.tsx +25 -0
  144. package/registry/ui/sheet.tsx +137 -0
  145. package/registry/ui/sidebar.tsx +723 -0
  146. package/registry/ui/skeleton.tsx +15 -0
  147. package/registry/ui/slider.tsx +54 -0
  148. package/registry/ui/sparkline.tsx +155 -0
  149. package/registry/ui/spinner.tsx +12 -0
  150. package/registry/ui/states.tsx +61 -0
  151. package/registry/ui/status-badge.tsx +79 -0
  152. package/registry/ui/switch.tsx +32 -0
  153. package/registry/ui/table.tsx +116 -0
  154. package/registry/ui/tabs.tsx +82 -0
  155. package/registry/ui/textarea.tsx +20 -0
  156. package/registry/ui/toast.tsx +250 -0
  157. package/registry/ui/toggle-group.tsx +89 -0
  158. package/registry/ui/toggle.tsx +45 -0
  159. package/registry/ui/tooltip.tsx +66 -0
  160. package/registry/ui/tracker.tsx +236 -0
  161. package/registry/ui/trend-indicator.tsx +62 -0
  162. package/skills/vantage-add-feature/SKILL.md +9 -7
  163. package/skills/vantage-design/SKILL.md +3 -1
  164. package/skills/vantage-design/references/format.md +1 -1
  165. package/skills/vantage-pitfalls/SKILL.md +5 -1
  166. package/skills/vantage-slide/SKILL.md +17 -0
  167. package/templates/AGENTS.md +10 -1
  168. package/templates/agents/api.md +29 -0
  169. package/templates/agents/csv.md +2 -1
  170. package/templates/agents/doc.md +4 -3
  171. package/templates/agents/page.md +22 -8
  172. package/templates/agents/slide.md +13 -1
  173. package/templates/agents/xlsx.md +2 -1
  174. package/theme.css +7 -1
  175. package/dist/add-DY4AXANK.js +0 -6
  176. package/dist/add-DY4AXANK.js.map +0 -1
  177. package/dist/chunk-BCE22JSM.js.map +0 -1
  178. package/dist/chunk-DTDVSFRY.js.map +0 -1
  179. package/dist/chunk-EP6JHXSR.js.map +0 -1
  180. package/dist/chunk-KLEIVDUV.js.map +0 -1
  181. package/dist/chunk-MP3QSOXL.js.map +0 -1
  182. package/dist/chunk-PVTHHV7X.js.map +0 -1
  183. package/dist/chunk-QI3XQKHS.js.map +0 -1
  184. package/dist/chunk-T3FLAGI6.js +0 -316
  185. package/dist/chunk-T3FLAGI6.js.map +0 -1
  186. package/dist/dev-FCEC3UKQ.js.map +0 -1
@@ -0,0 +1,6 @@
1
+ export { add, syncAgentsFile } from './chunk-AABMKHEU.js';
2
+ import './chunk-RNTDBX6S.js';
3
+ import './chunk-GNXCX4WE.js';
4
+ import './chunk-C2CX6GLX.js';
5
+ //# sourceMappingURL=add-4GHF2TX2.js.map
6
+ //# sourceMappingURL=add-4GHF2TX2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"add-4GHF2TX2.js"}
@@ -1,12 +1,12 @@
1
- import { runDiagnostics } from './chunk-BCE22JSM.js';
2
- import './chunk-JGRMRXXZ.js';
3
- import { vantagePlugin } from './chunk-T3FLAGI6.js';
4
- import { generateArtifacts } from './chunk-EP6JHXSR.js';
5
- import './chunk-KLEIVDUV.js';
6
- import { scanProject, timedAsync } from './chunk-ZVANIULZ.js';
1
+ import { runDiagnostics } from './chunk-7DZGJQ3P.js';
2
+ import './chunk-JKLLFVEU.js';
3
+ import { vantagePlugin } from './chunk-IBGOCWJB.js';
4
+ import { generateArtifacts } from './chunk-QEWCYW3I.js';
5
+ import './chunk-CEXAQQ5W.js';
6
+ import { scanProject, timedAsync } from './chunk-RNTDBX6S.js';
7
7
  import './chunk-46QI6GFC.js';
8
8
  import './chunk-B7LLBNLV.js';
9
- import { printDiagnostics, log, applyApiBaseUrlFlag } from './chunk-QI3XQKHS.js';
9
+ import { printDiagnostics, log, applyApiBaseUrlFlag } from './chunk-GNXCX4WE.js';
10
10
  import { VANTAGE_DIR, MANIFEST_SCHEMA_VERSION } from './chunk-C2CX6GLX.js';
11
11
  import fs from 'fs';
12
12
  import path from 'path';
@@ -104,5 +104,5 @@ function writeDeployManifest(root, model) {
104
104
  }
105
105
 
106
106
  export { build };
107
- //# sourceMappingURL=build-JB4VOMUI.js.map
108
- //# sourceMappingURL=build-JB4VOMUI.js.map
107
+ //# sourceMappingURL=build-MFWRPYKW.js.map
108
+ //# sourceMappingURL=build-MFWRPYKW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/build.ts"],"names":["viteBuild"],"mappings":"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","file":"build-JB4VOMUI.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { build as viteBuild, loadEnv } from \"vite\"\nimport { MANIFEST_SCHEMA_VERSION, VANTAGE_DIR } from \"../core/constants\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { generateArtifacts } from \"../core/generate\"\nimport { timedAsync } from \"../core/profile\"\nimport { scanProject } from \"../core/scan\"\nimport type { RouteModel } from \"../core/types\"\nimport { vantagePlugin } from \"../vite/index\"\nimport { applyApiBaseUrlFlag, log, printDiagnostics, type ParsedArgs } from \"./util\"\n\nconst SERVER_ENTRY = `// AUTO-GENERATED by @squadbase/vantage.\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { startNodeServer } from \"@squadbase/vantage/server/node\"\nimport { apiRoutes } from \"./server-routes.gen\"\n\nconst clientDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"../client\")\nstartNodeServer({ apiRoutes, clientDir })\n`\n\n/** `vantage build` — build client and (optionally) server into dist/. */\nexport async function build(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const errors = runDiagnostics(root, model).filter((d) => d.severity === \"error\")\n if (errors.length) {\n printDiagnostics(errors)\n log.error(\"Fix the errors above before building.\")\n return 1\n }\n\n const mode = \"production\"\n // `--api-base-url` feeds the client's PUBLIC_API_BASE_URL. Setting it on\n // process.env (before loadEnv/Vite read env) makes the flag win over any .env\n // value and keeps the single env-prefix mechanism — no Vite `define`.\n applyApiBaseUrlFlag(args)\n const env = { ...process.env, ...loadEnv(mode, root, \"\") }\n const quiet = Boolean(args.flags.json)\n\n // Write .vantage/ up front instead of letting the plugin do it at\n // configResolved: the server bundle reads server-routes.gen.ts, so once the\n // artifacts exist the two builds no longer depend on each other and can run\n // at the same time (they write to dist/client and dist/server respectively).\n generateArtifacts({ root, model })\n\n if (!quiet) log.step(model.hasServer ? \"Building client and server…\" : \"Building client…\")\n\n const clientBuild = timedAsync(\"build:client\", async () => {\n await viteBuild({\n configFile: false,\n root,\n mode,\n plugins: [vantagePlugin({ root, env, model, artifactsWritten: true })],\n logLevel: quiet ? \"silent\" : args.flags.verbose ? \"info\" : \"warn\",\n })\n // The HTML input lives in .vantage/, so Vite emits it to dist/client/.vantage/.\n // Hoist it to dist/client/index.html (asset URLs are already root-absolute).\n relocateClientHtml(root)\n })\n\n const serverBuild = model.hasServer\n ? timedAsync(\"build:server\", () => buildServer(root))\n : Promise.resolve()\n\n await Promise.all([clientBuild, serverBuild])\n\n writeDeployManifest(root, model)\n if (!quiet) log.ok(`Build complete → ${path.relative(process.cwd(), path.join(root, \"dist\")) || \"dist\"}/`)\n\n if (args.flags.json) {\n process.stdout.write(\n JSON.stringify({\n ok: true,\n mode: model.hasServer ? \"fullstack\" : \"spa\",\n output: \"dist\",\n pages: model.pages.length,\n apis: model.apis.length,\n }) + \"\\n\",\n )\n }\n return 0\n}\n\nfunction relocateClientHtml(root: string): void {\n const clientDir = path.join(root, \"dist\", \"client\")\n const nested = path.join(clientDir, VANTAGE_DIR, \"index.html\")\n const target = path.join(clientDir, \"index.html\")\n if (fs.existsSync(nested)) {\n fs.mkdirSync(clientDir, { recursive: true })\n fs.renameSync(nested, target)\n fs.rmSync(path.join(clientDir, VANTAGE_DIR), { recursive: true, force: true })\n }\n}\n\nasync function buildServer(root: string): Promise<void> {\n // Loaded here, not at module scope: an SPA project never builds a server and\n // should not pay for esbuild's binary being brought up.\n const { build: esbuildBuild } = await import(\"esbuild\")\n const vantageDir = path.join(root, VANTAGE_DIR)\n const entry = path.join(vantageDir, \"server-entry.ts\")\n fs.writeFileSync(entry, SERVER_ENTRY)\n await esbuildBuild({\n entryPoints: [entry],\n outfile: path.join(root, \"dist\", \"server\", \"index.mjs\"),\n bundle: true,\n platform: \"node\",\n format: \"esm\",\n target: \"node20\",\n logLevel: \"warning\",\n banner: { js: \"// @squadbase/vantage server bundle\" },\n })\n}\n\nfunction writeDeployManifest(root: string, model: RouteModel): void {\n const dist = path.join(root, \"dist\")\n fs.mkdirSync(dist, { recursive: true })\n const manifest = {\n schemaVersion: MANIFEST_SCHEMA_VERSION,\n mode: model.hasServer ? \"fullstack\" : \"spa\",\n client: \"./client\",\n ...(model.hasServer ? { server: \"./server/index.mjs\" } : {}),\n spaFallback: \"./client/index.html\",\n runtime: \"node\",\n }\n fs.writeFileSync(path.join(dist, \"vantage-manifest.json\"), JSON.stringify(manifest, null, 2) + \"\\n\")\n}\n"]}
1
+ {"version":3,"sources":["../src/cli/build.ts"],"names":["viteBuild"],"mappings":"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","file":"build-MFWRPYKW.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { build as viteBuild, loadEnv } from \"vite\"\nimport { MANIFEST_SCHEMA_VERSION, VANTAGE_DIR } from \"../core/constants\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { generateArtifacts } from \"../core/generate\"\nimport { timedAsync } from \"../core/profile\"\nimport { scanProject } from \"../core/scan\"\nimport type { RouteModel } from \"../core/types\"\nimport { vantagePlugin } from \"../vite/index\"\nimport { applyApiBaseUrlFlag, log, printDiagnostics, type ParsedArgs } from \"./util\"\n\nconst SERVER_ENTRY = `// AUTO-GENERATED by @squadbase/vantage.\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { startNodeServer } from \"@squadbase/vantage/server/node\"\nimport { apiRoutes } from \"./server-routes.gen\"\n\nconst clientDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), \"../client\")\nstartNodeServer({ apiRoutes, clientDir })\n`\n\n/** `vantage build` — build client and (optionally) server into dist/. */\nexport async function build(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const errors = runDiagnostics(root, model).filter((d) => d.severity === \"error\")\n if (errors.length) {\n printDiagnostics(errors)\n log.error(\"Fix the errors above before building.\")\n return 1\n }\n\n const mode = \"production\"\n // `--api-base-url` feeds the client's PUBLIC_API_BASE_URL. Setting it on\n // process.env (before loadEnv/Vite read env) makes the flag win over any .env\n // value and keeps the single env-prefix mechanism — no Vite `define`.\n applyApiBaseUrlFlag(args)\n const env = { ...process.env, ...loadEnv(mode, root, \"\") }\n const quiet = Boolean(args.flags.json)\n\n // Write .vantage/ up front instead of letting the plugin do it at\n // configResolved: the server bundle reads server-routes.gen.ts, so once the\n // artifacts exist the two builds no longer depend on each other and can run\n // at the same time (they write to dist/client and dist/server respectively).\n generateArtifacts({ root, model })\n\n if (!quiet) log.step(model.hasServer ? \"Building client and server…\" : \"Building client…\")\n\n const clientBuild = timedAsync(\"build:client\", async () => {\n await viteBuild({\n configFile: false,\n root,\n mode,\n plugins: [vantagePlugin({ root, env, model, artifactsWritten: true })],\n logLevel: quiet ? \"silent\" : args.flags.verbose ? \"info\" : \"warn\",\n })\n // The HTML input lives in .vantage/, so Vite emits it to dist/client/.vantage/.\n // Hoist it to dist/client/index.html (asset URLs are already root-absolute).\n relocateClientHtml(root)\n })\n\n const serverBuild = model.hasServer\n ? timedAsync(\"build:server\", () => buildServer(root))\n : Promise.resolve()\n\n await Promise.all([clientBuild, serverBuild])\n\n writeDeployManifest(root, model)\n if (!quiet) log.ok(`Build complete → ${path.relative(process.cwd(), path.join(root, \"dist\")) || \"dist\"}/`)\n\n if (args.flags.json) {\n process.stdout.write(\n JSON.stringify({\n ok: true,\n mode: model.hasServer ? \"fullstack\" : \"spa\",\n output: \"dist\",\n pages: model.pages.length,\n apis: model.apis.length,\n }) + \"\\n\",\n )\n }\n return 0\n}\n\nfunction relocateClientHtml(root: string): void {\n const clientDir = path.join(root, \"dist\", \"client\")\n const nested = path.join(clientDir, VANTAGE_DIR, \"index.html\")\n const target = path.join(clientDir, \"index.html\")\n if (fs.existsSync(nested)) {\n fs.mkdirSync(clientDir, { recursive: true })\n fs.renameSync(nested, target)\n fs.rmSync(path.join(clientDir, VANTAGE_DIR), { recursive: true, force: true })\n }\n}\n\nasync function buildServer(root: string): Promise<void> {\n // Loaded here, not at module scope: an SPA project never builds a server and\n // should not pay for esbuild's binary being brought up.\n const { build: esbuildBuild } = await import(\"esbuild\")\n const vantageDir = path.join(root, VANTAGE_DIR)\n const entry = path.join(vantageDir, \"server-entry.ts\")\n fs.writeFileSync(entry, SERVER_ENTRY)\n await esbuildBuild({\n entryPoints: [entry],\n outfile: path.join(root, \"dist\", \"server\", \"index.mjs\"),\n bundle: true,\n platform: \"node\",\n format: \"esm\",\n target: \"node20\",\n logLevel: \"warning\",\n banner: { js: \"// @squadbase/vantage server bundle\" },\n })\n}\n\nfunction writeDeployManifest(root: string, model: RouteModel): void {\n const dist = path.join(root, \"dist\")\n fs.mkdirSync(dist, { recursive: true })\n const manifest = {\n schemaVersion: MANIFEST_SCHEMA_VERSION,\n mode: model.hasServer ? \"fullstack\" : \"spa\",\n client: \"./client\",\n ...(model.hasServer ? { server: \"./server/index.mjs\" } : {}),\n spaFallback: \"./client/index.html\",\n runtime: \"node\",\n }\n fs.writeFileSync(path.join(dist, \"vantage-manifest.json\"), JSON.stringify(manifest, null, 2) + \"\\n\")\n}\n"]}
@@ -1,8 +1,8 @@
1
- import { runDiagnostics } from './chunk-BCE22JSM.js';
2
- import './chunk-JGRMRXXZ.js';
3
- import './chunk-KLEIVDUV.js';
4
- import { scanProject } from './chunk-ZVANIULZ.js';
5
- import { printJson, log, printDiagnostics } from './chunk-QI3XQKHS.js';
1
+ import { runDiagnostics } from './chunk-7DZGJQ3P.js';
2
+ import './chunk-JKLLFVEU.js';
3
+ import './chunk-CEXAQQ5W.js';
4
+ import { scanProject } from './chunk-RNTDBX6S.js';
5
+ import { printJson, log, printDiagnostics } from './chunk-GNXCX4WE.js';
6
6
  import './chunk-C2CX6GLX.js';
7
7
 
8
8
  // @squadbase/vantage — generated build. Do not edit.
@@ -34,5 +34,5 @@ async function check(root, args) {
34
34
  }
35
35
 
36
36
  export { check };
37
- //# sourceMappingURL=check-ZJYK6RLG.js.map
38
- //# sourceMappingURL=check-ZJYK6RLG.js.map
37
+ //# sourceMappingURL=check-ZBIH422T.js.map
38
+ //# sourceMappingURL=check-ZBIH422T.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/check.ts"],"names":[],"mappings":";;;;;;;;;;AAKA,eAAsB,KAAA,CAAM,MAAc,IAAA,EAAmC;AAC3E,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,IAAA,EAAM,KAAK,CAAA;AACxC,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,OAAO,CAAA;AACzD,EAAA,MAAM,WAAW,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,SAAS,CAAA;AAE7D,EAAA,IAAI,IAAA,CAAK,MAAM,IAAA,EAAM;AACnB,IAAA,SAAA,CAAU;AAAA,MACR,EAAA,EAAI,OAAO,MAAA,KAAW,CAAA;AAAA,MACtB,YAAY,MAAA,CAAO,MAAA;AAAA,MACnB,cAAc,QAAA,CAAS,MAAA;AAAA,MACvB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAO,MAAA,CAAO,SAAS,CAAA,GAAI,CAAA;AAAA,EAC7B;AAEA,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,GAAA,CAAI,GAAG,oBAAoB,CAAA;AAC3B,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,IAAI,MAAA,CAAO,MAAA,EAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,OAAO,MAAM,CAAA,WAAA,EAAc,QAAA,CAAS,MAAM,CAAA,YAAA,CAAc,CAAA;AAAA,OACnF,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,YAAA,CAAc,CAAA;AAC9C,EAAA,OAAO,MAAA,CAAO,SAAS,CAAA,GAAI,CAAA;AAC7B","file":"check-ZJYK6RLG.js","sourcesContent":["import { runDiagnostics } from \"../core/diagnostics\"\nimport { scanProject } from \"../core/scan\"\nimport { log, printDiagnostics, printJson, type ParsedArgs } from \"./util\"\n\n/** `vantage check` — static verification of the project. */\nexport async function check(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const diags = runDiagnostics(root, model)\n const errors = diags.filter((d) => d.severity === \"error\")\n const warnings = diags.filter((d) => d.severity === \"warning\")\n\n if (args.flags.json) {\n printJson({\n ok: errors.length === 0,\n errorCount: errors.length,\n warningCount: warnings.length,\n diagnostics: diags,\n })\n return errors.length ? 1 : 0\n }\n\n if (diags.length === 0) {\n log.ok(\"No problems found.\")\n return 0\n }\n printDiagnostics(diags)\n console.log(\"\")\n if (errors.length) log.error(`${errors.length} error(s), ${warnings.length} warning(s).`)\n else log.warn(`${warnings.length} warning(s).`)\n return errors.length ? 1 : 0\n}\n"]}
1
+ {"version":3,"sources":["../src/cli/check.ts"],"names":[],"mappings":";;;;;;;;;;AAKA,eAAsB,KAAA,CAAM,MAAc,IAAA,EAAmC;AAC3E,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,IAAA,EAAM,KAAK,CAAA;AACxC,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,OAAO,CAAA;AACzD,EAAA,MAAM,WAAW,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,SAAS,CAAA;AAE7D,EAAA,IAAI,IAAA,CAAK,MAAM,IAAA,EAAM;AACnB,IAAA,SAAA,CAAU;AAAA,MACR,EAAA,EAAI,OAAO,MAAA,KAAW,CAAA;AAAA,MACtB,YAAY,MAAA,CAAO,MAAA;AAAA,MACnB,cAAc,QAAA,CAAS,MAAA;AAAA,MACvB,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAO,MAAA,CAAO,SAAS,CAAA,GAAI,CAAA;AAAA,EAC7B;AAEA,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,GAAA,CAAI,GAAG,oBAAoB,CAAA;AAC3B,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,IAAI,MAAA,CAAO,MAAA,EAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,OAAO,MAAM,CAAA,WAAA,EAAc,QAAA,CAAS,MAAM,CAAA,YAAA,CAAc,CAAA;AAAA,OACnF,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,YAAA,CAAc,CAAA;AAC9C,EAAA,OAAO,MAAA,CAAO,SAAS,CAAA,GAAI,CAAA;AAC7B","file":"check-ZBIH422T.js","sourcesContent":["import { runDiagnostics } from \"../core/diagnostics\"\nimport { scanProject } from \"../core/scan\"\nimport { log, printDiagnostics, printJson, type ParsedArgs } from \"./util\"\n\n/** `vantage check` — static verification of the project. */\nexport async function check(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const diags = runDiagnostics(root, model)\n const errors = diags.filter((d) => d.severity === \"error\")\n const warnings = diags.filter((d) => d.severity === \"warning\")\n\n if (args.flags.json) {\n printJson({\n ok: errors.length === 0,\n errorCount: errors.length,\n warningCount: warnings.length,\n diagnostics: diags,\n })\n return errors.length ? 1 : 0\n }\n\n if (diags.length === 0) {\n log.ok(\"No problems found.\")\n return 0\n }\n printDiagnostics(diags)\n console.log(\"\")\n if (errors.length) log.error(`${errors.length} error(s), ${warnings.length} warning(s).`)\n else log.warn(`${warnings.length} warning(s).`)\n return errors.length ? 1 : 0\n}\n"]}
@@ -1,5 +1,6 @@
1
- import { detectApiMethods, maskSource, stripComments } from './chunk-JGRMRXXZ.js';
2
- import { timed } from './chunk-ZVANIULZ.js';
1
+ import { detectApiMethods, maskSource, stripComments } from './chunk-JKLLFVEU.js';
2
+ import { isHomePagePath, isPlaceholderHomePage } from './chunk-CEXAQQ5W.js';
3
+ import { timed } from './chunk-RNTDBX6S.js';
3
4
  import { PUBLIC_ENV_PREFIX, FORBIDDEN_FILES, ROUTED_EXTENSIONS, SRC_DIR, SUSPICIOUS_ROUTE_DIRS, FILE_PAGE_EXTENSIONS, FILE_PAGE_MAX_BYTES, API_METHODS } from './chunk-C2CX6GLX.js';
4
5
  import fs from 'fs';
5
6
  import path from 'path';
@@ -168,24 +169,42 @@ function checkSuspiciousRouteDirs(model) {
168
169
  }
169
170
  return diags;
170
171
  }
171
- function checkRouteConflicts(model) {
172
+ function checkRouteConflicts(ctx) {
172
173
  const byPath = /* @__PURE__ */ new Map();
173
- for (const page of model.pages) {
174
+ for (const page of ctx.model.pages) {
174
175
  const list = byPath.get(page.routePath) ?? [];
175
176
  list.push(page.file);
176
177
  byPath.set(page.routePath, list);
177
178
  }
178
179
  const diags = [];
179
180
  for (const [routePath, files] of byPath) {
180
- if (files.length > 1) {
181
- diags.push({
182
- code: "ROUTE_CONFLICT",
183
- severity: "error",
184
- message: `${files.length} files resolve to ${routePath}`,
185
- files,
186
- fix: "Rename or remove one route file so each route is unique. A page-kind suffix and a data-file extension both drop out of the URL, so `june.slide.tsx`, `june.csv` and `june.tsx` all resolve to /june."
181
+ if (files.length <= 1) continue;
182
+ if (routePath === "/") {
183
+ const nonPlaceholders = files.filter((file) => {
184
+ if (!isHomePagePath(file)) return true;
185
+ const abs = path.join(ctx.root, file);
186
+ const content = ctx.raw(abs);
187
+ return content === null || !isPlaceholderHomePage(content);
187
188
  });
189
+ if (nonPlaceholders.length <= 1) continue;
190
+ if (nonPlaceholders.length < files.length) {
191
+ diags.push({
192
+ code: "ROUTE_CONFLICT",
193
+ severity: "error",
194
+ message: `${nonPlaceholders.length} files resolve to ${routePath}`,
195
+ files: nonPlaceholders,
196
+ fix: "Rename or remove one route file so each route is unique. A page-kind suffix and a data-file extension both drop out of the URL, so `june.slide.tsx`, `june.csv` and `june.tsx` all resolve to /june."
197
+ });
198
+ continue;
199
+ }
188
200
  }
201
+ diags.push({
202
+ code: "ROUTE_CONFLICT",
203
+ severity: "error",
204
+ message: `${files.length} files resolve to ${routePath}`,
205
+ files,
206
+ fix: "Rename or remove one route file so each route is unique. A page-kind suffix and a data-file extension both drop out of the URL, so `june.slide.tsx`, `june.csv` and `june.tsx` all resolve to /june."
207
+ });
189
208
  }
190
209
  return diags;
191
210
  }
@@ -492,7 +511,7 @@ function runDiagnostics(root, model) {
492
511
  ...checkForbiddenFiles(ctx),
493
512
  ...checkSrcLayout(ctx),
494
513
  ...checkSuspiciousRouteDirs(model),
495
- ...checkRouteConflicts(model),
514
+ ...checkRouteConflicts(ctx),
496
515
  ...checkUnroutedFiles(ctx),
497
516
  ...checkFilePageSize(ctx),
498
517
  ...checkPageExports(ctx),
@@ -506,5 +525,5 @@ function runDiagnostics(root, model) {
506
525
  }
507
526
 
508
527
  export { runDiagnostics };
509
- //# sourceMappingURL=chunk-BCE22JSM.js.map
510
- //# sourceMappingURL=chunk-BCE22JSM.js.map
528
+ //# sourceMappingURL=chunk-7DZGJQ3P.js.map
529
+ //# sourceMappingURL=chunk-7DZGJQ3P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/diagnostics.ts"],"names":[],"mappings":"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","file":"chunk-7DZGJQ3P.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport {\n API_METHODS,\n FILE_PAGE_EXTENSIONS,\n FILE_PAGE_MAX_BYTES,\n FORBIDDEN_FILES,\n PUBLIC_ENV_PREFIX,\n ROUTED_EXTENSIONS,\n SRC_DIR,\n SUSPICIOUS_ROUTE_DIRS,\n} from \"./constants\"\nimport { isHomePagePath, isPlaceholderHomePage } from \"./placeholder\"\nimport { timed } from \"./profile\"\nimport { detectApiMethods } from \"./route-spec\"\nimport { maskSource, stripComments } from \"./source\"\nimport type { Diagnostic, RouteModel } from \"./types\"\n\n/** Vite/env identifiers that are always allowed on `import.meta.env`. */\nconst ALLOWED_ENV_KEYS = new Set([\"MODE\", \"DEV\", \"PROD\", \"SSR\", \"BASE_URL\", \"PUBLIC_\"])\n\n/** Whether a module has a default export (direct, aliased, or re-exported). */\nfunction hasDefaultExport(src: string): boolean {\n return (\n /\\bexport\\s+default\\b/.test(src) ||\n /\\bexport\\s*\\{[^}]*\\bas\\s+default\\b[^}]*\\}/.test(src) ||\n /\\bexport\\s*\\{[^}]*\\bdefault\\b[^}]*\\}\\s*from\\b/.test(src)\n )\n}\n\n/** Collect client-side source files (everything outside server/ and generated dirs). */\nfunction collectClientFiles(root: string): string[] {\n const out: string[] = []\n const skipDirs = new Set([\"node_modules\", \".vantage\", \"dist\", \"server\", \"public\"])\n const walk = (dir: string) => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\")) continue\n const abs = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (skipDirs.has(entry.name)) continue\n walk(abs)\n } else if (/\\.(tsx?|jsx?)$/.test(entry.name)) {\n out.push(abs)\n }\n }\n }\n walk(root)\n return out\n}\n\n/**\n * Per-run scratch space. Every checker reads the filesystem through this, so a\n * `check` walks the project once and reads (and `stripComments`) each source\n * file at most once — page modules used to be read three times over, and the\n * client tree used to be walked twice.\n */\ninterface Ctx {\n root: string\n model: RouteModel\n /** Raw file text for an absolute path; null when unreadable. */\n raw(abs: string): string | null\n /** Comment-stripped source for an absolute path; null when unreadable. */\n source(abs: string): string | null\n /**\n * Byte size of a file; null when unreadable. Separate from `source` because\n * `source` decodes as UTF-8 and strips comments — fine for a page module,\n * ruinous for a few MB of spreadsheet.\n */\n size(abs: string): number | null\n /** Client-side source files, walked lazily and only once. */\n clientFiles(): string[]\n /** `readdir` of the project root, read lazily and only once. */\n rootEntries(): string[]\n}\n\nfunction createCtx(root: string, model: RouteModel): Ctx {\n const raws = new Map<string, string | null>()\n const sources = new Map<string, string | null>()\n const sizes = new Map<string, number | null>()\n let clientFiles: string[] | null = null\n let rootEntries: string[] | null = null\n\n const raw = (abs: string): string | null => {\n const hit = raws.get(abs)\n if (hit !== undefined) return hit\n let text: string | null\n try {\n text = fs.readFileSync(abs, \"utf8\")\n } catch {\n text = null\n }\n raws.set(abs, text)\n return text\n }\n\n return {\n root,\n model,\n raw,\n source(abs) {\n const hit = sources.get(abs)\n if (hit !== undefined) return hit\n const text = raw(abs)\n const src = text === null ? null : stripComments(text)\n sources.set(abs, src)\n return src\n },\n size(abs) {\n const hit = sizes.get(abs)\n if (hit !== undefined) return hit\n let bytes: number | null\n try {\n bytes = fs.statSync(abs).size\n } catch {\n bytes = null\n }\n sizes.set(abs, bytes)\n return bytes\n },\n clientFiles() {\n return (clientFiles ??= collectClientFiles(root))\n },\n rootEntries() {\n if (rootEntries) return rootEntries\n try {\n rootEntries = fs.readdirSync(root)\n } catch {\n rootEntries = []\n }\n return rootEntries\n },\n }\n}\n\nfunction rel(root: string, abs: string): string {\n return path.relative(root, abs).split(path.sep).join(\"/\")\n}\n\n/** Detect forbidden config files at the project root. */\nfunction checkForbiddenFiles(ctx: Ctx): Diagnostic[] {\n const diags: Diagnostic[] = []\n for (const name of ctx.rootEntries()) {\n for (const rule of FORBIDDEN_FILES) {\n if (rule.pattern.test(name)) {\n diags.push({\n code: \"FORBIDDEN_FILE\",\n severity: \"error\",\n message: `${rule.label} file \"${name}\" is not allowed in a Vantage project.`,\n files: [name],\n fix: rule.remedy,\n })\n }\n }\n }\n return diags\n}\n\n/**\n * Detect a project split between `src/` and the project root. Once `src/`\n * exists it is the only page-scan root, so anything left behind at the root is\n * silently dead — and `server/` moved *into* `src/` is silently unserved.\n */\nfunction checkSrcLayout(ctx: Ctx): Diagnostic[] {\n const { root, model } = ctx\n if (model.pageDir === \"\") return []\n const diags: Diagnostic[] = []\n\n const entries = ctx.rootEntries()\n // Lowercased before matching, as scan does: `Sales.CSV` at the root is a\n // stray page too, and saying so is the whole point of this check.\n const strayPages = entries.filter((name) =>\n ROUTED_EXTENSIONS.some((ext) => name.toLowerCase().endsWith(ext)),\n )\n if (strayPages.length > 0) {\n diags.push({\n code: \"SRC_DIR_SPLIT\",\n severity: \"error\",\n message: `${strayPages.length} page module(s) sit at the project root, but ${SRC_DIR}/ exists so pages are only scanned from ${SRC_DIR}/.`,\n files: strayPages.sort(),\n fix: `Move them into ${SRC_DIR}/, or delete ${SRC_DIR}/ to keep a root-level layout.`,\n })\n }\n\n if (entries.includes(\"styles.css\")) {\n diags.push({\n code: \"SRC_DIR_SPLIT\",\n severity: \"error\",\n message: `styles.css sits at the project root, but ${SRC_DIR}/ exists so the global stylesheet is read from ${SRC_DIR}/styles.css.`,\n files: [\"styles.css\"],\n fix: `Move it to ${SRC_DIR}/styles.css.`,\n })\n }\n\n if (fs.existsSync(path.join(root, SRC_DIR, \"server\"))) {\n diags.push({\n code: \"SRC_DIR_SPLIT\",\n severity: \"error\",\n message: `${SRC_DIR}/server/ is never scanned: server code lives at the project root, outside the client source tree.`,\n files: [`${SRC_DIR}/server`],\n fix: `Move it to server/ at the project root.`,\n })\n }\n\n return diags\n}\n\n/** Flag routes generated from directories that are almost certainly scaffolding. */\nfunction checkSuspiciousRouteDirs(model: RouteModel): Diagnostic[] {\n const byDir = new Map<string, { files: string[]; routes: string[] }>()\n for (const page of model.pages) {\n const top = page.dir.split(\"/\")[0] ?? \"\"\n if (top === \"\" || !SUSPICIOUS_ROUTE_DIRS.has(top)) continue\n const hit = byDir.get(top) ?? { files: [], routes: [] }\n hit.files.push(page.file)\n hit.routes.push(page.routePath)\n byDir.set(top, hit)\n }\n\n const diags: Diagnostic[] = []\n for (const [dir, hit] of byDir) {\n diags.push({\n code: \"SUSPICIOUS_ROUTE_DIR\",\n severity: \"warning\",\n message: `${dir}/ is part of the URL: ${hit.routes.slice(0, 3).join(\", \")}${\n hit.routes.length > 3 ? \", …\" : \"\"\n }`,\n files: hit.files,\n fix: `Directory names become route segments. Non-page modules belong in components/, hooks/ or lib/ (never scanned); if ${dir}/ really is meant to be a URL segment, ignore this warning.`,\n })\n }\n return diags\n}\n\n/** Detect two page files resolving to the same route path. */\nfunction checkRouteConflicts(ctx: Ctx): Diagnostic[] {\n const byPath = new Map<string, string[]>()\n for (const page of ctx.model.pages) {\n const list = byPath.get(page.routePath) ?? []\n list.push(page.file)\n byPath.set(page.routePath, list)\n }\n const diags: Diagnostic[] = []\n for (const [routePath, files] of byPath) {\n if (files.length <= 1) continue\n\n // Special case: if route is \"/\" and one of the files is the untouched\n // template placeholder home page, exclude it from the conflict.\n // This allows new artifacts (e.g. index.slide.tsx) to claim \"/\" when\n // the placeholder has not been edited.\n if (routePath === \"/\") {\n const nonPlaceholders = files.filter((file) => {\n if (!isHomePagePath(file)) return true\n const abs = path.join(ctx.root, file)\n const content = ctx.raw(abs)\n return content === null || !isPlaceholderHomePage(content)\n })\n\n // If only one non-placeholder file remains, no conflict.\n if (nonPlaceholders.length <= 1) continue\n\n // If multiple non-placeholder files, report conflict with only those.\n if (nonPlaceholders.length < files.length) {\n diags.push({\n code: \"ROUTE_CONFLICT\",\n severity: \"error\",\n message: `${nonPlaceholders.length} files resolve to ${routePath}`,\n files: nonPlaceholders,\n fix: \"Rename or remove one route file so each route is unique. A page-kind suffix and a data-file extension both drop out of the URL, so `june.slide.tsx`, `june.csv` and `june.tsx` all resolve to /june.\",\n })\n continue\n }\n }\n\n diags.push({\n code: \"ROUTE_CONFLICT\",\n severity: \"error\",\n message: `${files.length} files resolve to ${routePath}`,\n files,\n fix: \"Rename or remove one route file so each route is unique. A page-kind suffix and a data-file extension both drop out of the URL, so `june.slide.tsx`, `june.csv` and `june.tsx` all resolve to /june.\",\n })\n }\n return diags\n}\n\n/**\n * Speak up about files the scan walked past. Neither case reaches the router,\n * so nothing else in the toolchain has an opportunity to mention them: the\n * page simply never appears in `routes`, in the nav, or at a URL. Without this\n * the only symptom is absence.\n */\nfunction checkUnroutedFiles(ctx: Ctx): Diagnostic[] {\n const diags: Diagnostic[] = []\n for (const entry of ctx.model.unrouted) {\n if (entry.reason === \"extension\") {\n diags.push({\n code: \"UNSUPPORTED_PAGE_FILE\",\n severity: \"warning\",\n message: `\"${entry.file}\" is not a page: Vantage has no viewer for \"${path.posix.extname(\n entry.file,\n )}\".`,\n files: [entry.file],\n fix: `Only ${FILE_PAGE_EXTENSIONS.join(\" and \")} files become pages. Convert it, or render it from a .tsx page with <TableViewer> from @squadbase/vantage/table.`,\n })\n continue\n }\n diags.push({\n code: \"INVALID_PAGE_VARIANT\",\n severity: \"error\",\n message: `\"${entry.file}\" carries the \"${entry.variant}\" page kind but is not a page module, so it is not routed.`,\n files: [entry.file],\n fix: `A page kind only applies to a page module that becomes a route: name it <name>.${entry.variant}.tsx. Layouts, _404/_error and underscore-prefixed modules cannot carry one.`,\n })\n }\n return diags\n}\n\n/**\n * Data-file pages are parsed in the browser, so an oversized file does not\n * fail the build — it renders an error on its own page. A warning, not an\n * error, keeps one large export from blocking a deploy of everything else.\n */\nfunction checkFilePageSize(ctx: Ctx): Diagnostic[] {\n const diags: Diagnostic[] = []\n for (const page of ctx.model.pages) {\n if (page.kind !== \"file\") continue\n const size = ctx.size(page.absFile)\n if (size === null || size <= FILE_PAGE_MAX_BYTES) continue\n diags.push({\n code: \"FILE_PAGE_TOO_LARGE\",\n severity: \"warning\",\n message: `${page.file} is ${(size / 1024 / 1024).toFixed(1)} MB, so ${page.routePath} will show an error instead of a table.`,\n files: [page.file],\n fix: `Data-file pages are parsed in the browser and capped at ${\n FILE_PAGE_MAX_BYTES / 1024 / 1024\n } MB. Serve larger data from server/api/ and render it with DataTable.`,\n })\n }\n return diags\n}\n\n/** Ensure every page module has a default export. */\nfunction checkPageExports(ctx: Ctx): Diagnostic[] {\n const { root, model } = ctx\n const diags: Diagnostic[] = []\n const pageFiles = [\n // Data-file pages have no default export to look for — their component is\n // the generated wrapper, not the `.csv` itself.\n ...model.pages.filter((p) => p.kind === \"module\").map((p) => p.absFile),\n ...model.layouts.map((l) => l.absFile),\n model.notFound && path.join(root, model.notFound),\n model.error && path.join(root, model.error),\n ].filter((x): x is string => Boolean(x))\n\n for (const abs of pageFiles) {\n const src = ctx.source(abs)\n if (src === null) continue\n if (!hasDefaultExport(src)) {\n diags.push({\n code: \"MISSING_DEFAULT_EXPORT\",\n severity: \"error\",\n message: `Page module has no default export.`,\n files: [rel(root, abs)],\n fix: \"A page/layout must `export default` a React component.\",\n })\n }\n }\n return diags\n}\n\n/** Ensure every API module exports at least one valid HTTP method handler. */\nfunction checkApiExports(ctx: Ctx): Diagnostic[] {\n const diags: Diagnostic[] = []\n for (const api of ctx.model.apis) {\n const src = ctx.source(api.absFile)\n if (src === null) continue\n const exported = detectApiMethods(src)\n if (exported.length === 0) {\n // Common mistake: lowercase method names.\n const lower = [\"get\", \"post\", \"put\", \"patch\", \"delete\", \"options\"].filter((m) =>\n new RegExp(`export\\\\s+(async\\\\s+)?function\\\\s+${m}\\\\b`).test(src),\n )\n diags.push({\n code: \"INVALID_API_EXPORT\",\n severity: \"error\",\n message: `API module exports no HTTP method handler${\n lower.length ? ` (found lowercase \"${lower.join(\", \")}\")` : \"\"\n }.`,\n files: [api.file],\n fix: `Export one of: ${API_METHODS.join(\", \")} (uppercase).`,\n })\n }\n }\n return diags\n}\n\n/**\n * The two source-level client checks — the server-import boundary and non-public\n * env reads — in a single pass over the client tree. They used to walk and read\n * the whole tree once each; the diagnostics are still emitted grouped by code so\n * the reported order is unchanged.\n */\nfunction checkClientSources(ctx: Ctx): { boundary: Diagnostic[]; env: Diagnostic[] } {\n const { root } = ctx\n const boundary: Diagnostic[] = []\n const env: Diagnostic[] = []\n const importRe = /(?:import|export)[^'\"]*?from\\s+[\"']([^\"']+)[\"']|import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g\n const envRe = /import\\.meta\\.env\\.([A-Za-z_][A-Za-z0-9_]*)/g\n\n for (const abs of ctx.clientFiles()) {\n const src = ctx.source(abs)\n if (src === null) continue\n\n let m: RegExpExecArray | null\n importRe.lastIndex = 0\n while ((m = importRe.exec(src))) {\n const spec = m[1] ?? m[2]\n if (!spec) continue\n const isServer =\n spec === \"server\" ||\n spec.startsWith(\"server/\") ||\n /(^|\\/)\\.\\.?\\/server(\\/|$)/.test(spec) ||\n /\\/server\\//.test(spec)\n if (isServer) {\n boundary.push({\n code: \"CLIENT_IMPORTS_SERVER\",\n severity: \"error\",\n message: `Client module imports from server/ (\"${spec}\").`,\n files: [rel(root, abs)],\n fix: \"server/ code must never be imported by the client. Move shared code to lib/.\",\n })\n }\n }\n\n envRe.lastIndex = 0\n const bad = new Set<string>()\n while ((m = envRe.exec(src))) {\n const key = m[1]!\n if (ALLOWED_ENV_KEYS.has(key)) continue\n if (key.startsWith(PUBLIC_ENV_PREFIX)) continue\n bad.add(key)\n }\n for (const key of bad) {\n env.push({\n code: \"PUBLIC_ENV_MISUSE\",\n severity: \"warning\",\n message: `Client reads non-public env \"import.meta.env.${key}\".`,\n files: [rel(root, abs)],\n fix: `Only ${PUBLIC_ENV_PREFIX}* vars reach the client. Read secrets via ApiContext.env in server/.`,\n })\n }\n }\n return { boundary, env }\n}\n\n// ── hard-coded colors ────────────────────────────────────────────────────────\n\n/** Tailwind utilities that take a color. */\nconst COLOR_PREFIXES =\n \"text|bg|border|ring|fill|stroke|from|via|to|outline|decoration|divide|accent|caret|shadow|placeholder\"\nconst PALETTES =\n \"slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose\"\nconst COLOR_FNS = \"rgba?|hsla?|oklch|oklab|lab|lch|color\"\n\n/** `dark:hover:bg-blue-500/50` — variants, prefix, palette, opacity. */\nconst PALETTE_CLASS_RE = new RegExp(\n `(?<![\\\\w-])((?:[\\\\w-]+:)*)(${COLOR_PREFIXES})-(${PALETTES})-(50|[1-9]00|950)(\\\\/(?:\\\\d+|\\\\[[^\\\\]\\\\s]+\\\\]))?(?![\\\\w-])`,\n \"g\",\n)\n/** `bg-[#0f172a]`, `text-[rgb(1,2,3)]`, `shadow-[0_0_4px_rgba(…)]`. */\nconst ARBITRARY_CLASS_RE = new RegExp(\n `(?<![\\\\w-])((?:[\\\\w-]+:)*)(${COLOR_PREFIXES})-\\\\[([^\\\\]\\\\s\"'\\`]+)\\\\]`,\n \"g\",\n)\nconst COLOR_FN_RE = new RegExp(\n `(?<![\\\\w-])(?:${COLOR_FNS})\\\\((?:[^()]|\\\\([^()]*\\\\))*\\\\)`,\n \"g\",\n)\nconst HEX_RE = /(?<![\\w&#/-])#([0-9a-fA-F]{3,8})(?![\\w-])/g\nconst HEX_LITERAL_RE = /(?<![\\w&])#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4})(?![\\w-])/\n/** `href=\"#abc\"`, `to=\"#add\"` — an anchor, not a color. */\nconst ANCHOR_BEFORE_RE = /\\b(?:href|to|id|hash)\\s*[=:]\\s*\\{?\\s*[\"'`]$/\n\nconst NEUTRAL_PALETTES = new Set([\"slate\", \"gray\", \"zinc\", \"neutral\", \"stone\"])\nconst DANGER_PALETTES = new Set([\"red\", \"rose\"])\n/** Nearest chart token per hue family — the `--chart-1..5` order in theme.css. */\nconst CHART_BY_PALETTE: Record<string, string> = {\n blue: \"chart-1\",\n indigo: \"chart-1\",\n sky: \"chart-1\",\n cyan: \"chart-1\",\n green: \"chart-2\",\n emerald: \"chart-2\",\n teal: \"chart-2\",\n lime: \"chart-2\",\n orange: \"chart-3\",\n amber: \"chart-3\",\n yellow: \"chart-3\",\n violet: \"chart-4\",\n purple: \"chart-4\",\n fuchsia: \"chart-4\",\n pink: \"chart-5\",\n}\nconst MAX_COLOR_HITS = 20\n\n/** Semantic-token candidates for a Tailwind palette class. */\nfunction suggestPaletteClass(variants: string, prefix: string, palette: string, opacity: string): string[] {\n const t = (token: string) => `${variants}${prefix}-${token}${opacity}`\n if (DANGER_PALETTES.has(palette)) return [t(\"destructive\")]\n if (NEUTRAL_PALETTES.has(palette)) {\n if (prefix === \"text\") return [t(\"foreground\"), t(\"muted-foreground\")]\n if (prefix === \"bg\") return [t(\"muted\"), t(\"card\")]\n if (prefix === \"border\" || prefix === \"divide\" || prefix === \"outline\") return [t(\"border\")]\n if (prefix === \"ring\") return [t(\"ring\")]\n return [t(\"muted-foreground\")]\n }\n const chart = CHART_BY_PALETTE[palette] ?? \"chart-1\"\n return chart === \"chart-1\" ? [t(\"primary\"), t(chart)] : [t(chart), t(\"primary\")]\n}\n\n/** Whether a Tailwind arbitrary value carries a literal color. */\nfunction isColorValue(value: string): boolean {\n if (value.includes(\"var(\")) return false\n return HEX_LITERAL_RE.test(value) || new RegExp(`(?<![\\\\w-])(?:${COLOR_FNS})\\\\(`).test(value)\n}\n\ninterface ColorHit {\n line: number\n text: string\n suggest: string[]\n}\n\n/** Every hard-coded color in one module, with raw-file line numbers. */\nfunction findColorHits(raw: string): ColorHit[] {\n const rawLines = raw.split(\"\\n\")\n if (rawLines.slice(0, 5).some((l) => l.includes(\"vantage-ignore-color-file\"))) return []\n // A marker exempts its own line (trailing comment) and the next (comment above).\n const ignored = new Set<number>()\n rawLines.forEach((l, i) => {\n if (l.includes(\"vantage-ignore-color\")) ignored.add(i + 1).add(i + 2)\n })\n\n const { code, inString } = maskSource(raw)\n const lineStarts = [0]\n for (let i = 0; i < raw.length; i++) if (raw[i] === \"\\n\") lineStarts.push(i + 1)\n const lineAt = (offset: number) => {\n let lo = 0\n let hi = lineStarts.length - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (lineStarts[mid]! <= offset) lo = mid\n else hi = mid - 1\n }\n return lo + 1\n }\n\n const hits: ColorHit[] = []\n const covered: [number, number][] = []\n const isCovered = (at: number) => covered.some(([s, e]) => at >= s && at < e)\n const push = (at: number, end: number, text: string, suggest: string[]) => {\n if (!inString[at] || isCovered(at)) return\n covered.push([at, end])\n const line = lineAt(at)\n if (ignored.has(line)) return\n hits.push({ line, text: text.length > 48 ? `${text.slice(0, 47)}…` : text, suggest })\n }\n\n let m: RegExpExecArray | null\n ARBITRARY_CLASS_RE.lastIndex = 0\n while ((m = ARBITRARY_CLASS_RE.exec(code))) {\n if (!isColorValue(m[3]!)) continue\n const token = (m[2] === \"shadow\" ? \"\" : m[2]!) || \"bg\"\n push(m.index, m.index + m[0].length, m[0], [\n `${m[1]}${token}-primary`,\n `${m[1]}${token}-chart-1`,\n ])\n }\n PALETTE_CLASS_RE.lastIndex = 0\n while ((m = PALETTE_CLASS_RE.exec(code))) {\n push(\n m.index,\n m.index + m[0].length,\n m[0],\n suggestPaletteClass(m[1]!, m[2]!, m[3]!, m[5] ?? \"\"),\n )\n }\n const literalSuggest = [\"var(--primary)\", \"var(--chart-1..5)\", \"var(--muted-foreground)\"]\n COLOR_FN_RE.lastIndex = 0\n while ((m = COLOR_FN_RE.exec(code))) {\n if (m[0].includes(\"var(\")) continue\n push(m.index, m.index + m[0].length, m[0], literalSuggest)\n }\n HEX_RE.lastIndex = 0\n while ((m = HEX_RE.exec(code))) {\n const hex = m[1]!\n if (![3, 4, 6, 8].includes(hex.length)) continue\n const before = code.slice(Math.max(0, m.index - 24), m.index)\n if (ANCHOR_BEFORE_RE.test(before)) continue\n // `\"Order #123\"` is a number, not a color, unless it opens a literal.\n if (hex.length <= 4 && /^\\d+$/.test(hex) && !/[\"'`[]$/.test(before)) continue\n push(m.index, m.index + m[0].length, m[0], literalSuggest)\n }\n return hits.sort((a, b) => a.line - b.line)\n}\n\n/**\n * Colors belong to the theme: `theme.css` / `styles.css` define the tokens and\n * DESIGN.md names them, so a literal in a component silently opts out of light/\n * dark, `styles.css` overrides and chart presets. Only `.ts`/`.tsx` is scanned —\n * `.css` is where the values are supposed to live. Warning, never error: a map\n * fill or a status color can legitimately carry data meaning.\n */\nfunction checkHardcodedColors(ctx: Ctx): Diagnostic[] {\n const diags: Diagnostic[] = []\n for (const abs of ctx.clientFiles()) {\n if (!/\\.tsx?$/.test(abs) || abs.endsWith(\".d.ts\")) continue\n const raw = ctx.raw(abs)\n if (raw === null) continue\n const hits = findColorHits(raw)\n if (hits.length === 0) continue\n const file = rel(ctx.root, abs)\n const shown = hits.slice(0, MAX_COLOR_HITS)\n const more = hits.length - shown.length\n const lines = shown.map((h) => `L${h.line}: ${h.text} → suggest: ${h.suggest.join(\" / \")}`)\n if (more > 0) lines.push(`+${more} more`)\n diags.push({\n code: \"HARDCODED_COLOR\",\n severity: \"warning\",\n message: `${file} hard-codes ${hits.length} color(s):\\n ${lines.join(\"\\n \")}`,\n files: [...new Set(shown.map((h) => `${file}:${h.line}`))].concat(more > 0 ? [`+${more} more`] : []),\n fix: \"Use theme tokens instead (bg-primary, text-muted-foreground, var(--chart-N), … as defined in styles.css and named in DESIGN.md). If a color carries data meaning (e.g. map fills), put `// vantage-ignore-color` (`{/* vantage-ignore-color */}` inside JSX) on that line or the line above; `vantage-ignore-color-file` within the first 5 lines exempts the whole file.\",\n })\n }\n return diags\n}\n\nconst DESIGN_MD_MAX_LINES = 150\n\n/** DESIGN.md is a map of token names, not a second copy of styles.css. */\nfunction checkDesignDoc(ctx: Ctx): Diagnostic[] {\n if (!ctx.rootEntries().includes(\"DESIGN.md\")) return []\n const raw = ctx.raw(path.join(ctx.root, \"DESIGN.md\"))\n if (raw === null) return []\n const lines = raw.replace(/\\n$/, \"\").split(\"\\n\").length\n if (lines <= DESIGN_MD_MAX_LINES) return []\n return [\n {\n code: \"DESIGN_MD_TOO_LONG\",\n severity: \"warning\",\n message: `DESIGN.md is ${lines} lines long (aim for ${DESIGN_MD_MAX_LINES} or fewer).`,\n files: [\"DESIGN.md\"],\n fix: \"Keep concrete values (colors, spacing, …) in styles.css and refer to them by token name (--primary, --chart-1, …) in DESIGN.md to keep it short.\",\n },\n ]\n}\n\n/** Run all static diagnostics for a project. */\nexport function runDiagnostics(root: string, model: RouteModel): Diagnostic[] {\n return timed(\"diagnostics\", () => {\n const ctx = createCtx(root, model)\n const client = checkClientSources(ctx)\n return [\n ...checkForbiddenFiles(ctx),\n ...checkSrcLayout(ctx),\n ...checkSuspiciousRouteDirs(model),\n ...checkRouteConflicts(ctx),\n ...checkUnroutedFiles(ctx),\n ...checkFilePageSize(ctx),\n ...checkPageExports(ctx),\n ...checkApiExports(ctx),\n ...client.boundary,\n ...client.env,\n ...checkHardcodedColors(ctx),\n ...checkDesignDoc(ctx),\n ]\n })\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { resolvePageRoot } from './chunk-ZVANIULZ.js';
2
- import { log } from './chunk-QI3XQKHS.js';
1
+ import { resolvePageRoot } from './chunk-RNTDBX6S.js';
2
+ import { log } from './chunk-GNXCX4WE.js';
3
3
  import fs from 'fs';
4
4
  import path from 'path';
5
5
  import { createRequire } from 'module';
@@ -315,5 +315,5 @@ async function add(root, args) {
315
315
  }
316
316
 
317
317
  export { add, syncAgentsFile };
318
- //# sourceMappingURL=chunk-U2M6HGKQ.js.map
319
- //# sourceMappingURL=chunk-U2M6HGKQ.js.map
318
+ //# sourceMappingURL=chunk-AABMKHEU.js.map
319
+ //# sourceMappingURL=chunk-AABMKHEU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/add.ts"],"names":["require"],"mappings":"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","file":"chunk-U2M6HGKQ.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\nimport { resolvePageRoot } from \"../core/scan\"\nimport { log, type ParsedArgs } from \"./util\"\n\nconst PKG = \"@squadbase/vantage\"\n\nfunction toPascalCase(segment: string): string {\n const cleaned = segment.replace(/\\[|\\]|\\./g, \"\").replace(/\\.\\.\\./g, \"\")\n const words = cleaned.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n const pascal = words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(\"\")\n return /^[A-Za-z]/.test(pascal) ? pascal : \"Page\"\n}\n\nfunction pageTemplate(name: string): string {\n const last = name.split(\"/\").pop() ?? name\n const component = last === \"index\" ? toPascalCase(name.split(\"/\").slice(-2)[0] ?? \"Home\") : toPascalCase(last)\n const title = last.replace(/-/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase())\n return `import { definePage } from \"${PKG}\"\n\nexport const page = definePage({ title: ${JSON.stringify(title)} })\n\nexport default function ${component}() {\n return (\n <main className=\"p-6\">\n <h1 className=\"text-2xl font-semibold\">${title}</h1>\n </main>\n )\n}\n`\n}\n\nfunction apiTemplate(): string {\n return `import type { ApiContext } from \"${PKG}/server\"\n\nexport async function GET({ request, params }: ApiContext) {\n return Response.json({ ok: true, params })\n}\n`\n}\n\nfunction resolvePackageDir(root: string, sub: string): string | null {\n try {\n const require = createRequire(path.join(root, \"noop.js\"))\n const pkgJson = require.resolve(`${PKG}/package.json`)\n return path.join(path.dirname(pkgJson), sub)\n } catch {\n return null\n }\n}\n\nfunction resolveRegistryDir(root: string): string | null {\n return resolvePackageDir(root, \"registry\")\n}\n\nconst SKILL_FILE = \"SKILL.md\"\n\n/** Directories a placed skill never lives in — skipped while scanning. */\nconst SKILL_SCAN_SKIP = new Set([\n \"node_modules\",\n \".git\",\n \".vantage\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".next\",\n \".turbo\",\n \".cache\",\n \".vercel\",\n])\n\n/** How deep below the root the scan goes (`.claude/skills/<name>` is depth 3). */\nconst SKILL_SCAN_DEPTH = 4\n\n/** List the skill directories bundled with the installed framework. */\nfunction listBundledSkills(skillsDir: string): string[] {\n try {\n return fs\n .readdirSync(skillsDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && fs.existsSync(path.join(skillsDir, e.name, SKILL_FILE)))\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/** Paths outside the project read better absolute than as a pile of `../`. */\nfunction displayPath(root: string, target: string): string {\n const rel = path.relative(root, target)\n return !rel ? \".\" : rel.startsWith(\"..\") ? target : rel\n}\n\n/**\n * Find where the bundled skills already live in this project.\n *\n * Placement is a convention, not a fixed path: apps keep them under the root,\n * under `.claude/skills/`, under `.squadbase/skills/`, … so `add skill` looks\n * for the skill *directories* rather than guessing one destination and adding a\n * second copy next to the one that is already there.\n */\nfunction findPlacedSkills(\n root: string,\n names: readonly string[],\n skillsDir: string,\n): Map<string, string[]> {\n const wanted = new Set(names)\n const found = new Map<string, string[]>()\n // A workspace that links the framework by path (not through node_modules)\n // would otherwise report the framework's own `skills/` as a placement.\n const isSource = (p: string) => !path.relative(skillsDir, p).startsWith(\"..\")\n const walk = (dir: string, depth: number): void => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || SKILL_SCAN_SKIP.has(entry.name)) continue\n const abs = path.join(dir, entry.name)\n if (wanted.has(entry.name) && fs.existsSync(path.join(abs, SKILL_FILE))) {\n if (!isSource(abs)) found.set(entry.name, [...(found.get(entry.name) ?? []), abs])\n continue // skills never nest inside one another\n }\n if (depth < SKILL_SCAN_DEPTH) walk(abs, depth + 1)\n }\n }\n walk(root, 1)\n for (const list of found.values()) list.sort()\n return found\n}\n\n/** Copy one bundled skill directory to `dest`, creating parents as needed. */\nfunction writeSkill(root: string, skillsDir: string, name: string, dest: string, verb: string): void {\n fs.mkdirSync(path.dirname(dest), { recursive: true })\n fs.cpSync(path.join(skillsDir, name), dest, { recursive: true, force: true })\n log.ok(`${verb} skill ${displayPath(root, dest)}/`)\n}\n\n/** `vantage add skill` with no name — the bundled list plus where each one sits. */\nfunction printSkillList(root: string, available: string[], placed: Map<string, string[]>): number {\n const width = Math.max(...available.map((n) => n.length))\n log.info(\"Bundled skills:\")\n for (const name of available) {\n const where = placed.get(name)\n const status = where?.length\n ? where.map((p) => displayPath(root, p) + \"/\").join(\", \")\n : \"not placed\"\n log.info(` ${name.padEnd(width)} ${status}`)\n }\n const missing = available.filter((n) => !placed.get(n)?.length)\n if (missing.length) {\n log.info(\"\")\n log.info(\"Place the missing ones with: vantage add skill --all [--dir <path>]\")\n }\n return 0\n}\n\n/**\n * `vantage add skill [<name>|--all] [--dir <path>]` — copy Claude Code skills\n * out of the package.\n *\n * The command scans the project first: a skill that is already placed anywhere\n * (root, `.claude/skills/`, `.squadbase/skills/`, …) is a no-op and its location\n * is reported, so re-running never produces a second copy. `--force` refreshes\n * the placements that were found, in place. Only when nothing is found does the\n * destination matter — the project root, or `--dir` when given (an explicit\n * `--dir` also wins over refreshing somewhere else).\n */\nfunction addSkill(\n root: string,\n name: string | undefined,\n all: boolean,\n force: boolean,\n dir: string | undefined,\n): number {\n const skillsDir = resolvePackageDir(root, \"skills\")\n if (!skillsDir) {\n log.error(\"Could not resolve the Vantage skills directory.\")\n return 1\n }\n const available = listBundledSkills(skillsDir)\n if (available.length === 0) {\n log.error(\"No skills are bundled with this version of Vantage.\")\n return 1\n }\n const placed = findPlacedSkills(root, available, skillsDir)\n if (!all && !name) return printSkillList(root, available, placed)\n\n const destDir = path.resolve(root, dir ?? \".\")\n const targets = all ? available : [name as string]\n let failed = 0\n for (const target of targets) {\n if (!available.includes(target)) {\n log.error(`Unknown skill \"${target}\". Available: ${available.join(\", \")}`)\n failed++\n continue\n }\n const existing = placed.get(target) ?? []\n if (existing.length > 0 && !force) {\n const where = existing.map((p) => displayPath(root, p) + \"/\").join(\", \")\n log.info(`Skill ${target} is already placed at ${where} — skipped (--force to refresh).`)\n continue\n }\n // `--dir` names a destination explicitly, so it wins over refreshing copies\n // that live somewhere else; without it, `--force` updates them where they are.\n const inDestDir = existing.filter((p) => path.dirname(p) === destDir)\n const refresh = dir === undefined ? existing : inDestDir\n if (refresh.length > 0) {\n for (const dest of refresh) writeSkill(root, skillsDir, target, dest, \"Updated\")\n continue\n }\n if (existing.length > 0) {\n const where = existing.map((p) => displayPath(root, p) + \"/\").join(\", \")\n log.warn(`Skill ${target} is also placed at ${where} — left untouched.`)\n }\n writeSkill(root, skillsDir, target, path.join(destDir, target), \"Added\")\n }\n return failed === 0 ? 0 : 1\n}\n\nconst AGENTS_FILE = \"AGENTS.md\"\nconst AGENTS_KNOWLEDGE_DIR = \"agents\"\n\n/** Path to the framework's canonical AGENTS.md, or null if unresolved/absent. */\nfunction bundledAgentsPath(root: string): string | null {\n const dir = resolvePackageDir(root, \"templates\")\n if (!dir) return null\n const src = path.join(dir, AGENTS_FILE)\n return fs.existsSync(src) ? src : null\n}\n\n/** Directory bundling the per-artifact-type knowledge files (`agents/*.md`). */\nfunction bundledAgentsDir(root: string): string | null {\n const dir = resolvePackageDir(root, \"templates\")\n if (!dir) return null\n const sub = path.join(dir, AGENTS_KNOWLEDGE_DIR)\n return fs.existsSync(sub) ? sub : null\n}\n\n/** List the bundled `agents/*.md` knowledge file names. */\nfunction listBundledAgentsFiles(agentsDir: string): string[] {\n try {\n return fs\n .readdirSync(agentsDir, { withFileTypes: true })\n .filter((e) => e.isFile() && e.name.endsWith(\".md\"))\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * `vantage add agents` — copy the app-author AGENTS.md map, plus the\n * per-artifact-type knowledge files under `agents/`, into the app root.\n */\nfunction addAgents(root: string, force: boolean): number {\n const src = bundledAgentsPath(root)\n if (!src) {\n log.error(\"AGENTS.md is not bundled with this version of Vantage.\")\n return 1\n }\n const dest = path.join(root, AGENTS_FILE)\n if (fs.existsSync(dest) && !force) {\n log.error(`${AGENTS_FILE} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.copyFileSync(src, dest)\n log.ok(`Added ${path.relative(root, dest) || AGENTS_FILE}`)\n\n const agentsDir = bundledAgentsDir(root)\n const destAgentsDir = path.join(root, AGENTS_KNOWLEDGE_DIR)\n if (agentsDir) {\n fs.mkdirSync(destAgentsDir, { recursive: true })\n const skipped: string[] = []\n for (const name of listBundledAgentsFiles(agentsDir)) {\n const destFile = path.join(destAgentsDir, name)\n if (fs.existsSync(destFile) && !force) {\n skipped.push(name)\n continue\n }\n fs.copyFileSync(path.join(agentsDir, name), destFile)\n log.ok(`Added ${path.relative(root, destFile)}`)\n }\n if (skipped.length > 0) {\n log.warn(\n `Skipped existing ${skipped.join(\", \")} in ${AGENTS_KNOWLEDGE_DIR}/. Use --force to overwrite.`,\n )\n }\n }\n return 0\n}\n\n/**\n * Re-sync a managed AGENTS.md (and its `agents/*.md` knowledge files) from the\n * framework's canonical copies. Only touches the app when AGENTS.md is already\n * present (opt-in via `vantage add agents`), and only rewrites files whose\n * content actually changed; bundled files missing locally are created, but\n * local files outside the bundle are never deleted. Used by `vantage upgrade`\n * so a single source-of-truth update reflects into apps that adopted the guide.\n */\nexport function syncAgentsFile(root: string): \"updated\" | \"unchanged\" | \"absent\" {\n const dest = path.join(root, AGENTS_FILE)\n if (!fs.existsSync(dest)) return \"absent\"\n\n let changed = false\n\n const src = bundledAgentsPath(root)\n if (src) {\n const next = fs.readFileSync(src, \"utf8\")\n if (fs.readFileSync(dest, \"utf8\") !== next) {\n fs.writeFileSync(dest, next)\n changed = true\n }\n }\n\n const agentsDir = bundledAgentsDir(root)\n if (agentsDir) {\n const destAgentsDir = path.join(root, AGENTS_KNOWLEDGE_DIR)\n fs.mkdirSync(destAgentsDir, { recursive: true })\n for (const name of listBundledAgentsFiles(agentsDir)) {\n const srcFile = path.join(agentsDir, name)\n const destFile = path.join(destAgentsDir, name)\n const next = fs.readFileSync(srcFile, \"utf8\")\n if (!fs.existsSync(destFile) || fs.readFileSync(destFile, \"utf8\") !== next) {\n fs.writeFileSync(destFile, next)\n changed = true\n }\n }\n }\n\n return changed ? \"updated\" : \"unchanged\"\n}\n\nfunction copyFromRegistry(root: string, kind: \"ui\" | \"block\", name: string, force: boolean): number {\n const registry = resolveRegistryDir(root)\n if (!registry) {\n log.error(\"Could not resolve the Vantage registry.\")\n return 1\n }\n const sub = kind === \"ui\" ? \"ui\" : \"blocks\"\n const src = path.join(registry, sub, `${name}.tsx`)\n if (!fs.existsSync(src)) {\n const available = fs.existsSync(path.join(registry, sub))\n ? fs.readdirSync(path.join(registry, sub)).map((f) => f.replace(/\\.tsx$/, \"\"))\n : []\n log.error(`Unknown ${kind} \"${name}\". Available: ${available.join(\", \") || \"(none)\"}`)\n return 1\n }\n // Copies land next to the pages that import them (src/components/… when the\n // project has a src/ layout).\n const destDir = path.join(resolvePageRoot(root).abs, \"components\", kind === \"ui\" ? \"ui\" : \"blocks\")\n const dest = path.join(destDir, `${name}.tsx`)\n if (fs.existsSync(dest) && !force) {\n log.error(`${path.relative(root, dest)} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.mkdirSync(destDir, { recursive: true })\n fs.copyFileSync(src, dest)\n log.ok(`Added ${path.relative(root, dest)}`)\n return 0\n}\n\n/** `vantage add <page|api|ui|block|skill> <name>` */\nexport async function add(root: string, args: ParsedArgs): Promise<number> {\n const kind = args.positionals[1]\n const name = args.positionals[2]\n const force = Boolean(args.flags.force)\n const all = Boolean(args.flags.all)\n\n // `skill` accepts `--all` in place of a name, and `agents` takes no name at\n // all; handle both before the name guard.\n if (kind === \"skill\") {\n const dir = typeof args.flags.dir === \"string\" ? args.flags.dir : undefined\n return addSkill(root, name, all, force, dir)\n }\n if (kind === \"agents\") return addAgents(root, force)\n\n if (!kind || !name) {\n log.error(\"Usage: vantage add <page|api|ui|block|skill|agents> <name>\")\n return 1\n }\n\n if (kind === \"page\") {\n // Pages are named by their route, so they go under the page root — src/\n // when the project has one, the project root otherwise.\n const pageRoot = resolvePageRoot(root).abs\n const file = path.join(pageRoot, name.endsWith(\".tsx\") ? name : `${name}.tsx`)\n if (fs.existsSync(file) && !force) {\n log.error(`${path.relative(root, file)} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.mkdirSync(path.dirname(file), { recursive: true })\n fs.writeFileSync(file, pageTemplate(name))\n log.ok(`Added page ${path.relative(root, file)}`)\n return 0\n }\n\n if (kind === \"api\") {\n const rel = name.startsWith(\"server/api/\") ? name : path.join(\"server\", \"api\", name)\n const file = path.join(root, rel.endsWith(\".ts\") ? rel : `${rel}.ts`)\n if (fs.existsSync(file) && !force) {\n log.error(`${path.relative(root, file)} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.mkdirSync(path.dirname(file), { recursive: true })\n fs.writeFileSync(file, apiTemplate())\n log.ok(`Added API ${path.relative(root, file)}`)\n return 0\n }\n\n if (kind === \"ui\") return copyFromRegistry(root, \"ui\", name, force)\n if (kind === \"block\") return copyFromRegistry(root, \"block\", name, force)\n\n log.error(`Unknown add target \"${kind}\". Use one of: page, api, ui, block, skill, agents.`)\n return 1\n}\n"]}
1
+ {"version":3,"sources":["../src/cli/add.ts"],"names":["require"],"mappings":"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","file":"chunk-AABMKHEU.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\nimport { resolvePageRoot } from \"../core/scan\"\nimport { log, type ParsedArgs } from \"./util\"\n\nconst PKG = \"@squadbase/vantage\"\n\nfunction toPascalCase(segment: string): string {\n const cleaned = segment.replace(/\\[|\\]|\\./g, \"\").replace(/\\.\\.\\./g, \"\")\n const words = cleaned.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n const pascal = words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(\"\")\n return /^[A-Za-z]/.test(pascal) ? pascal : \"Page\"\n}\n\nfunction pageTemplate(name: string): string {\n const last = name.split(\"/\").pop() ?? name\n const component = last === \"index\" ? toPascalCase(name.split(\"/\").slice(-2)[0] ?? \"Home\") : toPascalCase(last)\n const title = last.replace(/-/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase())\n return `import { definePage } from \"${PKG}\"\n\nexport const page = definePage({ title: ${JSON.stringify(title)} })\n\nexport default function ${component}() {\n return (\n <main className=\"p-6\">\n <h1 className=\"text-2xl font-semibold\">${title}</h1>\n </main>\n )\n}\n`\n}\n\nfunction apiTemplate(): string {\n return `import type { ApiContext } from \"${PKG}/server\"\n\nexport async function GET({ request, params }: ApiContext) {\n return Response.json({ ok: true, params })\n}\n`\n}\n\nfunction resolvePackageDir(root: string, sub: string): string | null {\n try {\n const require = createRequire(path.join(root, \"noop.js\"))\n const pkgJson = require.resolve(`${PKG}/package.json`)\n return path.join(path.dirname(pkgJson), sub)\n } catch {\n return null\n }\n}\n\nfunction resolveRegistryDir(root: string): string | null {\n return resolvePackageDir(root, \"registry\")\n}\n\nconst SKILL_FILE = \"SKILL.md\"\n\n/** Directories a placed skill never lives in — skipped while scanning. */\nconst SKILL_SCAN_SKIP = new Set([\n \"node_modules\",\n \".git\",\n \".vantage\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".next\",\n \".turbo\",\n \".cache\",\n \".vercel\",\n])\n\n/** How deep below the root the scan goes (`.claude/skills/<name>` is depth 3). */\nconst SKILL_SCAN_DEPTH = 4\n\n/** List the skill directories bundled with the installed framework. */\nfunction listBundledSkills(skillsDir: string): string[] {\n try {\n return fs\n .readdirSync(skillsDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && fs.existsSync(path.join(skillsDir, e.name, SKILL_FILE)))\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/** Paths outside the project read better absolute than as a pile of `../`. */\nfunction displayPath(root: string, target: string): string {\n const rel = path.relative(root, target)\n return !rel ? \".\" : rel.startsWith(\"..\") ? target : rel\n}\n\n/**\n * Find where the bundled skills already live in this project.\n *\n * Placement is a convention, not a fixed path: apps keep them under the root,\n * under `.claude/skills/`, under `.squadbase/skills/`, … so `add skill` looks\n * for the skill *directories* rather than guessing one destination and adding a\n * second copy next to the one that is already there.\n */\nfunction findPlacedSkills(\n root: string,\n names: readonly string[],\n skillsDir: string,\n): Map<string, string[]> {\n const wanted = new Set(names)\n const found = new Map<string, string[]>()\n // A workspace that links the framework by path (not through node_modules)\n // would otherwise report the framework's own `skills/` as a placement.\n const isSource = (p: string) => !path.relative(skillsDir, p).startsWith(\"..\")\n const walk = (dir: string, depth: number): void => {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || SKILL_SCAN_SKIP.has(entry.name)) continue\n const abs = path.join(dir, entry.name)\n if (wanted.has(entry.name) && fs.existsSync(path.join(abs, SKILL_FILE))) {\n if (!isSource(abs)) found.set(entry.name, [...(found.get(entry.name) ?? []), abs])\n continue // skills never nest inside one another\n }\n if (depth < SKILL_SCAN_DEPTH) walk(abs, depth + 1)\n }\n }\n walk(root, 1)\n for (const list of found.values()) list.sort()\n return found\n}\n\n/** Copy one bundled skill directory to `dest`, creating parents as needed. */\nfunction writeSkill(root: string, skillsDir: string, name: string, dest: string, verb: string): void {\n fs.mkdirSync(path.dirname(dest), { recursive: true })\n fs.cpSync(path.join(skillsDir, name), dest, { recursive: true, force: true })\n log.ok(`${verb} skill ${displayPath(root, dest)}/`)\n}\n\n/** `vantage add skill` with no name — the bundled list plus where each one sits. */\nfunction printSkillList(root: string, available: string[], placed: Map<string, string[]>): number {\n const width = Math.max(...available.map((n) => n.length))\n log.info(\"Bundled skills:\")\n for (const name of available) {\n const where = placed.get(name)\n const status = where?.length\n ? where.map((p) => displayPath(root, p) + \"/\").join(\", \")\n : \"not placed\"\n log.info(` ${name.padEnd(width)} ${status}`)\n }\n const missing = available.filter((n) => !placed.get(n)?.length)\n if (missing.length) {\n log.info(\"\")\n log.info(\"Place the missing ones with: vantage add skill --all [--dir <path>]\")\n }\n return 0\n}\n\n/**\n * `vantage add skill [<name>|--all] [--dir <path>]` — copy Claude Code skills\n * out of the package.\n *\n * The command scans the project first: a skill that is already placed anywhere\n * (root, `.claude/skills/`, `.squadbase/skills/`, …) is a no-op and its location\n * is reported, so re-running never produces a second copy. `--force` refreshes\n * the placements that were found, in place. Only when nothing is found does the\n * destination matter — the project root, or `--dir` when given (an explicit\n * `--dir` also wins over refreshing somewhere else).\n */\nfunction addSkill(\n root: string,\n name: string | undefined,\n all: boolean,\n force: boolean,\n dir: string | undefined,\n): number {\n const skillsDir = resolvePackageDir(root, \"skills\")\n if (!skillsDir) {\n log.error(\"Could not resolve the Vantage skills directory.\")\n return 1\n }\n const available = listBundledSkills(skillsDir)\n if (available.length === 0) {\n log.error(\"No skills are bundled with this version of Vantage.\")\n return 1\n }\n const placed = findPlacedSkills(root, available, skillsDir)\n if (!all && !name) return printSkillList(root, available, placed)\n\n const destDir = path.resolve(root, dir ?? \".\")\n const targets = all ? available : [name as string]\n let failed = 0\n for (const target of targets) {\n if (!available.includes(target)) {\n log.error(`Unknown skill \"${target}\". Available: ${available.join(\", \")}`)\n failed++\n continue\n }\n const existing = placed.get(target) ?? []\n if (existing.length > 0 && !force) {\n const where = existing.map((p) => displayPath(root, p) + \"/\").join(\", \")\n log.info(`Skill ${target} is already placed at ${where} — skipped (--force to refresh).`)\n continue\n }\n // `--dir` names a destination explicitly, so it wins over refreshing copies\n // that live somewhere else; without it, `--force` updates them where they are.\n const inDestDir = existing.filter((p) => path.dirname(p) === destDir)\n const refresh = dir === undefined ? existing : inDestDir\n if (refresh.length > 0) {\n for (const dest of refresh) writeSkill(root, skillsDir, target, dest, \"Updated\")\n continue\n }\n if (existing.length > 0) {\n const where = existing.map((p) => displayPath(root, p) + \"/\").join(\", \")\n log.warn(`Skill ${target} is also placed at ${where} — left untouched.`)\n }\n writeSkill(root, skillsDir, target, path.join(destDir, target), \"Added\")\n }\n return failed === 0 ? 0 : 1\n}\n\nconst AGENTS_FILE = \"AGENTS.md\"\nconst AGENTS_KNOWLEDGE_DIR = \"agents\"\n\n/** Path to the framework's canonical AGENTS.md, or null if unresolved/absent. */\nfunction bundledAgentsPath(root: string): string | null {\n const dir = resolvePackageDir(root, \"templates\")\n if (!dir) return null\n const src = path.join(dir, AGENTS_FILE)\n return fs.existsSync(src) ? src : null\n}\n\n/** Directory bundling the per-artifact-type knowledge files (`agents/*.md`). */\nfunction bundledAgentsDir(root: string): string | null {\n const dir = resolvePackageDir(root, \"templates\")\n if (!dir) return null\n const sub = path.join(dir, AGENTS_KNOWLEDGE_DIR)\n return fs.existsSync(sub) ? sub : null\n}\n\n/** List the bundled `agents/*.md` knowledge file names. */\nfunction listBundledAgentsFiles(agentsDir: string): string[] {\n try {\n return fs\n .readdirSync(agentsDir, { withFileTypes: true })\n .filter((e) => e.isFile() && e.name.endsWith(\".md\"))\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * `vantage add agents` — copy the app-author AGENTS.md map, plus the\n * per-artifact-type knowledge files under `agents/`, into the app root.\n */\nfunction addAgents(root: string, force: boolean): number {\n const src = bundledAgentsPath(root)\n if (!src) {\n log.error(\"AGENTS.md is not bundled with this version of Vantage.\")\n return 1\n }\n const dest = path.join(root, AGENTS_FILE)\n if (fs.existsSync(dest) && !force) {\n log.error(`${AGENTS_FILE} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.copyFileSync(src, dest)\n log.ok(`Added ${path.relative(root, dest) || AGENTS_FILE}`)\n\n const agentsDir = bundledAgentsDir(root)\n const destAgentsDir = path.join(root, AGENTS_KNOWLEDGE_DIR)\n if (agentsDir) {\n fs.mkdirSync(destAgentsDir, { recursive: true })\n const skipped: string[] = []\n for (const name of listBundledAgentsFiles(agentsDir)) {\n const destFile = path.join(destAgentsDir, name)\n if (fs.existsSync(destFile) && !force) {\n skipped.push(name)\n continue\n }\n fs.copyFileSync(path.join(agentsDir, name), destFile)\n log.ok(`Added ${path.relative(root, destFile)}`)\n }\n if (skipped.length > 0) {\n log.warn(\n `Skipped existing ${skipped.join(\", \")} in ${AGENTS_KNOWLEDGE_DIR}/. Use --force to overwrite.`,\n )\n }\n }\n return 0\n}\n\n/**\n * Re-sync a managed AGENTS.md (and its `agents/*.md` knowledge files) from the\n * framework's canonical copies. Only touches the app when AGENTS.md is already\n * present (opt-in via `vantage add agents`), and only rewrites files whose\n * content actually changed; bundled files missing locally are created, but\n * local files outside the bundle are never deleted. Used by `vantage upgrade`\n * so a single source-of-truth update reflects into apps that adopted the guide.\n */\nexport function syncAgentsFile(root: string): \"updated\" | \"unchanged\" | \"absent\" {\n const dest = path.join(root, AGENTS_FILE)\n if (!fs.existsSync(dest)) return \"absent\"\n\n let changed = false\n\n const src = bundledAgentsPath(root)\n if (src) {\n const next = fs.readFileSync(src, \"utf8\")\n if (fs.readFileSync(dest, \"utf8\") !== next) {\n fs.writeFileSync(dest, next)\n changed = true\n }\n }\n\n const agentsDir = bundledAgentsDir(root)\n if (agentsDir) {\n const destAgentsDir = path.join(root, AGENTS_KNOWLEDGE_DIR)\n fs.mkdirSync(destAgentsDir, { recursive: true })\n for (const name of listBundledAgentsFiles(agentsDir)) {\n const srcFile = path.join(agentsDir, name)\n const destFile = path.join(destAgentsDir, name)\n const next = fs.readFileSync(srcFile, \"utf8\")\n if (!fs.existsSync(destFile) || fs.readFileSync(destFile, \"utf8\") !== next) {\n fs.writeFileSync(destFile, next)\n changed = true\n }\n }\n }\n\n return changed ? \"updated\" : \"unchanged\"\n}\n\nfunction copyFromRegistry(root: string, kind: \"ui\" | \"block\", name: string, force: boolean): number {\n const registry = resolveRegistryDir(root)\n if (!registry) {\n log.error(\"Could not resolve the Vantage registry.\")\n return 1\n }\n const sub = kind === \"ui\" ? \"ui\" : \"blocks\"\n const src = path.join(registry, sub, `${name}.tsx`)\n if (!fs.existsSync(src)) {\n const available = fs.existsSync(path.join(registry, sub))\n ? fs.readdirSync(path.join(registry, sub)).map((f) => f.replace(/\\.tsx$/, \"\"))\n : []\n log.error(`Unknown ${kind} \"${name}\". Available: ${available.join(\", \") || \"(none)\"}`)\n return 1\n }\n // Copies land next to the pages that import them (src/components/… when the\n // project has a src/ layout).\n const destDir = path.join(resolvePageRoot(root).abs, \"components\", kind === \"ui\" ? \"ui\" : \"blocks\")\n const dest = path.join(destDir, `${name}.tsx`)\n if (fs.existsSync(dest) && !force) {\n log.error(`${path.relative(root, dest)} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.mkdirSync(destDir, { recursive: true })\n fs.copyFileSync(src, dest)\n log.ok(`Added ${path.relative(root, dest)}`)\n return 0\n}\n\n/** `vantage add <page|api|ui|block|skill> <name>` */\nexport async function add(root: string, args: ParsedArgs): Promise<number> {\n const kind = args.positionals[1]\n const name = args.positionals[2]\n const force = Boolean(args.flags.force)\n const all = Boolean(args.flags.all)\n\n // `skill` accepts `--all` in place of a name, and `agents` takes no name at\n // all; handle both before the name guard.\n if (kind === \"skill\") {\n const dir = typeof args.flags.dir === \"string\" ? args.flags.dir : undefined\n return addSkill(root, name, all, force, dir)\n }\n if (kind === \"agents\") return addAgents(root, force)\n\n if (!kind || !name) {\n log.error(\"Usage: vantage add <page|api|ui|block|skill|agents> <name>\")\n return 1\n }\n\n if (kind === \"page\") {\n // Pages are named by their route, so they go under the page root — src/\n // when the project has one, the project root otherwise.\n const pageRoot = resolvePageRoot(root).abs\n const file = path.join(pageRoot, name.endsWith(\".tsx\") ? name : `${name}.tsx`)\n if (fs.existsSync(file) && !force) {\n log.error(`${path.relative(root, file)} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.mkdirSync(path.dirname(file), { recursive: true })\n fs.writeFileSync(file, pageTemplate(name))\n log.ok(`Added page ${path.relative(root, file)}`)\n return 0\n }\n\n if (kind === \"api\") {\n const rel = name.startsWith(\"server/api/\") ? name : path.join(\"server\", \"api\", name)\n const file = path.join(root, rel.endsWith(\".ts\") ? rel : `${rel}.ts`)\n if (fs.existsSync(file) && !force) {\n log.error(`${path.relative(root, file)} already exists. Use --force to overwrite.`)\n return 1\n }\n fs.mkdirSync(path.dirname(file), { recursive: true })\n fs.writeFileSync(file, apiTemplate())\n log.ok(`Added API ${path.relative(root, file)}`)\n return 0\n }\n\n if (kind === \"ui\") return copyFromRegistry(root, \"ui\", name, force)\n if (kind === \"block\") return copyFromRegistry(root, \"block\", name, force)\n\n log.error(`Unknown add target \"${kind}\". Use one of: page, api, ui, block, skill, agents.`)\n return 1\n}\n"]}