@squadbase/vantage 0.0.1 → 0.1.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 (187) hide show
  1. package/README.md +24 -4
  2. package/dist/{chunk-ZGDU5YLH.js → chunk-5L2MH2NG.js} +16 -7
  3. package/dist/chunk-5L2MH2NG.js.map +1 -0
  4. package/dist/chunk-7IPAXPPY.js +51 -0
  5. package/dist/chunk-7IPAXPPY.js.map +1 -0
  6. package/dist/chunk-A2UUGASH.js +12 -0
  7. package/dist/chunk-A2UUGASH.js.map +1 -0
  8. package/dist/chunk-DTDVSFRY.js +29 -0
  9. package/dist/chunk-DTDVSFRY.js.map +1 -0
  10. package/dist/chunk-WQZYXXQW.js +2249 -0
  11. package/dist/chunk-WQZYXXQW.js.map +1 -0
  12. package/dist/{chunk-73J5ZD4C.js → chunk-YLAB6UQS.js} +17 -3
  13. package/dist/chunk-YLAB6UQS.js.map +1 -0
  14. package/dist/cli.js +607 -36
  15. package/dist/cli.js.map +1 -1
  16. package/dist/client/index.d.ts +2 -1
  17. package/dist/client/index.js +3 -1
  18. package/dist/client/index.js.map +1 -1
  19. package/dist/components/index.d.ts +575 -0
  20. package/dist/components/index.js +2097 -0
  21. package/dist/components/index.js.map +1 -0
  22. package/dist/{define-page-B6y9TOfZ.d.ts → define-page-BfhrK99G.d.ts} +5 -0
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/markdown/index.d.ts +9 -0
  27. package/dist/markdown/index.js +26 -0
  28. package/dist/markdown/index.js.map +1 -0
  29. package/dist/query/index.d.ts +95 -2
  30. package/dist/query/index.js +102 -1
  31. package/dist/query/index.js.map +1 -1
  32. package/dist/router/index.d.ts +86 -1
  33. package/dist/router/index.js +71 -7
  34. package/dist/router/index.js.map +1 -1
  35. package/dist/server/node.js +6 -1
  36. package/dist/server/node.js.map +1 -1
  37. package/dist/ui/index.d.ts +316 -200
  38. package/dist/ui/index.js +566 -511
  39. package/dist/ui/index.js.map +1 -1
  40. package/dist/vite/index.js +2 -2
  41. package/docs/en/agent-skills.md +89 -0
  42. package/docs/en/api-and-server.md +84 -0
  43. package/docs/en/build-and-deploy.md +280 -0
  44. package/docs/en/cli-reference.md +311 -0
  45. package/docs/en/components.md +235 -0
  46. package/docs/en/data-fetching.md +142 -0
  47. package/docs/en/environment-variables.md +69 -0
  48. package/docs/en/getting-started.md +95 -0
  49. package/docs/en/index.md +65 -0
  50. package/docs/en/markdown/markdown-renderer.md +44 -0
  51. package/docs/en/pages-and-metadata.md +59 -0
  52. package/docs/en/parts/app-shell.md +54 -0
  53. package/docs/en/parts/dashboard-card.md +64 -0
  54. package/docs/en/parts/data-table.md +86 -0
  55. package/docs/en/parts/date-range-picker.md +41 -0
  56. package/docs/en/parts/echart.md +53 -0
  57. package/docs/en/parts/filter-bar.md +66 -0
  58. package/docs/en/parts/funnel-steps.md +33 -0
  59. package/docs/en/parts/metric-value.md +23 -0
  60. package/docs/en/parts/multi-select.md +27 -0
  61. package/docs/en/parts/page-shell.md +45 -0
  62. package/docs/en/parts/placeholder.md +38 -0
  63. package/docs/en/parts/searchable-select.md +47 -0
  64. package/docs/en/parts/section-header.md +20 -0
  65. package/docs/en/parts/segmented-control.md +25 -0
  66. package/docs/en/parts/sparkline.md +47 -0
  67. package/docs/en/parts/status-badge.md +44 -0
  68. package/docs/en/parts/trend-indicator.md +26 -0
  69. package/docs/en/routing.md +177 -0
  70. package/docs/en/ui/accordion.md +36 -0
  71. package/docs/en/ui/alert.md +31 -0
  72. package/docs/en/ui/badge.md +23 -0
  73. package/docs/en/ui/breadcrumb.md +38 -0
  74. package/docs/en/ui/button.md +39 -0
  75. package/docs/en/ui/calendar.md +28 -0
  76. package/docs/en/ui/card.md +35 -0
  77. package/docs/en/ui/checkbox.md +34 -0
  78. package/docs/en/ui/cn.md +34 -0
  79. package/docs/en/ui/collapsible.md +21 -0
  80. package/docs/en/ui/command.md +37 -0
  81. package/docs/en/ui/dialog.md +52 -0
  82. package/docs/en/ui/dropdown-menu.md +50 -0
  83. package/docs/en/ui/empty.md +22 -0
  84. package/docs/en/ui/error-state.md +50 -0
  85. package/docs/en/ui/input-group.md +30 -0
  86. package/docs/en/ui/input.md +28 -0
  87. package/docs/en/ui/label.md +19 -0
  88. package/docs/en/ui/loading.md +19 -0
  89. package/docs/en/ui/popover.md +34 -0
  90. package/docs/en/ui/progress.md +28 -0
  91. package/docs/en/ui/scroll-area.md +23 -0
  92. package/docs/en/ui/select.md +63 -0
  93. package/docs/en/ui/separator.md +15 -0
  94. package/docs/en/ui/sheet.md +28 -0
  95. package/docs/en/ui/sidebar.md +92 -0
  96. package/docs/en/ui/skeleton.md +16 -0
  97. package/docs/en/ui/slider.md +21 -0
  98. package/docs/en/ui/spinner.md +14 -0
  99. package/docs/en/ui/switch.md +19 -0
  100. package/docs/en/ui/table.md +24 -0
  101. package/docs/en/ui/tabs.md +23 -0
  102. package/docs/en/ui/textarea.md +15 -0
  103. package/docs/en/ui/toggle-group.md +26 -0
  104. package/docs/en/ui/toggle.md +19 -0
  105. package/docs/en/ui/tooltip.md +22 -0
  106. package/docs/en/ui/use-is-mobile.md +18 -0
  107. package/docs/en/ui-and-theming.md +95 -0
  108. package/docs/index.json +1346 -0
  109. package/docs/ja/agent-skills.md +87 -0
  110. package/docs/ja/api-and-server.md +84 -0
  111. package/docs/ja/build-and-deploy.md +279 -0
  112. package/docs/ja/cli-reference.md +305 -0
  113. package/docs/ja/components.md +231 -0
  114. package/docs/ja/data-fetching.md +142 -0
  115. package/docs/ja/environment-variables.md +68 -0
  116. package/docs/ja/getting-started.md +95 -0
  117. package/docs/ja/index.md +65 -0
  118. package/docs/ja/markdown/markdown-renderer.md +43 -0
  119. package/docs/ja/pages-and-metadata.md +59 -0
  120. package/docs/ja/parts/app-shell.md +54 -0
  121. package/docs/ja/parts/dashboard-card.md +64 -0
  122. package/docs/ja/parts/data-table.md +85 -0
  123. package/docs/ja/parts/date-range-picker.md +41 -0
  124. package/docs/ja/parts/echart.md +52 -0
  125. package/docs/ja/parts/filter-bar.md +64 -0
  126. package/docs/ja/parts/funnel-steps.md +33 -0
  127. package/docs/ja/parts/metric-value.md +25 -0
  128. package/docs/ja/parts/multi-select.md +27 -0
  129. package/docs/ja/parts/page-shell.md +45 -0
  130. package/docs/ja/parts/placeholder.md +37 -0
  131. package/docs/ja/parts/searchable-select.md +47 -0
  132. package/docs/ja/parts/section-header.md +20 -0
  133. package/docs/ja/parts/segmented-control.md +26 -0
  134. package/docs/ja/parts/sparkline.md +47 -0
  135. package/docs/ja/parts/status-badge.md +44 -0
  136. package/docs/ja/parts/trend-indicator.md +26 -0
  137. package/docs/ja/routing.md +175 -0
  138. package/docs/ja/ui/accordion.md +37 -0
  139. package/docs/ja/ui/alert.md +31 -0
  140. package/docs/ja/ui/badge.md +23 -0
  141. package/docs/ja/ui/breadcrumb.md +38 -0
  142. package/docs/ja/ui/button.md +39 -0
  143. package/docs/ja/ui/calendar.md +28 -0
  144. package/docs/ja/ui/card.md +35 -0
  145. package/docs/ja/ui/checkbox.md +34 -0
  146. package/docs/ja/ui/cn.md +34 -0
  147. package/docs/ja/ui/collapsible.md +21 -0
  148. package/docs/ja/ui/command.md +36 -0
  149. package/docs/ja/ui/dialog.md +51 -0
  150. package/docs/ja/ui/dropdown-menu.md +50 -0
  151. package/docs/ja/ui/empty.md +22 -0
  152. package/docs/ja/ui/error-state.md +50 -0
  153. package/docs/ja/ui/input-group.md +30 -0
  154. package/docs/ja/ui/input.md +28 -0
  155. package/docs/ja/ui/label.md +19 -0
  156. package/docs/ja/ui/loading.md +19 -0
  157. package/docs/ja/ui/popover.md +34 -0
  158. package/docs/ja/ui/progress.md +28 -0
  159. package/docs/ja/ui/scroll-area.md +24 -0
  160. package/docs/ja/ui/select.md +64 -0
  161. package/docs/ja/ui/separator.md +15 -0
  162. package/docs/ja/ui/sheet.md +28 -0
  163. package/docs/ja/ui/sidebar.md +92 -0
  164. package/docs/ja/ui/skeleton.md +16 -0
  165. package/docs/ja/ui/slider.md +21 -0
  166. package/docs/ja/ui/spinner.md +14 -0
  167. package/docs/ja/ui/switch.md +19 -0
  168. package/docs/ja/ui/table.md +24 -0
  169. package/docs/ja/ui/tabs.md +24 -0
  170. package/docs/ja/ui/textarea.md +15 -0
  171. package/docs/ja/ui/toggle-group.md +27 -0
  172. package/docs/ja/ui/toggle.md +19 -0
  173. package/docs/ja/ui/tooltip.md +22 -0
  174. package/docs/ja/ui/use-is-mobile.md +18 -0
  175. package/docs/ja/ui-and-theming.md +95 -0
  176. package/package.json +29 -4
  177. package/registry/blocks/sales-overview.tsx +43 -19
  178. package/registry/ui/data-table.tsx +702 -102
  179. package/skills/vantage-add-feature/SKILL.md +153 -0
  180. package/skills/vantage-app/SKILL.md +291 -0
  181. package/skills/vantage-pitfalls/SKILL.md +139 -0
  182. package/templates/AGENTS.md +313 -0
  183. package/theme.css +178 -40
  184. package/dist/chunk-73J5ZD4C.js.map +0 -1
  185. package/dist/chunk-ATYZ45XL.js +0 -19
  186. package/dist/chunk-ATYZ45XL.js.map +0 -1
  187. package/dist/chunk-ZGDU5YLH.js.map +0 -1
@@ -0,0 +1,280 @@
1
+ # Build & deploy
2
+
3
+ > What's in dist/ and vantage-manifest.json. Same-origin serving, and splitting the client and server across origins (S3+CloudFront ⇄ Lambda, etc.).
4
+
5
+ `vantage build` emits the production artifacts into `dist/`. From there, serving splits into two shapes:
6
+ serve the client and server together from the **same origin**, or **split** them — the client on static
7
+ hosting (S3+CloudFront / Cloudflare Pages) and the server on a separate origin (Lambda / a container).
8
+ For the split shape, Vantage provides an **API base URL switch** and **CORS**.
9
+
10
+ ## Build output
11
+
12
+ ```bash
13
+ vantage build # → dist/
14
+ ```
15
+
16
+ ```text
17
+ dist/
18
+ ├── client/ Client (index.html + hashed assets, code-split per route)
19
+ ├── server/index.mjs Only when server/ exists (esbuild / node20 / ESM bundle)
20
+ └── vantage-manifest.json Deploy contract
21
+ ```
22
+
23
+ `vantage-manifest.json` is the one contract the host reads. Its fields:
24
+
25
+ | Field | Meaning |
26
+ |---|---|
27
+ | `schemaVersion` | Manifest schema version (currently `1`) |
28
+ | `mode` | `"spa"` (client only) / `"fullstack"` (has server). Derived from `server/` |
29
+ | `client` | Relative path to the client output (`"./client"`) |
30
+ | `server` | Relative path to the server bundle (`"./server/index.mjs"`). Fullstack only |
31
+ | `spaFallback` | HTML for the SPA fallback (`"./client/index.html"`) |
32
+ | `runtime` | Server runtime (`"node"`) |
33
+
34
+ > [!NOTE]
35
+ > `mode` is decided automatically by the presence of a `server/` directory: no `server/` → `spa`
36
+ > (client only); with it → `fullstack`. The same derivation is used by `vantage check` and
37
+ > `vantage routes`.
38
+
39
+ ## Preview locally
40
+
41
+ Before deploying, run the production build locally to verify it.
42
+
43
+ ```bash
44
+ vantage preview
45
+ ```
46
+
47
+ `vantage preview` reads `mode` from `vantage-manifest.json`: `fullstack` starts the Node server
48
+ (default `:4173`), `spa` serves a static preview.
49
+
50
+ ## Two deployment shapes
51
+
52
+ ### Same origin
53
+
54
+ One Node process serves both the client and `/api`. Minimal setup, and no CORS needed.
55
+
56
+ ### Split client & server
57
+
58
+ Client on S3+CloudFront etc., server on Lambda / a container. Needs the API base URL switch
59
+ and CORS.
60
+
61
+ ## Deploy to a single origin
62
+
63
+ The simplest shape. Place all of `dist/` on a host that runs Node (a container / VM) and start the
64
+ generated server. One process serves both static assets and `/api/*`, so there is nothing to switch
65
+ and no CORS to configure.
66
+
67
+ ```bash
68
+ # on the host where dist/ lives
69
+ PORT=8080 node dist/server/index.mjs
70
+ ```
71
+
72
+ The server listens on `PORT` (or `3000` if unset). The client calls relative `/api/...` paths on the
73
+ same origin.
74
+
75
+ > [!NOTE]
76
+ > `spa` mode (no `server/`) has no server to start. Upload `dist/client/` to any static host and fall
77
+ > back unknown paths to `index.html` (see the SPA fallback settings below).
78
+
79
+ ## Split the client and server (S3+CloudFront ⇄ Lambda)
80
+
81
+ Here the client lives on CDN static hosting and the server on a separate origin. A common pairing is
82
+ "`dist/client` on S3+CloudFront, `dist/server/index.mjs` on Lambda / a container". Because the
83
+ origins differ, two things are required.
84
+
85
+ ### 1. Switch the API base URL
86
+
87
+ Client API calls go through `apiFetch` / `apiUrl` from `@squadbase/vantage/query`. This is the one
88
+ seam that calls `/api`, and it's where the base URL is swapped.
89
+
90
+ ```tsx
91
+ import { apiFetch, useQuery } from "@squadbase/vantage/query";
92
+
93
+ useQuery({
94
+ queryKey: ["monthly-analysis"],
95
+ // Keep the path as it maps in server/api (include /api)
96
+ queryFn: () => apiFetch("/api/monthly-analysis").then((r) => r.json()),
97
+ });
98
+ ```
99
+
100
+ The base URL is read from `PUBLIC_API_BASE_URL`. **Unset means empty**, so requests stay same-origin
101
+ relative paths (`/api/monthly-analysis`). Set it and the value is prepended
102
+ (`https://api.example.com/api/monthly-analysis`). Two ways to set it:
103
+
104
+ **(a) Override via env** — put it in `.env` or a CI environment variable. Because of the `PUBLIC_`
105
+ prefix it is inlined into the client bundle.
106
+
107
+ ```bash
108
+ # .env (or a CI env var)
109
+ PUBLIC_API_BASE_URL=https://api.example.com
110
+ ```
111
+
112
+ **(b) Specify at build time** — pass `--api-base-url` to `vantage build`.
113
+
114
+ ```bash
115
+ vantage build --api-base-url https://api.example.com
116
+ ```
117
+
118
+ > [!NOTE]
119
+ > `--api-base-url` **takes precedence** over `PUBLIC_API_BASE_URL` from `.env`. You can keep a base
120
+ > value in `.env` and override per environment with the flag.
121
+
122
+ > [!TIP]
123
+ > Pass the path to `apiUrl("/api/...")` with the **`/api` prefix included**, matching how it maps under
124
+ > `server/api/**`. The base URL represents the origin (or up to a prefix); the path is concatenated
125
+ > as-is.
126
+
127
+ ### 2. Allow CORS
128
+
129
+ Once the client and server are on different origins, the browser requires CORS. Setting `CORS_ORIGIN`
130
+ on the server enables CORS on `/api` (including the preflight `OPTIONS` response). **Unset means CORS
131
+ is off**, leaving same-origin serving unchanged.
132
+
133
+ ```bash
134
+ # environment variables on the server (Lambda / container)
135
+ CORS_ORIGIN=https://app.example.com # a single origin
136
+ # CORS_ORIGIN=https://a.example.com,https://b.example.com # comma-separated for several
137
+ # CORS_ORIGIN=* # allow all (not usable with credentials)
138
+ CORS_CREDENTIALS=true # only if you allow cookies / credentials
139
+ ```
140
+
141
+ | Variable | Role |
142
+ |---|---|
143
+ | `CORS_ORIGIN` | Allowed origin(s): `*` / a single value / comma-separated. Unset → CORS off |
144
+ | `CORS_CREDENTIALS` | When `true`, allow credentials (cookies, etc.). Not used with `*` |
145
+
146
+ The allowed methods are set automatically to the ones Vantage APIs can use
147
+ (`GET,POST,PUT,PATCH,DELETE,OPTIONS`). This behavior is **shared** by the dev server and the
148
+ production Node server, so you can verify CORS during development.
149
+
150
+ ### 3. Put the client on static hosting
151
+
152
+ Upload `dist/client/` to S3 (+ CloudFront) or Cloudflare Pages. As an SPA, unknown paths must fall
153
+ back to `spaFallback` (`index.html`).
154
+
155
+ - **S3 + CloudFront**: use a CloudFront "custom error response" to rewrite `403` / `404` to
156
+ `/index.html` with status `200`.
157
+ - **S3 static website hosting**: set the error document to `index.html`.
158
+ - **Cloudflare Pages**: SPA fallback is on by default.
159
+
160
+ ### 4. Put the server on Lambda / a container
161
+
162
+ `dist/server/index.mjs` is a Node HTTP server that listens on `PORT` (the manifest's `runtime` is
163
+ `"node"`). It runs anywhere a Node process runs.
164
+
165
+ - **Container (Cloud Run / ECS·Fargate / Render / Fly, etc.)**: use `node dist/server/index.mjs` as
166
+ the start command and pass `PORT`.
167
+ - **AWS Lambda**: since it is a listening Node server, a container image + AWS Lambda Web Adapter (or
168
+ another "run an HTTP server on Lambda" approach) is a good fit.
169
+ - Pass secrets (DB credentials, API keys) as **server environment variables**. They are only readable
170
+ via `ApiContext.env` and never reach the client.
171
+
172
+ > [!WARNING]
173
+ > The production Node server snapshots `process.env` **once at startup** (dev re-reads it per request).
174
+ > Restart the server after changing environment variables.
175
+
176
+ ## Deploy to AWS Lambda (a concrete walkthrough)
177
+
178
+ The generated `dist/server/index.mjs` is a Node HTTP server that **listens** on `PORT`. Lambda, on the
179
+ other hand, invokes a handler per event, so the natural way to run a listening server there is to put
180
+ the [AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter) (LWA) in front of it.
181
+ LWA proxies Function URL / API Gateway events to the HTTP server running locally. No Vantage code
182
+ changes are needed.
183
+
184
+ ### 1. Run it as a container image (recommended)
185
+
186
+ esbuild bundles into a **single file** `dist/server/index.mjs`, so you don't need to carry
187
+ `node_modules`.
188
+
189
+ ```dockerfile
190
+ # Dockerfile
191
+ FROM public.ecr.aws/docker/library/node:20-slim
192
+
193
+ # Bundle the Lambda Web Adapter as an extension (bump the version as needed)
194
+ COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.9.1 /lambda-adapter /opt/extensions/lambda-adapter
195
+
196
+ WORKDIR /var/task
197
+ # Copy all of dist/ (the server resolves ../client, so keep the layout)
198
+ COPY dist ./dist
199
+
200
+ # Keep LWA and the Node server on the same port (LWA defaults to 8080)
201
+ ENV PORT=8080
202
+ CMD ["node", "dist/server/index.mjs"]
203
+ ```
204
+
205
+ ```bash
206
+ vantage build # produce dist/
207
+ docker build -t vantage-api .
208
+
209
+ # Log in to ECR and push (<acct> / <region> are yours)
210
+ aws ecr get-login-password --region ap-northeast-1 \
211
+ | docker login --username AWS --password-stdin <acct>.dkr.ecr.ap-northeast-1.amazonaws.com
212
+ docker tag vantage-api <acct>.dkr.ecr.ap-northeast-1.amazonaws.com/vantage-api:latest
213
+ docker push <acct>.dkr.ecr.ap-northeast-1.amazonaws.com/vantage-api:latest
214
+ ```
215
+
216
+ Create a Lambda function from this image and enable a **Function URL** to get an HTTPS endpoint. Use
217
+ it as the `/api/*` origin in CloudFront, or point the client's `PUBLIC_API_BASE_URL` at it directly.
218
+
219
+ > [!TIP]
220
+ > **Running from a zip**
221
+ > You can also run from a zip instead of a container. Since the output is bundled, zip
222
+ > `dist/server/index.mjs` (and `dist/client` if you want), attach LWA as a **Lambda layer**, set
223
+ > `AWS_LAMBDA_EXEC_WRAPPER=/opt/bootstrap` and `PORT=8080`, and use the Node.js 20.x runtime.
224
+
225
+ ### 2. Set the Lambda environment variables
226
+
227
+ Pass server config and secrets as Lambda environment variables (they never reach the client).
228
+
229
+ | Variable | Example | Purpose |
230
+ |---|---|---|
231
+ | `CORS_ORIGIN` | `https://d111111abcdef8.cloudfront.net` | Allow the client's origin |
232
+ | `CORS_CREDENTIALS` | `true` | Only if you use cookies / credentials |
233
+ | `SECRET_*`, etc. | `sk_live_xxx` | Secrets read via `ApiContext.env` |
234
+
235
+ `PORT` is already set in the Dockerfile (matching LWA's default 8080).
236
+
237
+ > [!NOTE]
238
+ > A Function URL has its own CORS settings, but configuring CORS **both** there and in the app
239
+ > (`CORS_ORIGIN`) **conflicts**. Consolidate on Vantage's `CORS_ORIGIN` and leave the Function URL's
240
+ > CORS empty for a clearer setup.
241
+
242
+ ### 3. Point the client at Lambda
243
+
244
+ At client build time, set `PUBLIC_API_BASE_URL` to the Lambda (or the CloudFront in front of it)
245
+ origin.
246
+
247
+ ```bash
248
+ vantage build --api-base-url https://d111111abcdef8.cloudfront.net
249
+ ```
250
+
251
+ `apiUrl("/api/monthly-analysis")` then calls that origin with `/api/monthly-analysis` appended.
252
+
253
+ > [!WARNING]
254
+ > Lambda starts the process on a cold start and reads `process.env` at that moment. After changing
255
+ > environment variables, deploy a new version to apply them (running environments are not updated
256
+ > retroactively).
257
+
258
+ ## Production environment variables at a glance
259
+
260
+ The boundary is the prefix (see also [Environment variables](environment-variables)).
261
+
262
+ | Kind | Set where | When it applies | Example |
263
+ |---|---|---|---|
264
+ | Public client value | Build time (`.env` / `--api-base-url`) | Baked into the build | `PUBLIC_API_BASE_URL` |
265
+ | Server config | Server environment variable | Read at startup | `PORT`, `CORS_ORIGIN`, `CORS_CREDENTIALS` |
266
+ | Secret | Server environment variable | Read at startup (`ApiContext.env`) | `SECRET_API_KEY`, etc. |
267
+
268
+ ## Pre-deploy checklist
269
+
270
+ - [ ] `vantage check` passes with no errors
271
+ - [ ] `vantage build` (with `--api-base-url` for a split setup, or `PUBLIC_API_BASE_URL` in `.env`)
272
+ - [ ] `vantage preview` verifies it locally
273
+ - [ ] For a split setup, set `CORS_ORIGIN` (the client's origin) on the server
274
+ - [ ] Configure SPA fallback (unknown paths → `index.html`) on the static host
275
+ - [ ] Keep secrets in server environment variables only (never expose to the client)
276
+
277
+ ## What to read next
278
+
279
+ - [CLI reference](cli-reference) — every command, including the `build` flags
280
+ - [Environment variables](environment-variables) — the public / secret boundary
@@ -0,0 +1,311 @@
1
+ # CLI reference
2
+
3
+ > Every vantage command. dev, build, preview, check, routes, add, docs, search, doctor, upgrade.
4
+
5
+ `vantage` is the only CLI an app author uses. Run it from the project root unless noted.
6
+
7
+ ## Commands
8
+
9
+ | Command | Role |
10
+ |---|---|
11
+ | `vantage dev` | Dev server (HMR + optional API). Default `:5173` |
12
+ | `vantage build` | Build client + optional server → `dist/` |
13
+ | `vantage preview` | Run the production build locally (fullstack default `:4173`; spa via Vite preview) |
14
+ | `vantage check` | Static checks (routes, boundaries, forbidden files). Exit 1 on error |
15
+ | `vantage routes` | Print the page + API URL map |
16
+ | `vantage add <kind> <name>` | Scaffold or place a `page` / `api` / `ui` / `block` / `skill` / `agents` (`--force` to overwrite) |
17
+ | `vantage docs [name]` | Show the bundled guide and component reference |
18
+ | `vantage search <query>` | Search that same reference in full text (natural language or `--regex`) |
19
+ | `vantage doctor` | Diagnose environment / installation health |
20
+ | `vantage upgrade` | Regenerate artifacts and sync a placed `AGENTS.md` from the canonical copy |
21
+
22
+ ## Quick mode (pass a path directly)
23
+
24
+ Instead of `cd`-ing in before running a command, you can pass a **project path directly**. When the
25
+ first argument isn't a known command but points at a filesystem path, Vantage starts `dev` with that
26
+ path as the root (printing `quick dev → <path>`).
27
+
28
+ ```bash
29
+ vantage ./demo # folder → run dev inside it
30
+ vantage ./demo/index.tsx # page file → use its parent folder as the root
31
+ ```
32
+
33
+ Path resolution rules:
34
+
35
+ | Path you pass | Root that's used |
36
+ |---|---|
37
+ | A directory | the directory itself |
38
+ | A `.tsx` / `.jsx` page file | its parent directory |
39
+ | A missing path / anything else | none (`Unknown command` error) |
40
+
41
+ Every root-scoped command except `add`, `docs` and `search` may also take a trailing path positional. You can spell out
42
+ `dev`, or pass the same path to `build` / `check` / `routes`, etc.
43
+
44
+ ```bash
45
+ vantage dev ./demo # explicit quick dev
46
+ vantage build ./demo # build ./demo
47
+ vantage check ./demo/index.tsx # a file argument still checks its parent directory
48
+ ```
49
+
50
+ > [!NOTE]
51
+ > `add`, `docs` and `search` use their positionals for their own arguments (`add page dashboard`,
52
+ > `docs button`, `search date picker`) rather than a path, so they are excluded from this shortcut.
53
+
54
+ ## `vantage docs` — read the docs from the CLI
55
+
56
+ The content of this site is **bundled into the package**, so `vantage docs` prints it as plain
57
+ Markdown. No network and no browser, which makes it the fastest way for a coding agent to check
58
+ props.
59
+
60
+ ```bash
61
+ vantage docs # list every page (guide + components)
62
+ vantage docs button # show one page (short name → ui/button)
63
+ vantage docs parts/data-table # full slugs work too
64
+ vantage docs --all # concatenate every page
65
+ ```
66
+
67
+ | Flag | Meaning |
68
+ |---|---|
69
+ | `--list` | List page names only (no body) |
70
+ | `--all` | Concatenate every page |
71
+ | `--json` | Machine-readable (`{ slug, title, description, section, content }`) |
72
+ | `--lang <ja\|en>` | Language (default `ja`) |
73
+
74
+ With no argument, `vantage docs` lists **slugs and descriptions** by section — the left column is what
75
+ you pass back in.
76
+
77
+ ```text
78
+ $ vantage docs --lang en
79
+
80
+ Guide
81
+ index A config-free React dashboard framework. You only write index.tsx.
82
+ getting-started From install to running your first Vantage app.
83
+ routing Dropping a file creates a route. Conventions for pages, layouts, dynamic params, and 404/error.
84
+
85
+
86
+ @squadbase/vantage/ui
87
+ ui/accordion A stack of headings that open and close. One at a time by default.
88
+ ui/alert An in-page notice that flags something while the content is still shown.
89
+ ui/badge A small label for counts, states and tags.
90
+
91
+
92
+ vantage docs <name> show one page --json machine-readable
93
+ vantage docs --all show every page --lang ja | en
94
+ ```
95
+
96
+ Pass a name and the page prints **as Markdown** (headings and quotes are coloured on a TTY, plain when
97
+ piped). Prop tables stay readable as Markdown tables.
98
+
99
+ ````text
100
+ $ vantage docs button --lang en
101
+
102
+ # Button
103
+
104
+ > The button, with six variants and eight sizes.
105
+
106
+ The component you'll reach for most. `variant` carries the meaning, `size` the scale.
107
+
108
+ ```tsx
109
+ import { Button, buttonVariants } from "@squadbase/vantage/ui";
110
+ ```
111
+
112
+ | Prop | Type | Default | Description |
113
+ | --- | --- | --- | --- |
114
+ | `variant` | `"default" \| "secondary" \| …` | `"default"` | Look and meaning. |
115
+ | `size` | `"default" \| "xs" \| "sm" \| …` | `"default"` | Height and padding. The `icon` sizes are square. |
116
+ | `render` | `ReactElement` | | Render as a different element (Radix's `asChild`). |
117
+
118
+ ````
119
+
120
+ Names resolve from their **short form**: `vantage docs button` finds `ui/button`, and
121
+ `vantage docs data-table` finds `parts/data-table`. An ambiguous or unknown name prints candidates and
122
+ exits 1.
123
+
124
+ ```text
125
+ $ vantage docs sele
126
+ ✗ No page named "sele". Did you mean: ui/select, parts/multi-select, parts/searchable-select?
127
+ ```
128
+
129
+ `--json` is one page, machine-readable; `content` holds the whole Markdown body.
130
+
131
+ ```json
132
+ {
133
+ "slug": "ui/badge",
134
+ "lang": "en",
135
+ "title": "Badge",
136
+ "description": "A small label for counts, states and tags.",
137
+ "section": "components/ui",
138
+ "sectionTitle": "@squadbase/vantage/ui",
139
+ "content": "# Badge\n\n> A small label for counts, states and tags.\n\nA small label to sit beside…"
140
+ }
141
+ ```
142
+
143
+ Links in the body are slugs, so `[DataTable](parts/data-table)` opens with
144
+ `vantage docs parts/data-table`.
145
+
146
+ > [!NOTE]
147
+ > What ships is the MDX converted to plain Markdown. Live previews are a site-only feature; the CLI
148
+ > gives you the prop tables, code samples, and callouts.
149
+
150
+ ## `vantage search` — find it without knowing its name
151
+
152
+ `vantage docs <name>` assumes you **know the name**. When you're coming from what you want to build —
153
+ "I need a UI for picking a date range" — use `vantage search`. It indexes the same bundled docs
154
+ (the guide plus every `ui` / `parts` / `markdown` component), and every result is a name you can hand
155
+ straight to `vantage docs <name>`.
156
+
157
+ ```bash
158
+ vantage search date range filter --lang en # natural language (quotes are optional)
159
+ vantage search "pagination" --lang en
160
+ vantage search "enable[A-Z]\w+" --regex # sweep prop names with a regular expression
161
+ vantage search chart --limit 3 --json # machine-readable
162
+ ```
163
+
164
+ | Flag | Meaning |
165
+ |---|---|
166
+ | `--regex` | Treat the query as a regular expression (case-insensitive) |
167
+ | `--limit <n>` | Results to show (default `10`) |
168
+ | `--json` | Machine-readable output |
169
+ | `--lang <ja\|en>` | Language (default `ja`) |
170
+
171
+ The default mode is **BM25 full-text search**. Names, titles and descriptions weigh more than body
172
+ prose, and each hit shows the **passage that matched**. Japanese is segmented at script boundaries
173
+ (kanji / katakana / hiragana), so a whole sentence works as a query.
174
+
175
+ ```text
176
+ $ vantage search date range picker --lang en --limit 3
177
+
178
+ parts/date-range-picker DateRangePicker · @squadbase/vantage/components
179
+ > A date-range picker with presets.
180
+ ui/calendar Calendar · @squadbase/vantage/ui
181
+ [`DateRangePicker`](parts/date-range-picker) gets you there faster than using this
182
+ components Components · Components
183
+ | [`DateRangePicker`](parts/date-range-picker) | Date range with presets |
184
+ ```
185
+
186
+ The left column is the slug to hand to `vantage docs <name>`, the right one is the title and where it
187
+ is imported from, and below each is the matching passage. The real output also prints a
188
+ `11 results for "…" en · bm25` header and a footer with what `--limit` hid (elided above). **The count
189
+ is how many pages matched at least one term**, so the tail is mostly irrelevant — read the first few
190
+ and raise `--limit` only if they miss.
191
+
192
+ `--json` is the same result set, machine-readable. `score` is the BM25 score and `command` is ready to
193
+ run (below: `vantage search pagination --lang en --limit 1 --json`).
194
+
195
+ ```json
196
+ {
197
+ "query": "pagination",
198
+ "mode": "bm25",
199
+ "lang": "en",
200
+ "count": 4,
201
+ "results": [
202
+ {
203
+ "slug": "parts/data-table",
204
+ "title": "DataTable",
205
+ "description": "The TanStack Table–backed table: sorting, search, pagination, selection.",
206
+ "section": "components/parts",
207
+ "sectionTitle": "@squadbase/vantage/components",
208
+ "command": "vantage docs parts/data-table",
209
+ "score": 5.404,
210
+ "snippet": "> The TanStack Table–backed table: sorting, search, pagination, selection."
211
+ }
212
+ ]
213
+ }
214
+ ```
215
+
216
+ `--regex` scans names, titles, descriptions and bodies, and prints matching lines **with line
217
+ numbers** — the mode to reach for when checking how a prop is spelled across pages.
218
+
219
+ ```text
220
+ $ vantage search "enable(Sorting|Filtering)" --regex --lang en
221
+
222
+ parts/data-table DataTable 4 matches
223
+ 30 | `enableSorting` | `boolean` | Sort by clicking a header. |
224
+ 31 | `enableFiltering` | `boolean` | Put a search box in the toolbar. |
225
+ 50 <DataTable columns={columns} data={data} enableSorting enableFiltering>
226
+ ```
227
+
228
+ Only the first 3 lines of a page are printed, but the `4 matches` count is exact. A page that matched
229
+ on its name, title or description alone is marked `name match` and prints no body lines. Finding
230
+ nothing is not an error (exit code 0, `"count": 0` with `--json`); only an invalid regular expression
231
+ exits 1.
232
+
233
+ > [!NOTE]
234
+ > The index is built at run time (tens of milliseconds, reading the bundled docs included). Nothing
235
+ > prebuilt ships alongside the docs, so search results can never drift from the documentation.
236
+ >
237
+ > **This page is part of the corpus too.** Run the queries above verbatim and this CLI reference — which
238
+ > contains them as examples — shows up among the hits; the sample output above leaves that row out.
239
+
240
+ ## `--json`
241
+
242
+ `check` / `routes` / `doctor` / `build` / `upgrade` / `docs` / `search` accept `--json`, useful for CI and agent
243
+ automation.
244
+
245
+ ```bash
246
+ vantage check --json
247
+ ```
248
+
249
+ ```json
250
+ {
251
+ "code": "ROUTE_CONFLICT",
252
+ "severity": "error",
253
+ "message": "2 files resolve to /sales",
254
+ "files": ["sales.tsx", "sales/index.tsx"],
255
+ "fix": "Rename or remove one route file so each route is unique."
256
+ }
257
+ ```
258
+
259
+ > [!NOTE]
260
+ > `build --json` prints a **compact single line**. Other commands' `--json` is pretty-printed with
261
+ > 2-space indentation.
262
+
263
+ ## `build --api-base-url`
264
+
265
+ `vantage build` accepts `--api-base-url` to set the base URL the client uses to call `/api`. Use it
266
+ when deploying the client and server on different origins.
267
+
268
+ ```bash
269
+ vantage build --api-base-url https://api.example.com
270
+ ```
271
+
272
+ The flag takes precedence over `PUBLIC_API_BASE_URL` from `.env`. Unset means empty (same-origin
273
+ relative paths). See [Build & deploy](build-and-deploy) for details.
274
+
275
+ ## Static diagnostics (`check`)
276
+
277
+ `vantage check` detects these six diagnostics (five errors, one warning).
278
+
279
+ | Code | Severity | Meaning |
280
+ |---|---|---|
281
+ | `FORBIDDEN_FILE` | error | A forbidden config file exists at the root |
282
+ | `ROUTE_CONFLICT` | error | Two files resolve to the same route |
283
+ | `MISSING_DEFAULT_EXPORT` | error | A page has no default export |
284
+ | `INVALID_API_EXPORT` | error | An API exports no valid HTTP method |
285
+ | `CLIENT_IMPORTS_SERVER` | error | Client code imports from `server/` |
286
+ | `PUBLIC_ENV_MISUSE` | warning | Client reads a non-`PUBLIC_` env variable |
287
+
288
+ None of them import or run your code — the checks are purely static.
289
+
290
+ ## Build output
291
+
292
+ Inside `dist/`:
293
+
294
+ ```text
295
+ dist/
296
+ ├── client/ Client (index.html + hashed assets)
297
+ ├── server/index.mjs Only when server/ exists
298
+ └── vantage-manifest.json Deploy contract (mode: "spa" | "fullstack")
299
+ ```
300
+
301
+ `vantage preview` reads the `mode` in `vantage-manifest.json` to decide between starting a Node
302
+ server or serving a static preview. Deployment is covered in detail in
303
+ [Build & deploy](build-and-deploy).
304
+
305
+ ## Done
306
+
307
+ That's the end of the app-author guide. Start from the smallest `index.tsx` and add pages, APIs, and
308
+ UI as you need them.
309
+
310
+ To hand those procedures to an AI agent, place the bundled [Agents and Skills](agent-skills)
311
+ with `vantage add skill`, and place the app map `AGENTS.md` with `vantage add agents`.