Meta/tracking issue + living build plan. Architecture is settled (#88 / ADR-0001); the phases below are ordered so each refactor lands on a stable base and the most-wanted features ship early. Check items off as they land.
Architecture (settled — #88, ADR-0001)
- State:
@preact/signals-core, migrated slice-by-slice. No UI framework (React/Preact/Solid). A Preact spike on the schema panel (spike/preact-schema, ADR-0001 addendum) confirmed a component model removes the in-place-mutation pain but buys a second render paradigm the roadmap doesn't justify.
- Shape: signals (state) · pure logic in
src/core/ · imperative adapters behind injected seams for the hard / third-party / high-frequency-pointer surfaces (editor, EXPLAIN + schema graphs, Chart.js, result grid). Extract a shared primitive (EditorPort, GraphSurface, a result-view registry, Drawer) on the second consumer — not speculatively (CLAUDE.md rule 5).
Build order
Phase 0 — baseline before refactors (cheap, do first)
Phase 1 — finish reactivity (#88)
Phase 2 — near-term wins (no CM6; ride on the textarea + the signals results pane)
Phase 3 — editor → CodeMirror 6 (#21, reopened)
Phase 4 — editor intelligence (on CM6)
Phase 5 — schema / data-flow graph
Cross-cutting
Release-blockers (1.0 must not ship without)
Nice-to-haves
Done
Parallelization (which issues can /ship concurrently)
Run parallel issues in separate git worktrees (claude --worktree <name> per session) — never two /ships in one working dir. Only parallelize dependency-independent issues; never run an issue against an unmerged dependency.
main now carries #89 + #90, so it's the clean base for everything downstream.
Meta/tracking issue + living build plan. Architecture is settled (#88 / ADR-0001); the phases below are ordered so each refactor lands on a stable base and the most-wanted features ship early. Check items off as they land.
Architecture (settled — #88, ADR-0001)
@preact/signals-core, migrated slice-by-slice. No UI framework (React/Preact/Solid). A Preact spike on the schema panel (spike/preact-schema, ADR-0001 addendum) confirmed a component model removes the in-place-mutation pain but buys a second render paradigm the roadmap doesn't justify.src/core/· imperative adapters behind injected seams for the hard / third-party / high-frequency-pointer surfaces (editor, EXPLAIN + schema graphs, Chart.js, result grid). Extract a shared primitive (EditorPort,GraphSurface, a result-view registry,Drawer) on the second consumer — not speculatively (CLAUDE.md rule 5).Build order
Phase 0 — baseline before refactors (cheap, do first)
html{zoom}dependency — fix landed (PR fix(zoom): correctly size fullscreen graph panels on Safari under html{zoom} (#70) #92). Manual Safari testing showed the only real divergence is viewport units underzoom(Chromium'svh/vwignore it, Safari's track it), which mis-sized the fullscreen graph panels on Safari; the divisor is now measured at runtime and published as--vp-zoom, plus the@supports not (zoom:1)1× fallback. (The pointer/caret/drag math self-calibrates, so it was already correct on Safari — the originally-planned "mis-scaling banner" was dropped as a false-positive.) Finding: Playwright WebKit ≠ real Safari forzoom×rect/viewport, so Add WebKit/Safari to e2e + decide the supported-browser stance #69's CI "Safari verified" didn't exercise this — folded into Document the supported-browser matrix (browsers, ClickHouse versions, IdP requirements) #71. Fullzoomremoval still folds into Phase 3/5.Phase 1 — finish reactivity (#88)
Phase 2 — near-term wins (no CM6; ride on the textarea + the signals results pane)
LIMIT, not a virtualized grid);-split + run a selection; statement-splitter pure incore/) — PR feat: multiquery + run-selection — run a ;-separated script (#83) #95 open (awaiting merge){{name}}CTE-merge (purecore/; no editor dependency)Phase 3 — editor → CodeMirror 6 (#21, reopened)
EditorPortinterface + atextarea-adapter(current editor behind it)codemirror-adapter(@codemirror/lang-sql) behind the seam; SQL logic stays pure incore/; gated likeapp.js/Chart/dagrePhase 4 — editor intelligence (on CM6)
schemaCompletionSourceon the live schema)Drawerhere (cell detail + schema detail + docs pane = its third consumer)Phase 5 — schema / data-flow graph
GraphSurface(src/ui/graph-surface.js) +src/core/graph-selection.js(pure) — shared by the schema graph and, where possible, the EXPLAIN pipeline graphGraphSurfacecore/)Cross-cutting
html{zoom}removal — folded into the Phase 3/5 coordinate-path rewritesRelease-blockers (1.0 must not ship without)
html{zoom}de-risk) ✅ fix via fix(zoom): correctly size fullscreen graph panels on Safari under html{zoom} (#70) #92 (Safari panel sizing, manually verified) · Document the supported-browser matrix (browsers, ClickHouse versions, IdP requirements) #71 (supported browsers / ClickHouse versions / IdP matrix) — Add WebKit/Safari to e2e + decide the supported-browser stance #69 (WebKit e2e) ✅ done via test(e2e): add WebKit/Safari to the Playwright matrix + decide the support stance (#69) #90Nice-to-haves
Done
main.main.Parallelization (which issues can
/shipconcurrently)Run parallel issues in separate git worktrees (
claude --worktree <name>per session) — never two/ships in one working dir. Only parallelize dependency-independent issues; never run an issue against an unmerged dependency.mainnow: De-risk the html{zoom} layout dependency (Safari verification + fallback/guard) #70, Composable queries: reference other library queries via {{name}} (CTE-merge) #39, Schema lineage: cap the EXPLAIN AST fan-out on large schemas #42 (purecore// infra; don't touch the signal-converted files).main: the Phase-1 schema slice (Convert the schema slice to signals (schema/schemaError/schemaFilter) — Phase 1 of #88 #91), Cap SELECT result rows (default 500) with a 100/500/1000/5000/10000 selector #86, Multiquery + run-selection: execute a ;-separated script (DDL / INSERT / single-row SELECT) with per-statement output #83 (they build on the signal-driven results pane / run flow).EditorPort) → Column-name autocompletion: FROM-driven column loading + alias/scope awareness #84, Version-exact reference docs in the editor from ClickHouse 26.6 embedded docs #60 → Schema graph: multi-select + group-move of nodes (marquee, Shift-click, ⌘A) with single-step undo #66 (afterGraphSurfaceis extracted).mainnow carries #89 + #90, so it's the clean base for everything downstream.