@squadbase/vantage 0.6.1 → 0.6.2-dev1.31accb1

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 (183) hide show
  1. package/dist/add-DY4AXANK.js +6 -0
  2. package/dist/add-DY4AXANK.js.map +1 -0
  3. package/dist/{build-O5TVNH4E.js → build-TVKFIVFQ.js} +8 -8
  4. package/dist/{build-O5TVNH4E.js.map → build-TVKFIVFQ.js.map} +1 -1
  5. package/dist/{check-WFBEDHDR.js → check-3KHZXZMQ.js} +6 -6
  6. package/dist/{check-WFBEDHDR.js.map → check-3KHZXZMQ.js.map} +1 -1
  7. package/dist/{chunk-PLST5Q7T.js → chunk-AG6RZ2RR.js} +1010 -23
  8. package/dist/chunk-AG6RZ2RR.js.map +1 -0
  9. package/dist/{chunk-KLEIVDUV.js → chunk-CEXAQQ5W.js} +150 -11
  10. package/dist/chunk-CEXAQQ5W.js.map +1 -0
  11. package/dist/{chunk-JGRMRXXZ.js → chunk-JKLLFVEU.js} +3 -3
  12. package/dist/{chunk-JGRMRXXZ.js.map → chunk-JKLLFVEU.js.map} +1 -1
  13. package/dist/{chunk-EP6JHXSR.js → chunk-LMUACBMA.js} +3 -3
  14. package/dist/{chunk-EP6JHXSR.js.map → chunk-LMUACBMA.js.map} +1 -1
  15. package/dist/{chunk-MXI3PZFT.js → chunk-OB6UBJXF.js} +156 -200
  16. package/dist/chunk-OB6UBJXF.js.map +1 -0
  17. package/dist/{chunk-BCE22JSM.js → chunk-P7W4LR3Z.js} +32 -13
  18. package/dist/chunk-P7W4LR3Z.js.map +1 -0
  19. package/dist/chunk-PXRX5PEC.js +54 -0
  20. package/dist/chunk-PXRX5PEC.js.map +1 -0
  21. package/dist/{chunk-3G43C6OL.js → chunk-QI3XQKHS.js} +39 -3
  22. package/dist/chunk-QI3XQKHS.js.map +1 -0
  23. package/dist/{chunk-QDZA5JSL.js → chunk-U2M6HGKQ.js} +3 -3
  24. package/dist/{chunk-QDZA5JSL.js.map → chunk-U2M6HGKQ.js.map} +1 -1
  25. package/dist/{chunk-T3FLAGI6.js → chunk-VA776YE5.js} +3 -3
  26. package/dist/{chunk-T3FLAGI6.js.map → chunk-VA776YE5.js.map} +1 -1
  27. package/dist/cli.js +14 -11
  28. package/dist/cli.js.map +1 -1
  29. package/dist/components/index.d.ts +223 -1
  30. package/dist/components/index.js +3 -2
  31. package/dist/{dev-NZRLOQCL.js → dev-GDKATCC7.js} +22 -11
  32. package/dist/dev-GDKATCC7.js.map +1 -0
  33. package/dist/doc/index.d.ts +4 -0
  34. package/dist/doc/index.js +107 -11
  35. package/dist/doc/index.js.map +1 -1
  36. package/dist/{docs-ZGDJUHJI.js → docs-EJJ3BECT.js} +3 -3
  37. package/dist/{docs-ZGDJUHJI.js.map → docs-EJJ3BECT.js.map} +1 -1
  38. package/dist/{doctor-VFKEMR54.js → doctor-WQXPXP6K.js} +7 -7
  39. package/dist/doctor-WQXPXP6K.js.map +1 -0
  40. package/dist/{preview-QDCIVVSR.js → preview-OGMCNQUO.js} +12 -4
  41. package/dist/preview-OGMCNQUO.js.map +1 -0
  42. package/dist/{routes-RHP5FVGD.js → routes-MWBWWOJ2.js} +5 -5
  43. package/dist/{routes-RHP5FVGD.js.map → routes-MWBWWOJ2.js.map} +1 -1
  44. package/dist/{search-RFBELGY7.js → search-6Y422SV6.js} +3 -3
  45. package/dist/{search-RFBELGY7.js.map → search-6Y422SV6.js.map} +1 -1
  46. package/dist/slide/index.js +61 -15
  47. package/dist/slide/index.js.map +1 -1
  48. package/dist/table/index.js +7 -5
  49. package/dist/table/index.js.map +1 -1
  50. package/dist/ui/index.d.ts +140 -10
  51. package/dist/ui/index.js +1406 -63
  52. package/dist/ui/index.js.map +1 -1
  53. package/dist/{upgrade-GF2P67M6.js → upgrade-HCANX4GQ.js} +6 -6
  54. package/dist/{upgrade-GF2P67M6.js.map → upgrade-HCANX4GQ.js.map} +1 -1
  55. package/dist/vite/index.js +3 -3
  56. package/docs/en/changelog.md +24 -0
  57. package/docs/en/cli-reference.md +30 -0
  58. package/docs/en/parts/page-shell.md +1 -1
  59. package/docs/en/routing.md +4 -2
  60. package/docs/index.json +291 -61
  61. package/docs/ja/changelog.md +50 -0
  62. package/docs/ja/cli-reference.md +29 -0
  63. package/docs/ja/components.md +33 -89
  64. package/docs/ja/page-types/csv.md +83 -0
  65. package/docs/ja/page-types/doc.md +83 -0
  66. package/docs/ja/page-types/excel.md +82 -0
  67. package/docs/ja/page-types/slide.md +132 -0
  68. package/docs/ja/page-types.md +47 -0
  69. package/docs/ja/parts/area-chart.md +61 -0
  70. package/docs/ja/parts/bar-chart.md +69 -0
  71. package/docs/ja/parts/bar-list.md +35 -0
  72. package/docs/ja/parts/category-bar.md +36 -0
  73. package/docs/ja/parts/donut-chart.md +47 -0
  74. package/docs/ja/parts/echart.md +3 -0
  75. package/docs/ja/parts/line-chart.md +58 -0
  76. package/docs/ja/parts/page-shell.md +1 -1
  77. package/docs/ja/parts/progress-circle.md +34 -0
  78. package/docs/ja/parts/sparkline.md +1 -1
  79. package/docs/ja/parts/tracker.md +32 -0
  80. package/docs/ja/routing.md +8 -84
  81. package/docs/ja/ui/alert-dialog.md +41 -0
  82. package/docs/ja/ui/avatar.md +31 -0
  83. package/docs/ja/ui/combobox.md +74 -0
  84. package/docs/ja/ui/drawer.md +41 -0
  85. package/docs/ja/ui/field.md +42 -0
  86. package/docs/ja/ui/hover-card.md +21 -0
  87. package/docs/ja/ui/kbd.md +16 -0
  88. package/docs/ja/ui/pagination.md +36 -0
  89. package/docs/ja/ui/radio-group.md +21 -0
  90. package/docs/ja/ui/toast.md +46 -0
  91. package/docs/ja/ui-and-theming.md +14 -7
  92. package/package.json +18 -12
  93. package/registry/ui/accordion.tsx +74 -0
  94. package/registry/ui/alert-dialog.tsx +189 -0
  95. package/registry/ui/alert.tsx +78 -0
  96. package/registry/ui/app-shell.tsx +281 -0
  97. package/registry/ui/area-chart.tsx +1015 -0
  98. package/registry/ui/avatar.tsx +110 -0
  99. package/registry/ui/badge.tsx +54 -0
  100. package/registry/ui/bar-chart.tsx +1013 -0
  101. package/registry/ui/bar-list.tsx +302 -0
  102. package/registry/ui/breadcrumb.tsx +126 -0
  103. package/registry/ui/button.tsx +60 -0
  104. package/registry/ui/calendar.tsx +221 -0
  105. package/registry/ui/card.tsx +105 -0
  106. package/registry/ui/category-bar.tsx +281 -0
  107. package/registry/ui/checkbox.tsx +28 -0
  108. package/registry/ui/collapsible.tsx +21 -0
  109. package/registry/ui/combobox.tsx +310 -0
  110. package/registry/ui/command.tsx +196 -0
  111. package/registry/ui/dashboard-card.tsx +174 -0
  112. package/registry/ui/data-table.tsx +16 -91
  113. package/registry/ui/date-range-picker.tsx +209 -0
  114. package/registry/ui/dialog.tsx +159 -0
  115. package/registry/ui/donut-chart.tsx +1004 -0
  116. package/registry/ui/drawer.tsx +229 -0
  117. package/registry/ui/dropdown-menu.tsx +272 -0
  118. package/registry/ui/echart.tsx +486 -0
  119. package/registry/ui/field.tsx +240 -0
  120. package/registry/ui/filter-bar.tsx +365 -0
  121. package/registry/ui/funnel-steps.tsx +274 -0
  122. package/registry/ui/hover-card.tsx +52 -0
  123. package/registry/ui/input-group.tsx +158 -0
  124. package/registry/ui/input.tsx +22 -0
  125. package/registry/ui/kbd.tsx +28 -0
  126. package/registry/ui/label.tsx +20 -0
  127. package/registry/ui/line-chart.tsx +1007 -0
  128. package/registry/ui/metric-value.tsx +54 -0
  129. package/registry/ui/multi-select.tsx +226 -0
  130. package/registry/ui/page-shell.tsx +227 -0
  131. package/registry/ui/pagination.tsx +138 -0
  132. package/registry/ui/placeholder.tsx +30 -0
  133. package/registry/ui/popover.tsx +90 -0
  134. package/registry/ui/progress-circle.tsx +272 -0
  135. package/registry/ui/progress.tsx +83 -0
  136. package/registry/ui/radio-group.tsx +39 -0
  137. package/registry/ui/scroll-area.tsx +55 -0
  138. package/registry/ui/searchable-select.tsx +209 -0
  139. package/registry/ui/section-header.tsx +41 -0
  140. package/registry/ui/segmented-control.tsx +71 -0
  141. package/registry/ui/select.tsx +253 -0
  142. package/registry/ui/separator.tsx +25 -0
  143. package/registry/ui/sheet.tsx +137 -0
  144. package/registry/ui/sidebar.tsx +723 -0
  145. package/registry/ui/skeleton.tsx +15 -0
  146. package/registry/ui/slider.tsx +54 -0
  147. package/registry/ui/sparkline.tsx +155 -0
  148. package/registry/ui/spinner.tsx +12 -0
  149. package/registry/ui/states.tsx +61 -0
  150. package/registry/ui/status-badge.tsx +79 -0
  151. package/registry/ui/switch.tsx +32 -0
  152. package/registry/ui/table.tsx +116 -0
  153. package/registry/ui/tabs.tsx +82 -0
  154. package/registry/ui/textarea.tsx +20 -0
  155. package/registry/ui/toast.tsx +250 -0
  156. package/registry/ui/toggle-group.tsx +89 -0
  157. package/registry/ui/toggle.tsx +45 -0
  158. package/registry/ui/tooltip.tsx +66 -0
  159. package/registry/ui/tracker.tsx +236 -0
  160. package/registry/ui/trend-indicator.tsx +62 -0
  161. package/skills/vantage-add-feature/SKILL.md +9 -7
  162. package/skills/vantage-design/SKILL.md +3 -1
  163. package/skills/vantage-design/references/format.md +1 -1
  164. package/skills/vantage-pitfalls/SKILL.md +5 -1
  165. package/skills/vantage-slide/SKILL.md +17 -0
  166. package/templates/AGENTS.md +10 -1
  167. package/templates/agents/api.md +29 -0
  168. package/templates/agents/csv.md +2 -1
  169. package/templates/agents/doc.md +6 -3
  170. package/templates/agents/page.md +22 -8
  171. package/templates/agents/slide.md +13 -1
  172. package/templates/agents/xlsx.md +2 -1
  173. package/theme.css +51 -1
  174. package/dist/add-EISGSZAH.js +0 -6
  175. package/dist/add-EISGSZAH.js.map +0 -1
  176. package/dist/chunk-3G43C6OL.js.map +0 -1
  177. package/dist/chunk-BCE22JSM.js.map +0 -1
  178. package/dist/chunk-KLEIVDUV.js.map +0 -1
  179. package/dist/chunk-MXI3PZFT.js.map +0 -1
  180. package/dist/chunk-PLST5Q7T.js.map +0 -1
  181. package/dist/dev-NZRLOQCL.js.map +0 -1
  182. package/dist/doctor-VFKEMR54.js.map +0 -1
  183. package/dist/preview-QDCIVVSR.js.map +0 -1
@@ -13,6 +13,13 @@ interface PageShellProps extends HTMLAttributes<HTMLDivElement> {
13
13
  declare const PageShell: React.ForwardRefExoticComponent<PageShellProps & React.RefAttributes<HTMLDivElement>>;
14
14
  interface PageShellHeaderProps extends HTMLAttributes<HTMLDivElement> {
15
15
  }
16
+ /**
17
+ * A wrapping flex row, not a two-column grid: when the heading cannot keep its
18
+ * 20rem basis next to `PageShellHeaderEnd`, the end block drops below it. A
19
+ * `1fr auto` grid would instead hand the heading whatever the end block leaves,
20
+ * and a CJK title — breakable between any two characters — collapses into a
21
+ * one-character column.
22
+ */
16
23
  declare const PageShellHeader: React.ForwardRefExoticComponent<PageShellHeaderProps & React.RefAttributes<HTMLDivElement>>;
17
24
  interface PageShellHeadingProps extends HTMLAttributes<HTMLDivElement> {
18
25
  }
@@ -155,6 +162,23 @@ interface SelectOptionGroup {
155
162
  type SelectOptions = SelectOption[] | SelectOptionGroup[];
156
163
  declare function isGroupedOptions(options: SelectOptions): options is SelectOptionGroup[];
157
164
  declare function flattenOptions(options: SelectOptions): SelectOption[];
165
+ /**
166
+ * A chart colour: one of the theme's series tokens (`"chart-1"`〜`"chart-5"`,
167
+ * which follow light/dark) or any CSS colour (`"#16a34a"`, `"var(--destructive)"`).
168
+ * Not a Tailwind class — the ECharts-based charts paint on a canvas.
169
+ */
170
+ type ChartColor = "chart-1" | "chart-2" | "chart-3" | "chart-4" | "chart-5" | (string & {});
171
+ /** Formats a value for tooltips, axes and labels (e.g. `(v) => \`¥${v.toLocaleString()}\``). */
172
+ type ValueFormatter = (value: number) => string;
173
+ /** What a typed chart reports through `onValueChange`; `null` when the selection is cleared. */
174
+ type ChartEventPayload = {
175
+ /** What was clicked: a bar, a line/area point, or a donut slice. */
176
+ eventType: "bar" | "dot" | "slice";
177
+ /** The series (`categories` entry) or slice name that was clicked. */
178
+ categoryClicked: string;
179
+ /** The clicked row of `data`, spread in. */
180
+ [key: string]: unknown;
181
+ } | null;
158
182
 
159
183
  interface AppShellSidebarProps {
160
184
  variant?: "sidebar";
@@ -278,6 +302,204 @@ interface EChartProps {
278
302
  }
279
303
  declare const EChart: React.ForwardRefExoticComponent<EChartProps & React.RefAttributes<HTMLDivElement>>;
280
304
 
305
+ type CartesianStackType = "default" | "stacked" | "percent";
306
+ type CartesianCurveType = "linear" | "smooth" | "step";
307
+ type AreaFill = "gradient" | "solid" | "none";
308
+ type BarLayout = "horizontal" | "vertical";
309
+ /** Props every cartesian typed chart (Area / Bar / Line) shares. */
310
+ interface CartesianChartBaseProps {
311
+ /** 行の配列。1 行 = x 軸の 1 点。数値の列は number か数値文字列(SQL の DECIMAL など)。 */
312
+ data: Record<string, unknown>[];
313
+ /** x 軸(カテゴリ軸)に使う列名。 */
314
+ index: string;
315
+ /** 系列として描く列名。並び順が凡例と配色の順になる。 */
316
+ categories: string[];
317
+ /** 系列色。`"chart-1"`〜`"chart-5"` か CSS カラー。省略時はテーマのトークン順。足りなければ繰り返す。 */
318
+ colors?: ChartColor[];
319
+ /** 軸目盛りとツールチップの数値の書式。 */
320
+ valueFormatter?: ValueFormatter;
321
+ /** 凡例を出す。既定 `true`。 */
322
+ showLegend?: boolean;
323
+ /** ホバー時のツールチップを出す。既定 `true`。 */
324
+ showTooltip?: boolean;
325
+ /** 値軸の目盛り線を出す。既定 `true`。 */
326
+ showGridLines?: boolean;
327
+ showXAxis?: boolean;
328
+ showYAxis?: boolean;
329
+ /** x 軸のラベルを最初と最後だけにする。 */
330
+ startEndOnly?: boolean;
331
+ /** y 軸ラベルの幅(px)。並べた複数グラフのプロット領域を揃えたいときに固定する。 */
332
+ yAxisWidth?: number;
333
+ minValue?: number;
334
+ maxValue?: number;
335
+ /** 値軸を 0 からではなくデータの範囲に合わせる。 */
336
+ autoMinValue?: boolean;
337
+ /** `false` で値軸の目盛りを整数に限る。 */
338
+ allowDecimals?: boolean;
339
+ xAxisLabel?: string;
340
+ yAxisLabel?: string;
341
+ /**
342
+ * 点(棒)のクリックで呼ばれる。クリックした行に `eventType` / `categoryClicked` を
343
+ * 足して渡し、同じ点をもう一度クリックすると `null`。渡すと選択以外が薄くなる。
344
+ */
345
+ onValueChange?: (value: ChartEventPayload) => void;
346
+ /** 高さ。数値は px。省略時は `h-80`(320px)で、`className` の高さクラスが勝つ。 */
347
+ height?: string | number;
348
+ loading?: boolean;
349
+ ariaLabel?: string;
350
+ className?: string;
351
+ }
352
+ type DonutVariant = "donut" | "pie";
353
+
354
+ interface AreaChartProps extends CartesianChartBaseProps {
355
+ /** `"stacked"` は積み上げ、`"percent"` は各点の合計を 100% にした積み上げ。既定 `"default"`。 */
356
+ type?: CartesianStackType;
357
+ /** 線の形。既定 `"linear"`。 */
358
+ curveType?: CartesianCurveType;
359
+ /** 面の塗り。既定 `"gradient"`。 */
360
+ fill?: AreaFill;
361
+ /** 値の欠けた点(`null` など)をまたいで線をつなぐ。既定 `false`。 */
362
+ connectNulls?: boolean;
363
+ }
364
+ declare const AreaChart: React.ForwardRefExoticComponent<AreaChartProps & React.RefAttributes<HTMLDivElement>>;
365
+
366
+ interface BarChartProps extends CartesianChartBaseProps {
367
+ /** `"stacked"` は積み上げ、`"percent"` は各カテゴリの合計を 100% にした積み上げ。既定 `"default"`(横並び)。 */
368
+ type?: CartesianStackType;
369
+ /**
370
+ * 棒の向き。既定 `"horizontal"`(カテゴリが横に並ぶ縦棒)。`"vertical"` はカテゴリを
371
+ * 縦に並べた横棒で、ラベルの長いランキングに向く(先頭の行が一番上)。
372
+ */
373
+ layout?: BarLayout;
374
+ /** カテゴリ間の隙間(`"20%"` や px)。省略時は ECharts の既定。 */
375
+ barCategoryGap?: string | number;
376
+ }
377
+ declare const BarChart: React.ForwardRefExoticComponent<BarChartProps & React.RefAttributes<HTMLDivElement>>;
378
+
379
+ interface LineChartProps extends CartesianChartBaseProps {
380
+ /** 線の形。既定 `"linear"`。 */
381
+ curveType?: CartesianCurveType;
382
+ /** 値の欠けた点(`null` など)をまたいで線をつなぐ。既定 `false`。 */
383
+ connectNulls?: boolean;
384
+ }
385
+ declare const LineChart: React.ForwardRefExoticComponent<LineChartProps & React.RefAttributes<HTMLDivElement>>;
386
+
387
+ interface DonutChartProps {
388
+ /** 行の配列。1 行 = 1 切片。 */
389
+ data: Record<string, unknown>[];
390
+ /** 切片の名前に使う列名。 */
391
+ category: string;
392
+ /** 切片の大きさに使う列名(number か数値文字列)。0 以下と欠損は 0 扱い。 */
393
+ value: string;
394
+ /** 切片の色(行の順)。`"chart-1"`〜`"chart-5"` か CSS カラー。省略時はトークン順で、足りなければ繰り返す。 */
395
+ colors?: ChartColor[];
396
+ /** `"donut"`(中央に穴とラベル)か `"pie"`。既定 `"donut"`。 */
397
+ variant?: DonutVariant;
398
+ /** ツールチップと中央ラベルの数値の書式。 */
399
+ valueFormatter?: ValueFormatter;
400
+ /** 中央ラベル。省略時は合計を `valueFormatter` で書いたもの。donut のみ。 */
401
+ label?: ReactNode;
402
+ /** 中央ラベルを出す。既定 `true`(donut のみ)。 */
403
+ showLabel?: boolean;
404
+ showTooltip?: boolean;
405
+ /** 切片のクリックで呼ばれる。同じ切片をもう一度クリックすると `null`。渡すと選択以外が薄くなる。 */
406
+ onValueChange?: (value: ChartEventPayload) => void;
407
+ loading?: boolean;
408
+ ariaLabel?: string;
409
+ /** 外枠のクラス。既定の大きさは `size-40`(160px 四方)。 */
410
+ className?: string;
411
+ }
412
+ declare const DonutChart: React.ForwardRefExoticComponent<DonutChartProps & React.RefAttributes<HTMLDivElement>>;
413
+
414
+ /**
415
+ * Chart helpers shared by the typed charts — colour tokens, number handling and
416
+ * the layout maths of the Tailwind/SVG charts (BarList, CategoryBar,
417
+ * ProgressCircle, Tracker). Pure and DOM-free, so it can be unit-tested; kept
418
+ * internal and inlined into each `vantage add ui` copy.
419
+ */
420
+
421
+ type BarListSortOrder = "ascending" | "descending" | "none";
422
+
423
+ interface BarListItem {
424
+ /** React の key。省略時は `name`。 */
425
+ key?: string;
426
+ /** 行のラベル(バーの上に出る)。 */
427
+ name: string;
428
+ value: number;
429
+ /** 渡すとラベルがリンクになる。 */
430
+ href?: string;
431
+ /** この行だけ色を変える。省略時は `color`。 */
432
+ color?: ChartColor;
433
+ }
434
+ interface BarListProps extends Omit<ComponentProps<"div">, "children"> {
435
+ data: BarListItem[];
436
+ /** 右端の数値の書式。 */
437
+ valueFormatter?: ValueFormatter;
438
+ /** 並べ順。既定 `"descending"`(大きい順)。`"none"` は渡した順。 */
439
+ sortOrder?: BarListSortOrder;
440
+ /** バーの色。`"chart-1"`〜`"chart-5"` か CSS カラー。既定 `"chart-1"`(淡く塗る)。 */
441
+ color?: ChartColor;
442
+ /** マウント時にバーを伸ばす。 */
443
+ showAnimation?: boolean;
444
+ /** 渡すと行がボタンになり、クリックした行を受け取る。 */
445
+ onValueChange?: (item: BarListItem) => void;
446
+ }
447
+ declare const BarList: React.ForwardRefExoticComponent<Omit<BarListProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
448
+
449
+ interface CategoryBarMarker {
450
+ /** マーカーの位置(`values` の合計と同じ尺度)。 */
451
+ value: number;
452
+ /** ホバーで出す説明。 */
453
+ tooltip?: string;
454
+ /** 位置の変化をアニメーションする。 */
455
+ showAnimation?: boolean;
456
+ }
457
+ interface CategoryBarProps extends Omit<ComponentProps<"div">, "children"> {
458
+ /** 各区間の幅(相対値)。合計が 100 である必要はない。負の値は 0 扱い。 */
459
+ values: number[];
460
+ /** 区間の色(順に対応)。`"chart-1"`〜`"chart-5"` か CSS カラー。省略時はトークン順。 */
461
+ colors?: ChartColor[];
462
+ marker?: CategoryBarMarker;
463
+ /** バーの上に区切りの累計値を出す。既定 `true`。 */
464
+ showLabels?: boolean;
465
+ /** 区切りの数値の書式。 */
466
+ valueFormatter?: ValueFormatter;
467
+ }
468
+ declare const CategoryBar: React.ForwardRefExoticComponent<Omit<CategoryBarProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
469
+
470
+ interface ProgressCircleProps extends ComponentProps<"div"> {
471
+ /** 現在値。`0`〜`max` に丸める。 */
472
+ value?: number;
473
+ /** 満タンの値。既定 `100`。 */
474
+ max?: number;
475
+ /** 外側の半径(px)。既定 `32`(64px 四方)。 */
476
+ radius?: number;
477
+ /** 線の太さ(px)。既定 `6`。 */
478
+ strokeWidth?: number;
479
+ /** 色。`"chart-1"`〜`"chart-5"` か CSS カラー。既定 `"chart-1"`。地のリングは同じ色を淡くしたもの。 */
480
+ color?: ChartColor;
481
+ /** マウント時と値の変化をアニメーションする。既定 `true`。 */
482
+ showAnimation?: boolean;
483
+ }
484
+ declare const ProgressCircle: React.ForwardRefExoticComponent<Omit<ProgressCircleProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
485
+
486
+ interface TrackerBlock {
487
+ /** React の key。省略時は位置。 */
488
+ key?: string | number;
489
+ /** ブロックの色。`"chart-1"`〜`"chart-5"` か CSS カラー(`"var(--destructive)"` など)。省略時は `defaultColor`。 */
490
+ color?: ChartColor;
491
+ /** ホバーで出す説明(例: `"10/12 稼働率 99.2%"`)。 */
492
+ tooltip?: string;
493
+ }
494
+ interface TrackerProps extends Omit<ComponentProps<"div">, "children"> {
495
+ data: TrackerBlock[];
496
+ /** `color` の無いブロックの色。既定は muted-foreground を淡くした灰色。 */
497
+ defaultColor?: ChartColor;
498
+ /** ホバー中のブロックを薄くする。既定 `true`。 */
499
+ hoverEffect?: boolean;
500
+ }
501
+ declare const Tracker: React.ForwardRefExoticComponent<Omit<TrackerProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
502
+
281
503
  interface FunnelStep {
282
504
  /** ステップのラベル(例: "ページビュー") */
283
505
  label: string;
@@ -578,4 +800,4 @@ interface PlaceholderProps extends HTMLAttributes<HTMLSpanElement> {
578
800
  }
579
801
  declare const Placeholder: React.ForwardRefExoticComponent<PlaceholderProps & React.RefAttributes<HTMLSpanElement>>;
580
802
 
581
- export { AppShell, type AppShellHeaderProps, type AppShellProps, type AppShellSidebarProps, DashboardCard, DashboardCardAction, type DashboardCardActionProps, DashboardCardContent, type DashboardCardContentProps, DashboardCardDescription, type DashboardCardDescriptionProps, DashboardCardFooter, type DashboardCardFooterProps, DashboardCardHeader, type DashboardCardHeaderProps, DashboardCardPreset, type DashboardCardPresetProps, type DashboardCardProps, DashboardCardSkeleton, type DashboardCardSkeletonProps, DashboardCardTitle, type DashboardCardTitleProps, DataTable, DataTableColumnVisibility, type DataTableColumnVisibilityProps, DataTableContent, type DataTableContentProps, DataTablePagination, type DataTablePaginationProps, DataTablePreset, type DataTablePresetProps, type DataTableProps, DataTableToolbar, type DataTableToolbarProps, type DateRange, DateRangePicker, type DateRangePickerProps, EChart, type EChartProps, FilterBar, FilterBarActiveChips, type FilterBarActiveChipsProps, FilterBarClearButton, type FilterBarClearButtonProps, FilterBarMultiSelect, type FilterBarMultiSelectProps, FilterBarPreset, type FilterBarPresetProps, type FilterBarProps, FilterBarSelect, type FilterBarSelectProps, type FilterConfig, type FilterOption, type FilterType, type FilterValues, type FunnelStep, FunnelSteps, type FunnelStepsProps, type MetricItem, MetricUnit, type MetricUnitProps, MetricValue, type MetricValueProps, type MetricVariant, MultiSelect, type MultiSelectProps, type NavGroup, type NavItem, PageShell, PageShellActions, type PageShellActionsProps, PageShellContent, type PageShellContentProps, PageShellDescription, type PageShellDescriptionProps, PageShellHeader, PageShellHeaderEnd, type PageShellHeaderEndProps, type PageShellHeaderProps, PageShellHeading, type PageShellHeadingProps, PageShellMeta, type PageShellMetaProps, type PageShellProps, PageShellSummary, PageShellSummaryCard, type PageShellSummaryCardProps, type PageShellSummaryProps, PageShellTitle, type PageShellTitleProps, Placeholder, type PlaceholderProps, type PresetItem, SearchableSelect, type SearchableSelectProps, SectionHeader, type SectionHeaderProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, type SelectOption, type SelectOptionGroup, type SelectOptions, Sparkline, type SparklineDataPoint, type SparklineProps, type SparklineVariant, StatusBadge, type StatusBadgeProps, type TrendDirection, TrendIndicator, type TrendIndicatorProps, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable };
803
+ export { AppShell, type AppShellHeaderProps, type AppShellProps, type AppShellSidebarProps, AreaChart, type AreaChartProps, BarChart, type BarChartProps, BarList, type BarListItem, type BarListProps, CategoryBar, type CategoryBarMarker, type CategoryBarProps, type ChartColor, type ChartEventPayload, DashboardCard, DashboardCardAction, type DashboardCardActionProps, DashboardCardContent, type DashboardCardContentProps, DashboardCardDescription, type DashboardCardDescriptionProps, DashboardCardFooter, type DashboardCardFooterProps, DashboardCardHeader, type DashboardCardHeaderProps, DashboardCardPreset, type DashboardCardPresetProps, type DashboardCardProps, DashboardCardSkeleton, type DashboardCardSkeletonProps, DashboardCardTitle, type DashboardCardTitleProps, DataTable, DataTableColumnVisibility, type DataTableColumnVisibilityProps, DataTableContent, type DataTableContentProps, DataTablePagination, type DataTablePaginationProps, DataTablePreset, type DataTablePresetProps, type DataTableProps, DataTableToolbar, type DataTableToolbarProps, type DateRange, DateRangePicker, type DateRangePickerProps, DonutChart, type DonutChartProps, EChart, type EChartProps, FilterBar, FilterBarActiveChips, type FilterBarActiveChipsProps, FilterBarClearButton, type FilterBarClearButtonProps, FilterBarMultiSelect, type FilterBarMultiSelectProps, FilterBarPreset, type FilterBarPresetProps, type FilterBarProps, FilterBarSelect, type FilterBarSelectProps, type FilterConfig, type FilterOption, type FilterType, type FilterValues, type FunnelStep, FunnelSteps, type FunnelStepsProps, LineChart, type LineChartProps, type MetricItem, MetricUnit, type MetricUnitProps, MetricValue, type MetricValueProps, type MetricVariant, MultiSelect, type MultiSelectProps, type NavGroup, type NavItem, PageShell, PageShellActions, type PageShellActionsProps, PageShellContent, type PageShellContentProps, PageShellDescription, type PageShellDescriptionProps, PageShellHeader, PageShellHeaderEnd, type PageShellHeaderEndProps, type PageShellHeaderProps, PageShellHeading, type PageShellHeadingProps, PageShellMeta, type PageShellMetaProps, type PageShellProps, PageShellSummary, PageShellSummaryCard, type PageShellSummaryCardProps, type PageShellSummaryProps, PageShellTitle, type PageShellTitleProps, Placeholder, type PlaceholderProps, type PresetItem, ProgressCircle, type ProgressCircleProps, SearchableSelect, type SearchableSelectProps, SectionHeader, type SectionHeaderProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, type SelectOption, type SelectOptionGroup, type SelectOptions, Sparkline, type SparklineDataPoint, type SparklineProps, type SparklineVariant, StatusBadge, type StatusBadgeProps, Tracker, type TrackerBlock, type TrackerProps, type TrendDirection, TrendIndicator, type TrendIndicatorProps, type ValueFormatter, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable };
@@ -1,5 +1,6 @@
1
- export { AppShell, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, EChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, TrendIndicator, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable } from '../chunk-PLST5Q7T.js';
2
- import '../chunk-MXI3PZFT.js';
1
+ export { AppShell, AreaChart, BarChart, BarList, CategoryBar, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, DonutChart, EChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, LineChart, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, ProgressCircle, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, Tracker, TrendIndicator, defaultPresets, flattenOptions, funnelStepsVariants, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, useDataTable } from '../chunk-AG6RZ2RR.js';
2
+ import '../chunk-OB6UBJXF.js';
3
+ import '../chunk-PXRX5PEC.js';
3
4
  import '../chunk-A2UUGASH.js';
4
5
  //# sourceMappingURL=index.js.map
5
6
  //# sourceMappingURL=index.js.map
@@ -1,12 +1,12 @@
1
- import { runDiagnostics } from './chunk-BCE22JSM.js';
2
- import './chunk-JGRMRXXZ.js';
3
- import { vantagePlugin } from './chunk-T3FLAGI6.js';
4
- import './chunk-EP6JHXSR.js';
5
- import './chunk-KLEIVDUV.js';
1
+ import { runDiagnostics } from './chunk-P7W4LR3Z.js';
2
+ import './chunk-JKLLFVEU.js';
3
+ import { vantagePlugin } from './chunk-VA776YE5.js';
4
+ import './chunk-LMUACBMA.js';
5
+ import './chunk-CEXAQQ5W.js';
6
6
  import { scanProject, timedAsync } from './chunk-ZVANIULZ.js';
7
7
  import './chunk-46QI6GFC.js';
8
8
  import './chunk-B7LLBNLV.js';
9
- import { printDiagnostics, log, applyApiBaseUrlFlag, resolvePortOptions, resolveHmrOverlay, reportPortInUse } from './chunk-3G43C6OL.js';
9
+ import { printDiagnostics, log, applyApiBaseUrlFlag, resolvePortOptions, resolveHostOptions, resolveHmrOverlay, reportPortInUse } from './chunk-QI3XQKHS.js';
10
10
  import './chunk-C2CX6GLX.js';
11
11
  import { loadEnv, createServer } from 'vite';
12
12
 
@@ -28,6 +28,11 @@ async function dev(root, args) {
28
28
  return 1;
29
29
  }
30
30
  const { port, strictPort } = ports;
31
+ const hosts = resolveHostOptions(args.flags);
32
+ if (!hosts.ok) {
33
+ log.error(hosts.error);
34
+ return 1;
35
+ }
31
36
  const overlay = resolveHmrOverlay(args.flags);
32
37
  const server = await timedAsync(
33
38
  "vite:createServer",
@@ -38,9 +43,15 @@ async function dev(root, args) {
38
43
  // The model was just scanned for diagnostics; hand it over so the plugin
39
44
  // does not walk the project again.
40
45
  plugins: [vantagePlugin({ root, env, model })],
41
- // `hmr` is left alone unless the overlay is being turned off, so Vite's
42
- // own defaults (host, port, protocol) keep applying.
43
- server: { port, strictPort, ...overlay ? {} : { hmr: { overlay: false } } },
46
+ // `host` / `allowedHosts` are only present when asked for, and `hmr` is
47
+ // left alone unless the overlay is being turned off, so Vite's own
48
+ // defaults (host, port, protocol) keep applying.
49
+ server: {
50
+ port,
51
+ strictPort,
52
+ ...hosts.options,
53
+ ...overlay ? {} : { hmr: { overlay: false } }
54
+ },
44
55
  clearScreen: false
45
56
  })
46
57
  );
@@ -66,5 +77,5 @@ async function dev(root, args) {
66
77
  }
67
78
 
68
79
  export { dev };
69
- //# sourceMappingURL=dev-NZRLOQCL.js.map
70
- //# sourceMappingURL=dev-NZRLOQCL.js.map
80
+ //# sourceMappingURL=dev-GDKATCC7.js.map
81
+ //# sourceMappingURL=dev-GDKATCC7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/dev.ts"],"names":[],"mappings":"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","file":"dev-GDKATCC7.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 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 })],\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"]}
@@ -33,6 +33,10 @@ interface DocumentProps extends HTMLAttributes<HTMLElement> {
33
33
  * the `[data-slot="document"]` rules in theme.css, so the page body needs no
34
34
  * classes. Those rules sit in `@layer components`, below Tailwind utilities, so
35
35
  * a `className` on any element still wins.
36
+ *
37
+ * It also carries its own way out: a button that opens the print dialog, where
38
+ * "Save as PDF" is the download. The print rules in theme.css leave only the
39
+ * document on paper.
36
40
  */
37
41
  declare const Document: React.ForwardRefExoticComponent<DocumentProps & React.RefAttributes<HTMLElement>>;
38
42
 
package/dist/doc/index.js CHANGED
@@ -1,8 +1,80 @@
1
- import { forwardRef } from 'react';
2
- import { jsx } from 'react/jsx-runtime';
1
+ import { Button } from '../chunk-PXRX5PEC.js';
2
+ import '../chunk-A2UUGASH.js';
3
+ import { forwardRef, useEffect } from 'react';
4
+ import { PrinterIcon } from 'lucide-react';
5
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
6
 
4
7
  // @squadbase/vantage — generated build. Do not edit.
5
8
 
9
+ // src/doc/print.ts
10
+ var DARK_CLASS = "dark";
11
+ var THEME_ATTR = "data-theme";
12
+ var restore = null;
13
+ function forceLight() {
14
+ if (restore) return;
15
+ const undo = [];
16
+ for (const el of [document.documentElement, document.body]) {
17
+ if (!el) continue;
18
+ if (el.classList.contains(DARK_CLASS)) {
19
+ el.classList.remove(DARK_CLASS);
20
+ undo.push(() => el.classList.add(DARK_CLASS));
21
+ }
22
+ if (el.getAttribute(THEME_ATTR) === "dark") {
23
+ el.setAttribute(THEME_ATTR, "light");
24
+ undo.push(() => el.setAttribute(THEME_ATTR, "dark"));
25
+ }
26
+ }
27
+ restore = () => {
28
+ for (const fn of undo) fn();
29
+ };
30
+ }
31
+ function restoreTheme() {
32
+ restore?.();
33
+ restore = null;
34
+ }
35
+ function nextFrame() {
36
+ return new Promise((resolve) => {
37
+ let settled = false;
38
+ const settle = () => {
39
+ if (settled) return;
40
+ settled = true;
41
+ resolve();
42
+ };
43
+ requestAnimationFrame(settle);
44
+ setTimeout(settle, 50);
45
+ });
46
+ }
47
+ var REPAINT_FRAMES = 4;
48
+ var CHART_TIMEOUT_MS = 3e3;
49
+ async function waitForCharts() {
50
+ const deadline = performance.now() + CHART_TIMEOUT_MS;
51
+ while (performance.now() < deadline) {
52
+ if (!document.querySelector('[data-slot="echart-canvas"][data-rendering]')) return;
53
+ await nextFrame();
54
+ }
55
+ }
56
+ async function printDocument() {
57
+ const wasForced = restore !== null;
58
+ forceLight();
59
+ try {
60
+ if (!wasForced && restore) {
61
+ for (let i = 0; i < REPAINT_FRAMES; i++) await nextFrame();
62
+ }
63
+ await waitForCharts();
64
+ window.print();
65
+ } catch (error) {
66
+ restoreTheme();
67
+ throw error;
68
+ }
69
+ }
70
+ function watchPrintEvents() {
71
+ window.addEventListener("beforeprint", forceLight);
72
+ window.addEventListener("afterprint", restoreTheme);
73
+ return () => {
74
+ window.removeEventListener("beforeprint", forceLight);
75
+ window.removeEventListener("afterprint", restoreTheme);
76
+ };
77
+ }
6
78
  function themeToCssVars(theme) {
7
79
  if (!theme) return void 0;
8
80
  const vars = {};
@@ -19,17 +91,41 @@ function themeToCssVars(theme) {
19
91
  if (theme.maxWidth) vars["--doc-max-width"] = theme.maxWidth;
20
92
  return Object.keys(vars).length > 0 ? vars : void 0;
21
93
  }
94
+ var PRINT_PAGE_CSS = "@media print { @page { margin: 0 } }";
95
+ function printLabel() {
96
+ return navigator.language.toLowerCase().startsWith("ja") ? "PDF \u3068\u3057\u3066\u4FDD\u5B58" : "Save as PDF";
97
+ }
22
98
  var Document = forwardRef(function Document2({ theme, style, ...props }, ref) {
23
99
  const themeVars = themeToCssVars(theme);
24
- return /* @__PURE__ */ jsx(
25
- "article",
26
- {
27
- ref,
28
- "data-slot": "document",
29
- style: themeVars || style ? { ...themeVars, ...style } : void 0,
30
- ...props
31
- }
32
- );
100
+ const label = printLabel();
101
+ useEffect(() => watchPrintEvents(), []);
102
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
103
+ /* @__PURE__ */ jsx(
104
+ "article",
105
+ {
106
+ ref,
107
+ "data-slot": "document",
108
+ style: themeVars || style ? { ...themeVars, ...style } : void 0,
109
+ ...props
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsx("style", { children: PRINT_PAGE_CSS }),
113
+ /* @__PURE__ */ jsxs(
114
+ Button,
115
+ {
116
+ "data-slot": "document-print",
117
+ variant: "outline",
118
+ size: "sm",
119
+ className: "fixed right-4 bottom-4 z-10 shadow-sm",
120
+ onClick: () => void printDocument(),
121
+ title: label,
122
+ children: [
123
+ /* @__PURE__ */ jsx(PrinterIcon, { "aria-hidden": "true" }),
124
+ label
125
+ ]
126
+ }
127
+ )
128
+ ] });
33
129
  });
34
130
  Document.displayName = "Document";
35
131
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/doc/document.tsx"],"names":["Document"],"mappings":";;;;;AAeA,SAAS,eAAe,KAAA,EAA6D;AACnF,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,OAA+B,EAAC;AACtC,EAAA,IAAI,KAAA,CAAM,EAAA,EAAI,IAAA,CAAK,UAAU,IAAI,KAAA,CAAM,EAAA;AACvC,EAAA,IAAI,KAAA,CAAM,KAAA,EAAO,IAAA,CAAK,aAAa,IAAI,KAAA,CAAM,KAAA;AAC7C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,cAAc,IAAI,KAAA,CAAM,MAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,cAAc,IAAI,KAAA,CAAM,MAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,cAAc,IAAI,KAAA,CAAM,MAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,IAAI,KAAA,CAAM,WAAA,EAAa,IAAA,CAAK,oBAAoB,IAAI,KAAA,CAAM,WAAA;AAC1D,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,IAAA,CAAK,mBAAmB,IAAI,KAAA,CAAM,UAAA;AACxD,EAAA,IAAI,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,iBAAiB,IAAI,KAAA,CAAM,QAAA;AACpD,EAAA,OAAO,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,IAAK,IAAA,GAAyB,MAAA;AAClE;AASO,IAAM,QAAA,GAAW,UAAA,CAAuC,SAASA,SAAAA,CACtE,EAAE,OAAO,KAAA,EAAO,GAAG,KAAA,EAAM,EACzB,GAAA,EACA;AACA,EAAA,MAAM,SAAA,GAAY,eAAe,KAAK,CAAA;AACtC,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,UAAA;AAAA,MACV,KAAA,EAAO,aAAa,KAAA,GAAQ,EAAE,GAAG,SAAA,EAAW,GAAG,OAAM,GAAI,MAAA;AAAA,MACxD,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AACD,QAAA,CAAS,WAAA,GAAc,UAAA","file":"index.js","sourcesContent":["import { forwardRef } from \"react\"\nimport type { CSSProperties, HTMLAttributes } from \"react\"\n\nimport type { DocumentTheme } from \"./types\"\n\nexport interface DocumentProps extends HTMLAttributes<HTMLElement> {\n /** Token overrides for this document; anything omitted follows the app's theme. */\n theme?: DocumentTheme\n}\n\n/**\n * Only the keys the document set are emitted — the rest resolve up the\n * cascade to `--doc-*` in theme.css. Writing defaults here would freeze every\n * document to light.\n */\nfunction themeToCssVars(theme: DocumentTheme | undefined): CSSProperties | undefined {\n if (!theme) return undefined\n const vars: Record<string, string> = {}\n if (theme.fg) vars[\"--doc-fg\"] = theme.fg\n if (theme.muted) vars[\"--doc-muted\"] = theme.muted\n if (theme.accent) vars[\"--doc-accent\"] = theme.accent\n if (theme.border) vars[\"--doc-border\"] = theme.border\n if (theme.subtle) vars[\"--doc-subtle\"] = theme.subtle\n if (theme.fontBody) vars[\"--doc-font-body\"] = theme.fontBody\n if (theme.fontHeading) vars[\"--doc-font-heading\"] = theme.fontHeading\n if (theme.fontMono) vars[\"--doc-font-mono\"] = theme.fontMono\n if (theme.sizeBody) vars[\"--doc-size-body\"] = theme.sizeBody\n if (theme.lineHeight) vars[\"--doc-line-height\"] = theme.lineHeight\n if (theme.maxWidth) vars[\"--doc-max-width\"] = theme.maxWidth\n return Object.keys(vars).length > 0 ? (vars as CSSProperties) : undefined\n}\n\n/**\n * The container of a document page. Plain elements written inside it —\n * headings, paragraphs, lists, tables, quotes, code, figures — are typeset by\n * the `[data-slot=\"document\"]` rules in theme.css, so the page body needs no\n * classes. Those rules sit in `@layer components`, below Tailwind utilities, so\n * a `className` on any element still wins.\n */\nexport const Document = forwardRef<HTMLElement, DocumentProps>(function Document(\n { theme, style, ...props },\n ref,\n) {\n const themeVars = themeToCssVars(theme)\n return (\n <article\n ref={ref}\n data-slot=\"document\"\n style={themeVars || style ? { ...themeVars, ...style } : undefined}\n {...props}\n />\n )\n})\nDocument.displayName = \"Document\"\n"]}
1
+ {"version":3,"sources":["../../src/doc/print.ts","../../src/doc/document.tsx"],"names":["Document"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Printing a document — the browser's own print dialog, where \"Save as PDF\"\n * is the download. Paper is white and backgrounds are dropped by default, so a\n * dark theme would print pale text on nothing: the page is switched to light\n * for the duration and put back afterwards.\n */\n\nconst DARK_CLASS = \"dark\"\nconst THEME_ATTR = \"data-theme\"\n\ntype Restore = () => void\n\nlet restore: Restore | null = null\n\n/** Drop every dark marker on `<html>`/`<body>`, remembering exactly what was there. */\nfunction forceLight(): void {\n if (restore) return\n const undo: Restore[] = []\n for (const el of [document.documentElement, document.body]) {\n if (!el) continue\n if (el.classList.contains(DARK_CLASS)) {\n el.classList.remove(DARK_CLASS)\n undo.push(() => el.classList.add(DARK_CLASS))\n }\n if (el.getAttribute(THEME_ATTR) === \"dark\") {\n el.setAttribute(THEME_ATTR, \"light\")\n undo.push(() => el.setAttribute(THEME_ATTR, \"dark\"))\n }\n }\n restore = () => {\n for (const fn of undo) fn()\n }\n}\n\nfunction restoreTheme(): void {\n restore?.()\n restore = null\n}\n\nfunction nextFrame(): Promise<void> {\n return new Promise((resolve) => {\n let settled = false\n const settle = () => {\n if (settled) return\n settled = true\n resolve()\n }\n requestAnimationFrame(settle)\n setTimeout(settle, 50)\n })\n}\n\n/**\n * Canvas charts keep the colours they were painted with, and a CSS switch at\n * print time does not repaint them. Their tokens are re-read a frame after the\n * theme flips, then React re-inits the chart, which animates in from empty —\n * printed mid-way, the bars are missing. So wait a few frames for the re-init\n * to start, then for every chart to report its paint done.\n */\nconst REPAINT_FRAMES = 4\nconst CHART_TIMEOUT_MS = 3000\n\nasync function waitForCharts(): Promise<void> {\n const deadline = performance.now() + CHART_TIMEOUT_MS\n while (performance.now() < deadline) {\n if (!document.querySelector('[data-slot=\"echart-canvas\"][data-rendering]')) return\n await nextFrame()\n }\n}\n\n/**\n * The theme comes back on `afterprint` (see `watchPrintEvents`), not after\n * `window.print()` returns — not every browser blocks on the dialog.\n */\nexport async function printDocument(): Promise<void> {\n const wasForced = restore !== null\n forceLight()\n try {\n if (!wasForced && restore) {\n for (let i = 0; i < REPAINT_FRAMES; i++) await nextFrame()\n }\n await waitForCharts()\n window.print()\n } catch (error) {\n restoreTheme()\n throw error\n }\n}\n\n/**\n * Must be mounted while a document is on screen. It also covers the browser's\n * own Print command, which skips the button: flipping the theme in\n * `beforeprint` still gets the text and rules right, though canvas charts\n * cannot repaint in time on that path.\n */\nexport function watchPrintEvents(): () => void {\n window.addEventListener(\"beforeprint\", forceLight)\n window.addEventListener(\"afterprint\", restoreTheme)\n return () => {\n window.removeEventListener(\"beforeprint\", forceLight)\n window.removeEventListener(\"afterprint\", restoreTheme)\n }\n}\n","import { forwardRef, useEffect } from \"react\"\nimport type { CSSProperties, HTMLAttributes } from \"react\"\nimport { PrinterIcon } from \"lucide-react\"\n\nimport { Button } from \"../ui/button\"\nimport { printDocument, watchPrintEvents } from \"./print\"\nimport type { DocumentTheme } from \"./types\"\n\nexport interface DocumentProps extends HTMLAttributes<HTMLElement> {\n /** Token overrides for this document; anything omitted follows the app's theme. */\n theme?: DocumentTheme\n}\n\n/**\n * Only the keys the document set are emitted — the rest resolve up the\n * cascade to `--doc-*` in theme.css. Writing defaults here would freeze every\n * document to light.\n */\nfunction themeToCssVars(theme: DocumentTheme | undefined): CSSProperties | undefined {\n if (!theme) return undefined\n const vars: Record<string, string> = {}\n if (theme.fg) vars[\"--doc-fg\"] = theme.fg\n if (theme.muted) vars[\"--doc-muted\"] = theme.muted\n if (theme.accent) vars[\"--doc-accent\"] = theme.accent\n if (theme.border) vars[\"--doc-border\"] = theme.border\n if (theme.subtle) vars[\"--doc-subtle\"] = theme.subtle\n if (theme.fontBody) vars[\"--doc-font-body\"] = theme.fontBody\n if (theme.fontHeading) vars[\"--doc-font-heading\"] = theme.fontHeading\n if (theme.fontMono) vars[\"--doc-font-mono\"] = theme.fontMono\n if (theme.sizeBody) vars[\"--doc-size-body\"] = theme.sizeBody\n if (theme.lineHeight) vars[\"--doc-line-height\"] = theme.lineHeight\n if (theme.maxWidth) vars[\"--doc-max-width\"] = theme.maxWidth\n return Object.keys(vars).length > 0 ? (vars as CSSProperties) : undefined\n}\n\n/**\n * With no page margin the browser has nowhere to print its date / URL header\n * and footer. Rendered by `<Document>` rather than put in theme.css because an\n * `@page` rule cannot be scoped — there it would reach every dashboard too.\n */\nconst PRINT_PAGE_CSS = \"@media print { @page { margin: 0 } }\"\n\n/** The one piece of chrome a document shows: English, Japanese for a Japanese browser. */\nfunction printLabel(): string {\n return navigator.language.toLowerCase().startsWith(\"ja\") ? \"PDF として保存\" : \"Save as PDF\"\n}\n\n/**\n * The container of a document page. Plain elements written inside it —\n * headings, paragraphs, lists, tables, quotes, code, figures — are typeset by\n * the `[data-slot=\"document\"]` rules in theme.css, so the page body needs no\n * classes. Those rules sit in `@layer components`, below Tailwind utilities, so\n * a `className` on any element still wins.\n *\n * It also carries its own way out: a button that opens the print dialog, where\n * \"Save as PDF\" is the download. The print rules in theme.css leave only the\n * document on paper.\n */\nexport const Document = forwardRef<HTMLElement, DocumentProps>(function Document(\n { theme, style, ...props },\n ref,\n) {\n const themeVars = themeToCssVars(theme)\n const label = printLabel()\n useEffect(() => watchPrintEvents(), [])\n return (\n <>\n <article\n ref={ref}\n data-slot=\"document\"\n style={themeVars || style ? { ...themeVars, ...style } : undefined}\n {...props}\n />\n <style>{PRINT_PAGE_CSS}</style>\n <Button\n data-slot=\"document-print\"\n variant=\"outline\"\n size=\"sm\"\n className=\"fixed right-4 bottom-4 z-10 shadow-sm\"\n onClick={() => void printDocument()}\n title={label}\n >\n <PrinterIcon aria-hidden=\"true\" />\n {label}\n </Button>\n </>\n )\n})\nDocument.displayName = \"Document\"\n"]}
@@ -1,5 +1,5 @@
1
1
  import { loadCatalog, isDocLang, DOC_LANGS, DEFAULT_DOC_LANG, docsForLang, readDoc, resolveDoc, groupBySection } from './chunk-2KRCGXBY.js';
2
- import { log, printJson } from './chunk-3G43C6OL.js';
2
+ import { log, printJson } from './chunk-QI3XQKHS.js';
3
3
  import './chunk-C2CX6GLX.js';
4
4
  import pc from 'picocolors';
5
5
 
@@ -110,5 +110,5 @@ async function docs(_root, args) {
110
110
  }
111
111
 
112
112
  export { docs };
113
- //# sourceMappingURL=docs-ZGDJUHJI.js.map
114
- //# sourceMappingURL=docs-ZGDJUHJI.js.map
113
+ //# sourceMappingURL=docs-EJJ3BECT.js.map
114
+ //# sourceMappingURL=docs-EJJ3BECT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/docs.ts"],"names":["content"],"mappings":"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","file":"docs-ZGDJUHJI.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n DEFAULT_DOC_LANG,\n DOC_LANGS,\n docsForLang,\n groupBySection,\n isDocLang,\n loadCatalog,\n readDoc,\n resolveDoc,\n type DocEntry,\n type DocLang,\n} from \"./docs-catalog\"\nimport { log, printJson, type ParsedArgs } from \"./util\"\n\n/** Highlight Markdown for a terminal. Piped output stays untouched. */\nfunction paint(markdown: string): string {\n if (!process.stdout.isTTY) return markdown\n let inFence = false\n return markdown\n .split(\"\\n\")\n .map((line) => {\n if (/^\\s*(```|~~~)/.test(line)) {\n inFence = !inFence\n return pc.dim(line)\n }\n if (inFence) return line\n if (/^#{1,6}\\s/.test(line)) return pc.bold(pc.magenta(line))\n if (/^>\\s?/.test(line)) return pc.dim(line)\n return line\n })\n .join(\"\\n\")\n}\n\nfunction printList(entries: DocEntry[]): void {\n const width = Math.max(...entries.map((doc) => doc.slug.length), 0)\n for (const group of groupBySection(entries)) {\n console.log(\"\")\n console.log(pc.bold(group.title))\n for (const doc of group.docs) {\n const slug = doc.slug.padEnd(width)\n console.log(` ${pc.cyan(slug)} ${doc.description || doc.title}`)\n }\n }\n console.log(\"\")\n console.log(pc.dim(\"vantage docs <name> show one page --json machine-readable\"))\n console.log(pc.dim(\"vantage docs --all show every page --lang ja | en\"))\n}\n\nfunction toJson(doc: DocEntry, content: string) {\n return {\n slug: doc.slug,\n lang: doc.lang,\n title: doc.title,\n description: doc.description,\n section: doc.section,\n sectionTitle: doc.sectionTitle,\n content,\n }\n}\n\n/** `vantage docs [name] [--list] [--all] [--json] [--lang ja|en]` */\nexport async function docs(_root: string, args: ParsedArgs): Promise<number> {\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 const json = Boolean(args.flags.json)\n const name = args.positionals[1]\n\n if (args.flags.all) {\n const pages = entries.map((doc) => ({ doc, content: readDoc(doc) }))\n if (json) {\n printJson({ lang, docs: pages.map(({ doc, content }) => toJson(doc, content)) })\n return 0\n }\n process.stdout.write(pages.map(({ content }) => content.trimEnd()).join(\"\\n\\n---\\n\\n\") + \"\\n\")\n return 0\n }\n\n if (!name || args.flags.list) {\n if (json) {\n printJson({\n lang,\n docs: entries.map(({ slug, title, description, section, sectionTitle }) => ({\n slug,\n title,\n description,\n section,\n sectionTitle,\n })),\n })\n return 0\n }\n printList(entries)\n return 0\n }\n\n const found = resolveDoc(entries, name)\n if (found.kind === \"ambiguous\") {\n log.error(`\"${name}\" matches several pages: ${found.matches.map((d) => d.slug).join(\", \")}`)\n return 1\n }\n if (found.kind === \"missing\") {\n const suggestions = found.suggestions.map((d) => d.slug)\n log.error(\n suggestions.length\n ? `No page named \"${name}\". Did you mean: ${suggestions.slice(0, 8).join(\", \")}?`\n : `No page named \"${name}\". Run \\`vantage docs\\` to list every page.`,\n )\n return 1\n }\n\n const content = readDoc(found.doc)\n if (json) {\n printJson(toJson(found.doc, content))\n return 0\n }\n process.stdout.write(paint(content.trimEnd()) + \"\\n\")\n return 0\n}\n"]}
1
+ {"version":3,"sources":["../src/cli/docs.ts"],"names":["content"],"mappings":"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","file":"docs-EJJ3BECT.js","sourcesContent":["import pc from \"picocolors\"\nimport {\n DEFAULT_DOC_LANG,\n DOC_LANGS,\n docsForLang,\n groupBySection,\n isDocLang,\n loadCatalog,\n readDoc,\n resolveDoc,\n type DocEntry,\n type DocLang,\n} from \"./docs-catalog\"\nimport { log, printJson, type ParsedArgs } from \"./util\"\n\n/** Highlight Markdown for a terminal. Piped output stays untouched. */\nfunction paint(markdown: string): string {\n if (!process.stdout.isTTY) return markdown\n let inFence = false\n return markdown\n .split(\"\\n\")\n .map((line) => {\n if (/^\\s*(```|~~~)/.test(line)) {\n inFence = !inFence\n return pc.dim(line)\n }\n if (inFence) return line\n if (/^#{1,6}\\s/.test(line)) return pc.bold(pc.magenta(line))\n if (/^>\\s?/.test(line)) return pc.dim(line)\n return line\n })\n .join(\"\\n\")\n}\n\nfunction printList(entries: DocEntry[]): void {\n const width = Math.max(...entries.map((doc) => doc.slug.length), 0)\n for (const group of groupBySection(entries)) {\n console.log(\"\")\n console.log(pc.bold(group.title))\n for (const doc of group.docs) {\n const slug = doc.slug.padEnd(width)\n console.log(` ${pc.cyan(slug)} ${doc.description || doc.title}`)\n }\n }\n console.log(\"\")\n console.log(pc.dim(\"vantage docs <name> show one page --json machine-readable\"))\n console.log(pc.dim(\"vantage docs --all show every page --lang ja | en\"))\n}\n\nfunction toJson(doc: DocEntry, content: string) {\n return {\n slug: doc.slug,\n lang: doc.lang,\n title: doc.title,\n description: doc.description,\n section: doc.section,\n sectionTitle: doc.sectionTitle,\n content,\n }\n}\n\n/** `vantage docs [name] [--list] [--all] [--json] [--lang ja|en]` */\nexport async function docs(_root: string, args: ParsedArgs): Promise<number> {\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 const json = Boolean(args.flags.json)\n const name = args.positionals[1]\n\n if (args.flags.all) {\n const pages = entries.map((doc) => ({ doc, content: readDoc(doc) }))\n if (json) {\n printJson({ lang, docs: pages.map(({ doc, content }) => toJson(doc, content)) })\n return 0\n }\n process.stdout.write(pages.map(({ content }) => content.trimEnd()).join(\"\\n\\n---\\n\\n\") + \"\\n\")\n return 0\n }\n\n if (!name || args.flags.list) {\n if (json) {\n printJson({\n lang,\n docs: entries.map(({ slug, title, description, section, sectionTitle }) => ({\n slug,\n title,\n description,\n section,\n sectionTitle,\n })),\n })\n return 0\n }\n printList(entries)\n return 0\n }\n\n const found = resolveDoc(entries, name)\n if (found.kind === \"ambiguous\") {\n log.error(`\"${name}\" matches several pages: ${found.matches.map((d) => d.slug).join(\", \")}`)\n return 1\n }\n if (found.kind === \"missing\") {\n const suggestions = found.suggestions.map((d) => d.slug)\n log.error(\n suggestions.length\n ? `No page named \"${name}\". Did you mean: ${suggestions.slice(0, 8).join(\", \")}?`\n : `No page named \"${name}\". Run \\`vantage docs\\` to list every page.`,\n )\n return 1\n }\n\n const content = readDoc(found.doc)\n if (json) {\n printJson(toJson(found.doc, content))\n return 0\n }\n process.stdout.write(paint(content.trimEnd()) + \"\\n\")\n return 0\n}\n"]}
@@ -1,8 +1,8 @@
1
- import { runDiagnostics } from './chunk-BCE22JSM.js';
2
- import './chunk-JGRMRXXZ.js';
3
- import './chunk-KLEIVDUV.js';
1
+ import { runDiagnostics } from './chunk-P7W4LR3Z.js';
2
+ import './chunk-JKLLFVEU.js';
3
+ import './chunk-CEXAQQ5W.js';
4
4
  import { scanProject } from './chunk-ZVANIULZ.js';
5
- import { printJson, frameworkVersion, log } from './chunk-3G43C6OL.js';
5
+ import { printJson, frameworkVersion, log } from './chunk-QI3XQKHS.js';
6
6
  import './chunk-C2CX6GLX.js';
7
7
  import fs from 'fs';
8
8
  import path from 'path';
@@ -19,7 +19,7 @@ async function doctor(root, args) {
19
19
  });
20
20
  const pkgPath = path.join(root, "package.json");
21
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"];
22
+ const lockfiles = ["bun.lock", "bun.lockb", "pnpm-lock.yaml", "package-lock.json", "yarn.lock"];
23
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
24
  facets.push({ name: "lockfile", ok: Boolean(lock), detail: lock ?? "none found" });
25
25
  let installedVantage = "not installed";
@@ -54,5 +54,5 @@ async function doctor(root, args) {
54
54
  }
55
55
 
56
56
  export { doctor };
57
- //# sourceMappingURL=doctor-VFKEMR54.js.map
58
- //# sourceMappingURL=doctor-VFKEMR54.js.map
57
+ //# sourceMappingURL=doctor-WQXPXP6K.js.map
58
+ //# sourceMappingURL=doctor-WQXPXP6K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/doctor.ts"],"names":["require"],"mappings":"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","file":"doctor-WQXPXP6K.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"]}