chore: scaffold website (Astro 6 + Starlight + Tailwind v4)

Phase A of docs/plans/20260604-adr-0042-website.md. Scaffolds the site
under website/ from the Starlight template; adds Tailwind v4 (via
@tailwindcss/vite) bridged to Starlight with @astrojs/starlight-tailwind
(src/styles/global.css + customCss). Production build is green: static
output, Pagefind search index, sharp image optimization.

Template placeholders (title, example pages, sidebar) are left for
Phase B/D. Reconciles the ADR/plan/index wording from "Astro 5" to
"Astro 6" to match the scaffolded toolchain.
This commit is contained in:
claude@clouddev1
2026-06-05 15:00:12 +00:00
parent 1fad29c0f9
commit cea99e8b70
18 changed files with 4608 additions and 4 deletions
@@ -26,7 +26,7 @@ planning + `/runda` pass with the user and are recorded below.
## Decision ## Decision
1. **Stack — Astro 5 + Starlight + Tailwind v4.** Astro's content-first, 1. **Stack — Astro 6 + Starlight + Tailwind v4.** Astro's content-first,
zero-JS-by-default model with the Starlight docs theme fits a zero-JS-by-default model with the Starlight docs theme fits a
marketing-landing-plus-heavy-docs site better than the alternative marketing-landing-plus-heavy-docs site better than the alternative
considered, SvelteKit + Tailwind (the usual go-to here). Interactive considered, SvelteKit + Tailwind (the usual go-to here). Interactive
@@ -65,7 +65,7 @@ planning + `/runda` pass with the user and are recorded below.
and the rusqlite **backup-API** undo (ADR-0006) → a SQL dump/restore. and the rusqlite **backup-API** undo (ADR-0006) → a SQL dump/restore.
When taken up, this becomes its own ADR + iteration plan. When taken up, this becomes its own ADR + iteration plan.
4. **Hosting — portable static build; Vercel is the likely target.** Astro 5 4. **Hosting — portable static build; Vercel is the likely target.** Astro 6
builds to static HTML/CSS with no adapter, so the output deploys equally builds to static HTML/CSS with no adapter, so the output deploys equally
to Vercel, Cloudflare Pages, Netlify, or GitHub Pages. We avoid coupling to Vercel, Cloudflare Pages, Netlify, or GitHub Pages. We avoid coupling
to any one host. **No CI yet** — the site is tested locally (`pnpm dev` / to any one host. **No CI yet** — the site is tested locally (`pnpm dev` /
+1 -1
View File
@@ -47,4 +47,4 @@ This directory contains the project's ADRs, recorded per
- [ADR-0039 — EXPLAIN over advanced-mode SQL queries](0039-explain-over-advanced-sql.md) — **Accepted** (2026-05-27), **implemented 2026-05-30 (issue #7)**, **supersedes ADR-0030 §13 OOS-2**. Lets `explain` wrap the advanced SQL commands (`Select`/`SqlInsert`/`SqlUpdate`/`SqlDelete`, plus `with`/CTE which builds a `Select`) in addition to the DSL `ShowData`/`Update`/`Delete` it already covers (ADR-0028), running `EXPLAIN QUERY PLAN` over the validated SQL text through the existing ADR-0028 span-styled plan tree (advanced mode only; DSL `explain` unchanged in both modes). Implemented via a second `Advanced` `explain` CommandNode (`EXPLAIN_SQL`) registered under the shared `explain` entry word — reusing the established `insert`/`update`/`delete` shared-word dispatch (`decide`: SQL-first / DSL-fallback), so `explain show data …` and DSL-only `--all-rows` still reach the DSL node; rejected a `DynamicSubgrammar` mode-gate (its resolution cache key omits `mode`). `build_explain_sql` slices the inner SQL off the source (excludes `explain`) and reuses the existing SQL builders; `do_explain_plan` runs the carried text verbatim, no params. Advanced `explain update`/`delete` now route through SQL (identical plan, full SQL syntax); DSL-explain tests pinned to simple mode. Reframed OOS-2 as a *deferred* exclusion (per ADR-0000's out-of-scope discipline), not a rejection. OOS (deferred): EXPLAIN of DDL (no query plan exists) - [ADR-0039 — EXPLAIN over advanced-mode SQL queries](0039-explain-over-advanced-sql.md) — **Accepted** (2026-05-27), **implemented 2026-05-30 (issue #7)**, **supersedes ADR-0030 §13 OOS-2**. Lets `explain` wrap the advanced SQL commands (`Select`/`SqlInsert`/`SqlUpdate`/`SqlDelete`, plus `with`/CTE which builds a `Select`) in addition to the DSL `ShowData`/`Update`/`Delete` it already covers (ADR-0028), running `EXPLAIN QUERY PLAN` over the validated SQL text through the existing ADR-0028 span-styled plan tree (advanced mode only; DSL `explain` unchanged in both modes). Implemented via a second `Advanced` `explain` CommandNode (`EXPLAIN_SQL`) registered under the shared `explain` entry word — reusing the established `insert`/`update`/`delete` shared-word dispatch (`decide`: SQL-first / DSL-fallback), so `explain show data …` and DSL-only `--all-rows` still reach the DSL node; rejected a `DynamicSubgrammar` mode-gate (its resolution cache key omits `mode`). `build_explain_sql` slices the inner SQL off the source (excludes `explain`) and reuses the existing SQL builders; `do_explain_plan` runs the carried text verbatim, no params. Advanced `explain update`/`delete` now route through SQL (identical plan, full SQL syntax); DSL-explain tests pinned to simple mode. Reframed OOS-2 as a *deferred* exclusion (per ADR-0000's out-of-scope discipline), not a rejection. OOS (deferred): EXPLAIN of DDL (no query plan exists)
- [ADR-0040 — A per-command completion marker (✓/✗) replaces the `[ok]` summary line](0040-completion-marker-replaces-ok-summary.md) — **Accepted 2026-05-30 (issue #9)**, amends ADR-0014 / ADR-0028 / ADR-0019 output conventions, builds on ADR-0037's mode-tagged echo. An audit of the whole command surface found the `[ok] <verb> <subject>` summary line duplicates the echo line above it (verb+subject) everywhere; its only unique contribution is the success-vs-error signal (and `explain select` even rendered `[ok] explain` with an empty subject post-ADR-0039). Decision: drop the `[ok]` line and the symmetric `"…" failed:` prefix; the echo line gains a trailing inline **✓** (green, success) / **✗** (red, failure) — `running:` becomes a pending state that resolves to `<input> ✓/✗` on completion (status set via the existing `rfind(Echo)` lookup). Content (row counts, structure, data, plan tree, teaching echo) unchanged. Scoped to the DSL/data/SQL family that has the redundant echo+`[ok]` pair; app-command `[ok]` lines (`rebuild`/`export`/`now editing`) are payload-bearing, have no echo to mark, and stay as-is. `ok.summary` retired; `dsl.failed` reduced to the rendered reason. Broad but mechanical snapshot churn. OOS: app-command `[ok]` lines, the `[WRN]` validity indicator, and the tag colours (issue #10) - [ADR-0040 — A per-command completion marker (✓/✗) replaces the `[ok]` summary line](0040-completion-marker-replaces-ok-summary.md) — **Accepted 2026-05-30 (issue #9)**, amends ADR-0014 / ADR-0028 / ADR-0019 output conventions, builds on ADR-0037's mode-tagged echo. An audit of the whole command surface found the `[ok] <verb> <subject>` summary line duplicates the echo line above it (verb+subject) everywhere; its only unique contribution is the success-vs-error signal (and `explain select` even rendered `[ok] explain` with an empty subject post-ADR-0039). Decision: drop the `[ok]` line and the symmetric `"…" failed:` prefix; the echo line gains a trailing inline **✓** (green, success) / **✗** (red, failure) — `running:` becomes a pending state that resolves to `<input> ✓/✗` on completion (status set via the existing `rfind(Echo)` lookup). Content (row counts, structure, data, plan tree, teaching echo) unchanged. Scoped to the DSL/data/SQL family that has the redundant echo+`[ok]` pair; app-command `[ok]` lines (`rebuild`/`export`/`now editing`) are payload-bearing, have no echo to mark, and stay as-is. `ok.summary` retired; `dsl.failed` reduced to the rendered reason. Broad but mechanical snapshot churn. OOS: app-command `[ok]` lines, the `[WRN]` validity indicator, and the tag colours (issue #10)
- [ADR-0041 — Copy the output panel to the system clipboard](0041-copy-output-to-clipboard.md) — **Accepted 2026-06-02 (issue #11)**, amends ADR-0003's app-command registry (adds **`copy`** / `copy all` / `copy last`). The friction it removes: filing a bug report meant terminal-selecting the output panel and fighting wrapping/borders. New **app-level command** (sigil-free, both modes): `copy` / `copy all` copy the whole panel; `copy last` copies from the most recent echo line to the end. **Mechanism — OSC 52 *and* native (`arboard`), always both**, because OSC 52 acceptance is undetectable (no terminal ack), so a true "fall back when unsupported" can't be built: emit the OSC 52 escape (no new dep — `base64`+`crossterm`; works over SSH; tmux-passthrough-wrapped via `$TMUX`), then a best-effort native write whose failure is ignored (headless host — OSC 52 carried it); the two carry identical content. **Format — plain text verbatim as rendered** (tags, `✓`/`✗`, box-drawing) joined by `\n`, without viewport padding/wrapping; a drift-lock test pins `OutputLine::plain_text` to `render_output_line`. `arboard` added **`--no-default-features`** (drops the `image` crate; X11-only on Linux — `wayland-data-control` deliberately omitted as it ~doubles the dep tree and OSC 52 covers native-Wayland). Security: write-only, scans clean for arboard's tree (cargo audit / osv-scanner / grype), 1Password-maintained, minimal surface. OOS: Markdown export, selection/range, a keybinding, OSC 52 read, `screen` passthrough - [ADR-0041 — Copy the output panel to the system clipboard](0041-copy-output-to-clipboard.md) — **Accepted 2026-06-02 (issue #11)**, amends ADR-0003's app-command registry (adds **`copy`** / `copy all` / `copy last`). The friction it removes: filing a bug report meant terminal-selecting the output panel and fighting wrapping/borders. New **app-level command** (sigil-free, both modes): `copy` / `copy all` copy the whole panel; `copy last` copies from the most recent echo line to the end. **Mechanism — OSC 52 *and* native (`arboard`), always both**, because OSC 52 acceptance is undetectable (no terminal ack), so a true "fall back when unsupported" can't be built: emit the OSC 52 escape (no new dep — `base64`+`crossterm`; works over SSH; tmux-passthrough-wrapped via `$TMUX`), then a best-effort native write whose failure is ignored (headless host — OSC 52 carried it); the two carry identical content. **Format — plain text verbatim as rendered** (tags, `✓`/`✗`, box-drawing) joined by `\n`, without viewport padding/wrapping; a drift-lock test pins `OutputLine::plain_text` to `render_output_line`. `arboard` added **`--no-default-features`** (drops the `image` crate; X11-only on Linux — `wayland-data-control` deliberately omitted as it ~doubles the dep tree and OSC 52 covers native-Wayland). Security: write-only, scans clean for arboard's tree (cargo audit / osv-scanner / grype), 1Password-maintained, minimal surface. OOS: Markdown export, selection/range, a keybinding, OSC 52 read, `screen` passthrough
- [ADR-0042 — Public website and documentation site](0042-public-website-and-documentation-site.md) — **Accepted 2026-06-04**. The first public website: a marketing landing page plus the **canonical** user docs. Stack **Astro 5 + Starlight + Tailwind v4** (chosen over SvelteKit + Tailwind for a docs-heavy + marketing site; interactive bits as Astro islands). Showcase demos are **asciinema** `.cast` recordings (scripted-input driver for paced, re-recordable sessions — *not* `history.log` replay), reused inline in docs. The **in-page WASM playground is deferred** (OOS: deferred) behind a stable `Demo` seam, with the portable-core (`dsl`/`app`/`ui`, in-memory `rusqlite` via `ffi-sqlite-wasm-rs`) vs native-edge (Tokio/worker-thread/`crossterm`/persistence/backup-API) boundary recorded for a future ADR + iteration plan. Portable **static build** (Vercel target, but host-agnostic); **no CI yet**; **monorepo** (`website/`). Docs cover the **full supported feature set** with "planned" callouts for the unshipped minority; two wording rules bind user-facing copy — **no engine name** (continues ADR-0002) and **no "DSL"** ("simple mode" / "advanced mode"). Install docs cover **prebuilt binaries + package managers** (D1D3 track the release tooling). Plan: `docs/plans/20260604-adr-0042-website.md` - [ADR-0042 — Public website and documentation site](0042-public-website-and-documentation-site.md) — **Accepted 2026-06-04**. The first public website: a marketing landing page plus the **canonical** user docs. Stack **Astro 6 + Starlight + Tailwind v4** (chosen over SvelteKit + Tailwind for a docs-heavy + marketing site; interactive bits as Astro islands). Showcase demos are **asciinema** `.cast` recordings (scripted-input driver for paced, re-recordable sessions — *not* `history.log` replay), reused inline in docs. The **in-page WASM playground is deferred** (OOS: deferred) behind a stable `Demo` seam, with the portable-core (`dsl`/`app`/`ui`, in-memory `rusqlite` via `ffi-sqlite-wasm-rs`) vs native-edge (Tokio/worker-thread/`crossterm`/persistence/backup-API) boundary recorded for a future ADR + iteration plan. Portable **static build** (Vercel target, but host-agnostic); **no CI yet**; **monorepo** (`website/`). Docs cover the **full supported feature set** with "planned" callouts for the unshipped minority; two wording rules bind user-facing copy — **no engine name** (continues ADR-0002) and **no "DSL"** ("simple mode" / "advanced mode"). Install docs cover **prebuilt binaries + package managers** (D1D3 track the release tooling). Plan: `docs/plans/20260604-adr-0042-website.md`
+1 -1
View File
@@ -3,7 +3,7 @@
**Date:** 2026-06-04 · **Status:** ready to build **Date:** 2026-06-04 · **Status:** ready to build
Decisions for this work are recorded in Decisions for this work are recorded in
[ADR-0042](../adr/0042-public-website-and-documentation-site.md): Astro 5 + [ADR-0042](../adr/0042-public-website-and-documentation-site.md): Astro 6 +
Starlight + Tailwind v4; asciinema demos reusable in docs; the in-page WASM Starlight + Tailwind v4; asciinema demos reusable in docs; the in-page WASM
playground deferred behind a stable demo seam; portable static hosting playground deferred behind a stable demo seam; portable static hosting
(Vercel target); monorepo (`website/`); website is the canonical docs home; (Vercel target); monorepo (`website/`); website is the canonical docs home;
+21
View File
@@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
+4
View File
@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
+11
View File
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
+49
View File
@@ -0,0 +1,49 @@
# Starlight Starter Kit: Basics
[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build)
```
pnpm create astro@latest -- --template starlight
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Astro + Starlight project, you'll see the following folders and files:
```
.
├── public/
├── src/
│ ├── assets/
│ ├── content/
│ │ └── docs/
│ └── content.config.ts
├── astro.config.mjs
├── package.json
└── tsconfig.json
```
Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
Images can be added to `src/assets/` and embedded in Markdown with a relative link.
Static assets, like favicons, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `pnpm install` | Installs dependencies |
| `pnpm dev` | Starts local dev server at `localhost:4321` |
| `pnpm build` | Build your production site to `./dist/` |
| `pnpm preview` | Preview your build locally, before deploying |
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |
| `pnpm astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Check out [Starlights docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
+33
View File
@@ -0,0 +1,33 @@
// @ts-check
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import tailwindcss from '@tailwindcss/vite';
// https://astro.build/config
export default defineConfig({
integrations: [
starlight({
title: 'My Docs',
social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' }],
customCss: ['./src/styles/global.css'],
sidebar: [
{
label: 'Guides',
items: [
// Each item here is one entry in the navigation menu.
{ label: 'Example Guide', slug: 'guides/example' },
],
},
{
label: 'Reference',
items: [{ autogenerate: { directory: 'reference' } }],
},
],
}),
],
vite: {
plugins: [tailwindcss()],
},
});
+21
View File
@@ -0,0 +1,21 @@
{
"name": "rdbms-playground-website",
"private": true,
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/starlight": "^0.39.3",
"@astrojs/starlight-tailwind": "^5.0.0",
"@tailwindcss/vite": "^4.3.0",
"astro": "^6.3.1",
"sharp": "^0.34.5",
"tailwindcss": "^4.3.0"
}
}
+4386
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg>

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

+7
View File
@@ -0,0 +1,7 @@
import { defineCollection } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
};
@@ -0,0 +1,11 @@
---
title: Example Guide
description: A guide in my new Starlight docs site.
---
Guides lead a user through a specific task they want to accomplish, often with a sequence of steps.
Writing a good guide requires thinking about what your users are trying to do.
## Further reading
- Read [about how-to guides](https://diataxis.fr/how-to-guides/) in the Diátaxis framework
+40
View File
@@ -0,0 +1,40 @@
---
title: Welcome to Starlight
description: Get started building your docs site with Starlight.
template: splash # Remove or comment out this line to display the site sidebar on this page.
hero:
tagline: Congrats on setting up a new Starlight project!
image:
file: ../../assets/houston.webp
actions:
- text: Example Guide
link: /guides/example/
icon: right-arrow
- text: Read the Starlight docs
link: https://starlight.astro.build
icon: external
variant: minimal
---
import { Card, CardGrid } from '@astrojs/starlight/components';
## Next steps
<CardGrid stagger>
<Card title="Update content" icon="pencil">
Edit `src/content/docs/index.mdx` to see this page change.
</Card>
<Card title="Change page layout" icon="document">
Delete `template: splash` in `src/content/docs/index.mdx` to display a
sidebar on this page.
</Card>
<Card title="Add new content" icon="add-document">
Add Markdown or MDX files to `src/content/docs` to create new pages.
</Card>
<Card title="Configure your site" icon="setting">
Edit your `sidebar` and other config in `astro.config.mjs`.
</Card>
<Card title="Read the docs" icon="open-book">
Learn more in [the Starlight Docs](https://starlight.astro.build/).
</Card>
</CardGrid>
@@ -0,0 +1,11 @@
---
title: Example Reference
description: A reference page in my new Starlight docs site.
---
Reference pages are ideal for outlining how things work in terse and clear terms.
Less concerned with telling a story or addressing a specific use case, they should give a comprehensive outline of what you're documenting.
## Further reading
- Read [about reference](https://diataxis.fr/reference/) in the Diátaxis framework
+4
View File
@@ -0,0 +1,4 @@
@layer base, starlight, theme, components, utilities;
@import '@astrojs/starlight-tailwind';
@import 'tailwindcss/theme.css' layer(theme);
@import 'tailwindcss/utilities.css' layer(utilities);
+5
View File
@@ -0,0 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}