@squadbase/vantage 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/{chunk-YLAB6UQS.js → chunk-46QI6GFC.js} +2 -2
- package/dist/{chunk-YLAB6UQS.js.map → chunk-46QI6GFC.js.map} +1 -1
- package/dist/{chunk-WQZYXXQW.js → chunk-DIABD3KZ.js} +2 -2
- package/dist/chunk-DIABD3KZ.js.map +1 -0
- package/dist/chunk-DTDVSFRY.js +29 -0
- package/dist/chunk-DTDVSFRY.js.map +1 -0
- package/dist/chunk-EHPJXDJU.js +51 -0
- package/dist/chunk-EHPJXDJU.js.map +1 -0
- package/dist/{chunk-PRFBSQA4.js → chunk-UHZ7XSAN.js} +10 -5
- package/dist/chunk-UHZ7XSAN.js.map +1 -0
- package/dist/cli.js +19 -11
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/components/index.d.ts +23 -2
- package/dist/components/index.js +116 -2
- package/dist/components/index.js.map +1 -1
- package/dist/{define-page-B6y9TOfZ.d.ts → define-page-BfhrK99G.d.ts} +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown/index.js.map +1 -1
- package/dist/query/index.d.ts +69 -2
- package/dist/query/index.js +85 -2
- package/dist/query/index.js.map +1 -1
- package/dist/router/index.d.ts +86 -1
- package/dist/router/index.js +71 -7
- package/dist/router/index.js.map +1 -1
- package/dist/server/node.js +1 -1
- package/dist/server/node.js.map +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/vite/index.js +2 -2
- package/docs/en/agent-skills.md +12 -8
- package/docs/en/changelog.md +98 -0
- package/docs/en/cli-reference.md +1 -1
- package/docs/en/components.md +2 -0
- package/docs/en/data-fetching.md +77 -13
- package/docs/en/pages-and-metadata.md +6 -3
- package/docs/en/parts/placeholder.md +38 -0
- package/docs/en/parts/sparkline.md +47 -0
- package/docs/en/routing.md +82 -4
- package/docs/index.json +75 -13
- package/docs/ja/agent-skills.md +13 -9
- package/docs/ja/changelog.md +89 -0
- package/docs/ja/cli-reference.md +1 -1
- package/docs/ja/components.md +2 -0
- package/docs/ja/data-fetching.md +76 -12
- package/docs/ja/pages-and-metadata.md +6 -3
- package/docs/ja/parts/placeholder.md +37 -0
- package/docs/ja/parts/sparkline.md +47 -0
- package/docs/ja/routing.md +80 -4
- package/package.json +1 -1
- package/skills/vantage-add-feature/SKILL.md +14 -12
- package/skills/vantage-app/SKILL.md +55 -24
- package/skills/vantage-pitfalls/SKILL.md +27 -13
- package/templates/AGENTS.md +65 -23
- package/dist/chunk-ATYZ45XL.js +0 -19
- package/dist/chunk-ATYZ45XL.js.map +0 -1
- package/dist/chunk-PRFBSQA4.js.map +0 -1
- package/dist/chunk-WQZYXXQW.js.map +0 -1
package/docs/en/routing.md
CHANGED
|
@@ -33,10 +33,6 @@ server/ API (its presence enables the server)
|
|
|
33
33
|
public/ Static assets
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
> [!NOTE]
|
|
37
|
-
> Imports between files use **runtime `.js` specifiers** (e.g. `./components/revenue-chart.js`) —
|
|
38
|
-
> required for ESM Node resolution.
|
|
39
|
-
|
|
40
36
|
## The three spellings of a dynamic param
|
|
41
37
|
|
|
42
38
|
The same param appears in three spellings depending on where it is. **They must match.**
|
|
@@ -85,6 +81,88 @@ export default function RootLayout() {
|
|
|
85
81
|
|
|
86
82
|
`_404.tsx` and `_error.tsx` are recognized at the **root only**.
|
|
87
83
|
|
|
84
|
+
## Build a nav from the route list
|
|
85
|
+
|
|
86
|
+
`useRoutes()` returns every page route in the app. The file system is the source of truth, so adding
|
|
87
|
+
one page file adds one nav entry — there is no link array to maintain.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
// _layout.tsx
|
|
91
|
+
import { Link, Outlet, useCurrentRoute, useRoutes } from "@squadbase/vantage/router";
|
|
92
|
+
|
|
93
|
+
export default function RootLayout() {
|
|
94
|
+
// Dynamic routes (/sales/:customerId) have no single URL, so leave them out.
|
|
95
|
+
const routes = useRoutes().filter((route) => !route.dynamic);
|
|
96
|
+
const current = useCurrentRoute();
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div>
|
|
100
|
+
<nav>
|
|
101
|
+
{routes.map((route) => (
|
|
102
|
+
<Link key={route.path} to={route.to} aria-current={route.path === current?.path}>
|
|
103
|
+
{route.label}
|
|
104
|
+
</Link>
|
|
105
|
+
))}
|
|
106
|
+
</nav>
|
|
107
|
+
<Outlet />
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The order is Vantage's scan order — shallow before deep, static before dynamic, alphabetical — which
|
|
114
|
+
is the order a nav wants.
|
|
115
|
+
|
|
116
|
+
Each entry is a `RouteInfo`:
|
|
117
|
+
|
|
118
|
+
| Field | Type | Contents |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `path` | `string` | Display path, `/sales/:customerId` |
|
|
121
|
+
| `to` | `string` | The form `Link`'s `to` expects, `/sales/$customerId` |
|
|
122
|
+
| `params` | `string[]` | Dynamic parameter names; a catch-all is `_splat` |
|
|
123
|
+
| `dynamic` | `boolean` | Whether the route has dynamic parameters |
|
|
124
|
+
| `index` | `boolean` | Whether it is a directory's index route |
|
|
125
|
+
| `label` | `string` | Display name: `navLabel`, else `title`, else `path` |
|
|
126
|
+
| `title` / `description` / `navLabel` | `string \| undefined` | Values from [`definePage`](pages-and-metadata) |
|
|
127
|
+
|
|
128
|
+
`useCurrentRoute()` returns the route being rendered, or `undefined` on the 404 route. Beyond the
|
|
129
|
+
"you are here" check above, it fits breadcrumbs and page headings.
|
|
130
|
+
|
|
131
|
+
> [!NOTE]
|
|
132
|
+
> `label` prefers `navLabel` because `title` drives `document.title` and therefore tends to carry the
|
|
133
|
+
> site name, which is usually too long for a nav.
|
|
134
|
+
|
|
135
|
+
## Keep filter state in the URL
|
|
136
|
+
|
|
137
|
+
A dashboard's filters belong in the URL: the view survives a reload and can be pasted to a colleague.
|
|
138
|
+
`useSearchParam` reads and writes one search-param key with a `useState` shape.
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
import { useSearchParam } from "@squadbase/vantage/router";
|
|
142
|
+
import { SegmentedControl } from "@squadbase/vantage/components";
|
|
143
|
+
|
|
144
|
+
export default function Sales() {
|
|
145
|
+
const [region, setRegion] = useSearchParam("region", "all");
|
|
146
|
+
|
|
147
|
+
return <SegmentedControl options={REGIONS} value={region} onChange={setRegion} />;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- The value is **always a string** (`?year=2024` parses as a number; this hook normalizes it back).
|
|
152
|
+
- Writing the **default value** (`"all"` above) or `null` removes the key from the URL.
|
|
153
|
+
- History defaults to `replace`, so filtering doesn't fill the back button. Pass `{ replace: false }`
|
|
154
|
+
to push instead.
|
|
155
|
+
|
|
156
|
+
For anything JSON-serializable — an array, an object — use `useSearchState`, which also accepts a
|
|
157
|
+
functional update.
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { useSearchState } from "@squadbase/vantage/router";
|
|
161
|
+
|
|
162
|
+
const [segments, setSegments] = useSearchState<string[]>("segments", []);
|
|
163
|
+
setSegments((prev) => [...prev, "enterprise"]);
|
|
164
|
+
```
|
|
165
|
+
|
|
88
166
|
## HMR and route regeneration
|
|
89
167
|
|
|
90
168
|
Adding or removing a `.tsx` page or a `server/api` file regenerates routes and triggers a full
|
package/docs/index.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
2
|
+
"schemaVersion": 2,
|
|
3
3
|
"generatedFrom": "docs/content",
|
|
4
4
|
"docs": [
|
|
5
5
|
{
|
|
@@ -108,10 +108,21 @@
|
|
|
108
108
|
"section": "guide",
|
|
109
109
|
"sectionTitle": "ガイド",
|
|
110
110
|
"title": "エージェントと Skills",
|
|
111
|
-
"description": "Vantage に同梱された Claude Code の Agent Skills。vantage add skill
|
|
111
|
+
"description": "Vantage に同梱された Claude Code の Agent Skills。vantage add skill でアプリに配置し(既定はルート直下、--dir で .claude/skills などに変更)、エージェントに手順を伴うワークフローを教える。",
|
|
112
112
|
"file": "ja/agent-skills.md",
|
|
113
113
|
"order": 9
|
|
114
114
|
},
|
|
115
|
+
{
|
|
116
|
+
"slug": "changelog",
|
|
117
|
+
"lang": "ja",
|
|
118
|
+
"section": "guide",
|
|
119
|
+
"sectionTitle": "ガイド",
|
|
120
|
+
"title": "変更履歴",
|
|
121
|
+
"description": "Vantage のリリースごとの変更点。新しいものが上。まだプロトタイプ(0.x)のため、リリース間で API が変わることがあります。",
|
|
122
|
+
"file": "ja/changelog.md",
|
|
123
|
+
"order": 10,
|
|
124
|
+
"searchable": false
|
|
125
|
+
},
|
|
115
126
|
{
|
|
116
127
|
"slug": "components",
|
|
117
128
|
"lang": "ja",
|
|
@@ -592,6 +603,16 @@
|
|
|
592
603
|
"file": "ja/parts/page-shell.md",
|
|
593
604
|
"order": 9
|
|
594
605
|
},
|
|
606
|
+
{
|
|
607
|
+
"slug": "parts/placeholder",
|
|
608
|
+
"lang": "ja",
|
|
609
|
+
"section": "components/parts",
|
|
610
|
+
"sectionTitle": "@squadbase/vantage/components",
|
|
611
|
+
"title": "Placeholder",
|
|
612
|
+
"description": "仮データであることを示す、インラインの目印。",
|
|
613
|
+
"file": "ja/parts/placeholder.md",
|
|
614
|
+
"order": 10
|
|
615
|
+
},
|
|
595
616
|
{
|
|
596
617
|
"slug": "parts/searchable-select",
|
|
597
618
|
"lang": "ja",
|
|
@@ -600,7 +621,7 @@
|
|
|
600
621
|
"title": "SearchableSelect",
|
|
601
622
|
"description": "検索できる単一選択。候補が多いときに。",
|
|
602
623
|
"file": "ja/parts/searchable-select.md",
|
|
603
|
-
"order":
|
|
624
|
+
"order": 11
|
|
604
625
|
},
|
|
605
626
|
{
|
|
606
627
|
"slug": "parts/section-header",
|
|
@@ -610,7 +631,7 @@
|
|
|
610
631
|
"title": "SectionHeader",
|
|
611
632
|
"description": "セクションの見出しとアクション。",
|
|
612
633
|
"file": "ja/parts/section-header.md",
|
|
613
|
-
"order":
|
|
634
|
+
"order": 12
|
|
614
635
|
},
|
|
615
636
|
{
|
|
616
637
|
"slug": "parts/segmented-control",
|
|
@@ -620,7 +641,17 @@
|
|
|
620
641
|
"title": "SegmentedControl",
|
|
621
642
|
"description": "単一選択のセグメント。ToggleGroup の配列を隠す。",
|
|
622
643
|
"file": "ja/parts/segmented-control.md",
|
|
623
|
-
"order":
|
|
644
|
+
"order": 13
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"slug": "parts/sparkline",
|
|
648
|
+
"lang": "ja",
|
|
649
|
+
"section": "components/parts",
|
|
650
|
+
"sectionTitle": "@squadbase/vantage/components",
|
|
651
|
+
"title": "Sparkline",
|
|
652
|
+
"description": "表のセルや KPI タイルに置く、インラインの推移グラフ。",
|
|
653
|
+
"file": "ja/parts/sparkline.md",
|
|
654
|
+
"order": 14
|
|
624
655
|
},
|
|
625
656
|
{
|
|
626
657
|
"slug": "parts/status-badge",
|
|
@@ -630,7 +661,7 @@
|
|
|
630
661
|
"title": "StatusBadge",
|
|
631
662
|
"description": "ドット付きのステータスバッジ。色は名前で決まる。",
|
|
632
663
|
"file": "ja/parts/status-badge.md",
|
|
633
|
-
"order":
|
|
664
|
+
"order": 15
|
|
634
665
|
},
|
|
635
666
|
{
|
|
636
667
|
"slug": "parts/trend-indicator",
|
|
@@ -640,7 +671,7 @@
|
|
|
640
671
|
"title": "TrendIndicator",
|
|
641
672
|
"description": "増減の矢印と変化率。良し悪しは positiveIsGood で決まる。",
|
|
642
673
|
"file": "ja/parts/trend-indicator.md",
|
|
643
|
-
"order":
|
|
674
|
+
"order": 16
|
|
644
675
|
},
|
|
645
676
|
{
|
|
646
677
|
"slug": "markdown/markdown-renderer",
|
|
@@ -758,10 +789,21 @@
|
|
|
758
789
|
"section": "guide",
|
|
759
790
|
"sectionTitle": "Guide",
|
|
760
791
|
"title": "Agents and Skills",
|
|
761
|
-
"description": "The Claude Code agent skills bundled with Vantage. Place them into your app
|
|
792
|
+
"description": "The Claude Code agent skills bundled with Vantage. Place them into your app with vantage add skill (the project root by default, or anywhere via --dir, e.g. .claude/skills) to teach agents step-by-step workflows.",
|
|
762
793
|
"file": "en/agent-skills.md",
|
|
763
794
|
"order": 9
|
|
764
795
|
},
|
|
796
|
+
{
|
|
797
|
+
"slug": "changelog",
|
|
798
|
+
"lang": "en",
|
|
799
|
+
"section": "guide",
|
|
800
|
+
"sectionTitle": "Guide",
|
|
801
|
+
"title": "Changelog",
|
|
802
|
+
"description": "What changed in each Vantage release, newest first. Still a prototype (0.x), so APIs may change between releases.",
|
|
803
|
+
"file": "en/changelog.md",
|
|
804
|
+
"order": 10,
|
|
805
|
+
"searchable": false
|
|
806
|
+
},
|
|
765
807
|
{
|
|
766
808
|
"slug": "components",
|
|
767
809
|
"lang": "en",
|
|
@@ -1242,6 +1284,16 @@
|
|
|
1242
1284
|
"file": "en/parts/page-shell.md",
|
|
1243
1285
|
"order": 9
|
|
1244
1286
|
},
|
|
1287
|
+
{
|
|
1288
|
+
"slug": "parts/placeholder",
|
|
1289
|
+
"lang": "en",
|
|
1290
|
+
"section": "components/parts",
|
|
1291
|
+
"sectionTitle": "@squadbase/vantage/components",
|
|
1292
|
+
"title": "Placeholder",
|
|
1293
|
+
"description": "An inline marker for sample, not-yet-real data.",
|
|
1294
|
+
"file": "en/parts/placeholder.md",
|
|
1295
|
+
"order": 10
|
|
1296
|
+
},
|
|
1245
1297
|
{
|
|
1246
1298
|
"slug": "parts/searchable-select",
|
|
1247
1299
|
"lang": "en",
|
|
@@ -1250,7 +1302,7 @@
|
|
|
1250
1302
|
"title": "SearchableSelect",
|
|
1251
1303
|
"description": "Single choice with search, for long option lists.",
|
|
1252
1304
|
"file": "en/parts/searchable-select.md",
|
|
1253
|
-
"order":
|
|
1305
|
+
"order": 11
|
|
1254
1306
|
},
|
|
1255
1307
|
{
|
|
1256
1308
|
"slug": "parts/section-header",
|
|
@@ -1260,7 +1312,7 @@
|
|
|
1260
1312
|
"title": "SectionHeader",
|
|
1261
1313
|
"description": "A section heading with its actions.",
|
|
1262
1314
|
"file": "en/parts/section-header.md",
|
|
1263
|
-
"order":
|
|
1315
|
+
"order": 12
|
|
1264
1316
|
},
|
|
1265
1317
|
{
|
|
1266
1318
|
"slug": "parts/segmented-control",
|
|
@@ -1270,7 +1322,17 @@
|
|
|
1270
1322
|
"title": "SegmentedControl",
|
|
1271
1323
|
"description": "Single-choice segments — it hides ToggleGroup's array.",
|
|
1272
1324
|
"file": "en/parts/segmented-control.md",
|
|
1273
|
-
"order":
|
|
1325
|
+
"order": 13
|
|
1326
|
+
},
|
|
1327
|
+
{
|
|
1328
|
+
"slug": "parts/sparkline",
|
|
1329
|
+
"lang": "en",
|
|
1330
|
+
"section": "components/parts",
|
|
1331
|
+
"sectionTitle": "@squadbase/vantage/components",
|
|
1332
|
+
"title": "Sparkline",
|
|
1333
|
+
"description": "An inline trend chart for table cells and KPI tiles.",
|
|
1334
|
+
"file": "en/parts/sparkline.md",
|
|
1335
|
+
"order": 14
|
|
1274
1336
|
},
|
|
1275
1337
|
{
|
|
1276
1338
|
"slug": "parts/status-badge",
|
|
@@ -1280,7 +1342,7 @@
|
|
|
1280
1342
|
"title": "StatusBadge",
|
|
1281
1343
|
"description": "A dot-and-label status badge, coloured by name.",
|
|
1282
1344
|
"file": "en/parts/status-badge.md",
|
|
1283
|
-
"order":
|
|
1345
|
+
"order": 15
|
|
1284
1346
|
},
|
|
1285
1347
|
{
|
|
1286
1348
|
"slug": "parts/trend-indicator",
|
|
@@ -1290,7 +1352,7 @@
|
|
|
1290
1352
|
"title": "TrendIndicator",
|
|
1291
1353
|
"description": "An arrow and a percentage; positiveIsGood decides the colour.",
|
|
1292
1354
|
"file": "en/parts/trend-indicator.md",
|
|
1293
|
-
"order":
|
|
1355
|
+
"order": 16
|
|
1294
1356
|
},
|
|
1295
1357
|
{
|
|
1296
1358
|
"slug": "markdown/markdown-renderer",
|
package/docs/ja/agent-skills.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# エージェントと Skills
|
|
2
2
|
|
|
3
|
-
> Vantage に同梱された Claude Code の Agent Skills。vantage add skill
|
|
3
|
+
> Vantage に同梱された Claude Code の Agent Skills。vantage add skill でアプリに配置し(既定はルート直下、--dir で .claude/skills などに変更)、エージェントに手順を伴うワークフローを教える。
|
|
4
4
|
|
|
5
5
|
Vantage は **Claude Code の Agent Skills** を同梱しています。Skill は「手順を伴うワークフロー」を、
|
|
6
6
|
エージェントが必要なときだけ呼び出せる形にしたものです。UI キットや CLI の使い方といった
|
|
@@ -18,16 +18,18 @@ Vantage は **Claude Code の Agent Skills** を同梱しています。Skill
|
|
|
18
18
|
|
|
19
19
|
## 配置する
|
|
20
20
|
|
|
21
|
-
Skill のソースは `@squadbase/vantage` パッケージに同梱されています。`vantage add skill`
|
|
22
|
-
|
|
21
|
+
Skill のソースは `@squadbase/vantage` パッケージに同梱されています。`vantage add skill` で
|
|
22
|
+
対象アプリにコピーします。配置先は既定で**プロジェクトルート直下**で、`--dir` で変えられます。
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
vantage add skill --all
|
|
26
|
-
vantage add skill vantage-app
|
|
27
|
-
vantage add skill
|
|
25
|
+
vantage add skill --all # 同梱スキルをすべて、ルート直下に配置
|
|
26
|
+
vantage add skill vantage-app # 名前を指定して1つだけ配置
|
|
27
|
+
vantage add skill --all --dir .claude/skills # Claude Code が読む場所に配置
|
|
28
|
+
vantage add skill vantage-app --force # 既存を上書き
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
`--dir` のパスはプロジェクトルートからの相対で解決されます(絶対パスも可)。Claude Code に
|
|
32
|
+
自動認識させるなら `.claude/skills/` に置きます:
|
|
31
33
|
|
|
32
34
|
```text
|
|
33
35
|
your-app/
|
|
@@ -41,7 +43,8 @@ your-app/
|
|
|
41
43
|
```
|
|
42
44
|
|
|
43
45
|
`.claude/skills/` は Claude Code が自動で認識します。エージェントはタスクに応じて、対応する
|
|
44
|
-
Skill
|
|
46
|
+
Skill の手順を読み込んで実行します。他のエージェントに読ませる場合は、そのツールが期待する
|
|
47
|
+
ディレクトリを `--dir` に渡してください。
|
|
45
48
|
|
|
46
49
|
> [!NOTE]
|
|
47
50
|
> `.claude/` はツール用の設定であり、アプリのコードではありません。`vantage check` の静的診断は
|
|
@@ -51,7 +54,8 @@ Skill の手順を読み込んで実行します。
|
|
|
51
54
|
|
|
52
55
|
- **source-of-truth はパッケージ内**にあります。Skill はフレームワークのバージョンと一緒に
|
|
53
56
|
配布・更新されるため、`@squadbase/vantage` を上げれば最新の手順が手に入ります。配置済みの
|
|
54
|
-
|
|
57
|
+
コピーを更新したいときは、配置したときと同じ `--dir` を付けて
|
|
58
|
+
`vantage add skill --all --force` を実行します。
|
|
55
59
|
- **Squadbase テンプレートには配置済み**です。テンプレートから作ったアプリには、最初から
|
|
56
60
|
`.claude/skills/` が入っています。手で作ったアプリには `vantage add skill` で足してください。
|
|
57
61
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# 変更履歴
|
|
2
|
+
|
|
3
|
+
> Vantage のリリースごとの変更点。新しいものが上。まだプロトタイプ(0.x)のため、リリース間で API が変わることがあります。
|
|
4
|
+
|
|
5
|
+
Vantage のリリースごとの変更点です。新しいものが上に来ます。
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
> まだプロトタイプ(**0.x**)です。0.x の間は **minor が実質のメジャー**扱いで、後方互換性の
|
|
9
|
+
> ない変更は minor で入ることがあります。patch は後方互換の機能追加とバグ修正のみです。
|
|
10
|
+
|
|
11
|
+
## v0.2.0
|
|
12
|
+
|
|
13
|
+
`vantage add skill` の配置先を選べるようにし、相対 import の `.js` 指定子の規約を廃止しました。
|
|
14
|
+
後方互換でない変更(既定の配置先)を含むため、0.x の方針に従って minor を上げています。
|
|
15
|
+
|
|
16
|
+
依存を `"@squadbase/vantage": "^0.1.0"` と書いているアプリには 0.2.0 は入りません。
|
|
17
|
+
`^0.2.0` に上げてください。
|
|
18
|
+
|
|
19
|
+
> [!WARNING]
|
|
20
|
+
> **`vantage add skill` の既定の配置先が変わりました。** これまで常に `.claude/skills/` へ
|
|
21
|
+
> 出していましたが、既定は**プロジェクトルート直下**になります。これまでと同じ場所に置くには
|
|
22
|
+
> `--dir .claude/skills` を明示してください。配置済みのコピーはそのまま残るので、更新する
|
|
23
|
+
> ときだけ `--dir` を付け直す形になります。
|
|
24
|
+
|
|
25
|
+
### 変更
|
|
26
|
+
|
|
27
|
+
- **`vantage add skill --dir <path>`** ― 配置先をコマンドで指定できるようになりました。
|
|
28
|
+
パスはプロジェクトルート(`--root` を尊重)からの相対で解決され、絶対パスも渡せます。
|
|
29
|
+
Claude Code に自動認識させたい場合は `--dir .claude/skills`、他のエージェント向けには
|
|
30
|
+
そのツールが期待するディレクトリを指定します(→ [エージェントと Skills](agent-skills))。
|
|
31
|
+
- **相対 import の `.js` 指定子の規約を廃止** ― `./components/revenue-chart.js` のように
|
|
32
|
+
拡張子を書く必要はなくなりました(`./components/revenue-chart` で構いません)。Vantage の
|
|
33
|
+
コードは常に Vite / tsup を通り、TypeScript も `moduleResolution: "Bundler"` で解決する
|
|
34
|
+
ため、Node が生の指定子を読む経路がそもそもありませんでした。**既存の `.js` 付きの
|
|
35
|
+
import はそのまま動きます** ― 書き換えは不要です。
|
|
36
|
+
|
|
37
|
+
## v0.1.1
|
|
38
|
+
|
|
39
|
+
一覧・URL 状態・API 呼び出しの hook を追加し、開発時の 2 つの不具合を修正しました。
|
|
40
|
+
すべて後方互換です。
|
|
41
|
+
|
|
42
|
+
### 追加
|
|
43
|
+
|
|
44
|
+
- **ルーティングの hook** ― `useRoutes()` / `useCurrentRoute()` を
|
|
45
|
+
[`@squadbase/vantage/router`](routing) に追加。ファイルベースルーティングの一覧を
|
|
46
|
+
そのまま受け取り、ナビゲーションを手で二重管理せずに組めます。
|
|
47
|
+
- **URL 同期の状態** ― `useSearchParam`(常に文字列。既定値/`null` を書くとキーを消す)と、
|
|
48
|
+
JSON 値と関数更新に対応した `useSearchState<T>` を追加。フィルタやタブの状態を URL に置けます。
|
|
49
|
+
- **API 呼び出しの hook** ― `useApiQuery` / `useApiMutation` を
|
|
50
|
+
[`@squadbase/vantage/query`](data-fetching) に追加。`server/api` を JSON で呼び、
|
|
51
|
+
エラーは `HttpError` → `ApiError`(`status` / `body` / `requestId`)に正規化されます。
|
|
52
|
+
- **`definePage` の `navLabel`** ― ナビゲーションに出す表示名を、ページのタイトルと
|
|
53
|
+
独立して指定できるフィールドを追加(→ [ページとメタデータ](pages-and-metadata))。
|
|
54
|
+
|
|
55
|
+
### 修正
|
|
56
|
+
|
|
57
|
+
- **dev の SPA フォールバック** ― `/sales` のような URL に直接アクセスすると、Vite が
|
|
58
|
+
`No matching HTML proxy module found` のエラーオーバーレイを出していた問題を修正
|
|
59
|
+
(ページ自体は描画されていました)。注入スクリプトの id をシェル文書の URL から
|
|
60
|
+
導くようにしました。
|
|
61
|
+
- **クエリが `paused` のまま止まる** ― ブラウザのオフライン判定が誤って offline を返すと、
|
|
62
|
+
失敗したクエリがエラーにならず停止し、ページが読み込み表示から戻らないことがありました。
|
|
63
|
+
管理された `QueryClient` の `networkMode` を `"always"` にして解消(自オリジンの API を
|
|
64
|
+
叩くダッシュボードでは、この判定に意味がありません)。
|
|
65
|
+
|
|
66
|
+
## v0.1.0
|
|
67
|
+
|
|
68
|
+
最初のプロトタイプリリース。設定ファイル不要(config-free)な React ダッシュボード
|
|
69
|
+
フレームワークの土台一式です。
|
|
70
|
+
|
|
71
|
+
### 追加
|
|
72
|
+
|
|
73
|
+
- **config-free な土台** ― Vite 8 の上に構築。アプリ作者が書くのは `index.tsx` だけで、
|
|
74
|
+
ルーティング・React・TanStack Query・Tailwind v4・UI キット・開発サーバー・
|
|
75
|
+
オプションの API サーバー・ビルドはすべて Vantage が所有します。
|
|
76
|
+
- **ファイルベースルーティング** ― `*.tsx`(デフォルトエクスポート)がルートに、
|
|
77
|
+
`_layout.tsx` がレイアウトに、`_404.tsx` / `_error.tsx` が not-found / error に、
|
|
78
|
+
`[param].tsx` が動的ルートになります(→ [ルーティング](routing))。
|
|
79
|
+
- **オプションの API サーバー** ― `server/api/**` を足すとバックエンドが有効になり、
|
|
80
|
+
`dev` と本番ビルドで同一に動きます(→ [API とサーバー](api-and-server))。
|
|
81
|
+
- **UI キットとコンポーネント** ― Tailwind v4、shadcn/ui(Base UI 版)、その上に組んだ
|
|
82
|
+
ダッシュボード向けの複合コンポーネント(→ [UI とテーマ](ui-and-theming))。
|
|
83
|
+
- **CLI** ― `dev` / `build` / `preview` / `check` / `routes` / `add` / `upgrade`
|
|
84
|
+
(→ [CLI リファレンス](cli-reference))。
|
|
85
|
+
- **同梱ドキュメントと検索** ― `vantage docs` がパッケージ同梱のガイドとコンポーネント
|
|
86
|
+
リファレンスをオフラインで表示し、`vantage search` が同じ内容を BM25 で検索します。
|
|
87
|
+
- **エージェント向けの配布物** ― `vantage add agents` が `AGENTS.md` を、
|
|
88
|
+
`vantage add skill` が Claude Code の Agent Skills をアプリへ配置します
|
|
89
|
+
(→ [エージェントと Skills](agent-skills))。
|
package/docs/ja/cli-reference.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| `vantage preview` | 本番ビルドをローカルで起動(fullstack は既定 `:4173`、spa は Vite プレビュー) |
|
|
14
14
|
| `vantage check` | 静的検査(ルート・境界・禁止ファイル)。エラーがあれば exit 1 |
|
|
15
15
|
| `vantage routes` | ページ + API の URL マップを表示 |
|
|
16
|
-
| `vantage add <kind> <name>` | `page` / `api` / `ui` / `block` / `skill` / `agents` を雛形生成・配置(`--force`
|
|
16
|
+
| `vantage add <kind> <name>` | `page` / `api` / `ui` / `block` / `skill` / `agents` を雛形生成・配置(`--force` で上書き、`skill` は `--dir` で配置先を指定) |
|
|
17
17
|
| `vantage docs [name]` | 同梱のガイド + コンポーネントリファレンスを表示 |
|
|
18
18
|
| `vantage search <query>` | 同じリファレンスを全文検索(自然言語 or `--regex`) |
|
|
19
19
|
| `vantage doctor` | 環境・インストールの健全性を診断 |
|
package/docs/ja/components.md
CHANGED
|
@@ -124,6 +124,7 @@ shadcn/ui のプリミティブです。名前も props も shadcn/ui のもの
|
|
|
124
124
|
| [`DataTable`](parts/data-table) | 並べ替え・検索・ページング・選択を備えた表 |
|
|
125
125
|
| [`EChart`](parts/echart) | Apache ECharts のラッパー |
|
|
126
126
|
| [`FunnelSteps`](parts/funnel-steps) | ファネルの棒表示 |
|
|
127
|
+
| [`Sparkline`](parts/sparkline) | セルやタイルに置くインラインの推移グラフ |
|
|
127
128
|
| [`FilterBar`](parts/filter-bar) | フィルタ一式を 1 つの値で扱う行 |
|
|
128
129
|
| [`DateRangePicker`](parts/date-range-picker) | プリセット付きの期間選択 |
|
|
129
130
|
| [`SegmentedControl`](parts/segmented-control) | 単一選択のセグメント |
|
|
@@ -132,6 +133,7 @@ shadcn/ui のプリミティブです。名前も props も shadcn/ui のもの
|
|
|
132
133
|
| [`MetricValue`](parts/metric-value) | KPI の数値と単位 |
|
|
133
134
|
| [`TrendIndicator`](parts/trend-indicator) | 増減の矢印と変化率 |
|
|
134
135
|
| [`StatusBadge`](parts/status-badge) | ドット付きステータスバッジ |
|
|
136
|
+
| [`Placeholder`](parts/placeholder) | 仮データであることを示すインラインの目印 |
|
|
135
137
|
|
|
136
138
|
## `@squadbase/vantage/markdown`
|
|
137
139
|
|
package/docs/ja/data-fetching.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Vantage はサーバー状態のために **管理された TanStack Query** を同梱しています。`QueryClient` の
|
|
6
6
|
セットアップは不要で、`@squadbase/vantage/query` から `useQuery` などを import するだけです。
|
|
7
|
+
自分の `server/api` を呼ぶなら、後述の [`useApiQuery`](#自分の-api-を呼ぶ--useapiquery) が近道です。
|
|
7
8
|
|
|
8
9
|
```tsx
|
|
9
10
|
import { useQuery } from "@squadbase/vantage/query";
|
|
@@ -39,6 +40,12 @@ Vantage が用意する `QueryClient` は 1 つだけで、次のデフォルト
|
|
|
39
40
|
| `staleTime` | 30 秒 |
|
|
40
41
|
| `retry` | 1 |
|
|
41
42
|
| `refetchOnWindowFocus` | `false` |
|
|
43
|
+
| `networkMode` | `"always"`(queries / mutations とも) |
|
|
44
|
+
|
|
45
|
+
`networkMode: "always"` は、ブラウザのオフライン判定を無視して常にリクエストとリトライを行う
|
|
46
|
+
設定です。既定の `"online"` だと、オフラインと判定された瞬間に失敗したクエリが *paused* に
|
|
47
|
+
なり、エラーにならないまま読み込み表示が残り続けます。ダッシュボードは自分のオリジン(または
|
|
48
|
+
設定した API ベース)と話すので、その判定は当てになりません。
|
|
42
49
|
|
|
43
50
|
カスタマイズは**クエリごとのオプションで上書き**します。`QueryClient` 丸ごとの差し替えは、
|
|
44
51
|
管理されたスタックを保つため意図的に公開していません。
|
|
@@ -57,21 +64,78 @@ useQuery({
|
|
|
57
64
|
> `@tanstack/react-query` を直接 import しないでください。`@squadbase/vantage/query` の
|
|
58
65
|
> キュレートされた再エクスポートを使うことで、Vantage が下層ライブラリを安全に進化させられます。
|
|
59
66
|
|
|
60
|
-
## API
|
|
67
|
+
## 自分の API を呼ぶ — useApiQuery
|
|
68
|
+
|
|
69
|
+
`server/api` のルートを呼ぶときは `useApiQuery` を使います。`useQuery` に、毎回書いていた
|
|
70
|
+
定型(ベース URL の解決・JSON パース・非 2xx のエラー化・クエリキー)を足したものです。
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { useApiQuery } from "@squadbase/vantage/query";
|
|
74
|
+
|
|
75
|
+
interface Monthly {
|
|
76
|
+
monthly: { month: string; revenue: number }[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default function MonthlyAnalysis() {
|
|
80
|
+
const { data, isPending, error } = useApiQuery<Monthly>("/api/monthly-analysis");
|
|
81
|
+
|
|
82
|
+
if (isPending) return <p>読み込み中…</p>;
|
|
83
|
+
if (error) return <p>{error.message}</p>;
|
|
84
|
+
return <Chart data={data.monthly} />;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
クエリ文字列は `search` で渡します。`undefined` の項目は落ちるので、未設定のフィルタは
|
|
89
|
+
URL にもクエリキーにも現れません。
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
const query = useApiQuery<Row[]>("/api/customers", {
|
|
93
|
+
search: { segment, from: range.from, to: range.to },
|
|
94
|
+
enabled: Boolean(segment), // useQuery のオプションはそのまま使える
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
クエリキーは既定で `["api", <クエリ文字列込みの URL>]` です。したがって `search` が変われば
|
|
99
|
+
再取得され、`invalidateQueries({ queryKey: ["api"] })` で API 由来のキャッシュを一括で捨てられます。
|
|
100
|
+
|
|
101
|
+
### エラーは ApiError
|
|
102
|
+
|
|
103
|
+
非 2xx のレスポンスは `ApiError` として throw されます。`message` は API が
|
|
104
|
+
[`HttpError`](api-and-server) で投げたメッセージ、それ以外は汎用のステータス文言です。
|
|
105
|
+
|
|
106
|
+
| プロパティ | 内容 |
|
|
107
|
+
|---|---|
|
|
108
|
+
| `message` | サーバーが `HttpError` で明示したメッセージ |
|
|
109
|
+
| `status` | HTTP ステータス |
|
|
110
|
+
| `body` | パース済みのレスポンスボディ |
|
|
111
|
+
| `requestId` | `x-vantage-request-id`。開発ターミナルのログと突き合わせられる |
|
|
112
|
+
|
|
113
|
+
### 書き込みは useApiMutation
|
|
114
|
+
|
|
115
|
+
変数はそのまま JSON ボディとして送られます。パスは関数でも渡せます。
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { useApiMutation, useQueryClient } from "@squadbase/vantage/query";
|
|
119
|
+
|
|
120
|
+
const queryClient = useQueryClient();
|
|
121
|
+
const save = useApiMutation<Customer, { id: string; name: string }>(
|
|
122
|
+
(vars) => `/api/customers/${vars.id}`,
|
|
123
|
+
{
|
|
124
|
+
method: "PUT",
|
|
125
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: ["api"] }),
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
save.mutate({ id: "1", name: "Northwind" });
|
|
130
|
+
```
|
|
61
131
|
|
|
62
|
-
|
|
63
|
-
`
|
|
132
|
+
hook が使えない場所(イベントハンドラなど)では `apiJson(path, init)` を直接呼べます。
|
|
133
|
+
生の `Response` が欲しい場合は `apiFetch` です。
|
|
64
134
|
|
|
65
135
|
> [!TIP]
|
|
66
|
-
>
|
|
67
|
-
>
|
|
68
|
-
>
|
|
69
|
-
>
|
|
70
|
-
> ```tsx
|
|
71
|
-
> import { apiFetch } from "@squadbase/vantage/query";
|
|
72
|
-
>
|
|
73
|
-
> queryFn: () => apiFetch("/api/customers").then((r) => r.json());
|
|
74
|
-
> ```
|
|
136
|
+
> 外部 API を呼ぶときは `useQuery` + `fetch` をそのまま使います。`useApiQuery` は
|
|
137
|
+
> `apiFetch` 経由なので、[`PUBLIC_API_BASE_URL`](build-and-deploy) を設定すれば
|
|
138
|
+
> フロントとサーバーを別オリジンにデプロイしても、ページのコードは変わりません。
|
|
75
139
|
|
|
76
140
|
## 次に読む
|
|
77
141
|
|
|
@@ -22,7 +22,8 @@ default export が無いページは `vantage check` が `MISSING_DEFAULT_EXPORT
|
|
|
22
22
|
import { definePage } from "@squadbase/vantage";
|
|
23
23
|
|
|
24
24
|
export const page = definePage({
|
|
25
|
-
title: "月次分析",
|
|
25
|
+
title: "月次分析 · Acme Analytics",
|
|
26
|
+
navLabel: "月次分析",
|
|
26
27
|
description: "売上と主要指標の月次サマリー",
|
|
27
28
|
});
|
|
28
29
|
|
|
@@ -33,8 +34,10 @@ export default function MonthlyAnalysis() {
|
|
|
33
34
|
|
|
34
35
|
- `title` は `document.title` を駆動します(末端のルートマッチのタイトルが使われ、無ければ
|
|
35
36
|
ドキュメント初期の `<title>` にフォールバック)。
|
|
36
|
-
- `
|
|
37
|
-
|
|
37
|
+
- `navLabel` は [`useRoutes()`](routing#ルート一覧からナビを作る) で組むナビの表示名です。
|
|
38
|
+
省略すると `title` が使われます。`title` にサイト名を含めるときに分けます。
|
|
39
|
+
- `title`/`description`/`navLabel` は **生成時に静的に読まれます**。Vantage はページを実行して
|
|
40
|
+
読むのではなく、ソースを静的に解析します。したがって値は**リテラル**にしてください。
|
|
38
41
|
|
|
39
42
|
> [!WARNING]
|
|
40
43
|
> `export const page = definePage({...})` の**エクスポート名は `page` 固定**です。別名にすると
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Placeholder
|
|
2
|
+
|
|
3
|
+
> 仮データであることを示す、インラインの目印。
|
|
4
|
+
|
|
5
|
+
まだ本物のデータを繋いでいない箇所を「仮置き」として見せます。薄い色と `animate-pulse` が
|
|
6
|
+
**「ここは差し替える値だ」**という合図になり、実データを入れ忘れたまま共有してしまう事故を防ぎます。
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { Placeholder } from "@squadbase/vantage/components";
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| Prop | Type | 説明 |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| `children` | `ReactNode` | 仮の値。文字列でも要素でもよい。 |
|
|
15
|
+
| `className` | `string` | 大きさ・太さなどの上書き(例: `text-2xl font-medium`)。 |
|
|
16
|
+
|
|
17
|
+
残りの props は `<span>` にそのまま渡ります。
|
|
18
|
+
|
|
19
|
+
## `Skeleton` との違い
|
|
20
|
+
|
|
21
|
+
| | 用途 | 要素 |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| [`Skeleton`](ui/skeleton) | **読み込み中**。実データが来れば消える | ブロック `<div>` |
|
|
24
|
+
| `Placeholder` | **仮の値**。実装者が差し替えるまで残る | インライン `<span>` |
|
|
25
|
+
|
|
26
|
+
インライン要素なので、`<p>` や見出しの**文中に置けます**。`Skeleton` はブロック要素なので、
|
|
27
|
+
文中に混ぜると行が崩れます。
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
<p>
|
|
31
|
+
今月の売上は <Placeholder>¥1,240,000</Placeholder> でした。
|
|
32
|
+
</p>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> [!TIP]
|
|
36
|
+
> テンプレートから作り始めたときは、`Placeholder` を検索して潰していけば「まだ繋いでいない箇所」の
|
|
37
|
+
> チェックリストになります。
|