Changelog
What changed in each Vantage release, newest first. Still a prototype (0.x), so APIs may change between releases.
What changed in each Vantage release. Newest is on top.
v0.5.3
Adds a bundled skill for working with Squadbase Project Storage from the browser.
Anything on ^0.5.0 picks this up as-is.
Added
-
A
project-storageskill now ships with Vantage. It covers reading and writing Squadbase Project Storage — the files a user uploaded — from a page or component throughuseStorage()from@squadbase/react: listing files, embedding images / video / PDFs (including refreshing the short-lived URL), reading file contents, and uploading, deleting or moving.Place it like any other skill with
vantage add skill --all(add--dirto choose where it lands). No library code changed, so no app-side change is needed.
v0.5.2
Fixes an already-open tab getting stuck on chunks from a build that is no longer
served. Anything on ^0.5.0 picks this up as-is.
Fixed
-
A tab left open across a re-publish now follows the new build on its own. A published app is served build by build, and its HTML points at content-hashed chunks. Re-publish the app and a tab that stayed open asks for a chunk hash the newly-served build no longer has — the dynamic import behind a page transition fails with
Failed to fetch dynamically imported module, and the screen sits on the error until someone reloads by hand.Vantage now listens for Vite’s
vite:preloadError(and for the same failure arriving as an unhandled promise rejection) and reloads the page once to pick up the new build. A 10-second cooldown insessionStoragekeeps that to a single attempt, so a chunk that is genuinely unreachable — offline, or a build that is gone for good — does not turn into a reload loop: the second failure surfaces to the error boundary as before. No app-side change is needed.
v0.5.1
Fixes dark: utilities not being wired to the same switch as the theme tokens.
Anything on ^0.5.0 picks this up as-is.
Fixed
-
dark:now follows the.darkclass, not the OS setting. Tailwind’s stockdark:is@media (prefers-color-scheme: dark), but Vantage’s tokens only flip when an ancestor carries.dark/[data-theme="dark"]. In a browser set to OS dark mode that split the theme in two — background and text tokens stayed light while everydark:class fired. Text vanished on white cards, badges inverted on their own, and so on.// 0.5.0: on an OS-dark browser, this text disappeared against the white card <div className="text-slate-900 dark:text-slate-100">{name}</div>theme.cssnow bindsdark:to the same class as the tokens. Unless you add.dark/[data-theme="dark"]yourself, the app always renders light (→ UI and theming). If your app meant to follow the OS setting, set the class on your root element explicitly. -
color-schemeis now declared — browser-owned UI (scrollbars,<select>popups, autofill) no longer goes dark on an OS-dark machine while the app itself stays light.
v0.5.0
Browser-to-terminal forwarding now runs on Vite’s native mechanism. Which levels are forwarded and how they are printed both change, so the minor goes up, per the 0.x policy.
Apps pinned to "@squadbase/vantage": "^0.4.0" will not pick up 0.5.0 — bump the
range to ^0.5.0.
Changed
-
Browser-to-terminal forwarding is now Vite’s
server.forwardConsole(→ CLI reference) — replacing the hand-rolled bridge means uncaught errors arrive source-mapped, with a code frame around the offending line.1:46:34 PM [vite] (client) [Unhandled error] TypeError: rows.map is not a function > src/sales/index.tsx:12:18 12 | return <ul>{rows.map((r) => <li key={r.id}>{r.name}</li>)}</ul> | ^ -
Only
warn/errorare forwarded — a singleconsole.logthat runs on every render would bury the server’s own output. There is no option to widen it.
Added
vantage dev --no-overlay— hides the full-screen overlay the browser shows on a runtime error. Use it when the overlay is in the way rather than helpful: screenshots and demos, or when the error already reached the terminal and you want to look at the page underneath. On by default;--overlaystates it explicitly.
v0.4.0
An explicit --port is now exact. This includes a backwards-incompatible
change, so the minor goes up, per the 0.x policy.
Apps pinned to "@squadbase/vantage": "^0.3.0" will not pick up 0.4.0 — bump the
range to ^0.4.0.
Changed
- An explicit
--portis exact (→ CLI reference) — writing--port 3000means the port is a contract with something outside the process: a reverse proxy, a container port mapping, an OAuth redirect URI. Binding 3001 instead is a silent failure, not a recovery — a supervisor that only checks “is anything listening on 3000” will happily report a server nobody can reach. Without--port, a busy default still walks, so running several projects side by side is as easy as before. - An invalid
--portvalue is an error — a non-integer, an out-of-range number, or a missing value used to start the server on the default port.
Added
--strict-port— fail instead of walking, even when the port came from the default.--no-strict-port— walk to the next free port, even when--portwas explicit. Use it where 0.3.x behaviour is required.
A fullstack vantage preview binds its Node server to exactly one port, so it
was already always strict; --no-strict-port has no effect there (and says so).
v0.3.1
CLI startup, dev server boot and builds got faster. Nothing here is meant to change behaviour — it is all backwards compatible.
Faster
check/routes/docs/search/add/doctorare about 3x faster (measured: 205ms → 65–75ms). None of them touch Vite or Tailwind, yet the CLI loaded both on every invocation. Each command now loads only what it needs. The difference shows most when an agent or CI runscheckandroutesin a loop.vantage devstarts faster — it used to scan the project four times at startup; now it scans once (and generates once instead of twice).vantage buildbuilds the client and the server in parallel (projects with aserver/only). The log goes from two lines — “Building client…”, “Building server…” — to a single “Building client and server…”.vantage checkno longer re-reads the same files — page modules were read three times over and the project tree was walked twice. The bigger the app, the bigger the difference.- The dev server rescans less — creating any directory used to trigger a full rescan; now only directories that could hold pages or API modules do.
- Dependency prebundling is declared up front — the kit’s dependencies (Base UI, ECharts, TanStack Table, …) are handed to Vite ahead of time, so opening a page that uses one of those components for the first time no longer triggers “new dependencies optimized” followed by a full page reload (on hoisted installs, i.e. npm/yarn).
Added
VANTAGE_PROFILE=1(→ CLI reference) — prints how long each phase of anyvantagecommand took, on stderr. A measuring point, so “it feels slow” can be checked before it is fixed. Nothing goes to stdout, so it composes with--json.
v0.3.0
Vantage now recognises src/ as a place to put pages. This carries a
backwards-incompatible change (what gets scanned in a project that has a src/),
so per the 0.x policy it goes out as a minor.
Apps pinned to "@squadbase/vantage": "^0.2.0" will not pick up 0.3.0 — bump the
range to ^0.3.0.
Changed
- The page-scan root is decided by whether
src/exists (see File-based routing) — pages live inside<root>/srcwhen it exists, at the project root otherwise. Nothing is configured; it is detected. A one-file app can stay at the root and move intosrc/once it grows.server/andpublic/always stay at the project root, andsrc/server/is never scanned. styles.cssis read from the same side as the pages —src/styles.csswhen the project has asrc/.vantage add page/add ui/add blockwrite relative to the page-scan root (src/reports/index.tsx,src/components/ui/data-table.tsx).- Quick mode given a page file now resolves the root by walking up to the
nearest
package.json—vantage ./demo/src/index.tsxruns in./demo(it used to take the parent directory, landing in./demo/src).
Added
SRC_DIR_SPLIT(error) — raised whensrc/exists but pages orstyles.csswere left at the project root, or whensrc/server/exists. Each of those is a “you placed it and nothing happened” failure, so it is an error rather than a warning.SUSPICIOUS_ROUTE_DIR(warning) — raised when a URL comes out of a scaffolding-looking directory such aspages/,app/orutils/(pages/report.tsx→/pages/report). Page scanning works off a deny list, so any name not on it silently becomes a URL. Scanning is not stopped, so you can ignore the warning when the URL is intentional.- The bundled
AGENTS.mdgained a “directory structure” section, and the skills (vantage-app,vantage-add-feature) follow it. Placed copies ofAGENTS.mdare synced byvantage upgrade.
v0.2.3
vantage routes can be narrowed to one side of the map, and can print the spec of
every route. Additions only, so it is backwards-compatible.
Added
vantage routestakes--pages/--apis(see CLI reference) — pages only (plus layout / 404 / error), or API routes only. They are not exclusive: passing both, or neither, prints everything exactly as before.--detailadds each route’s static spec — for a page, thedefinePagetitle / navLabel / description and its path params; for an API, per method, the query keys read throughsearchParams, the request body (json/formData/text, with its keys when destructured), the response status, content type and object keys, and the status and message of everyHttpError. It answers “how do I call this endpoint?” without opening the handler.- With
--json, every entry gains aspec. The existing keys (route,file,dynamic,params) are untouched, so current readers keep working. - Everything is inferred by reading the source — like
check, your code is never imported or executed. Keys assembled at runtime, or input and output hidden inside helper functions, will not show up: treat the output as a draft of the spec, not a contract.
- With
v0.2.2
vantage add skill now scans for where the skills already are, and charts follow
stylesheet swaps too. Both are backwards-compatible.
Changed
vantage add skilllooks for placed skills before copying — it walks the project for<skill>/SKILL.mdand skips anything already placed, reporting where it is. Under the root, under.claude/skills/, under.squadbase/skills/— it makes no difference, so re-running never creates a second copy, and an agent no longer has to know the candidate locations.--forcerewrites the copies where they were found (an explicit--dirstill wins as the destination), so refreshing placed copies doesn’t require remembering the--diryou used originally.vantage add skillwith no name is now a listing command: it prints the bundled skills and where each one sits, and writes nothing.- The bundled
AGENTS.mddrops itsls-the-usual-places routine in favour of letting the CLI find them (a placedAGENTS.mdis synced byvantage upgrade).
Fixed
EChartcould miss a CSS update — token changes were only watched through attributes on<html>/<body>, so a change that only rewrites the injected<style>(editingstyles.csswith the dev server running, applying a theme preset, …) left the chart painted in the previous colours while the DOM tokens were already new. A reload fixed it, which made it read as “the preset didn’t apply”. Stylesheet swaps are now watched as well, and the chart repaints only when the token values actually change.
v0.2.1
Charts now follow the theme tokens, and Select works out the value-to-label
map for you. Both are backwards-compatible.
Changed
EChartfollows the theme tokens — series come from--chart-1through--chart-5, while axes, legend and tooltip are built from the text and border tokens, and a light/dark switch is picked up. ECharts can’t read CSS variables while painting, so the tokens are resolved once at init. Setoption.colorto override just the series — axes keep following the tokens. To paint the whole chart yourself, pass thethemeprop (that turns token-following off entirely).Selectno longer needsitems— Base UI’sSelectValuerenders the raw selected value, so a trigger would readkantowhere the list said “Kanto”. Vantage now derives the map from yourSelectItems. An explicititemsstill wins, so existing code is unchanged (keep passing it when a separate component returns the options).
Fixed
- The
SegmentedControlexample inuseSearchParam’s JSDoc passed a non-existentonValueChangeprop (it’sonChange). - Refreshed the bundled
AGENTS.mdand Skills:vantage add ui|blockcan copy onlydata-tableandsales-overview; the mode follows from whetherserver/exists rather than being a “promote the SPA to fullstack” procedure; and look for already-placed Skills before adding them. A placedAGENTS.mdis synced byvantage upgrade.
v0.2.0
Makes the destination of vantage add skill selectable, and drops the .js
specifier convention for relative imports. This carries one backwards-incompatible
change (the default destination), so per the 0.x policy it goes out as a minor.
Apps pinned to "@squadbase/vantage": "^0.1.0" will not pick up 0.2.0 — bump the
range to ^0.2.0.
Changed
vantage add skill --dir <path>— the destination is now a flag. The path resolves from the project root (--rootis honored) and absolute paths work too. Use--dir .claude/skillsfor Claude Code to discover them automatically, or whatever directory another agent expects (see Agents and Skills).- Dropped the
.jsspecifier convention for relative imports — writing./components/revenue-chart.jsis no longer required (./components/revenue-chartis fine). Vantage code always goes through Vite or tsup, and TypeScript resolves it withmoduleResolution: "Bundler", so nothing ever handed a raw specifier to Node. Existing imports with.jskeep working — there is nothing to rewrite.
v0.1.1
Adds hooks for the route list, URL-synced state, and API calls, and fixes two dev-time issues. Everything here is backwards-compatible.
Added
- Routing hooks —
useRoutes()/useCurrentRoute()in@squadbase/vantage/router. They hand you the file-based route list directly, so you can build navigation without maintaining it by hand. - URL-synced state —
useSearchParam(always a string; writing the default ornullremoves the key) anduseSearchState<T>for JSON values with functional updates. Keep filter and tab state in the URL. - API-calling hooks —
useApiQuery/useApiMutationin@squadbase/vantage/query. They callserver/apiwith JSON, normalizing errors asHttpError→ApiError(status/body/requestId). navLabelondefinePage— a field to set the navigation display name independently of the page title (see Pages and metadata).
Fixed
- Dev SPA fallback — visiting a URL like
/salesdirectly made Vite show aNo matching HTML proxy module founderror overlay (the page itself still rendered). The injected-script ids are now derived from the shell document’s URL. - Queries stuck in
paused— when the browser’s offline heuristic wrongly reported offline, a failed query would stall instead of erroring and the page never left its loading state. The managedQueryClientnow usesnetworkMode: "always"(the heuristic is meaningless for a dashboard hitting its own origin).
v0.1.0
The first prototype release — the full foundation of a config-free React dashboard framework.
Added
- Config-free foundation — built on Vite 8. You write
index.tsx; Vantage owns routing, React, TanStack Query, Tailwind v4, the UI kit, the dev server, the optional API server, and the build. - File-based routing — a
*.tsxwith a default export is a route,_layout.tsxis a layout,_404.tsx/_error.tsxhandle not-found / error, and[param].tsxis a dynamic route (see Routing). - Optional API server — add
server/api/**to enable a backend that runs identically indevand in the production build (see API and server). - UI kit and components — Tailwind v4, shadcn/ui (Base UI variant), and composite dashboard components built on top (see UI and theming).
- CLI —
dev/build/preview/check/routes/add/upgrade(see CLI reference). - Bundled docs and search —
vantage docsprints the package’s guide and component reference offline, andvantage searchsearches the same content with BM25. - Distribution for agents —
vantage add agentsplaces anAGENTS.md, andvantage add skillinstalls the Claude Code Agent Skills into your app (see Agents and Skills).