A standalone web frontend for browsing VGI (Vector Gateway Interface) database catalogs. Cupola connects to any VGI HTTP server and presents its schemas, tables, views, and functions in a navigable catalog browser — with an embedded SQL shell, pivot tables, and an AI data analysis agent built in.
Designed to be shared across all VGI server implementations (Python, TypeScript, Go). VGI servers redirect browsers to the hosted frontend with ?service={url}.
- Catalog browser — sidebar tree of schemas, tables, views, functions, and macros with searchable navigation, detail panels, column statistics, and on-demand column profiling
- Embedded SQL shell — DuckDB-WASM running in the browser with the VGI extension, an xterm.js terminal, tab completion, session persistence, and dot commands
- AI data analysis — Claude-powered agent that can run SQL, inspect schemas, and answer questions about your data (bring your own Anthropic API key)
- Pivot tables — Perspective-based data grids backed directly by DuckDB-WASM
- Data preview — paginated table browsing, geometry (WKB) visualization, example queries, and Markdown descriptions via VGI tags
- Deep linking — selection state encoded in the URL hash so views can be shared
- OAuth / PKCE — works with VGI servers that require authentication, including per-catalog identity
- Theming — custom color themes loadable via
?theme=<url>, with a live editor at/theme-builder
- Astro + React — static site with React islands
- ShadCN/UI + Tailwind CSS — components and styling
- DuckDB-WASM — in-browser SQL engine
- Perspective — pivot tables and data grids
- xterm.js — terminal emulator for the SQL shell
- Bun — package manager and runtime
- Hosted on Cloudflare Pages with versioned assets served from R2
# Install dependencies
bun install
# Start the dev server at http://localhost:4321
bun run devCupola needs a running VGI server to talk to. Point it at one with the service query parameter:
http://localhost:4321/?service=http://localhost:9003
Without ?service=, a welcome / connect page is shown.
| Command | Action |
|---|---|
bun install |
Install dependencies |
bun run dev |
Start local dev server at localhost:4321 |
bun run build |
Build the production site to ./dist/ |
bun run preview |
Preview the production build locally |
bun run test |
Run unit tests |
./publish.sh |
Publish a new version (build, upload to R2, deploy) |
| Parameter | Purpose |
|---|---|
?service=<url> |
VGI server base URL to connect to |
?attach_options=<sql> |
Extra options spliced into the DuckDB ATTACH statement |
?theme=<url> |
URL of a theme JSON file (colors, logo, terminal theme) |
?fresh |
Clear any saved DuckDB session snapshot for this service |
#ai_key=<key> |
Anthropic API key for the AI agent (stripped from the URL after use) |
#/schema/<s>/table/<t> |
Deep link to a catalog selection |
Assets are served from Cloudflare R2 via a Worker with a versioned URL scheme (/v{version}/..., with /latest/ redirecting to the current version).
Publish locally:
- Bump
versioninpackage.json - Run
./publish.sh
Publish from GitHub Actions: run the Publish workflow (.github/workflows/publish.yml, manual trigger). It checks out the sibling repos (vgi-typescript, vgi-rpc-typescript), runs the tests, executes ./publish.sh --skip-commit against the pushed commit, and tags the release. Required repository secrets:
| Secret | Purpose |
|---|---|
SIBLING_REPOS_TOKEN |
PAT with read access to Query-farm/vgi-typescript (private; vgi is not on npm) |
SENTRY_AUTH_TOKEN |
Sentry source-map upload |
CLOUDFLARE_API_TOKEN |
Worker deploy |
R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY |
R2 S3-API asset upload |
Licensed under the Apache License 2.0.
Copyright © 2026 Query Farm LLC — https://query.farm