@squadbase/vantage 0.6.2-dev1.0ad29b0 → 0.6.2-dev1.100dfeb
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.
- package/dist/{build-A23M4GCH.js → build-U7GO26HR.js} +3 -3
- package/dist/{build-A23M4GCH.js.map → build-U7GO26HR.js.map} +1 -1
- package/dist/{check-FBHT6W6J.js → check-MRVAIHG5.js} +3 -3
- package/dist/{check-FBHT6W6J.js.map → check-MRVAIHG5.js.map} +1 -1
- package/dist/{chunk-5C2SEDPH.js → chunk-PJ4SPXHS.js} +4 -4
- package/dist/{chunk-5C2SEDPH.js.map → chunk-PJ4SPXHS.js.map} +1 -1
- package/dist/cli.js +4 -4
- package/dist/{dev-H4I2JL63.js → dev-O42JFQ64.js} +3 -3
- package/dist/{dev-H4I2JL63.js.map → dev-O42JFQ64.js.map} +1 -1
- package/dist/{doctor-B2O3GJDU.js → doctor-YD3XAAOT.js} +3 -3
- package/dist/{doctor-B2O3GJDU.js.map → doctor-YD3XAAOT.js.map} +1 -1
- package/docs/en/agent-skills.md +1 -1
- package/docs/ja/agent-skills.md +1 -1
- package/package.json +2 -2
- package/skills/vantage-design/SKILL.md +25 -27
- package/skills/vantage-design/references/extract.md +10 -13
- package/skills/vantage-design/references/format.md +12 -173
- package/skills/vantage-design/references/presets.md +0 -10
- package/templates/AGENTS.md +29 -15
- package/templates/agents/page.md +1 -1
- package/templates/agents/slide.md +7 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runDiagnostics } from './chunk-
|
|
1
|
+
import { runDiagnostics } from './chunk-PJ4SPXHS.js';
|
|
2
2
|
import './chunk-UWSQUHX6.js';
|
|
3
3
|
import { vantagePlugin } from './chunk-SDJTTMLK.js';
|
|
4
4
|
import { generateArtifacts } from './chunk-SHZM3EXB.js';
|
|
@@ -104,5 +104,5 @@ function writeDeployManifest(root, model) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
export { build };
|
|
107
|
-
//# sourceMappingURL=build-
|
|
108
|
-
//# sourceMappingURL=build-
|
|
107
|
+
//# sourceMappingURL=build-U7GO26HR.js.map
|
|
108
|
+
//# sourceMappingURL=build-U7GO26HR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/build.ts"],"names":["viteBuild"],"mappings":";;;;;;;;;;;;;;;AAYA,IAAM,YAAA,GAAe,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA;AAWrB,eAAsB,KAAA,CAAM,MAAc,IAAA,EAAmC;AAC3E,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,EAAM,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA;AAC/E,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,gBAAA,CAAiB,MAAM,CAAA;AACvB,IAAA,GAAA,CAAI,MAAM,uCAAuC,CAAA;AACjD,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO,YAAA;AAIb,EAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,OAAA,CAAQ,GAAA,EAAK,GAAG,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,EAAE,CAAA,EAAE;AACzD,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAMrC,EAAA,iBAAA,CAAkB,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA;AAEjC,EAAA,IAAI,CAAC,KAAA,EAAO,GAAA,CAAI,KAAK,KAAA,CAAM,SAAA,GAAY,qCAAgC,uBAAkB,CAAA;AAEzF,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,cAAA,EAAgB,YAAY;AACzD,IAAA,MAAMA,OAAA,CAAU;AAAA,MACd,UAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA,EAAS,CAAC,aAAA,CAAc,EAAE,IAAA,EAAM,KAAK,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,CAAC,CAAA;AAAA,MACrE,UAAU,KAAA,GAAQ,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,UAAU,MAAA,GAAS;AAAA,KAC5D,CAAA;AAGD,IAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,EACzB,CAAC,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,SAAA,GACtB,UAAA,CAAW,cAAA,EAAgB,MAAM,WAAA,CAAY,IAAI,CAAC,CAAA,GAClD,OAAA,CAAQ,OAAA,EAAQ;AAEpB,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,WAAA,EAAa,WAAW,CAAC,CAAA;AAE5C,EAAA,mBAAA,CAAoB,MAAM,KAAK,CAAA;AAC/B,EAAA,IAAI,CAAC,KAAA,EAAO,GAAA,CAAI,EAAA,CAAG,CAAA,sBAAA,EAAoB,KAAK,QAAA,CAAS,OAAA,CAAQ,GAAA,EAAI,EAAG,KAAK,IAAA,CAAK,IAAA,EAAM,MAAM,CAAC,CAAA,IAAK,MAAM,CAAA,CAAA,CAAG,CAAA;AAEzG,EAAA,IAAI,IAAA,CAAK,MAAM,IAAA,EAAM;AACnB,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb,KAAK,SAAA,CAAU;AAAA,QACb,EAAA,EAAI,IAAA;AAAA,QACJ,IAAA,EAAM,KAAA,CAAM,SAAA,GAAY,WAAA,GAAc,KAAA;AAAA,QACtC,MAAA,EAAQ,MAAA;AAAA,QACR,KAAA,EAAO,MAAM,KAAA,CAAM,MAAA;AAAA,QACnB,IAAA,EAAM,MAAM,IAAA,CAAK;AAAA,OAClB,CAAA,GAAI;AAAA,KACP;AAAA,EACF;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,mBAAmB,IAAA,EAAoB;AAC9C,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,QAAQ,QAAQ,CAAA;AAClD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,aAAa,YAAY,CAAA;AAC7D,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,YAAY,CAAA;AAChD,EAAA,IAAI,EAAA,CAAG,UAAA,CAAW,MAAM,CAAA,EAAG;AACzB,IAAA,EAAA,CAAG,SAAA,CAAU,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAC3C,IAAA,EAAA,CAAG,UAAA,CAAW,QAAQ,MAAM,CAAA;AAC5B,IAAA,EAAA,CAAG,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,WAAW,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,EAC/E;AACF;AAEA,eAAe,YAAY,IAAA,EAA6B;AAGtD,EAAA,MAAM,EAAE,KAAA,EAAO,YAAA,EAAa,GAAI,MAAM,OAAO,SAAS,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,WAAW,CAAA;AAC9C,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,iBAAiB,CAAA;AACrD,EAAA,EAAA,CAAG,aAAA,CAAc,OAAO,YAAY,CAAA;AACpC,EAAA,MAAM,YAAA,CAAa;AAAA,IACjB,WAAA,EAAa,CAAC,KAAK,CAAA;AAAA,IACnB,SAAS,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,UAAU,WAAW,CAAA;AAAA,IACtD,MAAA,EAAQ,IAAA;AAAA,IACR,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,MAAA,EAAQ,QAAA;AAAA,IACR,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,EAAE,EAAA,EAAI,qCAAA;AAAsC,GACrD,CAAA;AACH;AAEA,SAAS,mBAAA,CAAoB,MAAc,KAAA,EAAyB;AAClE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AACnC,EAAA,EAAA,CAAG,SAAA,CAAU,IAAA,EAAM,EAAE,SAAA,EAAW,MAAM,CAAA;AACtC,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,aAAA,EAAe,uBAAA;AAAA,IACf,IAAA,EAAM,KAAA,CAAM,SAAA,GAAY,WAAA,GAAc,KAAA;AAAA,IACtC,MAAA,EAAQ,UAAA;AAAA,IACR,GAAI,KAAA,CAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,oBAAA,KAAyB,EAAC;AAAA,IAC1D,WAAA,EAAa,qBAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AACA,EAAA,EAAA,CAAG,aAAA,CAAc,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,uBAAuB,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA,GAAI,IAAI,CAAA;AACrG","file":"build-
|
|
1
|
+
{"version":3,"sources":["../src/cli/build.ts"],"names":["viteBuild"],"mappings":"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","file":"build-U7GO26HR.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,4 +1,4 @@
|
|
|
1
|
-
import { runDiagnostics } from './chunk-
|
|
1
|
+
import { runDiagnostics } from './chunk-PJ4SPXHS.js';
|
|
2
2
|
import './chunk-UWSQUHX6.js';
|
|
3
3
|
import './chunk-S5MDTHH7.js';
|
|
4
4
|
import { scanProject } from './chunk-RNTDBX6S.js';
|
|
@@ -34,5 +34,5 @@ async function check(root, args) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export { check };
|
|
37
|
-
//# sourceMappingURL=check-
|
|
38
|
-
//# sourceMappingURL=check-
|
|
37
|
+
//# sourceMappingURL=check-MRVAIHG5.js.map
|
|
38
|
+
//# sourceMappingURL=check-MRVAIHG5.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-
|
|
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-MRVAIHG5.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"]}
|
|
@@ -497,7 +497,7 @@ function checkHardcodedColors(ctx) {
|
|
|
497
497
|
message: `${file} hard-codes ${hits.length} color(s):
|
|
498
498
|
${lines.join("\n ")}`,
|
|
499
499
|
files: [...new Set(shown.map((h) => `${file}:${h.line}`))].concat(more > 0 ? [`+${more} more`] : []),
|
|
500
|
-
fix: "Use theme tokens instead (bg-primary, text-muted-foreground, var(--chart-N), \u2026 as defined in styles.css and
|
|
500
|
+
fix: "Use theme tokens instead (bg-primary, text-muted-foreground, var(--chart-N), \u2026 as defined in styles.css; see the \u300C\u898B\u305F\u76EE\u306E\u898F\u7D04\u300D section of AGENTS.md, and to change colors switch the theme or override styles.css). 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."
|
|
501
501
|
});
|
|
502
502
|
}
|
|
503
503
|
return diags;
|
|
@@ -515,7 +515,7 @@ function checkDesignDoc(ctx) {
|
|
|
515
515
|
severity: "warning",
|
|
516
516
|
message: `DESIGN.md is ${lines} lines long (aim for ${DESIGN_MD_MAX_LINES} or fewer).`,
|
|
517
517
|
files: ["DESIGN.md"],
|
|
518
|
-
fix: "Keep
|
|
518
|
+
fix: "Keep DESIGN.md to your own intent (density, slide headings, brand material). Colors, fonts and radii belong to the theme / styles.css, and the usage rules to the \u300C\u898B\u305F\u76EE\u306E\u898F\u7D04\u300D section of AGENTS.md \u2014 do not copy values into DESIGN.md."
|
|
519
519
|
}
|
|
520
520
|
];
|
|
521
521
|
}
|
|
@@ -542,5 +542,5 @@ function runDiagnostics(root, model) {
|
|
|
542
542
|
}
|
|
543
543
|
|
|
544
544
|
export { runDiagnostics };
|
|
545
|
-
//# sourceMappingURL=chunk-
|
|
546
|
-
//# sourceMappingURL=chunk-
|
|
545
|
+
//# sourceMappingURL=chunk-PJ4SPXHS.js.map
|
|
546
|
+
//# sourceMappingURL=chunk-PJ4SPXHS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/diagnostics.ts"],"names":[],"mappings":"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","file":"chunk-5C2SEDPH.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 { DEFAULT_APP_LANG, isValidLang, readLayoutLang } from \"./route-tree\"\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/** Warn when the root layout's `lang` is not a valid language tag (the shell falls back to \"en\"). */\nfunction checkAppLang(ctx: Ctx): Diagnostic[] {\n const { root, model } = ctx\n const layout = model.layouts.find((l) => l.dir === \"\")\n if (!layout) return []\n const lang = readLayoutLang(layout.absFile)\n if (lang === undefined || isValidLang(lang)) return []\n return [\n {\n code: \"INVALID_APP_LANG\",\n severity: \"warning\",\n message: `Root layout exports lang ${JSON.stringify(lang)}, which is not a valid language tag; <html lang> falls back to \"${DEFAULT_APP_LANG}\".`,\n files: [rel(root, layout.absFile)],\n fix: 'Use a BCP 47 tag as a string literal, e.g. `export const lang = \"ja\"`.',\n },\n ]\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 ...checkAppLang(ctx),\n ...client.boundary,\n ...client.env,\n ...checkHardcodedColors(ctx),\n ...checkDesignDoc(ctx),\n ]\n })\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/diagnostics.ts"],"names":[],"mappings":";;;;;;;;AAoBA,IAAM,gBAAA,mBAAmB,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,OAAO,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAY,SAAS,CAAC,CAAA;AAGtF,SAAS,iBAAiB,GAAA,EAAsB;AAC9C,EAAA,OACE,sBAAA,CAAuB,IAAA,CAAK,GAAG,CAAA,IAC/B,2CAAA,CAA4C,KAAK,GAAG,CAAA,IACpD,+CAAA,CAAgD,IAAA,CAAK,GAAG,CAAA;AAE5D;AAGA,SAAS,mBAAmB,IAAA,EAAwB;AAClD,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,MAAM,QAAA,uBAAe,GAAA,CAAI,CAAC,gBAAgB,UAAA,EAAY,MAAA,EAAQ,QAAA,EAAU,QAAQ,CAAC,CAAA;AACjF,EAAA,MAAM,IAAA,GAAO,CAAC,GAAA,KAAgB;AAC5B,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,GAAG,WAAA,CAAY,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,IACvD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AAChC,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,CAAA;AACrC,MAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,QAAA,IAAI,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,EAAG;AAC9B,QAAA,IAAA,CAAK,GAAG,CAAA;AAAA,MACV,CAAA,MAAA,IAAW,gBAAA,CAAiB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAG;AAC5C,QAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAA;AACA,EAAA,IAAA,CAAK,IAAI,CAAA;AACT,EAAA,OAAO,GAAA;AACT;AA2BA,SAAS,SAAA,CAAU,MAAc,KAAA,EAAwB;AACvD,EAAA,MAAM,IAAA,uBAAW,GAAA,EAA2B;AAC5C,EAAA,MAAM,OAAA,uBAAc,GAAA,EAA2B;AAC/C,EAAA,MAAM,KAAA,uBAAY,GAAA,EAA2B;AAC7C,EAAA,IAAI,WAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,WAAA,GAA+B,IAAA;AAEnC,EAAA,MAAM,GAAA,GAAM,CAAC,GAAA,KAA+B;AAC1C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AACxB,IAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAC9B,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAO,EAAA,CAAG,YAAA,CAAa,GAAA,EAAK,MAAM,CAAA;AAAA,IACpC,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,GAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,CAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAA;AAAA,IACA,OAAO,GAAA,EAAK;AACV,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC3B,MAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAC9B,MAAA,MAAM,IAAA,GAAO,IAAI,GAAG,CAAA;AACpB,MAAA,MAAM,GAAA,GAAM,IAAA,KAAS,IAAA,GAAO,IAAA,GAAO,cAAc,IAAI,CAAA;AACrD,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,GAAG,CAAA;AACpB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA,KAAK,GAAA,EAAK;AACR,MAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AACzB,MAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAC9B,MAAA,IAAI,KAAA;AACJ,MAAA,IAAI;AACF,QAAA,KAAA,GAAQ,EAAA,CAAG,QAAA,CAAS,GAAG,CAAA,CAAE,IAAA;AAAA,MAC3B,CAAA,CAAA,MAAQ;AACN,QAAA,KAAA,GAAQ,IAAA;AAAA,MACV;AACA,MAAA,KAAA,CAAM,GAAA,CAAI,KAAK,KAAK,CAAA;AACpB,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,IACA,WAAA,GAAc;AACZ,MAAA,OAAQ,WAAA,KAAgB,mBAAmB,IAAI,CAAA;AAAA,IACjD,CAAA;AAAA,IACA,WAAA,GAAc;AACZ,MAAA,IAAI,aAAa,OAAO,WAAA;AACxB,MAAA,IAAI;AACF,QAAA,WAAA,GAAc,EAAA,CAAG,YAAY,IAAI,CAAA;AAAA,MACnC,CAAA,CAAA,MAAQ;AACN,QAAA,WAAA,GAAc,EAAC;AAAA,MACjB;AACA,MAAA,OAAO,WAAA;AAAA,IACT;AAAA,GACF;AACF;AAEA,SAAS,GAAA,CAAI,MAAc,GAAA,EAAqB;AAC9C,EAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,GAAG,CAAA,CAAE,MAAM,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC1D;AAGA,SAAS,oBAAoB,GAAA,EAAwB;AACnD,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,WAAA,EAAY,EAAG;AACpC,IAAA,KAAA,MAAW,QAAQ,eAAA,EAAiB;AAClC,MAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,EAAG;AAC3B,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACT,IAAA,EAAM,gBAAA;AAAA,UACN,QAAA,EAAU,OAAA;AAAA,UACV,OAAA,EAAS,CAAA,EAAG,IAAA,CAAK,KAAK,UAAU,IAAI,CAAA,sCAAA,CAAA;AAAA,UACpC,KAAA,EAAO,CAAC,IAAI,CAAA;AAAA,UACZ,KAAK,IAAA,CAAK;AAAA,SACX,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAOA,SAAS,eAAe,GAAA,EAAwB;AAC9C,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,GAAA;AACxB,EAAA,IAAI,KAAA,CAAM,OAAA,KAAY,EAAA,EAAI,OAAO,EAAC;AAClC,EAAA,MAAM,QAAsB,EAAC;AAE7B,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAGhC,EAAA,MAAM,aAAa,OAAA,CAAQ,MAAA;AAAA,IAAO,CAAC,IAAA,KACjC,iBAAA,CAAkB,IAAA,CAAK,CAAC,GAAA,KAAQ,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAAS,GAAG,CAAC;AAAA,GAClE;AACA,EAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,eAAA;AAAA,MACN,QAAA,EAAU,OAAA;AAAA,MACV,SAAS,CAAA,EAAG,UAAA,CAAW,MAAM,CAAA,6CAAA,EAAgD,OAAO,2CAA2C,OAAO,CAAA,EAAA,CAAA;AAAA,MACtI,KAAA,EAAO,WAAW,IAAA,EAAK;AAAA,MACvB,GAAA,EAAK,CAAA,eAAA,EAAkB,OAAO,CAAA,aAAA,EAAgB,OAAO,CAAA,8BAAA;AAAA,KACtD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,YAAY,CAAA,EAAG;AAClC,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,eAAA;AAAA,MACN,QAAA,EAAU,OAAA;AAAA,MACV,OAAA,EAAS,CAAA,yCAAA,EAA4C,OAAO,CAAA,+CAAA,EAAkD,OAAO,CAAA,YAAA,CAAA;AAAA,MACrH,KAAA,EAAO,CAAC,YAAY,CAAA;AAAA,MACpB,GAAA,EAAK,cAAc,OAAO,CAAA,YAAA;AAAA,KAC3B,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,EAAA,CAAG,WAAW,IAAA,CAAK,IAAA,CAAK,MAAM,OAAA,EAAS,QAAQ,CAAC,CAAA,EAAG;AACrD,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,eAAA;AAAA,MACN,QAAA,EAAU,OAAA;AAAA,MACV,OAAA,EAAS,GAAG,OAAO,CAAA,iGAAA,CAAA;AAAA,MACnB,KAAA,EAAO,CAAC,CAAA,EAAG,OAAO,CAAA,OAAA,CAAS,CAAA;AAAA,MAC3B,GAAA,EAAK,CAAA,uCAAA;AAAA,KACN,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,yBAAyB,KAAA,EAAiC;AACjE,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAmD;AACrE,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,KAAA,EAAO;AAC9B,IAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACtC,IAAA,IAAI,QAAQ,EAAA,IAAM,CAAC,qBAAA,CAAsB,GAAA,CAAI,GAAG,CAAA,EAAG;AACnD,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,IAAK,EAAE,KAAA,EAAO,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAE;AACtD,IAAA,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AACxB,IAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA;AAC9B,IAAA,KAAA,CAAM,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA,EACpB;AAEA,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,CAAA,IAAK,KAAA,EAAO;AAC9B,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,sBAAA;AAAA,MACN,QAAA,EAAU,SAAA;AAAA,MACV,SAAS,CAAA,EAAG,GAAG,yBAAyB,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,EAAG,CAAC,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,EACvE,GAAA,CAAI,OAAO,MAAA,GAAS,CAAA,GAAI,aAAQ,EAClC,CAAA,CAAA;AAAA,MACA,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,GAAA,EAAK,qHAAqH,GAAG,CAAA,2DAAA;AAAA,KAC9H,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,oBAAoB,GAAA,EAAwB;AACnD,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAsB;AACzC,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,KAAA,EAAO;AAClC,IAAA,MAAM,OAAO,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,SAAS,KAAK,EAAC;AAC5C,IAAA,IAAA,CAAK,IAAA,CAAK,KAAK,IAAI,CAAA;AACnB,IAAA,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,SAAA,EAAW,IAAI,CAAA;AAAA,EACjC;AACA,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,CAAC,SAAA,EAAW,KAAK,CAAA,IAAK,MAAA,EAAQ;AACvC,IAAA,IAAI,KAAA,CAAM,UAAU,CAAA,EAAG;AAMvB,IAAA,IAAI,cAAc,GAAA,EAAK;AACrB,MAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS;AAC7C,QAAA,IAAI,CAAC,cAAA,CAAe,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,MAAM,IAAI,CAAA;AACpC,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAC3B,QAAA,OAAO,OAAA,KAAY,IAAA,IAAQ,CAAC,qBAAA,CAAsB,OAAO,CAAA;AAAA,MAC3D,CAAC,CAAA;AAGD,MAAA,IAAI,eAAA,CAAgB,UAAU,CAAA,EAAG;AAGjC,MAAA,IAAI,eAAA,CAAgB,MAAA,GAAS,KAAA,CAAM,MAAA,EAAQ;AACzC,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACT,IAAA,EAAM,gBAAA;AAAA,UACN,QAAA,EAAU,OAAA;AAAA,UACV,OAAA,EAAS,CAAA,EAAG,eAAA,CAAgB,MAAM,qBAAqB,SAAS,CAAA,CAAA;AAAA,UAChE,KAAA,EAAO,eAAA;AAAA,UACP,GAAA,EAAK;AAAA,SACN,CAAA;AACD,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,gBAAA;AAAA,MACN,QAAA,EAAU,OAAA;AAAA,MACV,OAAA,EAAS,CAAA,EAAG,KAAA,CAAM,MAAM,qBAAqB,SAAS,CAAA,CAAA;AAAA,MACtD,KAAA;AAAA,MACA,GAAA,EAAK;AAAA,KACN,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT;AAQA,SAAS,mBAAmB,GAAA,EAAwB;AAClD,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,KAAA,IAAS,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU;AACtC,IAAA,IAAI,KAAA,CAAM,WAAW,WAAA,EAAa;AAChC,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA,EAAM,uBAAA;AAAA,QACN,QAAA,EAAU,SAAA;AAAA,QACV,SAAS,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,4CAAA,EAA+C,KAAK,KAAA,CAAM,OAAA;AAAA,UAC/E,KAAA,CAAM;AAAA,SACP,CAAA,EAAA,CAAA;AAAA,QACD,KAAA,EAAO,CAAC,KAAA,CAAM,IAAI,CAAA;AAAA,QAClB,GAAA,EAAK,CAAA,KAAA,EAAQ,oBAAA,CAAqB,IAAA,CAAK,OAAO,CAAC,CAAA,gHAAA;AAAA,OAChD,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,sBAAA;AAAA,MACN,QAAA,EAAU,OAAA;AAAA,MACV,SAAS,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,CAAA,eAAA,EAAkB,MAAM,OAAO,CAAA,0DAAA,CAAA;AAAA,MACtD,KAAA,EAAO,CAAC,KAAA,CAAM,IAAI,CAAA;AAAA,MAClB,GAAA,EAAK,CAAA,+EAAA,EAAkF,KAAA,CAAM,OAAO,CAAA,4EAAA;AAAA,KACrG,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT;AAOA,SAAS,kBAAkB,GAAA,EAAwB;AACjD,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,CAAI,KAAA,CAAM,KAAA,EAAO;AAClC,IAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA;AAClC,IAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,IAAQ,mBAAA,EAAqB;AAClD,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,qBAAA;AAAA,MACN,QAAA,EAAU,SAAA;AAAA,MACV,OAAA,EAAS,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,IAAA,EAAA,CAAQ,IAAA,GAAO,IAAA,GAAO,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,QAAA,EAAW,KAAK,SAAS,CAAA,uCAAA,CAAA;AAAA,MACpF,KAAA,EAAO,CAAC,IAAA,CAAK,IAAI,CAAA;AAAA,MACjB,GAAA,EAAK,CAAA,wDAAA,EACH,mBAAA,GAAsB,IAAA,GAAO,IAC/B,CAAA,qEAAA;AAAA,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,iBAAiB,GAAA,EAAwB;AAChD,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,GAAA;AACxB,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,MAAM,SAAA,GAAY;AAAA;AAAA;AAAA,IAGhB,GAAG,KAAA,CAAM,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AAAA,IACtE,GAAG,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AAAA,IACrC,MAAM,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAM,QAAQ,CAAA;AAAA,IAChD,MAAM,KAAA,IAAS,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAM,KAAK;AAAA,IAC1C,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAA,CAAQ,CAAC,CAAC,CAAA;AAEvC,EAAA,KAAA,MAAW,OAAO,SAAA,EAAW;AAC3B,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA;AAC1B,IAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,IAAA,IAAI,CAAC,gBAAA,CAAiB,GAAG,CAAA,EAAG;AAC1B,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA,EAAM,wBAAA;AAAA,QACN,QAAA,EAAU,OAAA;AAAA,QACV,OAAA,EAAS,CAAA,kCAAA,CAAA;AAAA,QACT,KAAA,EAAO,CAAC,GAAA,CAAI,IAAA,EAAM,GAAG,CAAC,CAAA;AAAA,QACtB,GAAA,EAAK;AAAA,OACN,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,aAAa,GAAA,EAAwB;AAC5C,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,GAAA;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,EAAE,CAAA;AACrD,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AACrB,EAAA,MAAM,IAAA,GAAO,cAAA,CAAe,MAAA,CAAO,OAAO,CAAA;AAC1C,EAAA,IAAI,SAAS,MAAA,IAAa,WAAA,CAAY,IAAI,CAAA,SAAU,EAAC;AACrD,EAAA,OAAO;AAAA,IACL;AAAA,MACE,IAAA,EAAM,kBAAA;AAAA,MACN,QAAA,EAAU,SAAA;AAAA,MACV,SAAS,CAAA,yBAAA,EAA4B,IAAA,CAAK,UAAU,IAAI,CAAC,mEAAmE,gBAAgB,CAAA,EAAA,CAAA;AAAA,MAC5I,OAAO,CAAC,GAAA,CAAI,IAAA,EAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,MACjC,GAAA,EAAK;AAAA;AACP,GACF;AACF;AAGA,SAAS,gBAAgB,GAAA,EAAwB;AAC/C,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,GAAA,IAAO,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM;AAChC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AAClC,IAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,IAAA,MAAM,QAAA,GAAW,iBAAiB,GAAG,CAAA;AACrC,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAEzB,MAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,EAAO,MAAA,EAAQ,OAAO,OAAA,EAAS,QAAA,EAAU,SAAS,CAAA,CAAE,MAAA;AAAA,QAAO,CAAC,MACzE,IAAI,MAAA,CAAO,qCAAqC,CAAC,CAAA,GAAA,CAAK,CAAA,CAAE,IAAA,CAAK,GAAG;AAAA,OAClE;AACA,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA,EAAM,oBAAA;AAAA,QACN,QAAA,EAAU,OAAA;AAAA,QACV,OAAA,EAAS,CAAA,yCAAA,EACP,KAAA,CAAM,MAAA,GAAS,CAAA,mBAAA,EAAsB,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,EAAA,CAAA,GAAO,EAC9D,CAAA,CAAA,CAAA;AAAA,QACA,KAAA,EAAO,CAAC,GAAA,CAAI,IAAI,CAAA;AAAA,QAChB,GAAA,EAAK,CAAA,eAAA,EAAkB,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,aAAA;AAAA,OAC9C,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAQA,SAAS,mBAAmB,GAAA,EAAyD;AACnF,EAAA,MAAM,EAAE,MAAK,GAAI,GAAA;AACjB,EAAA,MAAM,WAAyB,EAAC;AAChC,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,MAAM,QAAA,GAAW,sFAAA;AACjB,EAAA,MAAM,KAAA,GAAQ,8CAAA;AAEd,EAAA,KAAA,MAAW,GAAA,IAAO,GAAA,CAAI,WAAA,EAAY,EAAG;AACnC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA;AAC1B,IAAA,IAAI,QAAQ,IAAA,EAAM;AAElB,IAAA,IAAI,CAAA;AACJ,IAAA,QAAA,CAAS,SAAA,GAAY,CAAA;AACrB,IAAA,OAAQ,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA,EAAI;AAC/B,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,IAAK,EAAE,CAAC,CAAA;AACxB,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAM,QAAA,GACJ,IAAA,KAAS,QAAA,IACT,IAAA,CAAK,UAAA,CAAW,SAAS,CAAA,IACzB,2BAAA,CAA4B,IAAA,CAAK,IAAI,CAAA,IACrC,YAAA,CAAa,KAAK,IAAI,CAAA;AACxB,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA,EAAM,uBAAA;AAAA,UACN,QAAA,EAAU,OAAA;AAAA,UACV,OAAA,EAAS,wCAAwC,IAAI,CAAA,GAAA,CAAA;AAAA,UACrD,KAAA,EAAO,CAAC,GAAA,CAAI,IAAA,EAAM,GAAG,CAAC,CAAA;AAAA,UACtB,GAAA,EAAK;AAAA,SACN,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,KAAA,CAAM,SAAA,GAAY,CAAA;AAClB,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,IAAA,OAAQ,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,EAAI;AAC5B,MAAA,MAAM,GAAA,GAAM,EAAE,CAAC,CAAA;AACf,MAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC/B,MAAA,IAAI,GAAA,CAAI,UAAA,CAAW,iBAAiB,CAAA,EAAG;AACvC,MAAA,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,IACb;AACA,IAAA,KAAA,MAAW,OAAO,GAAA,EAAK;AACrB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,IAAA,EAAM,mBAAA;AAAA,QACN,QAAA,EAAU,SAAA;AAAA,QACV,OAAA,EAAS,gDAAgD,GAAG,CAAA,EAAA,CAAA;AAAA,QAC5D,KAAA,EAAO,CAAC,GAAA,CAAI,IAAA,EAAM,GAAG,CAAC,CAAA;AAAA,QACtB,GAAA,EAAK,QAAQ,iBAAiB,CAAA,oEAAA;AAAA,OAC/B,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,EAAE,UAAU,GAAA,EAAI;AACzB;AAKA,IAAM,cAAA,GACJ,uGAAA;AACF,IAAM,QAAA,GACJ,oIAAA;AACF,IAAM,SAAA,GAAY,uCAAA;AAGlB,IAAM,mBAAmB,IAAI,MAAA;AAAA,EAC3B,CAAA,2BAAA,EAA8B,cAAc,CAAA,GAAA,EAAM,QAAQ,CAAA,2DAAA,CAAA;AAAA,EAC1D;AACF,CAAA;AAEA,IAAM,qBAAqB,IAAI,MAAA;AAAA,EAC7B,8BAA8B,cAAc,CAAA,wBAAA,CAAA;AAAA,EAC5C;AACF,CAAA;AACA,IAAM,cAAc,IAAI,MAAA;AAAA,EACtB,iBAAiB,SAAS,CAAA,8BAAA,CAAA;AAAA,EAC1B;AACF,CAAA;AACA,IAAM,MAAA,GAAS,4CAAA;AACf,IAAM,cAAA,GAAiB,wEAAA;AAEvB,IAAM,gBAAA,GAAmB,6CAAA;AAEzB,IAAM,gBAAA,uBAAuB,GAAA,CAAI,CAAC,SAAS,MAAA,EAAQ,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAC,CAAA;AAC9E,IAAM,kCAAkB,IAAI,GAAA,CAAI,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA;AAE/C,IAAM,gBAAA,GAA2C;AAAA,EAC/C,IAAA,EAAM,SAAA;AAAA,EACN,MAAA,EAAQ,SAAA;AAAA,EACR,GAAA,EAAK,SAAA;AAAA,EACL,IAAA,EAAM,SAAA;AAAA,EACN,KAAA,EAAO,SAAA;AAAA,EACP,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,MAAA,EAAQ,SAAA;AAAA,EACR,KAAA,EAAO,SAAA;AAAA,EACP,MAAA,EAAQ,SAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA,EACR,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM;AACR,CAAA;AACA,IAAM,cAAA,GAAiB,EAAA;AAGvB,SAAS,mBAAA,CAAoB,QAAA,EAAkB,MAAA,EAAgB,OAAA,EAAiB,OAAA,EAA2B;AACzG,EAAA,MAAM,CAAA,GAAI,CAAC,KAAA,KAAkB,CAAA,EAAG,QAAQ,GAAG,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,EAAG,OAAO,CAAA,CAAA;AACpE,EAAA,IAAI,eAAA,CAAgB,IAAI,OAAO,CAAA,SAAU,CAAC,CAAA,CAAE,aAAa,CAAC,CAAA;AAC1D,EAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,OAAO,CAAA,EAAG;AACjC,IAAA,IAAI,MAAA,KAAW,QAAQ,OAAO,CAAC,EAAE,YAAY,CAAA,EAAG,CAAA,CAAE,kBAAkB,CAAC,CAAA;AACrE,IAAA,IAAI,MAAA,KAAW,MAAM,OAAO,CAAC,EAAE,OAAO,CAAA,EAAG,CAAA,CAAE,MAAM,CAAC,CAAA;AAClD,IAAA,IAAI,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,WAAW,OAAO,CAAC,CAAA,CAAE,QAAQ,CAAC,CAAA;AAC3F,IAAA,IAAI,WAAW,MAAA,EAAQ,OAAO,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AACxC,IAAA,OAAO,CAAC,CAAA,CAAE,kBAAkB,CAAC,CAAA;AAAA,EAC/B;AACA,EAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,OAAO,CAAA,IAAK,SAAA;AAC3C,EAAA,OAAO,UAAU,SAAA,GAAY,CAAC,CAAA,CAAE,SAAS,GAAG,CAAA,CAAE,KAAK,CAAC,CAAA,GAAI,CAAC,CAAA,CAAE,KAAK,CAAA,EAAG,CAAA,CAAE,SAAS,CAAC,CAAA;AACjF;AAGA,SAAS,aAAa,KAAA,EAAwB;AAC5C,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG,OAAO,KAAA;AACnC,EAAA,OAAO,cAAA,CAAe,IAAA,CAAK,KAAK,CAAA,IAAK,IAAI,MAAA,CAAO,CAAA,cAAA,EAAiB,SAAS,CAAA,IAAA,CAAM,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA;AAC9F;AASA,SAAS,cAAc,GAAA,EAAyB;AAC9C,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA;AAC/B,EAAA,IAAI,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,2BAA2B,CAAC,CAAA,SAAU,EAAC;AAEvF,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACzB,IAAA,IAAI,CAAA,CAAE,QAAA,CAAS,sBAAsB,CAAA,EAAG,OAAA,CAAQ,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AAAA,EACtE,CAAC,CAAA;AAED,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,WAAW,GAAG,CAAA;AACzC,EAAA,MAAM,UAAA,GAAa,CAAC,CAAC,CAAA;AACrB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,EAAM,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA;AAC/E,EAAA,MAAM,MAAA,GAAS,CAAC,MAAA,KAAmB;AACjC,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,IAAI,EAAA,GAAK,WAAW,MAAA,GAAS,CAAA;AAC7B,IAAA,OAAO,KAAK,EAAA,EAAI;AACd,MAAA,MAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,CAAA,IAAM,CAAA;AAC7B,MAAA,IAAI,UAAA,CAAW,GAAG,CAAA,IAAM,MAAA,EAAQ,EAAA,GAAK,GAAA;AAAA,gBAC3B,GAAA,GAAM,CAAA;AAAA,IAClB;AACA,IAAA,OAAO,EAAA,GAAK,CAAA;AAAA,EACd,CAAA;AAEA,EAAA,MAAM,OAAmB,EAAC;AAC1B,EAAA,MAAM,UAA8B,EAAC;AACrC,EAAA,MAAM,SAAA,GAAY,CAAC,EAAA,KAAe,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,EAAA,IAAM,CAAA,IAAK,KAAK,CAAC,CAAA;AAC5E,EAAA,MAAM,IAAA,GAAO,CAAC,EAAA,EAAY,GAAA,EAAa,MAAc,OAAA,KAAsB;AACzE,IAAA,IAAI,CAAC,QAAA,CAAS,EAAE,CAAA,IAAK,SAAA,CAAU,EAAE,CAAA,EAAG;AACpC,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,EAAA,EAAI,GAAG,CAAC,CAAA;AACtB,IAAA,MAAM,IAAA,GAAO,OAAO,EAAE,CAAA;AACtB,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,IAAA,IAAA,CAAK,KAAK,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,CAAK,SAAS,EAAA,GAAK,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA,MAAA,CAAA,GAAM,IAAA,EAAM,SAAS,CAAA;AAAA,EACtF,CAAA;AAEA,EAAA,IAAI,CAAA;AACJ,EAAA,kBAAA,CAAmB,SAAA,GAAY,CAAA;AAC/B,EAAA,OAAQ,CAAA,GAAI,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA,EAAI;AAC1C,IAAA,IAAI,CAAC,YAAA,CAAa,CAAA,CAAE,CAAC,CAAE,CAAA,EAAG;AAC1B,IAAA,MAAM,KAAA,GAAA,CAAS,EAAE,CAAC,CAAA,KAAM,WAAW,EAAA,GAAK,CAAA,CAAE,CAAC,CAAA,KAAO,IAAA;AAClD,IAAA,IAAA,CAAK,CAAA,CAAE,KAAA,EAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,EAAG;AAAA,MACzC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,GAAG,KAAK,CAAA,QAAA,CAAA;AAAA,MACf,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,GAAG,KAAK,CAAA,QAAA;AAAA,KAChB,CAAA;AAAA,EACH;AACA,EAAA,gBAAA,CAAiB,SAAA,GAAY,CAAA;AAC7B,EAAA,OAAQ,CAAA,GAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA,EAAI;AACxC,IAAA,IAAA;AAAA,MACE,CAAA,CAAE,KAAA;AAAA,MACF,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA;AAAA,MACf,EAAE,CAAC,CAAA;AAAA,MACH,mBAAA,CAAoB,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,CAAE,CAAC,KAAK,EAAE;AAAA,KACrD;AAAA,EACF;AACA,EAAA,MAAM,cAAA,GAAiB,CAAC,gBAAA,EAAkB,mBAAA,EAAqB,yBAAyB,CAAA;AACxF,EAAA,WAAA,CAAY,SAAA,GAAY,CAAA;AACxB,EAAA,OAAQ,CAAA,GAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAI;AACnC,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3B,IAAA,IAAA,CAAK,CAAA,CAAE,KAAA,EAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,EAAG,cAAc,CAAA;AAAA,EAC3D;AACA,EAAA,MAAA,CAAO,SAAA,GAAY,CAAA;AACnB,EAAA,OAAQ,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAI;AAC9B,IAAA,MAAM,GAAA,GAAM,EAAE,CAAC,CAAA;AACf,IAAA,IAAI,CAAC,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,EAAG;AACxC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,KAAA,GAAQ,EAAE,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA;AAC5D,IAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,MAAM,CAAA,EAAG;AAEnC,IAAA,IAAI,GAAA,CAAI,MAAA,IAAU,CAAA,IAAK,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,IAAK,CAAC,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA,EAAG;AACrE,IAAA,IAAA,CAAK,CAAA,CAAE,KAAA,EAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,EAAG,cAAc,CAAA;AAAA,EAC3D;AACA,EAAA,OAAO,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,IAAA,GAAO,EAAE,IAAI,CAAA;AAC5C;AASA,SAAS,qBAAqB,GAAA,EAAwB;AACpD,EAAA,MAAM,QAAsB,EAAC;AAC7B,EAAA,KAAA,MAAW,GAAA,IAAO,GAAA,CAAI,WAAA,EAAY,EAAG;AACnC,IAAA,IAAI,CAAC,UAAU,IAAA,CAAK,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,OAAO,CAAA,EAAG;AACnD,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AACvB,IAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,IAAA,MAAM,IAAA,GAAO,cAAc,GAAG,CAAA;AAC9B,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,GAAG,CAAA;AAC9B,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,cAAc,CAAA;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,GAAS,KAAA,CAAM,MAAA;AACjC,IAAA,MAAM,QAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,IAAI,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,CAAA,iBAAA,EAAe,CAAA,CAAE,QAAQ,IAAA,CAAK,KAAK,CAAC,CAAA,CAAE,CAAA;AAC1F,IAAA,IAAI,OAAO,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,IAAI,CAAA,KAAA,CAAO,CAAA;AACxC,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,iBAAA;AAAA,MACN,QAAA,EAAU,SAAA;AAAA,MACV,OAAA,EAAS,CAAA,EAAG,IAAI,CAAA,YAAA,EAAe,KAAK,MAAM,CAAA;AAAA,QAAA,EAAuB,KAAA,CAAM,IAAA,CAAK,YAAY,CAAC,CAAA,CAAA;AAAA,MACzF,KAAA,EAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAE,CAAC,CAAC,CAAA,CAAE,MAAA,CAAO,IAAA,GAAO,CAAA,GAAI,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,KAAA,CAAO,CAAA,GAAI,EAAE,CAAA;AAAA,MACnG,GAAA,EAAK;AAAA,KACN,CAAA;AAAA,EACH;AACA,EAAA,OAAO,KAAA;AACT;AAEA,IAAM,mBAAA,GAAsB,GAAA;AAG5B,SAAS,eAAe,GAAA,EAAwB;AAC9C,EAAA,IAAI,CAAC,IAAI,WAAA,EAAY,CAAE,SAAS,WAAW,CAAA,SAAU,EAAC;AACtD,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,KAAK,GAAA,CAAI,IAAA,EAAM,WAAW,CAAC,CAAA;AACpD,EAAA,IAAI,GAAA,KAAQ,IAAA,EAAM,OAAO,EAAC;AAC1B,EAAA,MAAM,KAAA,GAAQ,IAAI,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA;AACjD,EAAA,IAAI,KAAA,IAAS,mBAAA,EAAqB,OAAO,EAAC;AAC1C,EAAA,OAAO;AAAA,IACL;AAAA,MACE,IAAA,EAAM,oBAAA;AAAA,MACN,QAAA,EAAU,SAAA;AAAA,MACV,OAAA,EAAS,CAAA,aAAA,EAAgB,KAAK,CAAA,qBAAA,EAAwB,mBAAmB,CAAA,WAAA,CAAA;AAAA,MACzE,KAAA,EAAO,CAAC,WAAW,CAAA;AAAA,MACnB,GAAA,EAAK;AAAA;AACP,GACF;AACF;AAGO,SAAS,cAAA,CAAe,MAAc,KAAA,EAAiC;AAC5E,EAAA,OAAO,KAAA,CAAM,eAAe,MAAM;AAChC,IAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,EAAM,KAAK,CAAA;AACjC,IAAA,MAAM,MAAA,GAAS,mBAAmB,GAAG,CAAA;AACrC,IAAA,OAAO;AAAA,MACL,GAAG,oBAAoB,GAAG,CAAA;AAAA,MAC1B,GAAG,eAAe,GAAG,CAAA;AAAA,MACrB,GAAG,yBAAyB,KAAK,CAAA;AAAA,MACjC,GAAG,oBAAoB,GAAG,CAAA;AAAA,MAC1B,GAAG,mBAAmB,GAAG,CAAA;AAAA,MACzB,GAAG,kBAAkB,GAAG,CAAA;AAAA,MACxB,GAAG,iBAAiB,GAAG,CAAA;AAAA,MACvB,GAAG,gBAAgB,GAAG,CAAA;AAAA,MACtB,GAAG,aAAa,GAAG,CAAA;AAAA,MACnB,GAAG,MAAA,CAAO,QAAA;AAAA,MACV,GAAG,MAAA,CAAO,GAAA;AAAA,MACV,GAAG,qBAAqB,GAAG,CAAA;AAAA,MAC3B,GAAG,eAAe,GAAG;AAAA,KACvB;AAAA,EACF,CAAC,CAAA;AACH","file":"chunk-PJ4SPXHS.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 { DEFAULT_APP_LANG, isValidLang, readLayoutLang } from \"./route-tree\"\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/** Warn when the root layout's `lang` is not a valid language tag (the shell falls back to \"en\"). */\nfunction checkAppLang(ctx: Ctx): Diagnostic[] {\n const { root, model } = ctx\n const layout = model.layouts.find((l) => l.dir === \"\")\n if (!layout) return []\n const lang = readLayoutLang(layout.absFile)\n if (lang === undefined || isValidLang(lang)) return []\n return [\n {\n code: \"INVALID_APP_LANG\",\n severity: \"warning\",\n message: `Root layout exports lang ${JSON.stringify(lang)}, which is not a valid language tag; <html lang> falls back to \"${DEFAULT_APP_LANG}\".`,\n files: [rel(root, layout.absFile)],\n fix: 'Use a BCP 47 tag as a string literal, e.g. `export const lang = \"ja\"`.',\n },\n ]\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 * the 「見た目の規約」 section of AGENTS.md says how to use 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; see the 「見た目の規約」 section of AGENTS.md, and to change colors switch the theme or override styles.css). 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/** An optional DESIGN.md holds the user's own intent only, 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 DESIGN.md to your own intent (density, slide headings, brand material). Colors, fonts and radii belong to the theme / styles.css, and the usage rules to the 「見た目の規約」 section of AGENTS.md — do not copy values into DESIGN.md.\",\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 ...checkAppLang(ctx),\n ...client.boundary,\n ...client.env,\n ...checkHardcodedColors(ctx),\n ...checkDesignDoc(ctx),\n ]\n })\n}\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -50,15 +50,15 @@ ${pc.bold("Options")}
|
|
|
50
50
|
-h, --help Print this help
|
|
51
51
|
`;
|
|
52
52
|
var COMMANDS = {
|
|
53
|
-
dev: () => import('./dev-
|
|
54
|
-
build: () => import('./build-
|
|
53
|
+
dev: () => import('./dev-O42JFQ64.js').then((m) => m.dev),
|
|
54
|
+
build: () => import('./build-U7GO26HR.js').then((m) => m.build),
|
|
55
55
|
preview: () => import('./preview-T6CLSQVX.js').then((m) => m.preview),
|
|
56
|
-
check: () => import('./check-
|
|
56
|
+
check: () => import('./check-MRVAIHG5.js').then((m) => m.check),
|
|
57
57
|
routes: () => import('./routes-PVKNT777.js').then((m) => m.routes),
|
|
58
58
|
add: () => import('./add-4GHF2TX2.js').then((m) => m.add),
|
|
59
59
|
docs: () => import('./docs-JVP4RPKT.js').then((m) => m.docs),
|
|
60
60
|
search: () => import('./search-5LC4XPB5.js').then((m) => m.search),
|
|
61
|
-
doctor: () => import('./doctor-
|
|
61
|
+
doctor: () => import('./doctor-YD3XAAOT.js').then((m) => m.doctor),
|
|
62
62
|
upgrade: () => import('./upgrade-6DT7ADRP.js').then((m) => m.upgrade)
|
|
63
63
|
};
|
|
64
64
|
var NO_ROOT_POSITIONAL = /* @__PURE__ */ new Set(["add", "docs", "search"]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runDiagnostics } from './chunk-
|
|
1
|
+
import { runDiagnostics } from './chunk-PJ4SPXHS.js';
|
|
2
2
|
import './chunk-UWSQUHX6.js';
|
|
3
3
|
import { vantagePlugin } from './chunk-SDJTTMLK.js';
|
|
4
4
|
import './chunk-SHZM3EXB.js';
|
|
@@ -77,5 +77,5 @@ async function dev(root, args) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export { dev };
|
|
80
|
-
//# sourceMappingURL=dev-
|
|
81
|
-
//# sourceMappingURL=dev-
|
|
80
|
+
//# sourceMappingURL=dev-O42JFQ64.js.map
|
|
81
|
+
//# sourceMappingURL=dev-O42JFQ64.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/dev.ts"],"names":[],"mappings":"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","file":"dev-
|
|
1
|
+
{"version":3,"sources":["../src/cli/dev.ts"],"names":[],"mappings":"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","file":"dev-O42JFQ64.js","sourcesContent":["import { createServer, loadEnv } from \"vite\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { timedAsync } from \"../core/profile\"\nimport { scanProject } from \"../core/scan\"\nimport { vantagePlugin } from \"../vite/index\"\nimport {\n applyApiBaseUrlFlag,\n log,\n printDiagnostics,\n reportPortInUse,\n resolveDraftPreview,\n resolveHmrOverlay,\n resolveHostOptions,\n resolvePortOptions,\n type ParsedArgs,\n} from \"./util\"\n\n/** `vantage dev` — start the dev server with HMR and the optional API server. */\nexport async function dev(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 starting the dev server.\")\n return 1\n }\n\n const mode = \"development\"\n applyApiBaseUrlFlag(args)\n const env = { ...process.env, ...loadEnv(mode, root, \"\") }\n const ports = resolvePortOptions(args.flags, 5173)\n if (!ports.ok) {\n log.error(ports.error)\n return 1\n }\n const { port, strictPort } = ports\n const hosts = resolveHostOptions(args.flags)\n if (!hosts.ok) {\n log.error(hosts.error)\n return 1\n }\n const overlay = resolveHmrOverlay(args.flags)\n\n const server = await timedAsync(\"vite:createServer\", () =>\n createServer({\n configFile: false,\n root,\n mode,\n // The model was just scanned for diagnostics; hand it over so the plugin\n // does not walk the project again.\n plugins: [vantagePlugin({ root, env, model, draftPreview: resolveDraftPreview(args.flags) })],\n // `host` / `allowedHosts` are only present when asked for, and `hmr` is\n // left alone unless the overlay is being turned off, so Vite's own\n // defaults (host, port, protocol) keep applying.\n server: {\n port,\n strictPort,\n ...hosts.options,\n ...(overlay ? {} : { hmr: { overlay: false } }),\n },\n clearScreen: false,\n }),\n )\n\n try {\n await timedAsync(\"vite:listen\", () => server.listen())\n } catch (err) {\n await server.close().catch(() => {})\n if (reportPortInUse(err, port, strictPort)) return 1\n throw err\n }\n log.brand(\"dev server ready\")\n server.printUrls()\n if (model.hasServer) log.info(\" \" + \"server/api enabled\")\n\n const shutdown = async () => {\n await server.close()\n process.exit(0)\n }\n process.on(\"SIGINT\", shutdown)\n process.on(\"SIGTERM\", shutdown)\n\n // Keep the process alive; the listening server owns the lifecycle.\n return new Promise<number>(() => {})\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runDiagnostics } from './chunk-
|
|
1
|
+
import { runDiagnostics } from './chunk-PJ4SPXHS.js';
|
|
2
2
|
import './chunk-UWSQUHX6.js';
|
|
3
3
|
import './chunk-S5MDTHH7.js';
|
|
4
4
|
import { scanProject } from './chunk-RNTDBX6S.js';
|
|
@@ -54,5 +54,5 @@ async function doctor(root, args) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export { doctor };
|
|
57
|
-
//# sourceMappingURL=doctor-
|
|
58
|
-
//# sourceMappingURL=doctor-
|
|
57
|
+
//# sourceMappingURL=doctor-YD3XAAOT.js.map
|
|
58
|
+
//# sourceMappingURL=doctor-YD3XAAOT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/doctor.ts"],"names":["require"],"mappings":"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","file":"doctor-
|
|
1
|
+
{"version":3,"sources":["../src/cli/doctor.ts"],"names":["require"],"mappings":";;;;;;;;;;;AAcA,eAAsB,MAAA,CAAO,MAAc,IAAA,EAAmC;AAC5E,EAAA,MAAM,SAAkB,EAAC;AAEzB,EAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,QAAA,CAAS,KAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAC5D,EAAA,MAAA,CAAO,IAAA,CAAK;AAAA,IACV,IAAA,EAAM,MAAA;AAAA,IACN,IAAI,SAAA,IAAa,EAAA;AAAA,IACjB,MAAA,EAAQ,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG,SAAA,IAAa,EAAA,GAAK,EAAA,GAAK,mBAAmB,CAAA;AAAA,GAC/E,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,cAAc,CAAA;AAC9C,EAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,GAAG,UAAA,CAAW,OAAO,CAAA,EAAG,MAAA,EAAQ,GAAG,UAAA,CAAW,OAAO,CAAA,GAAI,OAAA,GAAU,WAAW,CAAA;AAEtH,EAAA,MAAM,YAAY,CAAC,UAAA,EAAY,WAAA,EAAa,gBAAA,EAAkB,qBAAqB,WAAW,CAAA;AAC9F,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,EAAA,CAAG,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,CAAC,CAAC,KAAK,EAAA,CAAG,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,CAAC,CAAC,KAAK,EAAA,CAAG,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAChK,EAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,OAAA,CAAQ,IAAI,CAAA,EAAG,MAAA,EAAQ,IAAA,IAAQ,YAAA,EAAc,CAAA;AAEjF,EAAA,IAAI,gBAAA,GAAmB,eAAA;AACvB,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI;AACF,IAAA,MAAMA,WAAU,aAAA,CAAc,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,SAAS,CAAC,CAAA;AACxD,IAAA,MAAM,CAAA,GAAIA,QAAAA,CAAQ,OAAA,CAAQ,iCAAiC,CAAA;AAC3D,IAAA,gBAAA,GAAoB,KAAK,KAAA,CAAM,EAAA,CAAG,aAAa,CAAA,EAAG,MAAM,CAAC,CAAA,CAA0B,OAAA;AACnF,IAAA,SAAA,GAAY,IAAA;AAAA,EACd,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,oBAAA,EAAsB,IAAI,SAAA,EAAW,MAAA,EAAQ,kBAAkB,CAAA;AAEnF,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,EAAM,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA;AAC/E,EAAA,MAAA,CAAO,IAAA,CAAK;AAAA,IACV,IAAA,EAAM,SAAA;AAAA,IACN,EAAA,EAAI,OAAO,MAAA,KAAW,CAAA;AAAA,IACtB,QAAQ,MAAA,CAAO,MAAA,KAAW,IAAI,oBAAA,GAAuB,CAAA,EAAG,OAAO,MAAM,CAAA,iCAAA;AAAA,GACtE,CAAA;AAED,EAAA,MAAM,QAAQ,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAEtC,EAAA,IAAI,IAAA,CAAK,MAAM,IAAA,EAAM;AACnB,IAAA,SAAA,CAAU,EAAE,EAAA,EAAI,KAAA,EAAO,KAAK,gBAAA,EAAiB,EAAG,QAAQ,CAAA;AACxD,IAAA,OAAO,QAAQ,CAAA,GAAI,CAAA;AAAA,EACrB;AAEA,EAAA,GAAA,CAAI,KAAA,CAAM,CAAA,aAAA,EAAgB,gBAAA,EAAkB,CAAA,CAAA,CAAG,CAAA;AAC/C,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,IAAA,GAAO,GAAG,CAAA,CAAE,IAAA,CAAK,OAAO,EAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,MAAM,CAAA,CAAA;AAC7C,IAAA,IAAI,CAAA,CAAE,EAAA,EAAI,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA;AAAA,SAChB,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,EACrB;AACA,EAAA,OAAO,QAAQ,CAAA,GAAI,CAAA;AACrB","file":"doctor-YD3XAAOT.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\nimport { runDiagnostics } from \"../core/diagnostics\"\nimport { scanProject } from \"../core/scan\"\nimport { frameworkVersion, log, printJson, type ParsedArgs } from \"./util\"\n\ninterface Facet {\n name: string\n ok: boolean\n detail: string\n}\n\n/** `vantage doctor` — environment and installation health checks. */\nexport async function doctor(root: string, args: ParsedArgs): Promise<number> {\n const facets: Facet[] = []\n\n const nodeMajor = Number(process.versions.node.split(\".\")[0])\n facets.push({\n name: \"node\",\n ok: nodeMajor >= 20,\n detail: `v${process.versions.node}${nodeMajor >= 20 ? \"\" : \" (requires >= 20)\"}`,\n })\n\n const pkgPath = path.join(root, \"package.json\")\n facets.push({ name: \"package.json\", ok: fs.existsSync(pkgPath), detail: fs.existsSync(pkgPath) ? \"found\" : \"missing\" })\n\n const lockfiles = [\"bun.lock\", \"bun.lockb\", \"pnpm-lock.yaml\", \"package-lock.json\", \"yarn.lock\"]\n const lock = lockfiles.find((f) => fs.existsSync(path.join(root, f)) || fs.existsSync(path.join(root, \"..\", f)) || fs.existsSync(path.join(root, \"..\", \"..\", f)))\n facets.push({ name: \"lockfile\", ok: Boolean(lock), detail: lock ?? \"none found\" })\n\n let installedVantage = \"not installed\"\n let vantageOk = false\n try {\n const require = createRequire(path.join(root, \"noop.js\"))\n const p = require.resolve(\"@squadbase/vantage/package.json\")\n installedVantage = (JSON.parse(fs.readFileSync(p, \"utf8\")) as { version: string }).version\n vantageOk = true\n } catch {\n /* not resolvable */\n }\n facets.push({ name: \"@squadbase/vantage\", ok: vantageOk, detail: installedVantage })\n\n const model = scanProject(root)\n const errors = runDiagnostics(root, model).filter((d) => d.severity === \"error\")\n facets.push({\n name: \"project\",\n ok: errors.length === 0,\n detail: errors.length === 0 ? \"no blocking errors\" : `${errors.length} error(s) (run \\`vantage check\\`)`,\n })\n\n const allOk = facets.every((f) => f.ok)\n\n if (args.flags.json) {\n printJson({ ok: allOk, cli: frameworkVersion(), facets })\n return allOk ? 0 : 1\n }\n\n log.brand(`doctor (cli v${frameworkVersion()})`)\n for (const f of facets) {\n const line = `${f.name.padEnd(22)} ${f.detail}`\n if (f.ok) log.ok(line)\n else log.error(line)\n }\n return allOk ? 0 : 1\n}\n"]}
|
package/docs/en/agent-skills.md
CHANGED
|
@@ -15,7 +15,7 @@ All of these target an agent that is **building a Vantage app**.
|
|
|
15
15
|
| `vantage-app` | Creating an app, and growing a single-file `index.tsx` SPA into a fullstack app with `server/api`, nested layouts, dynamic routes, and 404/error pages |
|
|
16
16
|
| `vantage-add-feature` | Adding a page / API / UI / block (`vantage add` through to `check` / `routes`) |
|
|
17
17
|
| `vantage-slide` | Writing a slide deck in `.slide.tsx` (the 1920×1080 canvas's vertical budget, the type scale, stepped reveals, transitions and morph, what a pptx export needs) |
|
|
18
|
-
| `vantage-design` |
|
|
18
|
+
| `vantage-design` | Choosing and applying the theme (`styles.css` values) — colors, chart palette, fonts, matching a brand from a URL, logo, document, or an external DESIGN.md, and checking contrast |
|
|
19
19
|
| `vantage-pitfalls` | A pitfalls reference (Base UI ≠ Radix, `SelectValue` behavior, never importing `server/` from the client, and more) |
|
|
20
20
|
| `project-storage` | Working with Squadbase Project Storage (uploaded files) from the browser — listing, embedding images / video / PDFs, uploading. For apps running on Squadbase |
|
|
21
21
|
|
package/docs/ja/agent-skills.md
CHANGED
|
@@ -15,7 +15,7 @@ Vantage は **Claude Code の Agent Skills** を同梱しています。Skill
|
|
|
15
15
|
| `vantage-app` | アプリの新規作成と、`index.tsx` 単体の SPA から `server/api`・ネストレイアウト・動的ルート・404/error を備えた fullstack への拡張 |
|
|
16
16
|
| `vantage-add-feature` | ページ / API / UI / ブロックの追加(`vantage add` + `check` / `routes` までの一連) |
|
|
17
17
|
| `vantage-slide` | `.slide.tsx` でスライドデッキを書く(1920×1080 キャンバスの縦方向の予算、タイプスケール、段階表示、トランジションとモーフ、pptx 書き出しの前提) |
|
|
18
|
-
| `vantage-design` |
|
|
18
|
+
| `vantage-design` | テーマ(`styles.css` の値と配色・チャートの色・書体)を決めて適用する(ブランド合わせ。URL・ロゴ・資料・外部の DESIGN.md からの取り込み、コントラストの確認) |
|
|
19
19
|
| `vantage-pitfalls` | 落とし穴リファレンス(Base UI ≠ Radix、`SelectValue` の挙動、クライアントから `server/` を import しない など) |
|
|
20
20
|
| `project-storage` | Squadbase の Project Storage(アップロード済みファイル)をブラウザから扱う(一覧、画像 / 動画 / PDF の埋め込み、アップロード)。Squadbase 上で動くアプリ向け |
|
|
21
21
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squadbase/vantage",
|
|
3
|
-
"version": "0.6.2-dev1.
|
|
3
|
+
"version": "0.6.2-dev1.100dfeb",
|
|
4
4
|
"description": "Data dashboard framework for Squadbase Editor. Vite-powered, config-free, one-file first.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
"vitest": "^5.0.5",
|
|
153
153
|
"@squadbase/squadkit": "0.0.0"
|
|
154
154
|
},
|
|
155
|
-
"gitHead": "
|
|
155
|
+
"gitHead": "100dfeb79a0e13334b19fe2408d7c5421e715acb",
|
|
156
156
|
"scripts": {
|
|
157
157
|
"build": "node scripts/build-docs.mjs && node scripts/build.mjs",
|
|
158
158
|
"build:js": "tsup --no-dts",
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vantage-design
|
|
3
|
-
description: Vantage(@squadbase/vantage)
|
|
3
|
+
description: Vantage(@squadbase/vantage)アプリのテーマ(色・チャートの色・書体・角丸)を、`styles.css` とテーマコマンドで作る / 更新する手順。配色・ブランドカラー・テーマ・チャートの色・フォント・角丸・トーンを変えたいとき、既存サイトやロゴ・資料に合わせたいとき、プロジェクト作成時の初期デザイン(テーマ neutral / ocean / forest / sunset / violet / rose / mono)を決めるときに使う。「色を変えて」「ブランドに合わせて」「このサイトに合わせて」「落ち着いた感じに」「フォントを変えて」「テーマを作って」、"change the colors", "match our brand", "match this website", "theme", "color palette", "font", "design system" で起動。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# テーマと styles.css を更新する
|
|
7
7
|
|
|
8
|
-
Vantage
|
|
8
|
+
Vantage アプリの色・書体・角丸の値と色の割り当ては、SquadKit のテーマだけが持つ。
|
|
9
9
|
|
|
10
|
-
|
|
|
11
|
-
| --- | --- |
|
|
12
|
-
| `
|
|
13
|
-
| `styles.css`(ページと同じ側。通常 `src/styles.css`)
|
|
10
|
+
| 手段 | 何を決めるか |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| ThemeDialog / `theme <id>` / `chart <preset>`(CLI) | 出発点のテーマとチャートの配色 |
|
|
13
|
+
| `styles.css`(ページと同じ側。通常 `src/styles.css`)の `/* squadkit-theme:end */` より後ろ | ブランド色・書体など、テーマに無い値の上書き |
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
デザイン変更の依頼(「もっと落ち着いた色に」など)は、**テーマの切り替えかスタイルシートの上書きで完結させる。**
|
|
16
|
+
`DESIGN.md` へは記録しない。今のテーマ名は `styles.css` の `/* theme: <name> */` マーカーから読む。
|
|
17
|
+
ページ単位の `className` 修正で済ませない。
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
見た目の規則(意味トークンの使い分け・カードで包む・KPI → チャート → 表など)は `AGENTS.md` の
|
|
20
|
+
「見た目の規約」節が正本。ここでは手順だけを扱い、規則は重複させない。
|
|
21
|
+
任意の `DESIGN.md`(ユーザー固有の意図を書くファイル)は、ユーザーが望んだときだけ扱う(`references/format.md`)。
|
|
19
22
|
|
|
20
23
|
## リファレンス
|
|
21
24
|
|
|
22
25
|
| ファイル | 読む場面 |
|
|
23
26
|
| --- | --- |
|
|
24
|
-
| `references/format.md` | `DESIGN.md`
|
|
25
|
-
| `references/extract.md` | URL・画像・pptx/pdf
|
|
27
|
+
| `references/format.md` | ユーザーが任意の `DESIGN.md` を望んだとき(位置づけと優先順位) |
|
|
28
|
+
| `references/extract.md` | URL・画像・pptx/pdf・言葉から色と書体を取り出すとき |
|
|
26
29
|
| `references/presets.md` | テーマ(`neutral` / `ocean` / `forest` / `sunset` / `violet` / `rose` / `mono`)の選び方と `theme` コマンド。旧プリセット id の読み替え |
|
|
27
30
|
| `scripts/contrast.mjs` | 文字色と背景色のコントラスト比を確かめるとき |
|
|
28
31
|
|
|
@@ -30,24 +33,23 @@ Vantage アプリの見た目は 2 つのファイルで決まる。
|
|
|
30
33
|
|
|
31
34
|
### 1. 入力を集める
|
|
32
35
|
|
|
33
|
-
- 何に合わせるのか(URL
|
|
36
|
+
- 何に合わせるのか(URL・ロゴ画像・資料・言葉)を確認し、
|
|
34
37
|
`references/extract.md` の該当する節の手順で色・書体・トーンを取り出す。
|
|
35
|
-
- 既存の `
|
|
38
|
+
- 既存の `styles.css` を読み、マーカーから今のテーマ名を確かめる。今回触らない上書きは残す。
|
|
39
|
+
- プロジェクトルートに `DESIGN.md` があれば読む(ユーザー所有。書き換えない)。色の割り当てはテーマが優先。
|
|
36
40
|
- スライド(`*.slide.tsx`)があるかを `ls` / `vantage routes` で確認しておく。
|
|
37
41
|
|
|
38
42
|
### 2. 提案して確認を取る
|
|
39
43
|
|
|
40
44
|
書き込む前に、次の 2 つをユーザーに見せて確認を取る。
|
|
41
45
|
|
|
42
|
-
- **役割 → トークンの対応表**(
|
|
46
|
+
- **役割 → トークンの対応表**(主色・背景の段階・文字・チャート 5 色・書体。良い/悪い/注意/情報/中立はテーマの意味トークンに任せる)。
|
|
43
47
|
各行に「何に合わせてその色にしたか」を 1 語添える。
|
|
44
|
-
- **トーンの説明**(2〜3
|
|
48
|
+
- **トーンの説明**(2〜3 行)。
|
|
45
49
|
|
|
46
50
|
テーマで足りる場合はテーマ id(`references/presets.md`)で提案してよい。旧プリセット id(`default` / `calm` / `vivid` / `mono`)で頼まれたら新 id に読み替える。
|
|
47
51
|
|
|
48
|
-
### 3. styles.css
|
|
49
|
-
|
|
50
|
-
`styles.css`:
|
|
52
|
+
### 3. テーマを当て、styles.css を書く
|
|
51
53
|
|
|
52
54
|
- **テーマ範囲・チャート範囲のマーカーの中は手で編集しない。** 色・角丸・書体の出発点は 7 テーマ
|
|
53
55
|
(`neutral` / `ocean` / `forest` / `sunset` / `violet` / `rose` / `mono`)から選び、コマンドで当てる:
|
|
@@ -100,10 +102,6 @@ Vantage アプリの見た目は 2 つのファイルで決まる。
|
|
|
100
102
|
長い表(ダッシュボード): カードに `max-h-*` + `overflow-y-auto` の縦スクロール領域を作らず、
|
|
101
103
|
ページング付きの `DataTablePreset`(`enablePagination`)にする(ホイールや End キーがページに届かなくなるため)。
|
|
102
104
|
|
|
103
|
-
`DESIGN.md`: `references/format.md` の書式で書く。**色コードを書かない**(トークン名だけ)。
|
|
104
|
-
150 行を超えない(超えると `vantage check` が `DESIGN_MD_TOO_LONG` を出す)。ロゴなどの素材は
|
|
105
|
-
`public/brand/logo.svg` のように `public/` 配下のパスで「ブランド素材」行に書く。
|
|
106
|
-
|
|
107
105
|
### 4. コントラストを確かめる
|
|
108
106
|
|
|
109
107
|
主な文字色 / 背景色の組を、**ライトとダークの両方で**確かめる。
|
|
@@ -133,11 +131,11 @@ node <このスキルの場所>/scripts/contrast.mjs '<文字色>' '<背景色>'
|
|
|
133
131
|
npx vantage check
|
|
134
132
|
```
|
|
135
133
|
|
|
136
|
-
`HARDCODED_COLOR`(ページ内の色コード)
|
|
134
|
+
`HARDCODED_COLOR`(ページ内の色コード)などが出たらその場で直す。
|
|
137
135
|
|
|
138
136
|
### 7. 完了を報告する
|
|
139
137
|
|
|
140
|
-
報告には、更新したファイル(`
|
|
138
|
+
報告には、更新したファイル(`styles.css` など)と当てたテーマ名に加えて次を**必ず**入れる。
|
|
141
139
|
|
|
142
140
|
- プレビューページのパスと URL(`src/design-preview.tsx` → `/design-preview`)。
|
|
143
141
|
- 「ホームなど既存の画面は一部の色しか使っていないので、変更が見えないことがある。配色はプレビュー
|
|
@@ -145,5 +143,5 @@ npx vantage check
|
|
|
145
143
|
|
|
146
144
|
## 会話中の指示との関係
|
|
147
145
|
|
|
148
|
-
- 会話中の個別の指示(「このグラフだけ赤で」)
|
|
149
|
-
- 同じ指示が 2 回以上出たら、`
|
|
146
|
+
- 会話中の個別の指示(「このグラフだけ赤で」)はテーマより優先する。そのページだけ直せばよい。
|
|
147
|
+
- 同じ指示が 2 回以上出たら、`styles.css` の上書きへ反映することを提案する(この手順の 2 から)。
|
|
@@ -44,7 +44,7 @@ grep -oE 'font-family:[^;]+' /tmp/site.css | sort | uniq -c | sort -rn | head
|
|
|
44
44
|
- SPA で HTML がほぼ空のときは、`<script>` より先に CSS の `<link>` を探す。それも無ければ
|
|
45
45
|
ユーザーにスクリーンショットかブランドカラーを聞く(推測で埋めない)。
|
|
46
46
|
- 取得できない(認証・ボット対策)ときは、その旨を伝えてスクリーンショットをもらう。
|
|
47
|
-
- ロゴを使うなら `public/brand/`
|
|
47
|
+
- ロゴを使うなら `public/brand/` に保存する。
|
|
48
48
|
|
|
49
49
|
## 画像・ロゴ
|
|
50
50
|
|
|
@@ -83,12 +83,10 @@ grep -oE 'font-family:[^;]+' /tmp/site.css | sort | uniq -c | sort -rn | head
|
|
|
83
83
|
|
|
84
84
|
## 外部の DESIGN.md(Stitch などが書いたもの)
|
|
85
85
|
|
|
86
|
-
外部の DESIGN.md
|
|
87
|
-
Vantage
|
|
88
|
-
書き直す**。
|
|
86
|
+
外部の DESIGN.md が値(hex・px・フォント名)を持っているときは、値だけを拾って**テーマ側**へ移す。
|
|
87
|
+
Vantage に `DESIGN.md` は作らない。
|
|
89
88
|
|
|
90
|
-
1. 値を拾う: primary / secondary / surface / background / on-* / error
|
|
91
|
-
フォント、角丸。
|
|
89
|
+
1. 値を拾う: primary / secondary / surface / background / on-* / error、フォント、角丸。
|
|
92
90
|
2. 対応づける:
|
|
93
91
|
|
|
94
92
|
| 外部の名前 | Vantage のトークン |
|
|
@@ -98,15 +96,14 @@ Vantage の `DESIGN.md` は値を持たないので、**値を `styles.css` へ
|
|
|
98
96
|
| background / surface / surface-container | `--background` / `--card` / `--muted` |
|
|
99
97
|
| on-background / on-surface / on-surface-variant | `--foreground` / `--card-foreground` / `--muted-foreground` |
|
|
100
98
|
| outline | `--border` |
|
|
101
|
-
| error | `--destructive` |
|
|
102
|
-
| success / warning |
|
|
99
|
+
| error | `--destructive`(意味トークンの negative) |
|
|
100
|
+
| success / warning | テーマの意味トークン(positive / warning)に任せる。チャートの色には割り当てない |
|
|
103
101
|
| radius / corner | `--radius` |
|
|
104
102
|
| display / headline font | `--slide-font-display`(+ ページの見出しなら `--font-sans`) |
|
|
105
103
|
| body font | `--font-sans`(ページ本文)と `--slide-font-body` |
|
|
106
104
|
|
|
107
105
|
3. `styles.css` のマーカーブロックの外に、`:root` と `.dark, [data-theme="dark"]` の両方で書く
|
|
108
|
-
(チャート色・書体の書き方は SKILL.md の手順 3)
|
|
109
|
-
|
|
110
|
-
4. `DESIGN.md`
|
|
111
|
-
|
|
112
|
-
5. 元のファイルは消さずに残すか(例: `docs/design-source.md`)、ユーザーに確認して削除する。
|
|
106
|
+
(チャート色・書体の書き方は SKILL.md の手順 3)。外部にダークの値が無ければ、ライトの色相を保って
|
|
107
|
+
明度だけ反転した値を作り、コントラストを確かめる。
|
|
108
|
+
4. 外部のトーン・Do/Don't・コンポーネントのルールは、ユーザーが望んだときだけ任意の `DESIGN.md`
|
|
109
|
+
(`format.md`)に要約して残す。値は書かない。
|
|
@@ -1,173 +1,12 @@
|
|
|
1
|
-
# DESIGN.md
|
|
2
|
-
|
|
3
|
-
`DESIGN.md`
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- **150 行以内。** 超えると `vantage check` が `DESIGN_MD_TOO_LONG` を警告する。エージェントが
|
|
14
|
-
毎回全文を読むファイルなので、網羅より判断に効くルールを優先する。
|
|
15
|
-
- **YAML frontmatter は付けない。** 先頭は下の「冒頭のコメント」から始める。
|
|
16
|
-
- **会話中の指示が優先。** `DESIGN.md` は既定値であって、個別の依頼を拒む根拠にしない。
|
|
17
|
-
- ロゴ・画像は `public/` 配下のパスで参照する(`public/brand/logo.svg`)。画像を埋め込まない。
|
|
18
|
-
|
|
19
|
-
## 節の順番と見出し
|
|
20
|
-
|
|
21
|
-
見出しは日本語 + 英語の括弧書き(外部の DESIGN.md — Stitch など — の節と対応づけやすくするため)。
|
|
22
|
-
この順番を崩さない。無い情報の節は消さずに「特になし」と書く。
|
|
23
|
-
|
|
24
|
-
| # | 見出し | 書くこと |
|
|
25
|
-
| --- | --- | --- |
|
|
26
|
-
| 0 | 冒頭のコメント(`<!-- … -->`) | 何のファイルか / 値は styles.css / 会話の指示が優先 / 「このサイトに合わせて」で更新できること / upgrade が触らないこと |
|
|
27
|
-
| 1 | `## 全体のトーン (Overview)` | 2〜4 行のトーン。最後に「ブランド素材:」行(任意。`public/` のパス) |
|
|
28
|
-
| 2 | `## 色 (Colors)` | 役割 → トークンの表。行は **主色 / 強調 / 良い / 悪い / 注意 / 背景の段階 / 境界 / 文字**。専用トークンが無い役割は「専用トークンなし」+ 代替 |
|
|
29
|
-
| 3 | `## チャート (Charts)` | 系列の順番(`--chart-1..5` とその色味)、1 系列だけ強調するときの色、良い / 悪いの色、禁止の組み合わせ、プリセット名 |
|
|
30
|
-
| 4 | `## 書体 (Typography)` | 見出し / 本文 / 数字 / スライドの書体(`--slide-font-display` / `--slide-font-body`)と、サイズの段階(Tailwind クラス・`--slide-size-*`) |
|
|
31
|
-
| 5 | `## レイアウトと密度 (Layout)` | カード・余白(`gap-*`)・`--radius`・並べ方・密度 |
|
|
32
|
-
| 6 | `## 成果物の種類ごとの規則 (Per-artifact)` | `### ダッシュボード` と `### スライド` の小節(他の種類があれば小節を足す) |
|
|
33
|
-
| 7 | `## Do / Don't` | 3 つずつ程度 |
|
|
34
|
-
|
|
35
|
-
外部の DESIGN.md の対応: Overview / Colors / Typography / Layout(Spacing・Elevation 含む)/
|
|
36
|
-
Components → 「成果物の種類ごとの規則」/ Do's and Don'ts。値は `styles.css` へ移す
|
|
37
|
-
(→ `extract.md` の「外部の DESIGN.md」)。
|
|
38
|
-
|
|
39
|
-
## 使えるトークン
|
|
40
|
-
|
|
41
|
-
| 系統 | トークン |
|
|
42
|
-
| --- | --- |
|
|
43
|
-
| 面と文字 | `--background` `--foreground` `--card` `--card-foreground` `--popover` `--popover-foreground` |
|
|
44
|
-
| 主色など | `--primary` `--primary-foreground` `--secondary` `--secondary-foreground` `--accent` `--accent-foreground` `--muted` `--muted-foreground` `--destructive` `--destructive-foreground` |
|
|
45
|
-
| 境界 | `--border` `--input` `--ring` |
|
|
46
|
-
| チャート | `--chart-1` 〜 `--chart-5` |
|
|
47
|
-
| 形 | `--radius` |
|
|
48
|
-
| サイドバー | `--sidebar` `--sidebar-foreground` `--sidebar-primary` … |
|
|
49
|
-
| スライド | `--slide-bg` `--slide-fg` `--slide-accent` `--slide-muted` `--slide-radius` `--slide-font-display` `--slide-font-body` `--slide-size-hero` `--slide-size-body` |
|
|
50
|
-
|
|
51
|
-
- `--muted` `--accent` `--secondary` `--border` は背景・境界用。文字色の役割に割り当てない。
|
|
52
|
-
- 良い / 注意の専用トークンは無い。`--chart-*` の中から割り当てるか、「専用トークンなし」と書く。
|
|
53
|
-
- ページ本文の書体は `--font-sans`(`styles.css` の `body` が `font-family: var(--font-sans)` で参照する。
|
|
54
|
-
テーマを当てると `--font-sans` もテーマの値になる。変えるときはテーマ範囲のマーカーの後ろで上書きする)。
|
|
55
|
-
- `--slide-bg` などは既定で `--background` などの別名。`.dark` に書き直す必要は無い。
|
|
56
|
-
|
|
57
|
-
## 雛形(中立の既定テーマ)
|
|
58
|
-
|
|
59
|
-
ベーステンプレート(`packages/vantage-template/template/DESIGN.md`)と**同じ内容**。どちらかを
|
|
60
|
-
直したらもう片方も合わせること。既定テーマ(無彩色の `--primary`、チャートは `blue` プリセット)を
|
|
61
|
-
そのまま説明しているので、新規に作るときはこれを写して、変えた役割の行だけを書き換える。
|
|
62
|
-
|
|
63
|
-
````markdown
|
|
64
|
-
<!--
|
|
65
|
-
DESIGN.md — このアプリの「見た目の意図」を書くファイルです。
|
|
66
|
-
|
|
67
|
-
- 実際の色・角丸・書体の値は src/styles.css にあります。ここにはトークン名(--primary など)と
|
|
68
|
-
使い分けのルールだけを書き、色コードは書きません。
|
|
69
|
-
- エージェントはページ・スライド・コンポーネントを書く前にこのファイルを読みます。
|
|
70
|
-
会話の中での指示はこのファイルより優先されます。
|
|
71
|
-
- 「このサイトに合わせて」「色を落ち着いた感じに」と頼めば、このファイルと styles.css を
|
|
72
|
-
まとめて更新します。
|
|
73
|
-
- このファイルはあなたのものです。`vantage upgrade` が書き換えることはありません。
|
|
74
|
-
-->
|
|
75
|
-
|
|
76
|
-
# デザイン
|
|
77
|
-
|
|
78
|
-
## 全体のトーン (Overview)
|
|
79
|
-
|
|
80
|
-
- 落ち着いた無彩色のベースに、データだけが色を持つ業務ダッシュボード。
|
|
81
|
-
- 装飾より読みやすさを優先する。影・グラデーション・アニメーションは最小限。
|
|
82
|
-
- 数字が主役。1 画面で伝えたいことを 1 つに絞り、補足は小さく添える。
|
|
83
|
-
- ブランド素材: なし(ロゴを使う場合は `public/brand/logo.svg` のように `public/` 配下のパスで書く)
|
|
84
|
-
|
|
85
|
-
## 色 (Colors)
|
|
86
|
-
|
|
87
|
-
色は必ずトークン(Tailwind のセマンティッククラス)で指定する。素のパレット(`bg-blue-600` など)や
|
|
88
|
-
色コードを直接書かない。
|
|
89
|
-
|
|
90
|
-
| 役割 | トークン | 使う場所 |
|
|
91
|
-
| --- | --- | --- |
|
|
92
|
-
| 主色 (Primary) | `--primary` / `--primary-foreground` | 主要ボタン、選択中の状態。既定は無彩色 |
|
|
93
|
-
| 強調 (Accent) | `--chart-1` | 1 つだけ目立たせたい数値・系列・リンク的な強調 |
|
|
94
|
-
| 良い (Positive) | `--chart-2` | 前期比のプラスなど、良い変化の小さな印 |
|
|
95
|
-
| 悪い (Negative) | `--destructive` | 前期比のマイナス、エラー、削除操作 |
|
|
96
|
-
| 注意 (Warning) | 専用トークンなし | 文言とアイコンで示し、色は `--muted-foreground` |
|
|
97
|
-
| 背景の段階 | `--background` → `--card` → `--muted` | ページ → カード → カード内の区画・ホバー |
|
|
98
|
-
| 境界 | `--border` / `--input` / `--ring` | 罫線、入力欄、フォーカス |
|
|
99
|
-
| 文字 | `--foreground` / `--muted-foreground` | 本文 / 補足・ラベル・単位 |
|
|
100
|
-
|
|
101
|
-
- `--muted`・`--accent`・`--secondary`・`--border` は背景・境界用。文字色に使わない。
|
|
102
|
-
- 増減(▲▼・前期比)は向きで色を分ける: 増加・プラスは `--chart-2`(または `--primary`)、
|
|
103
|
-
減少・マイナスは `--destructive`。下向きの矢印やマイナスを `--primary` で塗らない。
|
|
104
|
-
- ライトとダークの両方がトークンで決まるので `dark:` を並べない。
|
|
105
|
-
|
|
106
|
-
## チャート (Charts)
|
|
107
|
-
|
|
108
|
-
- 系列の順番は `--chart-1` → `--chart-2` → `--chart-3` → `--chart-4` → `--chart-5`
|
|
109
|
-
(現在はプリセット `blue`: 青 → ティール → フクシア → バイオレット → グレー)。
|
|
110
|
-
- 1 系列だけを目立たせるときは、その系列を `--chart-1`、残りをすべて `--chart-5`(グレー)にする。
|
|
111
|
-
- 良い / 悪いを色で塗り分けるときは `--chart-2` / `--destructive`。色だけに頼らず ▲▼ や符号も添える。
|
|
112
|
-
- 系列は 5 つまで。それ以上はグループ化するか「その他」にまとめる。
|
|
113
|
-
- 禁止: 同じチャートで `--destructive` を普通の系列色として使う(悪い値に見える)。
|
|
114
|
-
- 禁止: 隣り合う系列に `--chart-3` と `--chart-4` を並べて細い線で描く(見分けにくい)。
|
|
115
|
-
- 配色を丸ごと変えるときは `npx @squadbase/vantage-template theme <id>` を使う
|
|
116
|
-
(`neutral` / `ocean` / `forest` / `sunset` / `violet` / `rose` / `mono`)。チャートだけ別の配色にするときは
|
|
117
|
-
`chart <preset>`(`blue` / `ocean` / `sunset` / `forest` / `berry` / `mono`)。
|
|
118
|
-
|
|
119
|
-
## 書体 (Typography)
|
|
120
|
-
|
|
121
|
-
| 用途 | 指定 | 備考 |
|
|
122
|
-
| --- | --- | --- |
|
|
123
|
-
| 見出し・本文 | 日本語を含むシステムフォント(`--font-sans`) | Web フォントは使わない |
|
|
124
|
-
| 数字 | 同上 + `tabular-nums` | 桁がそろうように必ず付ける |
|
|
125
|
-
| スライドの見出し | `--slide-font-display` | 既定は日本語を含むシステムフォント |
|
|
126
|
-
| スライドの本文 | `--slide-font-body` | 既定は見出しと同じ |
|
|
127
|
-
|
|
128
|
-
サイズの段階(ダッシュボード):
|
|
129
|
-
|
|
130
|
-
- ページ見出し: `text-2xl font-bold`
|
|
131
|
-
- カード見出し・ラベル: `text-sm font-medium text-muted-foreground`
|
|
132
|
-
- KPI の数値: `text-3xl font-semibold tabular-nums`
|
|
133
|
-
- 本文・表: `text-sm`
|
|
134
|
-
- 注釈・出典: `text-xs text-muted-foreground`
|
|
135
|
-
|
|
136
|
-
スライドのサイズは `--slide-size-hero`(表紙・大きな数字)と `--slide-size-body`(本文)を基準にする。
|
|
137
|
-
|
|
138
|
-
## レイアウトと密度 (Layout)
|
|
139
|
-
|
|
140
|
-
- 情報はカード(`bg-card` + `border-border`)で区切る。角丸は `--radius` に従う(個別に変えない)。
|
|
141
|
-
- グリッドの間隔は `gap-4`。セクション間は `gap-6` 程度。
|
|
142
|
-
- KPI は 1 行に 2〜4 枚。その下にチャート、最後に明細の表。
|
|
143
|
-
- 密度は「中」。余白を削って詰め込むより、ページを分ける。
|
|
144
|
-
|
|
145
|
-
## 成果物の種類ごとの規則 (Per-artifact)
|
|
146
|
-
|
|
147
|
-
### ダッシュボード
|
|
148
|
-
|
|
149
|
-
- 先頭に KPI カード、次にトレンドのチャート、最後に明細の表。
|
|
150
|
-
- 各 KPI には比較対象(前月比・目標比など)を 1 つ添える。
|
|
151
|
-
- チャートのタイトルは結論を書く(「売上推移」より「売上は 3 か月連続で増加」)。
|
|
152
|
-
|
|
153
|
-
### スライド
|
|
154
|
-
|
|
155
|
-
- 1 枚に 1 メッセージ。見出しに結論を書く。
|
|
156
|
-
- 色は `--slide-bg` / `--slide-fg` / `--slide-accent` / `--slide-muted` を使う
|
|
157
|
-
(既定では `--background` / `--foreground` / `--primary` / `--muted-foreground` に連動)。
|
|
158
|
-
- 強調色は 1 枚につき 1 か所まで。
|
|
159
|
-
|
|
160
|
-
## Do / Don't
|
|
161
|
-
|
|
162
|
-
Do:
|
|
163
|
-
|
|
164
|
-
- トークンと Tailwind のセマンティッククラスで色を指定する。
|
|
165
|
-
- 数値には単位と比較対象を付ける。
|
|
166
|
-
- 色の意味(良い / 悪い / 強調)をアプリ全体でそろえる。
|
|
167
|
-
|
|
168
|
-
Don't:
|
|
169
|
-
|
|
170
|
-
- 色コードや素のパレットクラスを直接書く。
|
|
171
|
-
- 1 画面で強調色を何か所にも使う。
|
|
172
|
-
- 3D チャート・円グラフの多用・装飾目的のグラデーション。
|
|
173
|
-
````
|
|
1
|
+
# 任意の DESIGN.md
|
|
2
|
+
|
|
3
|
+
`DESIGN.md` は、プロジェクトルートに置く**ユーザー所有の任意のファイル**。新規プロジェクトには作らない。
|
|
4
|
+
ユーザーが望んだときだけ、ユーザー固有の意図(密度・スライドの見出し方針・ブランド素材など)を書く。
|
|
5
|
+
|
|
6
|
+
- 色・書体・角丸の値と色の割り当ては書かない。テーマ(`styles.css`、ThemeDialog、CLI の `theme` / `chart`)が持つ。
|
|
7
|
+
デザイン変更の依頼を `DESIGN.md` に記録しない。
|
|
8
|
+
- 見た目の規則は `AGENTS.md` の「見た目の規約」節が正本。`DESIGN.md` はそれに**加えて**従われる。
|
|
9
|
+
色の割り当てが食い違うときはテーマを優先する。
|
|
10
|
+
- 既存の `DESIGN.md` は消さない。`vantage upgrade` も `vantage add agents` も書き換えない。
|
|
11
|
+
- 150 行以内(超えると `vantage check` が `DESIGN_MD_TOO_LONG` を警告する)。YAML frontmatter は付けない。
|
|
12
|
+
- ロゴ・画像は `public/` 配下のパスで参照する(`public/brand/logo.svg`)。
|
|
@@ -48,13 +48,3 @@ npx @squadbase/vantage-template theme ocean --reset-chart # chart コマンド
|
|
|
48
48
|
**`/* squadkit-theme:end */`(チャート範囲があればその終端)より後ろ**に、変えたいトークンだけ
|
|
49
49
|
`:root` と `.dark, [data-theme="dark"]` の**両方**に書く。前に書くとテーマに負ける。
|
|
50
50
|
`scripts/contrast.mjs` で `--primary-foreground` / `--primary` をライトとダークで確かめる。
|
|
51
|
-
|
|
52
|
-
## DESIGN.md
|
|
53
|
-
|
|
54
|
-
`format.md` の雛形から作り、選んだテーマに合わせて次の行だけ書き換える。
|
|
55
|
-
|
|
56
|
-
- 「全体のトーン」: 上の表のトーンを 2〜3 行に。
|
|
57
|
-
- 主色の行: テーマの主色の色味(「青」「橙」など。**色コードは書かない**)。
|
|
58
|
-
- チャートの色味: テーマの `--chart-1..5` の並び(適用後の `styles.css` を見る)。
|
|
59
|
-
- 良い / 悪い / 注意: 専用トークンは無い。`--chart-*` から割り当てるか「専用トークンなし」と書く。
|
|
60
|
-
`--destructive` を普通の系列色に使わない。
|
package/templates/AGENTS.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
> このファイルと `agents/*.md` は、いずれも **Vantage フレームワークが所有する正本**の
|
|
8
8
|
> コピーです。手で書き換えても、`vantage upgrade` を実行するとフレームワーク同梱の正本から
|
|
9
9
|
> 再同期されて上書きされます。アプリ固有のメモは別ファイル(例: `README.md`)に書いてください。
|
|
10
|
-
>
|
|
11
|
-
> `vantage add agents`
|
|
10
|
+
> 例外はプロジェクトルートの任意の `DESIGN.md` で、これは**ユーザーが所有**します(`vantage upgrade` も
|
|
11
|
+
> `vantage add agents` も触らない。→「見た目の規約」)。
|
|
12
12
|
>
|
|
13
13
|
> 手順を伴う踏み込んだワークフローは、同梱の Claude Code Skill に分かれています。このファイルは
|
|
14
14
|
> 「地図」、`agents/*.md` は「種類ごとの静的リファレンス」、Skill は「手順書」という役割分担です。
|
|
@@ -47,8 +47,9 @@ UI キット・開発サーバー・API サーバー・ビルドはすべて Van
|
|
|
47
47
|
- **`definePage` の値はリテラルで書く。** title/description/navLabel はビルド時に静的抽出される
|
|
48
48
|
ため、変数・関数呼び出し・テンプレート補間は使わない。`page` エクスポートはランタイムでは
|
|
49
49
|
読まれない。
|
|
50
|
-
- **アプリの表示言語は、ルート `_layout.tsx` の `export const lang = "
|
|
50
|
+
- **アプリの表示言語は、ルート `_layout.tsx` の `export const lang = "en"`(リテラル。BCP 47)で指定する。**
|
|
51
51
|
`<html lang>` になり、日本語の文節改行とスライドの文言切り替えに効く。未指定は `"en"`。
|
|
52
|
+
画面の文言・docs・コメントは、ユーザーが使う言語に合わせる(`lang` もその言語にする)。
|
|
52
53
|
|
|
53
54
|
## ディレクトリ構造(ページをどこに置くか)
|
|
54
55
|
|
|
@@ -102,7 +103,7 @@ root/
|
|
|
102
103
|
| `@squadbase/vantage/markdown` | `MarkdownRenderer`(Shiki を隔離するための専用サブパス) |
|
|
103
104
|
| `@squadbase/vantage/server` | `ApiContext`・`ApiHandler`・`HttpError`・`isHttpError`・`json`(server/ 側でのみ使う) |
|
|
104
105
|
|
|
105
|
-
**KPI は `KpiCard`、増減は `Delta`(`comparison`
|
|
106
|
+
**KPI は `KpiCard`、増減は `Delta`(`comparison` を渡し、下がって良い指標は `betterWhen="down"`)。** 向き・率・色は値から計算
|
|
106
107
|
されるので手で渡さない。`TrendIndicator` は非推奨(`direction` を手で渡すので値と食い違いうる)。props は
|
|
107
108
|
`vantage docs kpi-card` / `vantage docs delta` を引く。
|
|
108
109
|
|
|
@@ -125,17 +126,30 @@ import { KpiCard, Delta } from "@squadbase/vantage/components";
|
|
|
125
126
|
- `server/` が**無い** → 外部 API を直接叩くなら `useQuery`(→ `agents/page.md`)。自前の API が
|
|
126
127
|
要るようになったら `server/api/*.ts` を足すだけでよい(設定変更は不要)。
|
|
127
128
|
|
|
128
|
-
##
|
|
129
|
+
## 見た目の規約
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
色・書体・角丸などの**値と色の割り当ては、テーマ(`styles.css` の `/* theme: <name> */` マーカー以降の
|
|
132
|
+
上書き)だけが持つ。** ここには値を書かず、使い分けの規則だけを置く。UI(ページ・スライド・
|
|
133
|
+
コンポーネント)はこの規則に従い、色は必ずトークンで指定する(色コード・素のパレットクラスは書かない)。
|
|
133
134
|
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
-
|
|
135
|
+
- **意味トークン:** 良い = `positive`、悪い = `negative`、注意 = `warning`、情報 = `info`、
|
|
136
|
+
中立 = `neutral`。系列色は `chart-1`〜`chart-5` を番号順に使う(5 系列まで。超えるなら「その他」に
|
|
137
|
+
まとめる)。増減の良否は指標の性質(コスト減・解約率減は良い)で決めて
|
|
138
|
+
positive / negative に分け(`KpiCard` / `Delta` の `betterWhen`。下がって良い指標は `betterWhen="down"`)、向きは ▲▼ や符号で表す。
|
|
139
|
+
- **レイアウト:** 内容はカードで包む。順序は KPI → チャート → 表。値が 1 つなら KPI にする
|
|
140
|
+
(1 本の棒グラフにしない)。強調は 1 画面(スライドは 1 枚)に 1 か所。数値には単位と比較対象を添える。
|
|
141
|
+
- **Do:** トークンで色を指定する / 色の意味をアプリ全体でそろえる / チャートのタイトルに結論を書く。
|
|
142
|
+
- **Don't:** 色コードや素のパレットクラスを書く / `dark:` を並べる / 3D・装飾目的のグラデーション・
|
|
143
|
+
円グラフの多用 / 同じチャートで `negative` を普通の系列色に使う。
|
|
144
|
+
- スライド固有の規則は `agents/slide.md`。
|
|
145
|
+
|
|
146
|
+
**任意の `DESIGN.md`:** プロジェクトルートにあれば読んで従う(密度・スライドの見出し方針・
|
|
147
|
+
ブランド素材などユーザー固有の意図)。AGENTS.md の規則に加えて従うが、**色の割り当てはテーマを優先**
|
|
148
|
+
する。新規には作らない。ユーザーの持ち物で、`vantage upgrade` は書き換えも削除もしない。
|
|
149
|
+
|
|
150
|
+
**デザイン変更の依頼**(「もっと落ち着いた色に」「ブランドに合わせて」など)は、ファイルごとに
|
|
151
|
+
直さず、テーマの切り替えかスタイルシートの上書きで完結させる。`DESIGN.md` には記録しない。今のテーマ名は
|
|
152
|
+
`styles.css` の `/* theme: <name> */` マーカーから読む。手順は Skill `vantage-design`。
|
|
139
153
|
|
|
140
154
|
## 何を書くか → どのファイルを読むか
|
|
141
155
|
|
|
@@ -174,7 +188,7 @@ vantage docs button # 1 ページ表示(短縮名。ui/button に解
|
|
|
174
188
|
vantage docs parts/data-table # 完全な slug でも引ける
|
|
175
189
|
vantage docs data-table --json # { slug, title, description, section, content }
|
|
176
190
|
vantage docs --all # 全ページを連結(まとめて読み込む用)
|
|
177
|
-
vantage docs routing --lang en # 英語版(
|
|
191
|
+
vantage docs routing --lang en # 英語版(`--lang` 省略時は ja。アプリの文言の言語とは無関係)
|
|
178
192
|
```
|
|
179
193
|
|
|
180
194
|
props の表・使用例・落とし穴はコンポーネントのページに載っている。**推測で props を書く前に
|
|
@@ -212,7 +226,7 @@ body・レスポンスの status と形)まで出る。`vantage check --json` /
|
|
|
212
226
|
- **`vantage-app`** — アプリを一から作る / 構成を広げるときの進め方と検証の順序
|
|
213
227
|
- **`vantage-add-feature`** — 既存アプリに page / api / ui を 1 つ足す定型
|
|
214
228
|
- **`vantage-slide`** — `.slide.tsx` でスライドデッキを書く(キャンバスの予算・段階表示・pptx 書き出し)
|
|
215
|
-
- **`vantage-design`** —
|
|
229
|
+
- **`vantage-design`** — テーマの切り替え・`styles.css` の上書きで見た目を直す(配色・書体・ブランド合わせ)
|
|
216
230
|
- **`vantage-pitfalls`** — Base UI(≠ Radix)の癖など、静かに壊れる落とし穴のリファレンス
|
|
217
231
|
- **`project-storage`** — Squadbase の Project Storage(アップロード済みファイル)をブラウザから読み書きする
|
|
218
232
|
|
package/templates/agents/page.md
CHANGED
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
スライドデッキを書くときに読んでください。不変条件・ディレクトリ構造は `AGENTS.md` を
|
|
5
5
|
先に読んでいる想定です。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
書き始める前に `AGENTS.md` の「見た目の規約」(と、あればプロジェクトルートの `DESIGN.md`)に従う。
|
|
8
|
+
スライド固有の規則:
|
|
9
|
+
|
|
10
|
+
- 1 枚に 1 メッセージ。見出しに結論を書く。
|
|
11
|
+
- 色は `--slide-bg` / `--slide-fg` / `--slide-accent` / `--slide-muted` を使う(既定では
|
|
12
|
+
`--background` / `--foreground` / `--primary` / `--muted-foreground` に連動)。
|
|
13
|
+
- 強調色は 1 枚につき 1 か所まで。
|
|
8
14
|
|
|
9
15
|
## スライドは `.slide.tsx` で書く
|
|
10
16
|
|