You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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)
Detached-tab pattern: extract shared primitive; add Data Pane Expand + convert Pipeline Expand #100 — detached-tab primitive (src/ui/detached-view.js) extracted from the schema graph's tab/overlay logic; now shared by the schema graph, the EXPLAIN pipeline graph (gains real-tab support), and a new Data Pane Expand (snapshot grid, sort/copy, in a tab or overlay). app.state.detachedView (a count) tracks open views. — PR open
extract GraphSurface (src/ui/graph-surface.js) + src/core/graph-selection.js (pure) — shared by the schema graph and, where possible, the EXPLAIN pipeline graph
Epic: open favorited Library queries as an interactive dashboard in a new tab
(/sql/dashboard). Spec + pinned decisions + sub-phases D1–D8 live in #149. Same architecture
(signals + hyperscript, no framework — reaffirmed against the React mockup); one artifact,
client-side route; auth via one-time postMessage handoff + login fallback. Builds on #134
({name:Type} params / varValues) and the chart core.
Note: this checklist previously had D3/D4 swapped (layout vs. global filters) relative to #149's
own body — corrected here during #152 to match #149, the source of truth for phase order.
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 4/5.Phase 1 — finish reactivity (#88)
Phase 2 — near-term wins
{name:Type}while editing, show an input strip, gate Run until filled, and substitute via ClickHouse's nativeparam_<name>args (server-side, type-correct); reads only, soCREATE VIEWdefinitions stay verbatim. Values shared by name + persisted (asb:varValues). Pure detection/classification insrc/core/query-params.js; no new dep. Distinct from Composable queries: reference other library queries via {{name}} (CTE-merge) #39 ({{name}}composable-query CTE-merge — different syntax and purpose). — merged (feat: query variables ({name:Type}) with native param_ substitution (#134) #138)Phase 3 — Windows
src/ui/detached-view.js) extracted from the schema graph's tab/overlay logic; now shared by the schema graph, the EXPLAIN pipeline graph (gains real-tab support), and a new Data Pane Expand (snapshot grid, sort/copy, in a tab or overlay).app.state.detachedView(a count) tracks open views. — PR openPhase 4 — editor: CodeMirror 6 + the features it unlocks
Strict sequence — each issue is the foundation of the next: #143 → #21 → #84 → #60.
EditorPortseam: every consumer moves onto an injected port; the current textarea editor becomes its first adapter. No behavior change — makes the CM6 swap reversible.core/completions.js; textarea adapter + supersededui/editor-*/core/editor-*modules deleted. — PR feat: adopt CodeMirror 6 behind the EditorPort seam (#21) #145 open; manual real-Safari pass still owed post-merge (De-risk the html{zoom} layout dependency (Safari verification + fallback/guard) #70 lesson).core/from-scope.js(FROM/alias resolution) + debounced idle-tick column loading feeding the completion source (never on the keystroke path). — PR feat: FROM-aware autocompletion — alias/scope resolution + debounced column loading (#84) #146 open (alias→table resolution, statement-scoped unqualified columns, 300ms idle-tick column prefetch;core/from-scope.js+core/completions.jsat 100%).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/)Phase 6 — Dashboard (#149)
Epic: open favorited Library queries as an interactive dashboard in a new tab
(
/sql/dashboard). Spec + pinned decisions + sub-phases D1–D8 live in #149. Same architecture(signals + hyperscript, no framework — reaffirmed against the React mockup); one artifact,
client-side route; auth via one-time
postMessagehandoff + login fallback. Builds on #134(
{name:Type}params /varValues) and the chart core.{name:Type}params detected across everyfavorite's SQL, sharing
state.varValueswith the workbench; debounced re-run, per-tileunfilled-param gating, stable per-favorite tile slots (**Phase D3 — global filters (text)**: filter bar over detected
{name:Type}params, re-run affected tiles #152) — PR pendingreadKpi/formatKpiValueincore/, 100%) (Phase D5 — KPI tiles:readKpi+formatKpiValueinsrc/core/(100%), single-row classification, KPI row, bare-scalar fallback, skipped-tiles note. #154)filter:/filter[]:queries, cascading)Note: this checklist previously had D3/D4 swapped (layout vs. global filters) relative to #149's
own body — corrected here during #152 to match #149, the source of truth for phase order.
Cross-cutting
{{name}}CTE-merge (purecore/; no editor dependency)html{zoom}removal — the 1.2× scale is gone (--zoom: 1, PR fix: remove html{zoom:1.2} to kill phantom scrollbars; restore editor bars #147): it was landing box sizes on fractional device pixels and painting phantom scrollbars (editor most visibly; feat: adopt CodeMirror 6 behind the EditorPort seam (#21) #145 had hidden the editor's bars to dodge it). Setting--zoom:1drops the app into the already-tested@supports not (zoom:1)state, so the bridging layer (--vp-zoom, Chart/menu/splitter correction) is now dormant at divisor 1. Remaining: tear out that dead scaffolding (Tear out the now-dormant html{zoom} bridging code (--zoom is 1 since #147) #148) — still wants aGraphSurfaceSchema graph: multi-select + group-move of nodes (marquee, Shift-click, ⌘A) with single-step undo #66 / real-Safari pass since Playwright WebKit ≠ real Safari for zoom×rect.Release-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) #90