@squadbase/vantage 0.2.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +1 -1
  2. package/dist/add-DWNDA57L.js +6 -0
  3. package/dist/add-DWNDA57L.js.map +1 -0
  4. package/dist/build-QP5BL3K7.js +108 -0
  5. package/dist/build-QP5BL3K7.js.map +1 -0
  6. package/dist/check-QPFERQLO.js +38 -0
  7. package/dist/check-QPFERQLO.js.map +1 -0
  8. package/dist/chunk-2KRCGXBY.js +56 -0
  9. package/dist/chunk-2KRCGXBY.js.map +1 -0
  10. package/dist/chunk-BAM33YZ6.js +202 -0
  11. package/dist/chunk-BAM33YZ6.js.map +1 -0
  12. package/dist/chunk-C4MQRWXS.js +81 -0
  13. package/dist/chunk-C4MQRWXS.js.map +1 -0
  14. package/dist/chunk-D4Y5RWJA.js +189 -0
  15. package/dist/chunk-D4Y5RWJA.js.map +1 -0
  16. package/dist/chunk-OFFJ3OL5.js +121 -0
  17. package/dist/chunk-OFFJ3OL5.js.map +1 -0
  18. package/dist/chunk-PSEYFYAP.js +276 -0
  19. package/dist/chunk-PSEYFYAP.js.map +1 -0
  20. package/dist/chunk-R2YYVCGS.js +345 -0
  21. package/dist/chunk-R2YYVCGS.js.map +1 -0
  22. package/dist/chunk-RA6Z3OX3.js +199 -0
  23. package/dist/chunk-RA6Z3OX3.js.map +1 -0
  24. package/dist/chunk-UTEKU3LG.js +267 -0
  25. package/dist/chunk-UTEKU3LG.js.map +1 -0
  26. package/dist/chunk-VXAV2435.js +142 -0
  27. package/dist/chunk-VXAV2435.js.map +1 -0
  28. package/dist/cli.js +24 -1604
  29. package/dist/cli.js.map +1 -1
  30. package/dist/dev-NX3PMYCT.js +55 -0
  31. package/dist/dev-NX3PMYCT.js.map +1 -0
  32. package/dist/docs-M5ZUI25V.js +114 -0
  33. package/dist/docs-M5ZUI25V.js.map +1 -0
  34. package/dist/doctor-N6JMEWKT.js +58 -0
  35. package/dist/doctor-N6JMEWKT.js.map +1 -0
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/index.js.map +1 -1
  39. package/dist/preview-CLALOEFE.js +49 -0
  40. package/dist/preview-CLALOEFE.js.map +1 -0
  41. package/dist/routes-YI25MKPF.js +119 -0
  42. package/dist/routes-YI25MKPF.js.map +1 -0
  43. package/dist/search-5TYAIQ7C.js +325 -0
  44. package/dist/search-5TYAIQ7C.js.map +1 -0
  45. package/dist/server/node.d.ts +1 -12
  46. package/dist/types-De3mo_hv.d.ts +59 -0
  47. package/dist/upgrade-3P5MBGE6.js +29 -0
  48. package/dist/upgrade-3P5MBGE6.js.map +1 -0
  49. package/dist/vite/index.d.ts +13 -0
  50. package/dist/vite/index.js +5 -1
  51. package/docs/en/changelog.md +82 -0
  52. package/docs/en/cli-reference.md +34 -4
  53. package/docs/en/components.md +2 -1
  54. package/docs/en/getting-started.md +6 -3
  55. package/docs/en/routing.md +27 -1
  56. package/docs/en/ui-and-theming.md +4 -2
  57. package/docs/ja/changelog.md +74 -0
  58. package/docs/ja/cli-reference.md +34 -4
  59. package/docs/ja/components.md +3 -2
  60. package/docs/ja/getting-started.md +6 -3
  61. package/docs/ja/routing.md +26 -1
  62. package/docs/ja/ui-and-theming.md +4 -2
  63. package/package.json +7 -4
  64. package/skills/vantage-add-feature/SKILL.md +14 -5
  65. package/skills/vantage-app/SKILL.md +9 -5
  66. package/templates/AGENTS.md +50 -6
  67. package/dist/chunk-3QKPNWKJ.js +0 -762
  68. package/dist/chunk-3QKPNWKJ.js.map +0 -1
@@ -0,0 +1,58 @@
1
+ import { runDiagnostics } from './chunk-PSEYFYAP.js';
2
+ import './chunk-BAM33YZ6.js';
3
+ import './chunk-VXAV2435.js';
4
+ import { scanProject } from './chunk-D4Y5RWJA.js';
5
+ import { printJson, frameworkVersion, log } from './chunk-OFFJ3OL5.js';
6
+ import './chunk-C4MQRWXS.js';
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { createRequire } from 'module';
10
+
11
+ // @squadbase/vantage — generated build. Do not edit.
12
+ async function doctor(root, args) {
13
+ const facets = [];
14
+ const nodeMajor = Number(process.versions.node.split(".")[0]);
15
+ facets.push({
16
+ name: "node",
17
+ ok: nodeMajor >= 20,
18
+ detail: `v${process.versions.node}${nodeMajor >= 20 ? "" : " (requires >= 20)"}`
19
+ });
20
+ const pkgPath = path.join(root, "package.json");
21
+ facets.push({ name: "package.json", ok: fs.existsSync(pkgPath), detail: fs.existsSync(pkgPath) ? "found" : "missing" });
22
+ const lockfiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock"];
23
+ const lock = lockfiles.find((f) => fs.existsSync(path.join(root, f)) || fs.existsSync(path.join(root, "..", f)) || fs.existsSync(path.join(root, "..", "..", f)));
24
+ facets.push({ name: "lockfile", ok: Boolean(lock), detail: lock ?? "none found" });
25
+ let installedVantage = "not installed";
26
+ let vantageOk = false;
27
+ try {
28
+ const require2 = createRequire(path.join(root, "noop.js"));
29
+ const p = require2.resolve("@squadbase/vantage/package.json");
30
+ installedVantage = JSON.parse(fs.readFileSync(p, "utf8")).version;
31
+ vantageOk = true;
32
+ } catch {
33
+ }
34
+ facets.push({ name: "@squadbase/vantage", ok: vantageOk, detail: installedVantage });
35
+ const model = scanProject(root);
36
+ const errors = runDiagnostics(root, model).filter((d) => d.severity === "error");
37
+ facets.push({
38
+ name: "project",
39
+ ok: errors.length === 0,
40
+ detail: errors.length === 0 ? "no blocking errors" : `${errors.length} error(s) (run \`vantage check\`)`
41
+ });
42
+ const allOk = facets.every((f) => f.ok);
43
+ if (args.flags.json) {
44
+ printJson({ ok: allOk, cli: frameworkVersion(), facets });
45
+ return allOk ? 0 : 1;
46
+ }
47
+ log.brand(`doctor (cli v${frameworkVersion()})`);
48
+ for (const f of facets) {
49
+ const line = `${f.name.padEnd(22)} ${f.detail}`;
50
+ if (f.ok) log.ok(line);
51
+ else log.error(line);
52
+ }
53
+ return allOk ? 0 : 1;
54
+ }
55
+
56
+ export { doctor };
57
+ //# sourceMappingURL=doctor-N6JMEWKT.js.map
58
+ //# sourceMappingURL=doctor-N6JMEWKT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/doctor.ts"],"names":["require"],"mappings":"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","file":"doctor-N6JMEWKT.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 = [\"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/dist/index.d.ts CHANGED
@@ -10,6 +10,6 @@ import 'react';
10
10
  */
11
11
 
12
12
  /** Framework version, kept in sync with package.json at build time. */
13
- declare const VERSION = "0.2.3";
13
+ declare const VERSION = "0.3.1";
14
14
 
15
15
  export { VERSION };
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ function definePage(config) {
6
6
  }
7
7
 
8
8
  // src/index.ts
9
- var VERSION = "0.2.3";
9
+ var VERSION = "0.3.1";
10
10
 
11
11
  export { VERSION, definePage };
12
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime/define-page.ts","../src/index.ts"],"names":[],"mappings":";;;AAyCO,SAAS,WAAW,MAAA,EAAgC;AACzD,EAAA,OAAO,MAAA;AACT;;;AChCO,IAAM,OAAA,GAAU","file":"index.js","sourcesContent":["import type { ComponentType, ReactNode } from \"react\"\n\n/**\n * Optional per-page configuration. The only required part of a page module is\n * its default-exported component; `definePage` covers everything else.\n */\nexport interface PageConfig {\n /** Document title applied when this route is active. */\n title?: string\n /** Description metadata for the page. */\n description?: string\n /**\n * Short label for navigation built from `useRoutes()`. Defaults to `title`,\n * which is often too long for a nav (\"Overview · Acme Analytics\").\n */\n navLabel?: string\n /**\n * Component rendered while the route is loading.\n * (Reserved — not yet applied to Vantage's code-split routes in the prototype.)\n */\n pendingComponent?: ComponentType\n /**\n * Component rendered when the route throws.\n * (Reserved — not yet applied to Vantage's code-split routes in the prototype.)\n */\n errorComponent?: ComponentType<{ error: unknown }>\n /**\n * Validate/transform the URL search params for this route.\n * (Reserved — not yet applied to Vantage's code-split routes in the prototype.)\n */\n validateSearch?: (search: Record<string, unknown>) => Record<string, unknown>\n}\n\n/**\n * Declare optional page configuration.\n *\n * ```tsx\n * export const page = definePage({ title: \"Monthly Analysis\" })\n * export default function MonthlyAnalysis() { return <div/> }\n * ```\n */\nexport function definePage(config: PageConfig): PageConfig {\n return config\n}\n\n/** Convenience type for a Vantage page component. */\nexport type PageComponent = ComponentType & { (): ReactNode }\n","/**\n * `@squadbase/vantage` — public runtime surface.\n *\n * The only import most pages need. Server state lives in\n * `@squadbase/vantage/query`, navigation in `@squadbase/vantage/router`,\n * UI in `@squadbase/vantage/ui`, and API types in `@squadbase/vantage/server`.\n */\nexport { definePage } from \"./runtime/define-page\"\nexport type { PageConfig, PageComponent } from \"./runtime/define-page\"\n\n/** Framework version, kept in sync with package.json at build time. */\nexport const VERSION = \"0.2.3\"\n"]}
1
+ {"version":3,"sources":["../src/runtime/define-page.ts","../src/index.ts"],"names":[],"mappings":";;;AAyCO,SAAS,WAAW,MAAA,EAAgC;AACzD,EAAA,OAAO,MAAA;AACT;;;AChCO,IAAM,OAAA,GAAU","file":"index.js","sourcesContent":["import type { ComponentType, ReactNode } from \"react\"\n\n/**\n * Optional per-page configuration. The only required part of a page module is\n * its default-exported component; `definePage` covers everything else.\n */\nexport interface PageConfig {\n /** Document title applied when this route is active. */\n title?: string\n /** Description metadata for the page. */\n description?: string\n /**\n * Short label for navigation built from `useRoutes()`. Defaults to `title`,\n * which is often too long for a nav (\"Overview · Acme Analytics\").\n */\n navLabel?: string\n /**\n * Component rendered while the route is loading.\n * (Reserved — not yet applied to Vantage's code-split routes in the prototype.)\n */\n pendingComponent?: ComponentType\n /**\n * Component rendered when the route throws.\n * (Reserved — not yet applied to Vantage's code-split routes in the prototype.)\n */\n errorComponent?: ComponentType<{ error: unknown }>\n /**\n * Validate/transform the URL search params for this route.\n * (Reserved — not yet applied to Vantage's code-split routes in the prototype.)\n */\n validateSearch?: (search: Record<string, unknown>) => Record<string, unknown>\n}\n\n/**\n * Declare optional page configuration.\n *\n * ```tsx\n * export const page = definePage({ title: \"Monthly Analysis\" })\n * export default function MonthlyAnalysis() { return <div/> }\n * ```\n */\nexport function definePage(config: PageConfig): PageConfig {\n return config\n}\n\n/** Convenience type for a Vantage page component. */\nexport type PageComponent = ComponentType & { (): ReactNode }\n","/**\n * `@squadbase/vantage` — public runtime surface.\n *\n * The only import most pages need. Server state lives in\n * `@squadbase/vantage/query`, navigation in `@squadbase/vantage/router`,\n * UI in `@squadbase/vantage/ui`, and API types in `@squadbase/vantage/server`.\n */\nexport { definePage } from \"./runtime/define-page\"\nexport type { PageConfig, PageComponent } from \"./runtime/define-page\"\n\n/** Framework version, kept in sync with package.json at build time. */\nexport const VERSION = \"0.3.1\"\n"]}
@@ -0,0 +1,49 @@
1
+ import { log, parsePort } from './chunk-OFFJ3OL5.js';
2
+ import './chunk-C4MQRWXS.js';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { spawn } from 'child_process';
6
+
7
+ // @squadbase/vantage — generated build. Do not edit.
8
+ async function preview(root, args) {
9
+ const manifestPath = path.join(root, "dist", "vantage-manifest.json");
10
+ if (!fs.existsSync(manifestPath)) {
11
+ log.error("No build found. Run `vantage build` first.");
12
+ return 1;
13
+ }
14
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
15
+ const port = parsePort(args.flags.port, 4173);
16
+ if (manifest.mode === "fullstack") {
17
+ const serverPath = path.join(root, "dist", "server", "index.mjs");
18
+ if (!fs.existsSync(serverPath)) {
19
+ log.error("Server bundle missing. Re-run `vantage build`.");
20
+ return 1;
21
+ }
22
+ log.brand(`preview (fullstack) \u2192 http://localhost:${port}`);
23
+ const child = spawn(process.execPath, [serverPath], {
24
+ stdio: "inherit",
25
+ env: { ...process.env, PORT: String(port) }
26
+ });
27
+ return new Promise((resolve) => {
28
+ child.on("exit", (code) => resolve(code ?? 0));
29
+ const stop = () => child.kill("SIGINT");
30
+ process.on("SIGINT", stop);
31
+ process.on("SIGTERM", stop);
32
+ });
33
+ }
34
+ const { preview: vitePreview } = await import('vite');
35
+ const server = await vitePreview({
36
+ configFile: false,
37
+ root,
38
+ build: { outDir: path.join(root, "dist", "client") },
39
+ preview: { port }
40
+ });
41
+ log.brand("preview (spa)");
42
+ server.printUrls();
43
+ return new Promise(() => {
44
+ });
45
+ }
46
+
47
+ export { preview };
48
+ //# sourceMappingURL=preview-CLALOEFE.js.map
49
+ //# sourceMappingURL=preview-CLALOEFE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/preview.ts"],"names":[],"mappings":";;;;;;;AAMA,eAAsB,OAAA,CAAQ,MAAc,IAAA,EAAmC;AAC7E,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,QAAQ,uBAAuB,CAAA;AACpE,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,YAAY,CAAA,EAAG;AAChC,IAAA,GAAA,CAAI,MAAM,4CAA4C,CAAA;AACtD,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,GAAG,YAAA,CAAa,YAAA,EAAc,MAAM,CAAC,CAAA;AACjE,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,KAAA,CAAM,MAAM,IAAI,CAAA;AAE5C,EAAA,IAAI,QAAA,CAAS,SAAS,WAAA,EAAa;AACjC,IAAA,MAAM,aAAa,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,UAAU,WAAW,CAAA;AAChE,IAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,MAAA,GAAA,CAAI,MAAM,gDAAgD,CAAA;AAC1D,MAAA,OAAO,CAAA;AAAA,IACT;AACA,IAAA,GAAA,CAAI,KAAA,CAAM,CAAA,4CAAA,EAA0C,IAAI,CAAA,CAAE,CAAA;AAC1D,IAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,CAAC,UAAU,CAAA,EAAG;AAAA,MAClD,KAAA,EAAO,SAAA;AAAA,MACP,GAAA,EAAK,EAAE,GAAG,OAAA,CAAQ,KAAK,IAAA,EAAM,MAAA,CAAO,IAAI,CAAA;AAAE,KAC3C,CAAA;AACD,IAAA,OAAO,IAAI,OAAA,CAAgB,CAAC,OAAA,KAAY;AACtC,MAAA,KAAA,CAAM,GAAG,MAAA,EAAQ,CAAC,SAAS,OAAA,CAAQ,IAAA,IAAQ,CAAC,CAAC,CAAA;AAC7C,MAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AACtC,MAAA,OAAA,CAAQ,EAAA,CAAG,UAAU,IAAI,CAAA;AACzB,MAAA,OAAA,CAAQ,EAAA,CAAG,WAAW,IAAI,CAAA;AAAA,IAC5B,CAAC,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAY,GAAI,MAAM,OAAO,MAAM,CAAA;AACpD,EAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY;AAAA,IAC/B,UAAA,EAAY,KAAA;AAAA,IACZ,IAAA;AAAA,IACA,KAAA,EAAO,EAAE,MAAA,EAAQ,IAAA,CAAK,KAAK,IAAA,EAAM,MAAA,EAAQ,QAAQ,CAAA,EAAE;AAAA,IACnD,OAAA,EAAS,EAAE,IAAA;AAAK,GACjB,CAAA;AACD,EAAA,GAAA,CAAI,MAAM,eAAe,CAAA;AACzB,EAAA,MAAA,CAAO,SAAA,EAAU;AACjB,EAAA,OAAO,IAAI,QAAgB,MAAM;AAAA,EAAC,CAAC,CAAA;AACrC","file":"preview-CLALOEFE.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { spawn } from \"node:child_process\"\nimport { log, parsePort, type ParsedArgs } from \"./util\"\n\n/** `vantage preview` — run the production build locally. */\nexport async function preview(root: string, args: ParsedArgs): Promise<number> {\n const manifestPath = path.join(root, \"dist\", \"vantage-manifest.json\")\n if (!fs.existsSync(manifestPath)) {\n log.error(\"No build found. Run `vantage build` first.\")\n return 1\n }\n const manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as { mode: string }\n const port = parsePort(args.flags.port, 4173)\n\n if (manifest.mode === \"fullstack\") {\n const serverPath = path.join(root, \"dist\", \"server\", \"index.mjs\")\n if (!fs.existsSync(serverPath)) {\n log.error(\"Server bundle missing. Re-run `vantage build`.\")\n return 1\n }\n log.brand(`preview (fullstack) → http://localhost:${port}`)\n const child = spawn(process.execPath, [serverPath], {\n stdio: \"inherit\",\n env: { ...process.env, PORT: String(port) },\n })\n return new Promise<number>((resolve) => {\n child.on(\"exit\", (code) => resolve(code ?? 0))\n const stop = () => child.kill(\"SIGINT\")\n process.on(\"SIGINT\", stop)\n process.on(\"SIGTERM\", stop)\n })\n }\n\n // SPA-only preview via Vite's static preview server.\n const { preview: vitePreview } = await import(\"vite\")\n const server = await vitePreview({\n configFile: false,\n root,\n build: { outDir: path.join(root, \"dist\", \"client\") },\n preview: { port },\n })\n log.brand(\"preview (spa)\")\n server.printUrls()\n return new Promise<number>(() => {})\n}\n"]}
@@ -0,0 +1,119 @@
1
+ import { extractPageSpec, extractApiSpec } from './chunk-BAM33YZ6.js';
2
+ import './chunk-VXAV2435.js';
3
+ import { scanProject } from './chunk-D4Y5RWJA.js';
4
+ import { printJson } from './chunk-OFFJ3OL5.js';
5
+ import './chunk-C4MQRWXS.js';
6
+ import pc from 'picocolors';
7
+
8
+ // @squadbase/vantage — generated build. Do not edit.
9
+ var ROUTE_COLUMN = 28;
10
+ var LABEL_COLUMN = 9;
11
+ function detailLine(indent, label, value) {
12
+ console.log(`${indent}${pc.dim(label.padEnd(LABEL_COLUMN))}${value}`);
13
+ }
14
+ function formatParams(params) {
15
+ return params.map((p) => p.kind === "catchall" ? `*${p.name}` : `:${p.name}`).join(", ");
16
+ }
17
+ function formatKeys(keys) {
18
+ return keys?.length ? ` { ${keys.join(", ")} }` : "";
19
+ }
20
+ function printPageSpec(spec) {
21
+ const indent = " ";
22
+ if (spec.title) detailLine(indent, "title", spec.title);
23
+ if (spec.navLabel) detailLine(indent, "nav", spec.navLabel);
24
+ if (spec.description) detailLine(indent, "desc", spec.description);
25
+ if (spec.params.length) detailLine(indent, "params", formatParams(spec.params));
26
+ }
27
+ function printApiMethodSpec(method, params) {
28
+ const indent = " ";
29
+ console.log(` ${pc.bold(method.method)}`);
30
+ if (params.length) detailLine(indent, "path", formatParams(params));
31
+ if (method.query.length) detailLine(indent, "query", method.query.join(", "));
32
+ if (method.body) detailLine(indent, "body", method.body.format + formatKeys(method.body.keys));
33
+ for (const res of method.responses) {
34
+ const parts = [String(res.status), res.contentType].filter(Boolean).join(" ");
35
+ detailLine(indent, "response", parts + formatKeys(res.keys));
36
+ }
37
+ for (const err of method.errors) {
38
+ detailLine(indent, "error", `${err.status}${err.message ? ` "${err.message}"` : ""}`);
39
+ }
40
+ }
41
+ function printPages(model, detail) {
42
+ console.log(pc.bold("\nPages"));
43
+ if (model.pages.length === 0) console.log(pc.dim(" (none)"));
44
+ for (const p of model.pages) {
45
+ console.log(` ${pc.green(p.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(p.file)}`);
46
+ if (detail) printPageSpec(extractPageSpec(p));
47
+ }
48
+ if (model.layouts.length || model.notFound || model.error) {
49
+ console.log(pc.bold("\nSpecial"));
50
+ for (const l of model.layouts) {
51
+ const label = "layout " + (l.dir === "" ? "/" : "/" + l.dir);
52
+ console.log(` ${pc.cyan(label.padEnd(ROUTE_COLUMN))} ${pc.dim(l.file)}`);
53
+ }
54
+ if (model.notFound) console.log(` ${pc.cyan("404".padEnd(ROUTE_COLUMN))} ${pc.dim(model.notFound)}`);
55
+ if (model.error) console.log(` ${pc.cyan("error".padEnd(ROUTE_COLUMN))} ${pc.dim(model.error)}`);
56
+ }
57
+ }
58
+ function printApis(model, detail) {
59
+ console.log(pc.bold("\nAPI"));
60
+ if (!model.hasServer) {
61
+ console.log(pc.dim(" (none \u2014 this project has no server/ directory)"));
62
+ return;
63
+ }
64
+ if (model.apis.length === 0) console.log(pc.dim(" (none)"));
65
+ for (const a of model.apis) {
66
+ console.log(` ${pc.yellow(a.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(a.file)}`);
67
+ if (!detail) continue;
68
+ const spec = extractApiSpec(a);
69
+ if (spec.methods.length === 0) console.log(` ${pc.dim("(no HTTP method handler exported)")}`);
70
+ for (const method of spec.methods) printApiMethodSpec(method, spec.params);
71
+ }
72
+ }
73
+ function pageJson(p, detail) {
74
+ return {
75
+ route: p.routePath,
76
+ file: p.file,
77
+ dynamic: p.dynamic,
78
+ ...detail ? { spec: extractPageSpec(p) } : {}
79
+ };
80
+ }
81
+ function apiJson(a, detail) {
82
+ return {
83
+ route: a.routePath,
84
+ file: a.file,
85
+ params: a.params,
86
+ ...detail ? { spec: extractApiSpec(a) } : {}
87
+ };
88
+ }
89
+ async function routes(root, args) {
90
+ const model = scanProject(root);
91
+ const onlyPages = Boolean(args.flags.pages);
92
+ const onlyApis = Boolean(args.flags.apis);
93
+ const showPages = onlyPages || !onlyApis;
94
+ const showApis = onlyApis || !onlyPages;
95
+ const detail = Boolean(args.flags.detail);
96
+ if (args.flags.json) {
97
+ const payload = {};
98
+ if (showPages) {
99
+ payload.pages = model.pages.map((p) => pageJson(p, detail));
100
+ payload.layouts = model.layouts.map((l) => ({ dir: l.dir === "" ? "/" : l.dir, file: l.file }));
101
+ payload.notFound = model.notFound;
102
+ payload.error = model.error;
103
+ }
104
+ if (showApis) {
105
+ payload.apis = model.apis.map((a) => apiJson(a, detail));
106
+ payload.hasServer = model.hasServer;
107
+ }
108
+ printJson(payload);
109
+ return 0;
110
+ }
111
+ if (showPages) printPages(model, detail);
112
+ if (showApis && (model.hasServer || onlyApis)) printApis(model, detail);
113
+ console.log("");
114
+ return 0;
115
+ }
116
+
117
+ export { routes };
118
+ //# sourceMappingURL=routes-YI25MKPF.js.map
119
+ //# sourceMappingURL=routes-YI25MKPF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/routes.ts"],"names":[],"mappings":"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","file":"routes-YI25MKPF.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n extractApiSpec,\n extractPageSpec,\n type ApiMethodSpec,\n type PageSpec,\n type RouteParam,\n} from \"../core/route-spec\"\nimport { scanProject } from \"../core/scan\"\nimport type { ApiRoute, PageRoute, RouteModel } from \"../core/types\"\nimport { printJson, type ParsedArgs } from \"./util\"\n\nconst ROUTE_COLUMN = 28\nconst LABEL_COLUMN = 9\n\n/** Print an indented `label value` line under a route. */\nfunction detailLine(indent: string, label: string, value: string): void {\n console.log(`${indent}${pc.dim(label.padEnd(LABEL_COLUMN))}${value}`)\n}\n\n/** Render params as `:id`, `*rest`. */\nfunction formatParams(params: RouteParam[]): string {\n return params.map((p) => (p.kind === \"catchall\" ? `*${p.name}` : `:${p.name}`)).join(\", \")\n}\n\nfunction formatKeys(keys: string[] | undefined): string {\n return keys?.length ? ` { ${keys.join(\", \")} }` : \"\"\n}\n\nfunction printPageSpec(spec: PageSpec): void {\n const indent = \" \"\n if (spec.title) detailLine(indent, \"title\", spec.title)\n if (spec.navLabel) detailLine(indent, \"nav\", spec.navLabel)\n if (spec.description) detailLine(indent, \"desc\", spec.description)\n if (spec.params.length) detailLine(indent, \"params\", formatParams(spec.params))\n}\n\nfunction printApiMethodSpec(method: ApiMethodSpec, params: RouteParam[]): void {\n const indent = \" \"\n console.log(` ${pc.bold(method.method)}`)\n if (params.length) detailLine(indent, \"path\", formatParams(params))\n if (method.query.length) detailLine(indent, \"query\", method.query.join(\", \"))\n if (method.body) detailLine(indent, \"body\", method.body.format + formatKeys(method.body.keys))\n for (const res of method.responses) {\n const parts = [String(res.status), res.contentType].filter(Boolean).join(\" \")\n detailLine(indent, \"response\", parts + formatKeys(res.keys))\n }\n for (const err of method.errors) {\n detailLine(indent, \"error\", `${err.status}${err.message ? ` \"${err.message}\"` : \"\"}`)\n }\n}\n\nfunction printPages(model: RouteModel, detail: boolean): void {\n console.log(pc.bold(\"\\nPages\"))\n if (model.pages.length === 0) console.log(pc.dim(\" (none)\"))\n for (const p of model.pages) {\n console.log(` ${pc.green(p.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(p.file)}`)\n if (detail) printPageSpec(extractPageSpec(p))\n }\n\n if (model.layouts.length || model.notFound || model.error) {\n console.log(pc.bold(\"\\nSpecial\"))\n for (const l of model.layouts) {\n const label = \"layout \" + (l.dir === \"\" ? \"/\" : \"/\" + l.dir)\n console.log(` ${pc.cyan(label.padEnd(ROUTE_COLUMN))} ${pc.dim(l.file)}`)\n }\n if (model.notFound) console.log(` ${pc.cyan(\"404\".padEnd(ROUTE_COLUMN))} ${pc.dim(model.notFound)}`)\n if (model.error) console.log(` ${pc.cyan(\"error\".padEnd(ROUTE_COLUMN))} ${pc.dim(model.error)}`)\n }\n}\n\nfunction printApis(model: RouteModel, detail: boolean): void {\n console.log(pc.bold(\"\\nAPI\"))\n if (!model.hasServer) {\n console.log(pc.dim(\" (none — this project has no server/ directory)\"))\n return\n }\n if (model.apis.length === 0) console.log(pc.dim(\" (none)\"))\n for (const a of model.apis) {\n console.log(` ${pc.yellow(a.routePath.padEnd(ROUTE_COLUMN))} ${pc.dim(a.file)}`)\n if (!detail) continue\n const spec = extractApiSpec(a)\n if (spec.methods.length === 0) console.log(` ${pc.dim(\"(no HTTP method handler exported)\")}`)\n for (const method of spec.methods) printApiMethodSpec(method, spec.params)\n }\n}\n\nfunction pageJson(p: PageRoute, detail: boolean) {\n return {\n route: p.routePath,\n file: p.file,\n dynamic: p.dynamic,\n ...(detail ? { spec: extractPageSpec(p) } : {}),\n }\n}\n\nfunction apiJson(a: ApiRoute, detail: boolean) {\n return {\n route: a.routePath,\n file: a.file,\n params: a.params,\n ...(detail ? { spec: extractApiSpec(a) } : {}),\n }\n}\n\n/**\n * `vantage routes` — show the page and API URL map.\n * `--pages` / `--apis` narrow the map to one side; `--detail` adds the static\n * spec of each route (page path params + definePage meta, API methods with\n * their request input and response shape).\n */\nexport async function routes(root: string, args: ParsedArgs): Promise<number> {\n const model = scanProject(root)\n const onlyPages = Boolean(args.flags.pages)\n const onlyApis = Boolean(args.flags.apis)\n // Neither flag (or both) means \"everything\", so the two are never exclusive.\n const showPages = onlyPages || !onlyApis\n const showApis = onlyApis || !onlyPages\n const detail = Boolean(args.flags.detail)\n\n if (args.flags.json) {\n const payload: Record<string, unknown> = {}\n if (showPages) {\n payload.pages = model.pages.map((p) => pageJson(p, detail))\n payload.layouts = model.layouts.map((l) => ({ dir: l.dir === \"\" ? \"/\" : l.dir, file: l.file }))\n payload.notFound = model.notFound\n payload.error = model.error\n }\n if (showApis) {\n payload.apis = model.apis.map((a) => apiJson(a, detail))\n payload.hasServer = model.hasServer\n }\n printJson(payload)\n return 0\n }\n\n if (showPages) printPages(model, detail)\n // Without --apis, an API-less project stays silent (nothing to say about it).\n if (showApis && (model.hasServer || onlyApis)) printApis(model, detail)\n console.log(\"\")\n return 0\n}\n"]}
@@ -0,0 +1,325 @@
1
+ import { loadCatalog, isDocLang, DOC_LANGS, DEFAULT_DOC_LANG, docsForLang, readDoc } from './chunk-2KRCGXBY.js';
2
+ import { log, printJson } from './chunk-OFFJ3OL5.js';
3
+ import './chunk-C4MQRWXS.js';
4
+ import pc from 'picocolors';
5
+
6
+ // @squadbase/vantage — generated build. Do not edit.
7
+
8
+ // src/cli/search-index.ts
9
+ var FIELD_WEIGHTS = { slug: 3, title: 3, description: 2, body: 1 };
10
+ var K1 = 1.2;
11
+ var B = 0.75;
12
+ var TOKEN_RE = /[a-z0-9]+|[぀-ヿ㐀-䶿一-鿿]+/g;
13
+ var LATIN_RE = /^[a-z0-9]+$/;
14
+ var TOKEN_RE_ANYCASE = /[a-zA-Z0-9]+|[぀-ヿ㐀-䶿一-鿿]+/g;
15
+ var CJK_RE = /[぀-ヿ㐀-䶿一-鿿]/;
16
+ var SCRIPT_RE = /[ぁ-ゟ]+|[゠-ヿ]+|[㐀-䶿一-鿿]+/g;
17
+ var HIRAGANA_RE = /^[ぁ-ゟ]$/;
18
+ function singular(word) {
19
+ if (word.length >= 5 && word.endsWith("ies")) return `${word.slice(0, -3)}y`;
20
+ if (word.length >= 4 && word.endsWith("s") && !/(ss|us|is)$/.test(word)) return word.slice(0, -1);
21
+ return word;
22
+ }
23
+ function tokenize(text) {
24
+ const normalized = text.normalize("NFKC").replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase();
25
+ const tokens = [];
26
+ for (const match of normalized.matchAll(TOKEN_RE)) {
27
+ const run = match[0];
28
+ if (LATIN_RE.test(run)) {
29
+ tokens.push(singular(run));
30
+ continue;
31
+ }
32
+ for (const segment of run.match(SCRIPT_RE) ?? []) {
33
+ if (segment.length === 1 && HIRAGANA_RE.test(segment)) continue;
34
+ if (segment.length <= 2) {
35
+ tokens.push(segment);
36
+ continue;
37
+ }
38
+ tokens.push(segment);
39
+ for (let i = 0; i < segment.length - 1; i++) tokens.push(segment.slice(i, i + 2));
40
+ }
41
+ }
42
+ return tokens;
43
+ }
44
+ function queryPhrases(query) {
45
+ const phrases = [];
46
+ for (const match of query.normalize("NFKC").matchAll(TOKEN_RE_ANYCASE)) {
47
+ const run = match[0];
48
+ if (!CJK_RE.test(run)) {
49
+ phrases.push(run);
50
+ continue;
51
+ }
52
+ for (const segment of run.match(SCRIPT_RE) ?? []) {
53
+ if (segment.length === 1 && HIRAGANA_RE.test(segment)) continue;
54
+ phrases.push(segment);
55
+ }
56
+ }
57
+ return [...new Set(phrases)];
58
+ }
59
+ function buildIndex(entries) {
60
+ const docs = entries.map((entry) => {
61
+ const body = readDoc(entry);
62
+ const tf = /* @__PURE__ */ new Map();
63
+ let length = 0;
64
+ const add = (text, weight) => {
65
+ for (const token of tokenize(text)) {
66
+ tf.set(token, (tf.get(token) ?? 0) + weight);
67
+ length += weight;
68
+ }
69
+ };
70
+ add(entry.slug, FIELD_WEIGHTS.slug);
71
+ add(entry.title, FIELD_WEIGHTS.title);
72
+ add(entry.description, FIELD_WEIGHTS.description);
73
+ add(body, FIELD_WEIGHTS.body);
74
+ return { entry, body, tf, length };
75
+ });
76
+ const df = /* @__PURE__ */ new Map();
77
+ for (const doc of docs) {
78
+ for (const term of doc.tf.keys()) df.set(term, (df.get(term) ?? 0) + 1);
79
+ }
80
+ const total = docs.length;
81
+ const avgLength = total ? docs.reduce((sum, doc) => sum + doc.length, 0) / total : 1;
82
+ return {
83
+ search(query) {
84
+ const terms = [...new Set(tokenize(query))];
85
+ if (terms.length === 0) return [];
86
+ const hits = [];
87
+ for (const doc of docs) {
88
+ let score = 0;
89
+ for (const term of terms) {
90
+ const tf = doc.tf.get(term);
91
+ if (!tf) continue;
92
+ const n = df.get(term) ?? 0;
93
+ const idf = Math.log(1 + (total - n + 0.5) / (n + 0.5));
94
+ const norm = 1 - B + B * doc.length / avgLength;
95
+ score += idf * (tf * (K1 + 1) / (tf + K1 * norm));
96
+ }
97
+ if (score > 0) hits.push({ entry: doc.entry, score, terms, body: doc.body });
98
+ }
99
+ hits.sort((a, b) => b.score - a.score || a.entry.slug.localeCompare(b.entry.slug));
100
+ return hits;
101
+ }
102
+ };
103
+ }
104
+ var SNIPPET_LENGTH = 150;
105
+ function snippet(body, terms, length = SNIPPET_LENGTH) {
106
+ let best = "";
107
+ let bestHits = 0;
108
+ let bestIndex = 0;
109
+ let bestIsHeading = true;
110
+ for (const raw of body.split("\n").slice(1)) {
111
+ const line = raw.replace(/^\s*[-*]\s+/, "").replace(/\s+/g, " ").trim();
112
+ if (!line || /^(```|~~~|\|\s*-{2,})/.test(line)) continue;
113
+ const haystack = line.toLowerCase();
114
+ const heading = line.startsWith("#");
115
+ let hits = 0;
116
+ let first = -1;
117
+ for (const term of terms) {
118
+ const at = haystack.indexOf(term);
119
+ if (at === -1) continue;
120
+ hits++;
121
+ if (first === -1 || at < first) first = at;
122
+ }
123
+ if (hits > bestHits || hits === bestHits && hits > 0 && bestIsHeading && !heading) {
124
+ best = line;
125
+ bestHits = hits;
126
+ bestIndex = first;
127
+ bestIsHeading = heading;
128
+ }
129
+ }
130
+ if (!bestHits) return "";
131
+ if (best.length <= length) return best;
132
+ const start = Math.max(0, bestIndex - Math.floor(length / 4));
133
+ const text = best.slice(start, start + length).trim();
134
+ return `${start > 0 ? "\u2026" : ""}${text}${start + length < best.length ? "\u2026" : ""}`;
135
+ }
136
+
137
+ // src/cli/search.ts
138
+ var DEFAULT_LIMIT = 10;
139
+ var MAX_REGEX_LINES = 3;
140
+ function parseLimit(value, fallback) {
141
+ if (typeof value === "string") {
142
+ const n = Number(value);
143
+ if (Number.isInteger(n) && n > 0) return n;
144
+ }
145
+ return fallback;
146
+ }
147
+ function escapeRegExp(value) {
148
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
149
+ }
150
+ function paintMatches(text, re) {
151
+ if (!process.stdout.isTTY) return text;
152
+ let out = "";
153
+ let last = 0;
154
+ for (const match of text.matchAll(re)) {
155
+ const at = match.index ?? 0;
156
+ if (!match[0]) continue;
157
+ out += pc.dim(text.slice(last, at)) + pc.yellow(match[0]);
158
+ last = at + match[0].length;
159
+ }
160
+ return out + pc.dim(text.slice(last));
161
+ }
162
+ function paintTerms(text, words) {
163
+ if (!process.stdout.isTTY) return text;
164
+ if (words.length === 0) return pc.dim(text);
165
+ return paintMatches(text, new RegExp(words.map(escapeRegExp).join("|"), "gi"));
166
+ }
167
+ function header(count, query, lang, mode) {
168
+ const label = `${count} result${count === 1 ? "" : "s"} for "${query}"`;
169
+ console.log("");
170
+ console.log(pc.bold(label) + pc.dim(` ${lang} \xB7 ${mode}`));
171
+ console.log("");
172
+ }
173
+ function footer(total, shown, lines) {
174
+ if (total > shown) {
175
+ console.log("");
176
+ console.log(pc.dim(` ${total - shown} more \u2014 raise --limit to see them`));
177
+ }
178
+ console.log("");
179
+ for (const line of lines) console.log(pc.dim(line));
180
+ }
181
+ function noResults(query) {
182
+ log.warn(`Nothing matches "${query}".`);
183
+ console.log(pc.dim(" Try fewer or more general words, or run `vantage docs --list` to browse every page."));
184
+ }
185
+ function meta(entry) {
186
+ return {
187
+ slug: entry.slug,
188
+ title: entry.title,
189
+ description: entry.description,
190
+ section: entry.section,
191
+ sectionTitle: entry.sectionTitle,
192
+ command: `vantage docs ${entry.slug}`
193
+ };
194
+ }
195
+ function runRanked(entries, query, lang, limit, json) {
196
+ const hits = buildIndex(entries).search(query);
197
+ const shown = hits.slice(0, limit);
198
+ const passage = (hit) => snippet(hit.body, hit.terms);
199
+ if (json) {
200
+ printJson({
201
+ query,
202
+ mode: "bm25",
203
+ lang,
204
+ count: hits.length,
205
+ results: shown.map((hit) => ({
206
+ ...meta(hit.entry),
207
+ score: Math.round(hit.score * 1e3) / 1e3,
208
+ snippet: passage(hit)
209
+ }))
210
+ });
211
+ return 0;
212
+ }
213
+ if (hits.length === 0) {
214
+ noResults(query);
215
+ return 0;
216
+ }
217
+ const words = queryPhrases(query);
218
+ const width = Math.max(...shown.map((hit) => hit.entry.slug.length));
219
+ header(hits.length, query, lang, "bm25");
220
+ for (const hit of shown) {
221
+ const title = `${hit.entry.title}${pc.dim(` \xB7 ${hit.entry.sectionTitle}`)}`;
222
+ console.log(` ${pc.cyan(hit.entry.slug.padEnd(width))} ${title}`);
223
+ const text = passage(hit);
224
+ if (text) console.log(` ${" ".repeat(width)} ${paintTerms(text, words)}`);
225
+ }
226
+ footer(hits.length, shown.length, [
227
+ "vantage docs <name> open one result --regex treat the query as a regular expression",
228
+ "vantage search --json machine-readable --limit max results (default 10)"
229
+ ]);
230
+ return 0;
231
+ }
232
+ function runRegex(entries, query, lang, limit, json) {
233
+ let scan;
234
+ let probe;
235
+ try {
236
+ scan = new RegExp(query, "gi");
237
+ probe = new RegExp(query, "i");
238
+ } catch (err) {
239
+ log.error(err instanceof Error ? err.message : `Invalid regular expression: ${String(err)}`);
240
+ return 1;
241
+ }
242
+ const results = [];
243
+ for (const entry of entries) {
244
+ const lines = readDoc(entry).split("\n");
245
+ const matches = [];
246
+ let matchCount = 0;
247
+ for (let i = 0; i < lines.length; i++) {
248
+ const found = [...lines[i].matchAll(scan)];
249
+ if (found.length === 0) continue;
250
+ matchCount += found.length;
251
+ if (matches.length < MAX_REGEX_LINES) {
252
+ matches.push({ line: i + 1, text: lines[i].replace(/\s+/g, " ").trim() });
253
+ }
254
+ }
255
+ const inMeta = probe.test(entry.slug) || probe.test(entry.title) || probe.test(entry.description);
256
+ if (matchCount === 0 && !inMeta) continue;
257
+ results.push({ entry, matchCount, matches });
258
+ }
259
+ results.sort((a, b) => b.matchCount - a.matchCount);
260
+ const shown = results.slice(0, limit);
261
+ if (json) {
262
+ printJson({
263
+ query,
264
+ mode: "regex",
265
+ lang,
266
+ count: results.length,
267
+ results: shown.map((result) => ({
268
+ ...meta(result.entry),
269
+ matchCount: result.matchCount,
270
+ matches: result.matches
271
+ }))
272
+ });
273
+ return 0;
274
+ }
275
+ if (results.length === 0) {
276
+ noResults(query);
277
+ return 0;
278
+ }
279
+ header(results.length, query, lang, "regex");
280
+ for (const result of shown) {
281
+ const count = pc.dim(
282
+ result.matchCount ? ` ${result.matchCount} match${result.matchCount === 1 ? "" : "es"}` : " name match"
283
+ );
284
+ console.log(` ${pc.cyan(result.entry.slug)} ${result.entry.title}${count}`);
285
+ for (const match of result.matches) {
286
+ console.log(` ${pc.dim(String(match.line).padStart(4))} ${paintMatches(match.text, scan)}`);
287
+ }
288
+ }
289
+ footer(results.length, shown.length, [
290
+ "vantage docs <name> open one result --limit max results (default 10)",
291
+ "vantage search --json machine-readable --lang ja | en"
292
+ ]);
293
+ return 0;
294
+ }
295
+ async function search(_root, args) {
296
+ const query = args.positionals.slice(1).join(" ").trim();
297
+ if (!query) {
298
+ log.error("Usage: vantage search <query> [--regex] [--limit <n>] [--lang ja|en] [--json]");
299
+ return 1;
300
+ }
301
+ const catalog = loadCatalog();
302
+ if (!catalog) {
303
+ log.error("The bundled documentation is missing. Reinstall @squadbase/vantage, or run `pnpm build` in the framework repo.");
304
+ return 1;
305
+ }
306
+ const langFlag = args.flags.lang;
307
+ if (langFlag !== void 0 && !isDocLang(langFlag)) {
308
+ log.error(`Unknown --lang "${String(langFlag)}". Available: ${DOC_LANGS.join(", ")}`);
309
+ return 1;
310
+ }
311
+ const lang = isDocLang(langFlag) ? langFlag : DEFAULT_DOC_LANG;
312
+ const entries = docsForLang(catalog, lang);
313
+ if (entries.length === 0) {
314
+ log.error(`No documentation bundled for "${lang}".`);
315
+ return 1;
316
+ }
317
+ const searchable = entries.filter((entry) => entry.searchable !== false);
318
+ const limit = parseLimit(args.flags.limit, DEFAULT_LIMIT);
319
+ const json = Boolean(args.flags.json);
320
+ return args.flags.regex ? runRegex(searchable, query, lang, limit, json) : runRanked(searchable, query, lang, limit, json);
321
+ }
322
+
323
+ export { search };
324
+ //# sourceMappingURL=search-5TYAIQ7C.js.map
325
+ //# sourceMappingURL=search-5TYAIQ7C.js.map