Skip to content

Commit 2041d7f

Browse files
authored
restructure CLAUDE.md (#382)
1 parent a28ccd0 commit 2041d7f

9 files changed

Lines changed: 693 additions & 1374 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ shapes (#368)
2525
before registering them back to the backend. We now keep the data purely on the
2626
backend until the layer query as was always intended (#363)
2727
- Simplified internal approach to DataFrame with DuckDB reader (#365)
28+
- Restructured CLAUDE.md to better deal with the rising complexity of the project (#382)
2829

2930
### Removed
3031

CLAUDE.md

Lines changed: 63 additions & 1374 deletions
Large diffs are not rendered by default.

doc/CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# `doc/` — Quarto documentation site
2+
3+
Source for the public ggsql documentation at <https://ggsql.org>. **This directory is the authoritative reference for ggsql syntax and semantics.** Other CLAUDE.md files in the repo link here rather than restate.
4+
5+
If you are about to document a clause, layer type, scale, or aesthetic anywhere else: stop and put it here instead.
6+
7+
## Layout
8+
9+
```
10+
doc/
11+
├── _quarto.yml Quarto project config (navbar, sidebar, theme, llms-txt)
12+
├── _brand.yml, styles.scss, ggsql.xml Branding + the ggsql syntax-highlight definition
13+
├── index.qmd Landing page
14+
├── faq.qmd
15+
├── get_started/
16+
│ ├── installation.qmd Platform-specific install + CLI quick reference
17+
│ ├── first_plot.qmd Tutorial: first visualization
18+
│ ├── grammar.qmd Grammar of Graphics conceptual foundation
19+
│ ├── anatomy.qmd Anatomy of a ggsql query
20+
│ ├── tooling.qmd VS Code / Positron / Jupyter / Python / R / CLI integrations
21+
│ └── the_rest.qmd Advanced features
22+
├── syntax/
23+
│ ├── index.qmd
24+
│ ├── clause/ draw, facet, label, place, project, scale, visualise
25+
│ ├── layer/
26+
│ │ ├── type/ one .qmd per layer type (point, line, bar, …)
27+
│ │ └── position/ identity, stack, dodge, jitter
28+
│ ├── scale/
29+
│ │ ├── type/ binned, continuous, discrete, identity, ordinal
30+
│ │ └── aesthetic/ position, color, opacity, size, linewidth, shape, linetype, faceting
31+
│ └── coord/ cartesian, polar
32+
├── gallery/
33+
│ ├── index.qmd
34+
│ └── examples/ Runnable example queries
35+
├── assets/, vendor/ Static resources
36+
├── data/CSVs Sample datasets used by examples (data.csv, sales.csv, …)
37+
└── wasm/ Built playground (copied from /ggsql-wasm/demo/dist by build-wasm.sh)
38+
```
39+
40+
Generated artefacts not to edit by hand:
41+
42+
- `_site/` — Quarto build output. Not committed (see `.gitignore`).
43+
- `*.quarto_ipynb*` — Quarto's intermediate notebook files for `.qmd` pages with executable cells. Regenerated on build.
44+
- `wasm/` — produced by [`/ggsql-wasm/build-wasm.sh`](../ggsql-wasm/build-wasm.sh).
45+
46+
## Authoring conventions
47+
48+
- Pages are Quarto markdown (`.qmd`) — markdown plus YAML front-matter.
49+
- Code blocks tagged ```` ```ggsql ```` use the syntax definition in `ggsql.xml` (referenced from `_quarto.yml` under `syntax-definitions`). Use that fence for runnable / illustrative ggsql snippets.
50+
- Each clause page under `syntax/clause/` follows the same shape: short narrative, a "Clause syntax" code block listing all subclauses, then sections per subclause with examples. Mirror that shape when adding pages.
51+
- Examples that need data reference the CSV files at the top of `doc/` (e.g. `data.csv`, `sales.csv`, `metrics.csv`, `timeseries.csv`).
52+
- The site has `llms-txt: true` in `_quarto.yml`, so an `llms.txt` is generated for AI tooling — keep page titles and descriptions clean.
53+
54+
## Site structure (from `_quarto.yml`)
55+
56+
- **Navbar**: Get started · Syntax (drop-down per clause) · Gallery · FAQ · News · Playground · Python · R.
57+
- **Syntax sidebar**: clauses → layers (type + position) → scales (type + aesthetic) → coordinate systems. New `.qmd` files in those folders are picked up automatically via `auto:` glob entries.
58+
- **Get-started sidebar**: hand-ordered list (`installation``first_plot``grammar``anatomy``tooling``the_rest`).
59+
60+
## Build & preview
61+
62+
```sh
63+
cd doc
64+
quarto preview # local server with hot reload
65+
quarto render # full site build → _site/
66+
```
67+
68+
The site is published from the `gh-pages` branch (see `_quarto.yml`'s `repo-branch`). Quarto extensions live in `_extensions/`.
69+
70+
## What goes here vs. CLAUDE.md
71+
72+
- **Here**: anything a ggsql user might want to read — clause syntax, layer types, scales, aesthetics, examples, CLI usage, installation.
73+
- **In CLAUDE.md files**: implementation details for contributors — module layouts, build pipelines, where to add a new geom, internal types.
74+
75+
If you find clause/layer/scale syntax described in any CLAUDE.md file, that is a duplication bug — move it here and link from there.
76+
77+
## See also
78+
79+
- [`/CLAUDE.md`](../CLAUDE.md) — workspace overview.
80+
- [`/ggsql-wasm/CLAUDE.md`](../ggsql-wasm/CLAUDE.md) — how the embedded playground at `wasm/` is built.

ggsql-jupyter/CLAUDE.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# `ggsql-jupyter/` — Jupyter kernel
2+
3+
Standalone Rust binary that speaks the Jupyter messaging protocol over ZeroMQ. Embeds the `ggsql` library and renders results as Vega-Lite (visual queries) or HTML tables (pure SQL). Workspace member; published to crates.io and to PyPI (as a binary wheel via maturin).
4+
5+
End-user installation and usage live in [`README.md`](README.md). End-user notebook docs live in [`/doc/get_started/tooling.qmd`](../doc/get_started/tooling.qmd). This file describes the *implementation*.
6+
7+
## Layout
8+
9+
```
10+
ggsql-jupyter/
11+
├── Cargo.toml Rust binary + library, depends on ggsql with duckdb + vegalite
12+
├── pyproject.toml maturin config (bindings = "bin") for the PyPI wheel
13+
├── README.md User-facing install + usage
14+
├── src/
15+
│ ├── main.rs Binary entry: clap CLI (start kernel, --install)
16+
│ ├── lib.rs Library root (so internals can be unit-tested)
17+
│ ├── kernel.rs Jupyter messaging loop (ZMQ, message dispatch)
18+
│ ├── executor.rs Runs queries via ggsql::Reader, returns rendered output
19+
│ ├── connection.rs Reader lifecycle, connection-string parsing
20+
│ ├── data_explorer.rs Positron data-explorer comm channel
21+
│ ├── display.rs Output formatting (Vega-Lite + vega-embed HTML, SQL → HTML table)
22+
│ ├── message.rs Jupyter message structs (ZMQ frames, HMAC signing)
23+
│ └── util.rs
24+
└── tests/
25+
├── test_compliance.py Jupyter protocol conformance
26+
├── test_integration.py End-to-end via jupyter_client
27+
├── fixtures/ Sample notebooks / queries
28+
└── requirements.txt
29+
```
30+
31+
## How it runs
32+
33+
1. `ggsql-jupyter --install` writes a kernelspec into the active Python environment (Jupyter, conda, uv, virtualenv — auto-detected).
34+
2. `ggsql-jupyter <connection-file>` is the entry point Jupyter invokes; it reads the connection JSON, opens the five ZMQ sockets (shell, control, iopub, stdin, heartbeat), and runs `kernel.rs`'s message loop.
35+
3. Each `execute_request` is dispatched through `executor.rs``ggsql::reader::DuckDBReader::execute(...)`. The kernel keeps a single persistent in-memory DuckDB session so cells share state.
36+
4. The result is wrapped by `display.rs` into a Jupyter `display_data` message — Vega-Lite specs go through vega-embed in an HTML payload (works in classic Jupyter, JupyterLab, and Positron); pure SQL goes out as an HTML table.
37+
38+
## Positron-specific bits
39+
40+
- Kernel info advertises `"output_location": "plot"` so visualizations route to Positron's Plot pane.
41+
- `data_explorer.rs` implements Positron's data-explorer comm channel (registered query results become explorable tables).
42+
- The companion VS Code extension (`ggsql-vscode/`) discovers this binary via the `ggsql.kernelPath` setting, the active Jupyter kernelspec, or `PATH`.
43+
44+
## Build & install
45+
46+
```sh
47+
# Dev: build the binary and register with the active env
48+
cargo build --release --package ggsql-jupyter
49+
./target/release/ggsql-jupyter --install
50+
51+
# Run a one-off install from crates.io
52+
cargo install ggsql-jupyter
53+
ggsql-jupyter --install
54+
55+
# PyPI distribution (built via maturin in CI; pyproject.toml is a wheel-builder shim)
56+
pip install ggsql-jupyter && ggsql-jupyter --install
57+
```
58+
59+
`pyproject.toml` declares `bindings = "bin"` — there is no Python module, the wheel just delivers the binary cross-platform.
60+
61+
## Features
62+
63+
```toml
64+
default = ["all-readers"]
65+
all-readers = ["sqlite", "odbc", "duckdb"]
66+
```
67+
68+
Each feature passes through to `ggsql/<feature>`. The default install therefore supports DuckDB, SQLite, and ODBC connection strings.
69+
70+
## Testing
71+
72+
The Rust side has unit tests inline (`cargo test -p ggsql-jupyter`). The Jupyter protocol tests are Python:
73+
74+
```sh
75+
cd ggsql-jupyter/tests
76+
python -m venv .venv && source .venv/bin/activate
77+
pip install -r requirements.txt
78+
pytest
79+
```
80+
81+
`test_compliance.py` verifies handler coverage (`execute_request`, `kernel_info_request`, `is_complete_request`, `shutdown_request`); `test_integration.py` drives a real kernel via `jupyter_client`.
82+
83+
## See also
84+
85+
- [`/CLAUDE.md`](../CLAUDE.md) — workspace overview.
86+
- [`/ggsql-vscode/CLAUDE.md`](../ggsql-vscode/CLAUDE.md) — the VS Code / Positron extension that drives this kernel.
87+
- [`/src/CLAUDE.md`](../src/CLAUDE.md) — the underlying `ggsql` library.
88+
- [`/doc/get_started/tooling.qmd`](../doc/get_started/tooling.qmd) — user-facing notebook docs.

ggsql-vscode/CLAUDE.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# `ggsql-vscode/` — VS Code / Positron extension
2+
3+
TypeScript extension that adds ggsql language support to VS Code and Positron: syntax highlighting, code-cell execution, connection management, and (in Positron) a registered language runtime that drives the `ggsql-jupyter` kernel.
4+
5+
Not a Cargo workspace member — this is a standalone npm project. End-user docs live in [`README.md`](README.md). Tooling overview for users: [`/doc/get_started/tooling.qmd`](../doc/get_started/tooling.qmd). This file describes the *implementation*.
6+
7+
## Layout
8+
9+
```
10+
ggsql-vscode/
11+
├── package.json Extension manifest (commands, keybindings, languages, runtime)
12+
├── tsconfig.json
13+
├── esbuild.js Bundler config (builds out/extension.js)
14+
├── eslint.config.mjs
15+
├── language-configuration.json Bracket pairs, comment markers
16+
├── logo.png, icon.png
17+
├── src/
18+
│ ├── extension.ts activate(): registers commands, manager, code lenses
19+
│ ├── manager.ts Kernel discovery + Positron language-runtime registration
20+
│ ├── connections.ts Connection-string handling for the Connections pane
21+
│ ├── cellParser.ts Splits .ggsql files into cells for Run-Cell commands
22+
│ ├── codelens.ts "▶ Run cell" lens above each cell
23+
│ ├── decorations.ts Cell separator decorations
24+
│ ├── context.ts Sets editor context keys (e.g. ggsql.hasCodeCells)
25+
│ └── types.ts Shared interfaces
26+
├── syntaxes/
27+
│ └── ggsql.tmLanguage.json TextMate grammar (used for tokenization in VS Code)
28+
├── examples/ Sample .ggsql files
29+
├── resources/ Static assets bundled with the extension
30+
└── ggsql-0.1.0.vsix Packaged extension (build artifact, may be stale)
31+
```
32+
33+
## File extensions and language ID
34+
35+
`package.json` registers `id: ggsql` for `.ggsql`, `.ggsql.sql`, and `.gsql`. The TextMate grammar at `syntaxes/ggsql.tmLanguage.json` provides tokenization. Tree-sitter highlights — used by editors that prefer the grammar package directly — live in [`/tree-sitter-ggsql/queries/highlights.scm`](../tree-sitter-ggsql/queries/highlights.scm).
36+
37+
## Commands and keybindings
38+
39+
Declared in `package.json` and wired up in `extension.ts`:
40+
41+
| Command | Default key | Purpose |
42+
| --- | --- | --- |
43+
| `ggsql.runCurrentAdvance` | Cmd/Ctrl+Enter, Shift+Enter | Run current cell, advance to next |
44+
| `ggsql.runQuery` | Cmd/Ctrl+Shift+Enter | Run current cell only |
45+
| `ggsql.runNextCell` || Run the next cell |
46+
| `ggsql.runCellsAbove` || Run all cells above the cursor |
47+
| `ggsql.sourceCurrentFile` || Run the entire file (also exposed as the editor "Run" button) |
48+
49+
Cells are detected by `cellParser.ts`; `codelens.ts` puts a CodeLens above each cell.
50+
51+
## Positron integration
52+
53+
The extension declares `contributes.languageRuntimes` for `ggsql` (see `package.json`) and depends on `@posit-dev/positron`. When activated under Positron, `manager.ts`:
54+
55+
1. Discovers a `ggsql-jupyter` binary via, in order: the `ggsql.kernelPath` setting, an installed Jupyter kernelspec named `ggsql`, or `ggsql-jupyter` on `PATH`.
56+
2. Registers it as a Positron language runtime so `▶ Run` and the Console route to the kernel.
57+
3. Routes plot output to Positron's Plot pane via metadata coming back from the kernel (`output_location: "plot"`).
58+
59+
Outside Positron, the same commands fall back to writing query output to the active terminal.
60+
61+
## Settings
62+
63+
```json
64+
{
65+
"ggsql.kernelPath": "string" // empty → use 'ggsql-jupyter' from PATH
66+
}
67+
```
68+
69+
## Build & package
70+
71+
```sh
72+
cd ggsql-vscode
73+
npm install # one-time
74+
npm run check-types # tsc --noEmit
75+
npm run package # esbuild → out/extension.js (production)
76+
npx vsce package # produces ggsql-<version>.vsix
77+
code --install-extension ggsql-<version>.vsix
78+
```
79+
80+
Watch mode for development: `npm run watch` (runs esbuild + tsc in parallel).
81+
82+
## See also
83+
84+
- [`/CLAUDE.md`](../CLAUDE.md) — workspace overview.
85+
- [`/ggsql-jupyter/CLAUDE.md`](../ggsql-jupyter/CLAUDE.md) — the kernel this extension drives.
86+
- [`/tree-sitter-ggsql/CLAUDE.md`](../tree-sitter-ggsql/CLAUDE.md) — grammar that powers more advanced editor highlighting.
87+
- [`/doc/get_started/tooling.qmd`](../doc/get_started/tooling.qmd) — user-facing tooling docs.

ggsql-wasm/CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# `ggsql-wasm/` — WebAssembly bindings
2+
3+
Compiles the `ggsql` core to WebAssembly so it can run in browsers. Used by the playground at [`/doc/wasm/`](../doc/wasm/) and published as an npm package. Workspace member.
4+
5+
End-user playground: <https://ggsql.org/wasm/>. This file describes the *build*.
6+
7+
## Layout
8+
9+
```
10+
ggsql-wasm/
11+
├── Cargo.toml cdylib; ggsql with default-features = false + vegalite, sqlite, builtin-data
12+
├── build-wasm.sh End-to-end build orchestrator (library + wasm + demo → doc/wasm)
13+
├── src/
14+
│ └── lib.rs wasm-bindgen entry points (the only Rust here)
15+
├── library/ TypeScript wrapper distributed on npm
16+
│ ├── package.json npm package (build with `npm run build`)
17+
│ ├── build.mjs esbuild script
18+
│ └── src/
19+
├── demo/ Browser demo + playground used by the doc site
20+
│ ├── package.json
21+
│ ├── build.mjs
22+
│ └── src/ UI code (editor + Vega-Lite preview)
23+
└── pkg/ wasm-pack output (committed; consumed by library/ and demo/)
24+
├── ggsql_wasm_bg.wasm
25+
├── ggsql_wasm.js, .d.ts
26+
└── package.json
27+
```
28+
29+
`pkg/` is generated but committed so contributors don't need a wasm toolchain just to run the docs.
30+
31+
## Toolchain
32+
33+
- Rust target `wasm32-unknown-unknown` and [`wasm-pack`](https://rustwasm.github.io/wasm-pack/) for compilation.
34+
- A clang/llvm with wasm backend support (the build script verifies this with a one-line probe).
35+
- `wasm-opt` (from binaryen) for the `-Oz` optimization step.
36+
- Node.js for `library/` and `demo/`.
37+
38+
## Build
39+
40+
The full build:
41+
42+
```sh
43+
cd ggsql-wasm
44+
./build-wasm.sh
45+
```
46+
47+
This sequentially:
48+
49+
1. `npm install && npm run build` in `library/` — produces the typed JS wrapper.
50+
2. `wasm-pack build --target web --profile wasm --no-opt` — compiles `src/lib.rs` to `pkg/`. The `wasm` profile is defined in the workspace `Cargo.toml` (release-style, `opt-level = "z"`, LTO, `panic = "abort"`).
51+
3. `wasm-opt pkg/ggsql_wasm_bg.wasm -o pkg/ggsql_wasm_bg.wasm -Oz` — shrinks the binary further.
52+
4. `npm install && npm run build` in `demo/` — bundles the playground UI.
53+
5. Copies `demo/dist/` to `/doc/wasm/` so Quarto can serve it under the docs site.
54+
55+
Flags:
56+
57+
- `--skip-binary` — reuse the existing `pkg/` (skip steps 2–3); useful when iterating on `library/` or `demo/`.
58+
- `--skip-opt` — compile but skip `wasm-opt` (faster, larger binary).
59+
60+
## Wasm-specific feature constraints
61+
62+
`Cargo.toml` carves out wasm32-only dependency overrides:
63+
64+
- `getrandom` and `uuid` are forced to the `js` feature so they get randomness from the browser.
65+
- `sqlite-wasm-rs` replaces `rusqlite` for SQLite support in the browser.
66+
- `tokio` is reduced to `default-features = false` (no I/O reactor on wasm).
67+
68+
ODBC is not enabled here — it requires host APIs that aren't available in the browser.
69+
70+
## Distribution
71+
72+
- **npm**: `library/` is published as the user-facing JS/TS wrapper. The `pkg/` artifact is bundled with it.
73+
- **GitHub Releases**: the wasm binary is also attached to releases (see commit `071cff6`).
74+
- **Docs site**: `demo/dist/` is committed into [`/doc/wasm/`](../doc/wasm/) by `build-wasm.sh` and embedded in Quarto pages via `_quarto.yml`.
75+
76+
## See also
77+
78+
- [`/CLAUDE.md`](../CLAUDE.md) — workspace overview.
79+
- [`/src/CLAUDE.md`](../src/CLAUDE.md) — the underlying `ggsql` library.
80+
- [`/doc/CLAUDE.md`](../doc/CLAUDE.md) — how the playground gets embedded into the Quarto site.

0 commit comments

Comments
 (0)