@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 @@
1
+ {"version":3,"sources":["../src/cli/search-index.ts","../src/cli/search.ts"],"names":[],"mappings":"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","file":"search-5TYAIQ7C.js","sourcesContent":["import { readDoc, type DocEntry } from \"./docs-catalog\"\n\n/**\n * A tiny BM25F ranker over the bundled documentation. The corpus is the catalog\n * `docs-catalog.ts` exposes — the same one `vantage docs` prints, so search never\n * creates a second source of truth.\n *\n * The index is built at run time: 65 pages per language (~300 KB) tokenize in a\n * few milliseconds, which is cheaper than shipping and version-locking a\n * prebuilt index alongside the docs bundle.\n */\n\n/**\n * Field weights. A name or a title match says far more about relevance than one\n * more occurrence in a long body, and BM25F models that as a weighted term\n * frequency (and a matching weighted document length).\n */\nconst FIELD_WEIGHTS = { slug: 3, title: 3, description: 2, body: 1 } as const\n\n/** Standard BM25 constants: term-frequency saturation and length normalization. */\nconst K1 = 1.2\nconst B = 0.75\n\n/**\n * Latin/digit runs, or runs of Japanese script (kana + CJK ideographs). CJK\n * punctuation (U+3000–U+303F, 。and 、) is deliberately outside the ranges, so\n * runs break at sentence boundaries.\n */\nconst TOKEN_RE = /[a-z0-9]+|[぀-ヿ㐀-䶿一-鿿]+/g\nconst LATIN_RE = /^[a-z0-9]+$/\n/** `TOKEN_RE`, but before lowercasing — for text that is not being indexed. */\nconst TOKEN_RE_ANYCASE = /[a-zA-Z0-9]+|[぀-ヿ㐀-䶿一-鿿]+/g\nconst CJK_RE = /[぀-ヿ㐀-䶿一-鿿]/\n\n/**\n * One run of a single script: hiragana (U+3041–U+309F), katakana (U+30A0–U+30FF,\n * so ー stays inside テーブル), or kanji. Japanese writes content words in\n * katakana and kanji and the grammatical glue between them in hiragana, so\n * cutting at every script change segments 「テーブルにページングを付けたい」into\n * テーブル · に · ページング · を · 付 · けたい without a morphological analyser.\n */\nconst SCRIPT_RE = /[ぁ-ゟ]+|[゠-ヿ]+|[㐀-䶿一-鿿]+/g\nconst HIRAGANA_RE = /^[ぁ-ゟ]$/\n\n/** Plural forms, so `colors` finds `color` and `queries` finds `query`. */\nfunction singular(word: string): string {\n if (word.length >= 5 && word.endsWith(\"ies\")) return `${word.slice(0, -3)}y`\n if (word.length >= 4 && word.endsWith(\"s\") && !/(ss|us|is)$/.test(word)) return word.slice(0, -1)\n return word\n}\n\n/**\n * Split text into index terms. Latin runs become words (`DataTable` splits into\n * `data` + `table`, so a two-word query finds it). Japanese runs are segmented\n * by script change; each segment is indexed whole *and* as character bigrams,\n * so an exact word scores high while a near miss (ページング / ページネーション)\n * still shares enough terms to be found.\n */\nexport function tokenize(text: string): string[] {\n const normalized = text\n .normalize(\"NFKC\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase()\n const tokens: string[] = []\n for (const match of normalized.matchAll(TOKEN_RE)) {\n const run = match[0]!\n if (LATIN_RE.test(run)) {\n tokens.push(singular(run))\n continue\n }\n for (const segment of run.match(SCRIPT_RE) ?? []) {\n // A lone hiragana is a particle (を, に, が …): it appears in every page\n // and would make every page a match.\n if (segment.length === 1 && HIRAGANA_RE.test(segment)) continue\n // A 2-character segment is its own only bigram — pushing both would\n // double-count it.\n if (segment.length <= 2) {\n tokens.push(segment)\n continue\n }\n tokens.push(segment)\n for (let i = 0; i < segment.length - 1; i++) tokens.push(segment.slice(i, i + 2))\n }\n }\n return tokens\n}\n\n/**\n * The words a snippet should highlight: whole words and whole Japanese\n * segments as the user typed them, without the derived bigrams (highlighting\n * those would paint most of a Japanese line yellow) and without the singular\n * rewrite (which no longer appears verbatim in the text).\n */\nexport function queryPhrases(query: string): string[] {\n const phrases: string[] = []\n for (const match of query.normalize(\"NFKC\").matchAll(TOKEN_RE_ANYCASE)) {\n const run = match[0]!\n if (!CJK_RE.test(run)) {\n phrases.push(run)\n continue\n }\n for (const segment of run.match(SCRIPT_RE) ?? []) {\n if (segment.length === 1 && HIRAGANA_RE.test(segment)) continue\n phrases.push(segment)\n }\n }\n return [...new Set(phrases)]\n}\n\n/** One ranked document, with the body kept for snippet extraction. */\nexport interface SearchHit {\n entry: DocEntry\n score: number\n /** Query terms that were looked up — the input for `snippet()`. */\n terms: string[]\n body: string\n}\n\ninterface IndexedDoc {\n entry: DocEntry\n body: string\n /** Weighted term frequency across all fields. */\n tf: Map<string, number>\n /** Weighted document length. */\n length: number\n}\n\nexport interface SearchIndex {\n /** Every document with a non-zero score, best first. */\n search(query: string): SearchHit[]\n}\n\n/** Build the index for one language's catalog entries. */\nexport function buildIndex(entries: DocEntry[]): SearchIndex {\n const docs: IndexedDoc[] = entries.map((entry) => {\n const body = readDoc(entry)\n const tf = new Map<string, number>()\n let length = 0\n const add = (text: string, weight: number) => {\n for (const token of tokenize(text)) {\n tf.set(token, (tf.get(token) ?? 0) + weight)\n length += weight\n }\n }\n add(entry.slug, FIELD_WEIGHTS.slug)\n add(entry.title, FIELD_WEIGHTS.title)\n add(entry.description, FIELD_WEIGHTS.description)\n add(body, FIELD_WEIGHTS.body)\n return { entry, body, tf, length }\n })\n\n const df = new Map<string, number>()\n for (const doc of docs) {\n for (const term of doc.tf.keys()) df.set(term, (df.get(term) ?? 0) + 1)\n }\n const total = docs.length\n const avgLength = total ? docs.reduce((sum, doc) => sum + doc.length, 0) / total : 1\n\n return {\n search(query: string): SearchHit[] {\n const terms = [...new Set(tokenize(query))]\n if (terms.length === 0) return []\n\n const hits: SearchHit[] = []\n for (const doc of docs) {\n let score = 0\n for (const term of terms) {\n const tf = doc.tf.get(term)\n if (!tf) continue\n const n = df.get(term) ?? 0\n const idf = Math.log(1 + (total - n + 0.5) / (n + 0.5))\n const norm = 1 - B + (B * doc.length) / avgLength\n score += idf * ((tf * (K1 + 1)) / (tf + K1 * norm))\n }\n if (score > 0) hits.push({ entry: doc.entry, score, terms, body: doc.body })\n }\n hits.sort((a, b) => b.score - a.score || a.entry.slug.localeCompare(b.entry.slug))\n return hits\n },\n }\n}\n\n/** How much of a line to show around the first matched term. */\nconst SNIPPET_LENGTH = 150\n\n/**\n * Pick the passage that best covers the query terms. Lines are compared\n * lowercased only (no NFKC, no camelCase splitting) so offsets stay aligned\n * with the text that is printed.\n */\nexport function snippet(body: string, terms: string[], length = SNIPPET_LENGTH): string {\n let best = \"\"\n let bestHits = 0\n let bestIndex = 0\n let bestIsHeading = true\n\n // The first line is the page's own `# Title`, which the caller already shows.\n for (const raw of body.split(\"\\n\").slice(1)) {\n const line = raw.replace(/^\\s*[-*]\\s+/, \"\").replace(/\\s+/g, \" \").trim()\n if (!line || /^(```|~~~|\\|\\s*-{2,})/.test(line)) continue\n const haystack = line.toLowerCase()\n const heading = line.startsWith(\"#\")\n let hits = 0\n let first = -1\n for (const term of terms) {\n const at = haystack.indexOf(term)\n if (at === -1) continue\n hits++\n if (first === -1 || at < first) first = at\n }\n // Equal coverage: prose says more than a heading does.\n if (hits > bestHits || (hits === bestHits && hits > 0 && bestIsHeading && !heading)) {\n best = line\n bestHits = hits\n bestIndex = first\n bestIsHeading = heading\n }\n }\n\n if (!bestHits) return \"\"\n if (best.length <= length) return best\n\n const start = Math.max(0, bestIndex - Math.floor(length / 4))\n const text = best.slice(start, start + length).trim()\n return `${start > 0 ? \"…\" : \"\"}${text}${start + length < best.length ? \"…\" : \"\"}`\n}\n","import pc from \"picocolors\"\nimport {\n DEFAULT_DOC_LANG,\n DOC_LANGS,\n docsForLang,\n isDocLang,\n loadCatalog,\n readDoc,\n type DocEntry,\n type DocLang,\n} from \"./docs-catalog\"\nimport { buildIndex, queryPhrases, snippet, type SearchHit } from \"./search-index\"\nimport { log, printJson, type ParsedArgs } from \"./util\"\n\n/** Results shown when `--limit` is absent. */\nconst DEFAULT_LIMIT = 10\n\n/** Matching lines printed per page in regex mode (the count is always exact). */\nconst MAX_REGEX_LINES = 3\n\n/** Parse `--limit`, falling back silently like `parsePort` does. */\nfunction parseLimit(value: string | boolean | undefined, fallback: number): number {\n if (typeof value === \"string\") {\n const n = Number(value)\n if (Number.isInteger(n) && n > 0) return n\n }\n return fallback\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n/** Dim a line, with every match of `re` picked out. Piped output stays plain. */\nfunction paintMatches(text: string, re: RegExp): string {\n if (!process.stdout.isTTY) return text\n let out = \"\"\n let last = 0\n for (const match of text.matchAll(re)) {\n const at = match.index ?? 0\n if (!match[0]) continue // zero-length match: nothing to highlight\n out += pc.dim(text.slice(last, at)) + pc.yellow(match[0])\n last = at + match[0].length\n }\n return out + pc.dim(text.slice(last))\n}\n\n/** Same, for the words of a natural-language query. */\nfunction paintTerms(text: string, words: string[]): string {\n if (!process.stdout.isTTY) return text\n if (words.length === 0) return pc.dim(text)\n return paintMatches(text, new RegExp(words.map(escapeRegExp).join(\"|\"), \"gi\"))\n}\n\nfunction header(count: number, query: string, lang: DocLang, mode: string): void {\n const label = `${count} result${count === 1 ? \"\" : \"s\"} for \"${query}\"`\n console.log(\"\")\n console.log(pc.bold(label) + pc.dim(` ${lang} · ${mode}`))\n console.log(\"\")\n}\n\nfunction footer(total: number, shown: number, lines: string[]): void {\n if (total > shown) {\n console.log(\"\")\n console.log(pc.dim(` ${total - shown} more — raise --limit to see them`))\n }\n console.log(\"\")\n for (const line of lines) console.log(pc.dim(line))\n}\n\nfunction noResults(query: string): void {\n log.warn(`Nothing matches \"${query}\".`)\n console.log(pc.dim(\" Try fewer or more general words, or run `vantage docs --list` to browse every page.\"))\n}\n\nfunction meta(entry: DocEntry) {\n return {\n slug: entry.slug,\n title: entry.title,\n description: entry.description,\n section: entry.section,\n sectionTitle: entry.sectionTitle,\n command: `vantage docs ${entry.slug}`,\n }\n}\n\n/** Default mode: rank the corpus with BM25 and show the best passage of each hit. */\nfunction runRanked(entries: DocEntry[], query: string, lang: DocLang, limit: number, json: boolean): number {\n const hits = buildIndex(entries).search(query)\n const shown = hits.slice(0, limit)\n const passage = (hit: SearchHit) => snippet(hit.body, hit.terms)\n\n if (json) {\n printJson({\n query,\n mode: \"bm25\",\n lang,\n count: hits.length,\n results: shown.map((hit) => ({\n ...meta(hit.entry),\n score: Math.round(hit.score * 1000) / 1000,\n snippet: passage(hit),\n })),\n })\n return 0\n }\n\n if (hits.length === 0) {\n noResults(query)\n return 0\n }\n\n const words = queryPhrases(query)\n const width = Math.max(...shown.map((hit) => hit.entry.slug.length))\n header(hits.length, query, lang, \"bm25\")\n for (const hit of shown) {\n const title = `${hit.entry.title}${pc.dim(` · ${hit.entry.sectionTitle}`)}`\n console.log(` ${pc.cyan(hit.entry.slug.padEnd(width))} ${title}`)\n const text = passage(hit)\n if (text) console.log(` ${\" \".repeat(width)} ${paintTerms(text, words)}`)\n }\n footer(hits.length, shown.length, [\n \"vantage docs <name> open one result --regex treat the query as a regular expression\",\n \"vantage search --json machine-readable --limit max results (default 10)\",\n ])\n return 0\n}\n\n/** `--regex` mode: scan names, titles and bodies for a regular expression. */\nfunction runRegex(entries: DocEntry[], query: string, lang: DocLang, limit: number, json: boolean): number {\n let scan: RegExp\n let probe: RegExp\n try {\n scan = new RegExp(query, \"gi\")\n probe = new RegExp(query, \"i\")\n } catch (err) {\n log.error(err instanceof Error ? err.message : `Invalid regular expression: ${String(err)}`)\n return 1\n }\n\n const results: { entry: DocEntry; matchCount: number; matches: { line: number; text: string }[] }[] = []\n for (const entry of entries) {\n const lines = readDoc(entry).split(\"\\n\")\n const matches: { line: number; text: string }[] = []\n let matchCount = 0\n for (let i = 0; i < lines.length; i++) {\n const found = [...lines[i]!.matchAll(scan)]\n if (found.length === 0) continue\n matchCount += found.length\n if (matches.length < MAX_REGEX_LINES) {\n matches.push({ line: i + 1, text: lines[i]!.replace(/\\s+/g, \" \").trim() })\n }\n }\n const inMeta = probe.test(entry.slug) || probe.test(entry.title) || probe.test(entry.description)\n if (matchCount === 0 && !inMeta) continue\n results.push({ entry, matchCount, matches })\n }\n // Stable sort: pages with more matches first, catalog order within ties.\n results.sort((a, b) => b.matchCount - a.matchCount)\n const shown = results.slice(0, limit)\n\n if (json) {\n printJson({\n query,\n mode: \"regex\",\n lang,\n count: results.length,\n results: shown.map((result) => ({\n ...meta(result.entry),\n matchCount: result.matchCount,\n matches: result.matches,\n })),\n })\n return 0\n }\n\n if (results.length === 0) {\n noResults(query)\n return 0\n }\n\n header(results.length, query, lang, \"regex\")\n for (const result of shown) {\n // A page can match on its name, title or description alone — with no body line to show.\n const count = pc.dim(\n result.matchCount ? ` ${result.matchCount} match${result.matchCount === 1 ? \"\" : \"es\"}` : \" name match\",\n )\n console.log(` ${pc.cyan(result.entry.slug)} ${result.entry.title}${count}`)\n for (const match of result.matches) {\n console.log(` ${pc.dim(String(match.line).padStart(4))} ${paintMatches(match.text, scan)}`)\n }\n }\n footer(results.length, shown.length, [\n \"vantage docs <name> open one result --limit max results (default 10)\",\n \"vantage search --json machine-readable --lang ja | en\",\n ])\n return 0\n}\n\n/** `vantage search <query> [--regex] [--limit n] [--json] [--lang ja|en]` */\nexport async function search(_root: string, args: ParsedArgs): Promise<number> {\n const query = args.positionals.slice(1).join(\" \").trim()\n if (!query) {\n log.error(\"Usage: vantage search <query> [--regex] [--limit <n>] [--lang ja|en] [--json]\")\n return 1\n }\n\n const catalog = loadCatalog()\n if (!catalog) {\n log.error(\"The bundled documentation is missing. Reinstall @squadbase/vantage, or run `pnpm build` in the framework repo.\")\n return 1\n }\n\n const langFlag = args.flags.lang\n if (langFlag !== undefined && !isDocLang(langFlag)) {\n log.error(`Unknown --lang \"${String(langFlag)}\". Available: ${DOC_LANGS.join(\", \")}`)\n return 1\n }\n const lang: DocLang = isDocLang(langFlag) ? langFlag : DEFAULT_DOC_LANG\n\n const entries = docsForLang(catalog, lang)\n if (entries.length === 0) {\n log.error(`No documentation bundled for \"${lang}\".`)\n return 1\n }\n\n // Pages that opted out with `search: false` (e.g. the changelog) are still\n // reachable via `vantage docs` but never surface here.\n const searchable = entries.filter((entry) => entry.searchable !== false)\n\n const limit = parseLimit(args.flags.limit, DEFAULT_LIMIT)\n const json = Boolean(args.flags.json)\n return args.flags.regex\n ? runRegex(searchable, query, lang, limit, json)\n : runRanked(searchable, query, lang, limit, json)\n}\n"]}
@@ -1,17 +1,6 @@
1
+ import { S as Segment } from '../types-De3mo_hv.js';
1
2
  import { ApiModule } from './index.js';
2
3
 
3
- /** A parsed path segment of a page or API route. */
4
- type Segment = {
5
- kind: "static";
6
- value: string;
7
- } | {
8
- kind: "param";
9
- name: string;
10
- } | {
11
- kind: "catchall";
12
- name: string;
13
- };
14
-
15
4
  /** A statically-imported API route for the production server. */
16
5
  interface ProdApiRoute {
17
6
  routePath: string;
@@ -0,0 +1,59 @@
1
+ /** A parsed path segment of a page or API route. */
2
+ type Segment = {
3
+ kind: "static";
4
+ value: string;
5
+ } | {
6
+ kind: "param";
7
+ name: string;
8
+ } | {
9
+ kind: "catchall";
10
+ name: string;
11
+ };
12
+ /** A discovered page route. */
13
+ interface PageRoute {
14
+ /** Project-relative POSIX path, e.g. `sales/[customerId].tsx`. */
15
+ file: string;
16
+ /** Absolute filesystem path. */
17
+ absFile: string;
18
+ /** Display route path, e.g. `/sales/:customerId` or `/files/*`. */
19
+ routePath: string;
20
+ /** Parsed segments. */
21
+ segments: Segment[];
22
+ /** Directory (POSIX, relative), e.g. `sales` or "" for root. */
23
+ dir: string;
24
+ /** Whether the file has a dynamic (param/catchall) segment. */
25
+ dynamic: boolean;
26
+ }
27
+ /** A discovered layout module. */
28
+ interface LayoutRoute {
29
+ /** Project-relative POSIX path, e.g. `_layout.tsx` or `sales/_layout.tsx`. */
30
+ file: string;
31
+ absFile: string;
32
+ /** Directory the layout applies to (POSIX, relative), "" for root. */
33
+ dir: string;
34
+ }
35
+ /** A discovered server API route. */
36
+ interface ApiRoute {
37
+ /** Project-relative POSIX path, e.g. `server/api/customers/[id].ts`. */
38
+ file: string;
39
+ absFile: string;
40
+ /** Display route path, e.g. `/api/customers/:id`. */
41
+ routePath: string;
42
+ /** Hono-style match pattern, e.g. `/api/customers/:id` or `/api/files/*`. */
43
+ pattern: string;
44
+ segments: Segment[];
45
+ params: string[];
46
+ }
47
+ /** The full route model derived from a project scan. */
48
+ interface RouteModel {
49
+ pages: PageRoute[];
50
+ layouts: LayoutRoute[];
51
+ notFound: string | null;
52
+ error: string | null;
53
+ apis: ApiRoute[];
54
+ hasServer: boolean;
55
+ /** Page-scan root relative to the project root: `"src"` or `""`. */
56
+ pageDir: string;
57
+ }
58
+
59
+ export type { RouteModel as R, Segment as S };
@@ -0,0 +1,29 @@
1
+ import { syncAgentsFile } from './chunk-UTEKU3LG.js';
2
+ import { generateArtifacts } from './chunk-RA6Z3OX3.js';
3
+ import './chunk-VXAV2435.js';
4
+ import { scanProject } from './chunk-D4Y5RWJA.js';
5
+ import { frameworkVersion, printJson, log } from './chunk-OFFJ3OL5.js';
6
+ import './chunk-C4MQRWXS.js';
7
+
8
+ // @squadbase/vantage — generated build. Do not edit.
9
+
10
+ // src/cli/upgrade.ts
11
+ async function upgrade(root, args) {
12
+ const version = frameworkVersion();
13
+ const model = scanProject(root);
14
+ generateArtifacts({ root, model });
15
+ const agents = syncAgentsFile(root);
16
+ if (args.flags.json) {
17
+ printJson({ ok: true, version, transforms: [], regenerated: true, agentsSynced: agents === "updated" });
18
+ return 0;
19
+ }
20
+ log.brand(`upgrade \u2192 v${version}`);
21
+ log.ok("Regenerated .vantage artifacts.");
22
+ if (agents === "updated") log.ok("Synced AGENTS.md from the framework.");
23
+ log.info("No breaking code transforms required for this version.");
24
+ return 0;
25
+ }
26
+
27
+ export { upgrade };
28
+ //# sourceMappingURL=upgrade-3P5MBGE6.js.map
29
+ //# sourceMappingURL=upgrade-3P5MBGE6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/upgrade.ts"],"names":[],"mappings":";;;;;;;;;;AAWA,eAAsB,OAAA,CAAQ,MAAc,IAAA,EAAmC;AAC7E,EAAA,MAAM,UAAU,gBAAA,EAAiB;AACjC,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,iBAAA,CAAkB,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA;AAIjC,EAAA,MAAM,MAAA,GAAS,eAAe,IAAI,CAAA;AAElC,EAAA,IAAI,IAAA,CAAK,MAAM,IAAA,EAAM;AACnB,IAAA,SAAA,CAAU,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,EAAC,EAAG,WAAA,EAAa,IAAA,EAAM,YAAA,EAAc,MAAA,KAAW,SAAA,EAAW,CAAA;AACtG,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,GAAA,CAAI,KAAA,CAAM,CAAA,gBAAA,EAAc,OAAO,CAAA,CAAE,CAAA;AACjC,EAAA,GAAA,CAAI,GAAG,iCAAiC,CAAA;AACxC,EAAA,IAAI,MAAA,KAAW,SAAA,EAAW,GAAA,CAAI,EAAA,CAAG,sCAAsC,CAAA;AACvE,EAAA,GAAA,CAAI,KAAK,wDAAwD,CAAA;AACjE,EAAA,OAAO,CAAA;AACT","file":"upgrade-3P5MBGE6.js","sourcesContent":["import { generateArtifacts } from \"../core/generate\"\nimport { scanProject } from \"../core/scan\"\nimport { syncAgentsFile } from \"./add\"\nimport { frameworkVersion, log, printJson, type ParsedArgs } from \"./util\"\n\n/**\n * `vantage upgrade` — reconcile generated artifacts with the installed\n * framework version and apply any needed code transforms. v0.1 only\n * regenerates artifacts and re-syncs a managed AGENTS.md; the migration hook\n * exists for future major versions.\n */\nexport async function upgrade(root: string, args: ParsedArgs): Promise<number> {\n const version = frameworkVersion()\n const model = scanProject(root)\n generateArtifacts({ root, model })\n\n // Keep an adopted AGENTS.md (the app-author map) in step with the framework's\n // canonical copy. No-op when the app never ran `vantage add agents`.\n const agents = syncAgentsFile(root)\n\n if (args.flags.json) {\n printJson({ ok: true, version, transforms: [], regenerated: true, agentsSynced: agents === \"updated\" })\n return 0\n }\n\n log.brand(`upgrade → v${version}`)\n log.ok(\"Regenerated .vantage artifacts.\")\n if (agents === \"updated\") log.ok(\"Synced AGENTS.md from the framework.\")\n log.info(\"No breaking code transforms required for this version.\")\n return 0\n}\n"]}
@@ -1,9 +1,22 @@
1
1
  import { PluginOption } from 'vite';
2
+ import { R as RouteModel } from '../types-De3mo_hv.js';
2
3
 
3
4
  interface VantagePluginOptions {
4
5
  root: string;
5
6
  /** Server-side env (process.env + loaded .env), passed to API handlers. */
6
7
  env?: Record<string, string | undefined>;
8
+ /**
9
+ * A route model the caller already scanned. `dev`/`build` run diagnostics
10
+ * before starting Vite, so without this the project would be walked a second
11
+ * time for an answer that is milliseconds old.
12
+ */
13
+ model?: RouteModel;
14
+ /**
15
+ * Set when the caller has already written `.vantage/` for `model`. `build`
16
+ * does, so that the server bundle — which reads `server-routes.gen.ts` — can
17
+ * be produced at the same time as the client instead of after it.
18
+ */
19
+ artifactsWritten?: boolean;
7
20
  }
8
21
  /**
9
22
  * The single plugin that turns a plain Vite instance into Vantage: file-based
@@ -1,5 +1,9 @@
1
- export { vantagePlugin } from '../chunk-3QKPNWKJ.js';
1
+ export { vantagePlugin } from '../chunk-R2YYVCGS.js';
2
+ import '../chunk-RA6Z3OX3.js';
2
3
  import '../chunk-46QI6GFC.js';
4
+ import '../chunk-VXAV2435.js';
5
+ import '../chunk-D4Y5RWJA.js';
6
+ import '../chunk-C4MQRWXS.js';
3
7
  import '../chunk-B7LLBNLV.js';
4
8
  //# sourceMappingURL=index.js.map
5
9
  //# sourceMappingURL=index.js.map
@@ -9,6 +9,88 @@ What changed in each Vantage release. Newest is on top.
9
9
  > minor release may include backwards-incompatible changes. A patch is limited to
10
10
  > backwards-compatible additions and bug fixes.
11
11
 
12
+ ## v0.3.1
13
+
14
+ CLI startup, dev server boot and builds got faster. Nothing here is meant to
15
+ change behaviour — it is all backwards compatible.
16
+
17
+ ### Faster
18
+
19
+ - **`check` / `routes` / `docs` / `search` / `add` / `doctor` are about 3x faster**
20
+ (measured: 205ms → 65–75ms). None of them touch Vite or Tailwind, yet the CLI
21
+ loaded both on every invocation. Each command now loads only what it needs.
22
+ The difference shows most when an agent or CI runs `check` and `routes` in a
23
+ loop.
24
+ - **`vantage dev` starts faster** — it used to scan the project four times at
25
+ startup; now it scans once (and generates once instead of twice).
26
+ - **`vantage build` builds the client and the server in parallel** (projects with
27
+ a `server/` only). The log goes from two lines — "Building client…",
28
+ "Building server…" — to a single "Building client and server…".
29
+ - **`vantage check` no longer re-reads the same files** — page modules were read
30
+ three times over and the project tree was walked twice. The bigger the app, the
31
+ bigger the difference.
32
+ - **The dev server rescans less** — creating any directory used to trigger a full
33
+ rescan; now only directories that could hold pages or API modules do.
34
+ - **Dependency prebundling is declared up front** — the kit's dependencies (Base
35
+ UI, ECharts, TanStack Table, …) are handed to Vite ahead of time, so opening a
36
+ page that uses one of those components for the first time no longer triggers
37
+ "new dependencies optimized" followed by a full page reload (on hoisted
38
+ installs, i.e. npm/yarn).
39
+
40
+ ### Added
41
+
42
+ - **`VANTAGE_PROFILE=1`** (→ [CLI reference](cli-reference)) — prints how long
43
+ each phase of any `vantage` command took, on **stderr**. A measuring point, so
44
+ "it feels slow" can be checked before it is fixed. Nothing goes to stdout, so it
45
+ composes with `--json`.
46
+
47
+ ## v0.3.0
48
+
49
+ Vantage now recognises `src/` as a place to put pages. This carries a
50
+ backwards-incompatible change (what gets scanned in a project that has a `src/`),
51
+ so per the 0.x policy it goes out as a minor.
52
+
53
+ Apps pinned to `"@squadbase/vantage": "^0.2.0"` will not pick up 0.3.0 — bump the
54
+ range to `^0.3.0`.
55
+
56
+ > [!WARNING]
57
+ > **In a project with a `src/`, only `src/` is scanned for pages.** `src/` used to be
58
+ > an ordinary directory, so `src/App.tsx` served `/src/App`. From 0.3.0, `src/`
59
+ > becomes the page-scan root and drops out of the URL (`src/sales/index.tsx` →
60
+ > `/sales`). **Pages and `styles.css` left at the project root are no longer
61
+ > scanned**, and `vantage check` reports them as `SRC_DIR_SPLIT`. Projects without a
62
+ > `src/` behave exactly as before.
63
+
64
+ ### Changed
65
+
66
+ - **The page-scan root is decided by whether `src/` exists**
67
+ (see [File-based routing](routing)) — pages live inside `<root>/src` when it
68
+ exists, at the project root otherwise. Nothing is configured; it is detected. A
69
+ one-file app can stay at the root and move into `src/` once it grows. `server/`
70
+ and `public/` always stay at the project root, and `src/server/` is never scanned.
71
+ - **`styles.css` is read from the same side as the pages** — `src/styles.css` when
72
+ the project has a `src/`.
73
+ - **`vantage add page` / `add ui` / `add block` write relative to the page-scan
74
+ root** (`src/reports/index.tsx`, `src/components/ui/data-table.tsx`).
75
+ - **Quick mode given a page file** now resolves the root by walking up to the
76
+ nearest `package.json` — `vantage ./demo/src/index.tsx` runs in `./demo` (it used
77
+ to take the parent directory, landing in `./demo/src`).
78
+
79
+ ### Added
80
+
81
+ - **`SRC_DIR_SPLIT` (error)** — raised when `src/` exists but pages or `styles.css`
82
+ were left at the project root, or when `src/server/` exists. Each of those is a
83
+ "you placed it and nothing happened" failure, so it is an error rather than a
84
+ warning.
85
+ - **`SUSPICIOUS_ROUTE_DIR` (warning)** — raised when a URL comes out of a
86
+ scaffolding-looking directory such as `pages/`, `app/` or `utils/`
87
+ (`pages/report.tsx` → `/pages/report`). Page scanning works off a deny list, so
88
+ any name not on it silently becomes a URL. Scanning is not stopped, so you can
89
+ ignore the warning when the URL is intentional.
90
+ - The bundled `AGENTS.md` gained a "directory structure" section, and the skills
91
+ (`vantage-app`, `vantage-add-feature`) follow it. Placed copies of `AGENTS.md`
92
+ are synced by `vantage upgrade`.
93
+
12
94
  ## v0.2.3
13
95
 
14
96
  `vantage routes` can be narrowed to one side of the map, and can print the spec of
@@ -26,8 +26,9 @@ first argument isn't a known command but points at a filesystem path, Vantage st
26
26
  path as the root (printing `quick dev → <path>`).
27
27
 
28
28
  ```bash
29
- vantage ./demo # folder → run dev inside it
30
- vantage ./demo/index.tsx # page file → use its parent folder as the root
29
+ vantage ./demo # folder → run dev inside it
30
+ vantage ./demo/index.tsx # page file → the folder holding its package.json
31
+ vantage ./demo/src/index.tsx # same with a src/ layout (the root is ./demo)
31
32
  ```
32
33
 
33
34
  Path resolution rules:
@@ -35,7 +36,7 @@ Path resolution rules:
35
36
  | Path you pass | Root that's used |
36
37
  |---|---|
37
38
  | A directory | the directory itself |
38
- | A `.tsx` / `.jsx` page file | its parent directory |
39
+ | A `.tsx` / `.jsx` page file | the nearest directory above it with a `package.json` (its parent otherwise) |
39
40
  | A missing path / anything else | none (`Unknown command` error) |
40
41
 
41
42
  Every root-scoped command except `add`, `docs` and `search` may also take a trailing path positional. You can spell out
@@ -323,17 +324,46 @@ vantage build --api-base-url https://api.example.com
323
324
  The flag takes precedence over `PUBLIC_API_BASE_URL` from `.env`. Unset means empty (same-origin
324
325
  relative paths). See [Build & deploy](build-and-deploy) for details.
325
326
 
327
+ ## `VANTAGE_PROFILE` — measure before you tune
328
+
329
+ Set `VANTAGE_PROFILE=1` on any command to see how long each phase took.
330
+
331
+ ```bash
332
+ VANTAGE_PROFILE=1 vantage dev
333
+ ```
334
+
335
+ ```text
336
+ [vantage:profile] scan 1.6ms @0.146s
337
+ [vantage:profile] diagnostics 2.1ms @0.148s
338
+ [vantage:profile] generate 1.5ms @0.159s
339
+ [vantage:profile] vite:createServer 16.2ms @0.165s
340
+ [vantage:profile] vite:listen 41.3ms @0.206s
341
+ ```
342
+
343
+ The left column is the duration; `@` is the time since the process started. The
344
+ phases are `scan` (route discovery), `diagnostics` (the static checks),
345
+ `generate` (writing `.vantage/`), `vite:*`, and `build:client` / `build:server`.
346
+
347
+ > [!NOTE]
348
+ > Everything goes to **stderr**. stdout stays clean, so this composes with `--json`.
349
+ >
350
+ > ```bash
351
+ > VANTAGE_PROFILE=1 vantage check --json > result.json
352
+ > ```
353
+
326
354
  ## Static diagnostics (`check`)
327
355
 
328
- `vantage check` detects these six diagnostics (five errors, one warning).
356
+ `vantage check` detects these eight diagnostics (six errors, two warnings).
329
357
 
330
358
  | Code | Severity | Meaning |
331
359
  |---|---|---|
332
360
  | `FORBIDDEN_FILE` | error | A forbidden config file exists at the root |
361
+ | `SRC_DIR_SPLIT` | error | `src/` exists but pages or `styles.css` were left at the project root (or `src/server/` exists) |
333
362
  | `ROUTE_CONFLICT` | error | Two files resolve to the same route |
334
363
  | `MISSING_DEFAULT_EXPORT` | error | A page has no default export |
335
364
  | `INVALID_API_EXPORT` | error | An API exports no valid HTTP method |
336
365
  | `CLIENT_IMPORTS_SERVER` | error | Client code imports from `server/` |
366
+ | `SUSPICIOUS_ROUTE_DIR` | warning | A scaffolding-looking directory (`pages/`, `app/`, `utils/`, …) shows up in a URL |
337
367
  | `PUBLIC_ENV_MISUSE` | warning | Client reads a non-`PUBLIC_` env variable |
338
368
 
339
369
  None of them import or run your code — the checks are purely static.
@@ -209,7 +209,8 @@ export default function Overview() {
209
209
  ## Theming
210
210
 
211
211
  The look is decided by CSS variables (design tokens). To change colours or radii, override just the
212
- variables in a `styles.css` at the project root see [UI & theming](ui-and-theming).
212
+ variables in a `styles.css` placed on the same side as your pages (`src/styles.css` when the project
213
+ has a `src/`) — see [UI & theming](ui-and-theming).
213
214
 
214
215
  ## When you want to edit the source
215
216
 
@@ -20,7 +20,9 @@ pnpm add @squadbase/vantage
20
20
  ### Write index.tsx
21
21
 
22
22
  Put a single `index.tsx` at the project root. The **default-exported component** becomes the
23
- route `/`.
23
+ route `/`. To keep pages under `src/`, write `src/index.tsx` instead — **once `src/` exists it
24
+ is the only page-scan root**, and `src/` never shows up in a URL
25
+ (→ [Where pages live](routing)).
24
26
 
25
27
  ```tsx
26
28
  // index.tsx
@@ -67,8 +69,9 @@ Instead of `cd`-ing into a project, you can pass its **path directly** to start
67
69
  Point at a folder or an entry file and `dev` boots on it.
68
70
 
69
71
  ```bash
70
- vantage ./demo # folder → run dev inside it
71
- vantage ./demo/index.tsx # page file → use its parent folder as the root
72
+ vantage ./demo # folder → run dev inside it
73
+ vantage ./demo/index.tsx # page file → use the folder holding its package.json
74
+ vantage ./demo/src/index.tsx # same with a src/ layout (the root is ./demo)
72
75
  ```
73
76
 
74
77
  When the first argument isn't a known command but points at a path, Vantage runs `dev` with that
@@ -4,8 +4,28 @@
4
4
 
5
5
  In Vantage, **where you place a file is its URL**. You never configure a router.
6
6
 
7
+ ## Where pages live
8
+
9
+ There are two layouts, and which one applies is decided by **whether `src/` exists** — detected,
10
+ never configured.
11
+
12
+ | Project | Page-scan root | The file that becomes `/` |
13
+ |---|---|---|
14
+ | Has `src/` | Inside `src/` only | `src/index.tsx` |
15
+ | No `src/` | The project root | `index.tsx` |
16
+
17
+ `src/` itself never appears in a URL (`src/sales/index.tsx` → `/sales`). A one-file app can stay at
18
+ the root; once it grows, create `src/` and move the pages in.
19
+
20
+ > [!WARNING]
21
+ > **The two layouts cannot be mixed.** Once `src/` exists, `.tsx` files at the project root are not
22
+ > scanned and `vantage check` reports `SRC_DIR_SPLIT`. `server/` and `public/` always stay at the
23
+ > project root (`src/server/` is never scanned), and `styles.css` belongs on the same side as the pages.
24
+
7
25
  ## Page conventions
8
26
 
27
+ The "File" column below is relative to the page-scan root above.
28
+
9
29
  | File | Route |
10
30
  |---|---|
11
31
  | `index.tsx` | `/` |
@@ -23,7 +43,7 @@ In Vantage, **where you place a file is its URL**. You never configure a router.
23
43
 
24
44
  ## Directories that are never routed
25
45
 
26
- These directories are never scanned. Put whatever code you like here.
46
+ These directories are never scanned, at any depth. Put whatever code you like here.
27
47
 
28
48
  ```text
29
49
  components/ Reusable React components
@@ -33,6 +53,12 @@ server/ API (its presence enables the server)
33
53
  public/ Static assets
34
54
  ```
35
55
 
56
+ > [!WARNING]
57
+ > **Every other directory name becomes a URL segment.** `pages/report.tsx` serves `/pages/report`,
58
+ > `utils/format.tsx` serves `/utils/format`. When routes come out of scaffolding directories like
59
+ > `pages/`, `app/` or `utils/`, `vantage check` raises a `SUSPICIOUS_ROUTE_DIR` warning — move
60
+ > non-page modules into one of the three directories above.
61
+
36
62
  ## The three spellings of a dynamic param
37
63
 
38
64
  The same param appears in three spellings depending on where it is. **They must match.**
@@ -53,8 +53,10 @@ import { cn } from "@squadbase/vantage/ui";
53
53
 
54
54
  ## Override theme tokens
55
55
 
56
- Design tokens like colors and radii are CSS variables. To override them, place a `styles.css` at the
57
- project root and override **only CSS variables**. The file is auto-imported after the theme.
56
+ Design tokens like colors and radii are CSS variables. To override them, place a `styles.css` **on the
57
+ same side as your pages** `src/styles.css` if the project has a `src/`, at the project root
58
+ otherwise (→ [Where pages live](routing)) — and override **only CSS variables**. The file is
59
+ auto-imported after the theme.
58
60
 
59
61
  ```css
60
62
  /* styles.css — CSS variable overrides only */
@@ -8,6 +8,80 @@ Vantage のリリースごとの変更点です。新しいものが上に来ま
8
8
  > まだプロトタイプ(**0.x**)です。0.x の間は **minor が実質のメジャー**扱いで、後方互換性の
9
9
  > ない変更は minor で入ることがあります。patch は後方互換の機能追加とバグ修正のみです。
10
10
 
11
+ ## v0.3.1
12
+
13
+ CLI の起動と、開発サーバー・ビルドの立ち上がりを速くしました。挙動を変える意図の変更は
14
+ 含まれておらず、すべて後方互換です。
15
+
16
+ ### 速くなったもの
17
+
18
+ - **`check` / `routes` / `docs` / `search` / `add` / `doctor` が約 3 倍速くなりました**
19
+ (実測 205ms → 65〜75ms)。これらのコマンドは Vite も Tailwind も使わないのに、CLI が
20
+ 起動時に必ず読み込んでいました。コマンドごとに必要なものだけを読むようにしています。
21
+ エージェントや CI が `check` と `routes` を繰り返し叩く場面ほど効きます。
22
+ - **`vantage dev` の起動が速くなりました** ― 起動時にプロジェクトを 4 回走査していたのを
23
+ 1 回にしました(生成も 2 回 → 1 回)。
24
+ - **`vantage build` でクライアントとサーバーを並列に建てるようになりました**
25
+ (`server/` があるプロジェクトのみ)。ログは「Building client…」「Building server…」の
26
+ 2 行から「Building client and server…」の 1 行になります。
27
+ - **`vantage check` が同じファイルを読み直さなくなりました** ― ページモジュールは 3 回、
28
+ プロジェクトツリーの走査は 2 回行われていました。大きなアプリほど差が出ます。
29
+ - **開発サーバーの無駄な再走査を減らしました** ― ディレクトリが作られるたびに全走査して
30
+ いたのを、ページや API になり得る場所のときだけにしました。
31
+ - **依存のプリバンドルを先に宣言するようになりました** ― UI キットが使う依存
32
+ (Base UI・ECharts・TanStack Table など)を Vite に先に伝えるので、初めてその
33
+ コンポーネントを使ったページを開いたときの「依存が見つかった → ページ全体がリロード」が
34
+ 起きなくなります(`npm` / `yarn` のように依存が巻き上げられる構成のとき)。
35
+
36
+ ### 追加
37
+
38
+ - **`VANTAGE_PROFILE=1`**(→ [CLI リファレンス](cli-reference))― 任意の `vantage` コマンドの
39
+ 各フェーズの所要時間を **stderr** に出します。「遅い」を測ってから直すための計測口です。
40
+ stdout には出さないので `--json` と併用できます。
41
+
42
+ ## v0.3.0
43
+
44
+ ページの置き場所として `src/` を認識するようになりました。後方互換でない変更(`src/` を持つ
45
+ プロジェクトの走査範囲)を含むため、0.x の方針に従って minor を上げています。
46
+
47
+ 依存を `"@squadbase/vantage": "^0.2.0"` と書いているアプリには 0.3.0 は入りません。
48
+ `^0.3.0` に上げてください。
49
+
50
+ > [!WARNING]
51
+ > **`src/` があるプロジェクトでは、ページ走査が `src/` の中だけになります。** これまで `src/` は
52
+ > ただのディレクトリで、`src/App.tsx` は `/src/App` というルートになっていました。0.3.0 では
53
+ > `src/` があればそこがページ探索ルートになり、`src/` は URL から落ちます
54
+ > (`src/sales/index.tsx` → `/sales`)。**ルート直下に残ったページと `styles.css` は走査されなく
55
+ > なる**ので、`vantage check` が `SRC_DIR_SPLIT` エラーで指摘します。`src/` を持たないアプリの
56
+ > 挙動は変わりません。
57
+
58
+ ### 変更
59
+
60
+ - **ページ探索ルートが `src/` の有無だけで決まるようになりました**
61
+ (→ [ファイルベースルーティング](routing))― `<root>/src` があればページはその中だけ、
62
+ 無ければルート直下。設定は無く、検出されるだけです。1 ファイルのアプリは直下のままでよく、
63
+ 育ったら `src/` を作ってまとめて移せます。`server/` と `public/` は常にプロジェクトルート
64
+ 直下で、`src/server/` はスキャンされません。
65
+ - **`styles.css` はページと同じ側から読まれます** ― `src/` があれば `src/styles.css`。
66
+ - **`vantage add page` / `add ui` / `add block` の書き込み先**もページ探索ルート基準になりました
67
+ (`src/reports/index.tsx`・`src/components/ui/data-table.tsx`)。
68
+ - **クイックモードにページファイルを渡したときの root** が、そのファイルから上に辿って最初に
69
+ `package.json` があるディレクトリになりました ― `vantage ./demo/src/index.tsx` の root は
70
+ `./demo` です(これまでは親ディレクトリ固定で `./demo/src` になっていました)。
71
+
72
+ ### 追加
73
+
74
+ - **`SRC_DIR_SPLIT`(エラー)** ― `src/` があるのにルート直下にページや `styles.css` が残って
75
+ いる、または `src/server/` がある場合に指摘します。いずれも「置いたのに動かない」形の事故に
76
+ なるため、警告ではなくエラーです。
77
+ - **`SUSPICIOUS_ROUTE_DIR`(警告)** ― `pages/`・`app/`・`utils/` のような足場に見えるディレクトリ
78
+ から URL が生まれたときに知らせます(`pages/report.tsx` → `/pages/report`)。ページ走査は除外
79
+ リスト方式なので、リストに無い名前は黙って URL になります。走査自体は止めないので、意図して
80
+ その URL を作っている場合は無視できます。
81
+ - 同梱の `AGENTS.md` に「ディレクトリ構造」の節が入り、Skill(`vantage-app` /
82
+ `vantage-add-feature`)も追随しました。配置済みの `AGENTS.md` は `vantage upgrade` で
83
+ 同期されます。
84
+
11
85
  ## v0.2.3
12
86
 
13
87
  `vantage routes` を片側だけに絞れるようになり、各ルートの仕様も出せるようになりました。
@@ -26,8 +26,9 @@
26
26
  (ターミナルに `quick dev → <path>` と表示されます)。
27
27
 
28
28
  ```bash
29
- vantage ./demo # ディレクトリ → その中で dev を起動
30
- vantage ./demo/index.tsx # ページファイル → 親ディレクトリを root にして dev
29
+ vantage ./demo # ディレクトリ → その中で dev を起動
30
+ vantage ./demo/index.tsx # ページファイル → その `package.json` があるディレクトリで dev
31
+ vantage ./demo/src/index.tsx # src/ レイアウトでも同じ(root は ./demo)
31
32
  ```
32
33
 
33
34
  パスの解決ルール:
@@ -35,7 +36,7 @@ vantage ./demo/index.tsx # ページファイル → 親ディレクトリを
35
36
  | 渡したパス | root になるもの |
36
37
  |---|---|
37
38
  | ディレクトリ | そのディレクトリ自身 |
38
- | `.tsx` / `.jsx` のページファイル | その親ディレクトリ |
39
+ | `.tsx` / `.jsx` のページファイル | そこから上に辿って最初に `package.json` があるディレクトリ(無ければ親ディレクトリ) |
39
40
  | 存在しないパス・その他 | 該当なし(`Unknown command` エラー) |
40
41
 
41
42
  `add`・`docs`・`search` を除く root スコープの各コマンドも、末尾に path positional を取れます。`dev` を明示しても
@@ -317,17 +318,46 @@ vantage build --api-base-url https://api.example.com
317
318
  このフラグは `.env` の `PUBLIC_API_BASE_URL` より優先されます。未指定なら空(同一オリジンの
318
319
  相対パス)。詳細は[ビルドとデプロイ](build-and-deploy)を参照してください。
319
320
 
321
+ ## `VANTAGE_PROFILE` — 遅いときに測る
322
+
323
+ どのコマンドでも `VANTAGE_PROFILE=1` を付けると、フェーズごとの所要時間が出ます。
324
+
325
+ ```bash
326
+ VANTAGE_PROFILE=1 vantage dev
327
+ ```
328
+
329
+ ```text
330
+ [vantage:profile] scan 1.6ms @0.146s
331
+ [vantage:profile] diagnostics 2.1ms @0.148s
332
+ [vantage:profile] generate 1.5ms @0.159s
333
+ [vantage:profile] vite:createServer 16.2ms @0.165s
334
+ [vantage:profile] vite:listen 41.3ms @0.206s
335
+ ```
336
+
337
+ 左が所要時間、右の `@` はプロセス開始からの経過です。`scan`(ルートの走査)・
338
+ `diagnostics`(静的診断)・`generate`(`.vantage/` の生成)・`vite:*`・`build:client` /
339
+ `build:server` が出ます。
340
+
341
+ > [!NOTE]
342
+ > 出力先は **stderr** です。stdout は汚さないので、`--json` と一緒に使っても JSON は壊れません。
343
+ >
344
+ > ```bash
345
+ > VANTAGE_PROFILE=1 vantage check --json > result.json
346
+ > ```
347
+
320
348
  ## 静的診断(`check`)
321
349
 
322
- `vantage check` が検出する診断は次の 6 種類です(エラー 5・警告 1)。
350
+ `vantage check` が検出する診断は次の 8 種類です(エラー 6・警告 2)。
323
351
 
324
352
  | コード | 深刻度 | 意味 |
325
353
  |---|---|---|
326
354
  | `FORBIDDEN_FILE` | エラー | 禁止された設定ファイルがルートに存在する |
355
+ | `SRC_DIR_SPLIT` | エラー | `src/` があるのに、ページ・`styles.css` がルート直下に残っている(または `src/server/`) |
327
356
  | `ROUTE_CONFLICT` | エラー | 2 つのファイルが同じルートに解決される |
328
357
  | `MISSING_DEFAULT_EXPORT` | エラー | ページに default export がない |
329
358
  | `INVALID_API_EXPORT` | エラー | API が有効な HTTP メソッドをエクスポートしていない |
330
359
  | `CLIENT_IMPORTS_SERVER` | エラー | クライアントが `server/` から import している |
360
+ | `SUSPICIOUS_ROUTE_DIR` | 警告 | `pages/`・`app/`・`utils/` など、足場に見えるディレクトリ名が URL に出ている |
331
361
  | `PUBLIC_ENV_MISUSE` | 警告 | クライアントが `PUBLIC_` 以外の env を読んでいる |
332
362
 
333
363
  いずれもユーザーコードを import・実行しません(純粋に静的な検査です)。