Commit Graph

426 Commits

Author SHA1 Message Date
claude@clouddev1 9f5f76b05d fix(ui): geometry-fixed hint-panel height kills the typing jump (#20, ADR-0046 DA1/DA2)
The hint panel's height was recomputed every frame from the wrapped
hint content (1–3 rows), so it resized as the user typed and shoved
the input/output panels — the flicker visible in the screencasts.

Make the height a pure function of terminal geometry (new hint_rows),
fixed between resizes: 2 content rows on compact (<40-row) terminals,
3 only on comfortable terminals narrow enough (<54 inner cols) to wrap
the longest catalog hint past two lines, degrading toward 1 on tiny
terminals to protect the output Min(5). resolve_hint_lines clamps to
that fixed budget (long hints ellipsize; short ones leave rows blank).

This reverses issue #12's shrink-to-content "reclaim"; its two tests
are replaced by an anti-jump invariant plus geometry-helper and
third-row tests. Two layout snapshots regenerated.
2026-06-10 17:08:25 +00:00
claude@clouddev1 93266b99c9 docs: ADR-0046 UI sidebar nav-mode + responsive input/hint (#20/#21/#23)
Accepted; implementation pending, phased A→B→C. Treats the three
coupled UI issues as one decision (shared width/height budget):

- #20 hint jumpiness: hint height becomes a function of terminal
  geometry, fixed between resizes, so it no longer shoves the
  input/output panels.
- #21 left column: kept but width-optional (hidden by default ≤90),
  with a new relationships sibling panel and a Ctrl-O navigation/focus
  mode (peek-reveal, expand-on-focus overlay, scroll).
- #23 long input: single-logical-line horizontal scroll plus a 2-row
  display when tall, preserving the ADR-0027 indicator reserve.

A pre-build /runda DA pass drove key corrections: Ctrl-B→Ctrl-O (Ctrl-B
is the tmux prefix), an additive SchemaCache.relationship_details field
(retyping would break completion), full nav-mode key disposition +
modal gate, and Tier-2 snapshot coverage. Reconciles requirements
S1 (evolved), S2 (overridden — separate relationships panel), and
S4 (corrected — the stale "keyboard-toggleable" hint claim is struck;
no toggle added).

Updates docs/adr/README.md index and docs/requirements.md S1/S2/S4.
2026-06-10 16:57:46 +00:00
claude@clouddev1 52860c3267 feat(website): casts for first-project/modes/undo-redo; quit invisibly via Ctrl-C
Three more casts on "doing" pages:
- first-project reuses the quickstart cast (the create→insert→show tour)
- modes (new): a simple command, then `mode advanced` where the same command
  also prints "Executing SQL: …" (the teaching echo — "learn the SQL underneath")
- undo-redo (new): insert two rows, `undo` (Y-confirm modal) backs one out,
  `redo` restores it

Also fix the cast endings (review feedback): scripts ended by typing a `quit`
command, which — once the trim drops the shell exit — left a dangling "quit" in
frame with no payoff. End every cast with Ctrl-C instead (the app's quit key,
KeyCode::Char('c')+CTRL): it types nothing, so the cast ends cleanly on the
last content frame. Generator gains a `CtrlC` key; all six casts regenerated.

Convert the three pages to .mdx and embed. Build clean (26 pages); 6 casts.
2026-06-10 16:36:07 +00:00
claude@clouddev1 ce153bde4c docs(website): add SQL queries reference page (advanced query surface)
New dedicated Reference page for the advanced-mode SQL query features
under-covered by "Querying & inspecting": DISTINCT, GROUP BY/HAVING, set
operations (UNION/INTERSECT/EXCEPT), subqueries (IN + correlated NOT EXISTS),
CTEs (WITH), and expressions (CASE/CAST/functions) — each with a worked example
on the library schema and real captured output. Adds an explicit "supported
subset" boundary note (views, triggers, transactions, window functions,
multi-statement batches are not available) rather than linking to general SQL,
which would advertise unsupported features. Grounded in ADR-0030 §3/§13 and the
SQL grammar tests.

Cross-link added from Querying & inspecting. Build clean (26 pages);
box-drawing output verified; forbidden terms clean.
2026-06-10 15:31:05 +00:00
claude@clouddev1 302329d5b2 docs(website): record the cast-placement policy in STYLE.md
"A cast wherever the app does something": broad on Getting-started /
Using-the-playground / Guides + the landing; selective on Reference (motion
beats the still, static output kept regardless); skip pure-lookup/conceptual.
Casts are selective (a representative slice, not every command); autoplay only
the landing; all re-record via `pnpm casts`.
2026-06-10 14:32:48 +00:00
claude@clouddev1 f88018b4be docs: session handoff 62 — C4 m:n convenience command + issue #19 2026-06-10 14:28:50 +00:00
claude@clouddev1 8bd43ccadf feat: create m:n relationship convenience command (C4, ADR-0045)
`create m:n relationship from <T1> to <T2> [as <name>]` generates a
junction table with one FK column per parent PK column ({table}_{pkcol},
typed via fk_target_type), a compound PK over them, and two CASCADE 1:n
relationships -- all in one do_create_table call = one undo step.
Auto-named {T1}_{T2} (optional `as`), both modes, compound-parent PKs
supported (ADR-0043). Self-referential m:n / PK-less parent / internal
junction name / name collision all refused.

Wired across every surface: grammar (separate CREATE_M2N node), worker
executor, runtime dispatch, completion ("m:n" composite), hints,
highlighting, help + usage catalog + disambiguator, and the advanced-mode
DSL->SQL teaching echo (render_create_m2n, round-trips as valid SQL).

Generalized/fixed framework assumptions the build + two /runda passes
surfaced (all behaviour-preserving for existing commands):
- simple-mode dispatch committed simple.first() unconditionally -> tries
  candidates, so `create table` no longer shadows `create m:n`.
- the completion continuation-merge was advanced-only -> runs in simple
  mode too when an entry word has >1 DSL form (gated simple_count>1).
- do_create_table now rejects internal `__rdbms_*` names (closes a
  pre-existing hole on the DSL create-table path too, not just m:n).
- usage disambiguator now recognizes the `m:n` opener.

Tests: 14 integration (tests/it/m2n.rs), 7 typing-surface matrix, echo /
highlight / usage / internal-name units. Closes C4.
2237 pass / 0 fail / 1 ignored. Clippy clean.
2026-06-10 14:26:33 +00:00
claude@clouddev1 65a48fa5ae feat(website): joins cast on the querying-with-joins guide
Fourth cast: build a minimal two-table schema with rows, switch to advanced
mode (`mode advanced`), and run a join pairing each book with its author —
shows the mode switch + SQL + multi-table result, motion that complements the
guide's static examples. Convert the guide to .mdx and embed above the intro.

Recorded via `pnpm casts`; build clean (25 pages).
2026-06-10 14:26:27 +00:00
claude@clouddev1 bb7887ea82 feat(website): relationship-diagram cast on the relationships page
Third earmarked cast: declare a 1:n relationship, then `show relationship`
draws the two-table connector diagram — showcases the V1 relationship
visualization with motion a still block can't. Convert the relationships
reference page to .mdx and embed it above the syntax (the static diagrams
below remain the exact reference).

Recorded via `pnpm casts`; build clean (25 pages).
2026-06-10 14:13:14 +00:00
claude@clouddev1 a8f84c9d17 feat(website): refine casts — trim shell, autoplay+loop landing, cap size
Address cast review feedback:

- Trim every cast to the in-app region (generate.mjs): the recording now
  starts with the app already running and ends on the last in-app frame —
  drops the `$ rdbms-playground` launch and the return-to-shell frame (the
  latter was the stray cursor-under-$ artifact). Opt out per cast with
  `keepShell: true` for demos that document the CLI launch.
- Landing quickstart cast: autoPlay + loop, with a 2.5s hold on the final
  frame so it pauses before restarting.
- Cap the demo at max-width 46rem and centre it, so the player (fit:'width')
  no longer scales its font up to the full splash column.

Casts re-recorded via `pnpm casts`. Build clean (25 pages).

Tab-keypress visibility deferred to an in-app overlay primitive (filed as
issue #22 — also serves the planned guided-lesson system); the cast notes
Tab in its caption for now.
2026-06-10 13:56:39 +00:00
claude@clouddev1 e598008ecf docs: ADR-0045 m:n convenience command (C4); accepted
create m:n relationship from <T1> to <T2> [as <name>] generates a
junction table (compound PK over the two FK column sets, CASCADE FKs)
plus two 1:n relationships, in one do_create_table call = one undo
step. Forks user-confirmed; /runda DA pass verified the reuse against
code and the no-PK-tables-exist-in-advanced-mode fact (parent-PK guard
retained). Self-referential m:n refused; FK cols named {table}_{pkcol}.
2026-06-10 13:18:07 +00:00
claude@clouddev1 e44d2983ab test+docs: lock drop-PK-refused on advanced surface; document no-PK advanced mode (#19)
Dropping a PK column was already refused in both modes via the shared
do_drop_column guard; this adds end-to-end coverage on the advanced
ALTER surface (single-column + compound PK, asserting refusal for the
right reason) and documents the asymmetry that advanced-mode SQL can
create a PK-less table (SQLite's implicit rowid keys it) while simple
mode forbids it. See issue #19 comment for the full assessment.
2026-06-10 13:18:07 +00:00
claude@clouddev1 1f82fb2c79 chore(website): upgrade astro 6.4.5 + starlight 0.40.0 (clears markdown deprecation)
Astro 6.4.5 deprecated markdown.remarkPlugins/rehypePlugins/remarkRehype in
favour of the new unified() API. The warning came from @astrojs/starlight
0.39.3's own integration code, not our config; Starlight 0.40.0 adopts the new
API, so it's gone.

- astro 6.4.4 -> 6.4.5; @astrojs/starlight 0.39.3 -> 0.40.0
  (brings astro-expressive-code 0.43.1, @astrojs/markdown-remark 7.2.0)
- Starlight 0.40.0 adds an optional @astrojs/markdown-satteri peer (an opt-in
  high-performance markdown engine); it's an optional peer so pnpm doesn't
  install it, and we have no need for it — we stay on the default
  markdown-remark/unified pipeline

Verified: deprecation gone; pnpm build clean (25 pages); rendering signals
unchanged vs baseline (highlighting, > prompt + copy-button :has() CSS, asides,
embedded casts); pnpm audit clean.
2026-06-10 13:17:49 +00:00
claude@clouddev1 44f91724b6 feat(website): assistive-editor cast content (completes c904dbb)
The previous commit captured only the .md→.mdx rename — a botched `git add`
(a stale .md pathspec aborted the whole add) dropped the actual content. This
adds it:

- casts.mjs: the assistive-editor cast definition (Tab completion → the [ERR]
  validity indicator catching a misspelled table → friendly error → corrected
  command). Behavior verified by a throwaway spike before scripting.
- public/casts/assistive-editor.cast (generated via `pnpm casts`)
- embed the cast under the intro on the assistive-editor page

Verified: pnpm build clean (25 pages); cast bundled, served, and referenced.
Visual playback check pending (verify via dev server/tunnel).
2026-06-10 13:05:04 +00:00
claude@clouddev1 c904dbb68b feat(website): assistive-editor cast (completion + [ERR] indicator)
Add a second demo, earmarked as prime cast material: Tab completes a table
name, then the [ERR] validity indicator catches a misspelled table before
submit, the friendly error confirms it, and the corrected command runs.
Behavior verified by a throwaway spike before scripting.

- casts.mjs: assistive-editor cast definition
- public/casts/assistive-editor.cast (generated)
- convert the-assistive-editor.md -> .mdx and embed the cast under the intro

Verified: pnpm build clean (25 pages); cast bundled, served, and referenced
on the page. Visual playback check pending (verify via dev server/tunnel).
2026-06-10 13:04:31 +00:00
claude@clouddev1 fbf449f9e0 feat(website): asciinema cast pipeline + landing quickstart demo
Settle the cast toolchain (STYLE.md #9) and build the demo pipeline end to
end. Driver: autocast, chosen by spike — its !Interactive feeds keys to the
running TUI and captures the redraw, the right model for a full-screen
crossterm app. asciinema-automation was rejected (assumes shell echo/\n Enter;
produced a garbled cast against the TUI).

- add asciinema-player; Cast.astro (player island) + Demo.astro (the WASM-swap
  seam, ADR-website-001 §3)
- casts-src/: human-readable command-lists (casts.mjs) + generate.mjs, exposed
  as `pnpm casts`; expands steps to autocast YAML and records to public/casts/.
  Command-lists are the durable source; .cast files are regenerable (final
  re-record sweep due once the app is locked).
- quickstart.cast (create -> add columns -> insert -> show data) embedded on
  the landing page above the feature cards.

Verified: pnpm build clean (25 pages); player + cast bundled and served;
landing HTML references the cast. Visual playback check pending (no headless
browser here — verify via dev server over the tunnel).
2026-06-10 12:59:50 +00:00
claude@clouddev1 b8034682ab docs: session handoff 61 — X1 logging full sweep + T3 residuals closed 2026-06-10 12:24:01 +00:00
claude@clouddev1 c0cc92a741 docs(website): rewrite Build the library + add Querying with joins guide
Build the library: polish and extend from a 2-table draft into the full
guided build — all four tables, the authors→books 1:n and the books↔members
m:n through the loans bridge (bridge-table concept taught in context), the
isbn unique constraint, and captured show-relationships / show-data output.
Remove the draft marker; it is now publication-quality. Uses the same sample
rows as the Reference pages so output matches across the site.

Querying with joins (new): joins built up from two tables → the three-table
bridge join → a filtered join → a group-by aggregate, all in advanced mode
with real captured output.

Verified: pnpm build clean (25 pages); no forbidden terms; internal links
resolve. Advanced-mode `mode advanced`/`mode simple` and the unique
constraint checked against source.
2026-06-10 12:11:39 +00:00
claude@clouddev1 5a33f2aeea fix(fk): compound-FK violation message names every column pair
ADR-0043 residual: a compound-FK violation's friendly error named only the
first child->parent column pair (the ADR-0019 facts model is single-column).
enrich_fk_violation now gathers all pairs of the matched relationship and
carries them comma-joined in the existing single-column facts slots, so the
headline reads e.g. "no parent row in `Region` has `country, code` = `7, 8`."
instead of naming just `country`.

Single-column behaviour is unchanged (a one-element join is the element
itself). No facts-model or catalog change -- the joined strings flow through
the existing `{parent_column}` / `{value}` placeholders.

Tests: enrichment facts (compound names every pair, single-column
regression) + translate rendering (headline names both columns). 2211 pass
/ 0 fail / 1 ignored. Clippy clean.
2026-06-10 11:59:14 +00:00
claude@clouddev1 10655e46de docs(website): fill the six Reference stubs with worked examples + output
Expand columns, relationships, indexes, constraints, inserting-and-editing-
data, and querying-and-inspecting from syntax-only stubs into full pages,
each with worked examples on the library schema and real captured app output
(structure boxes, relationship diagrams, data tables, show-lists, query
plans, cascade summaries). All output captured verbatim from the app — never
hand-drawn. Both simple- and advanced-mode forms shown where both apply;
advanced syntax verified against tests/source.

STYLE.md: record the output-block convention (plain unlabelled fence,
captured from a throwaway harness, not hand-drawn).

Verified: pnpm build clean (24 pages); no forbidden terms; internal links
and heading anchors resolve.
2026-06-10 11:50:18 +00:00
claude@clouddev1 6985a43f31 fix(fk): inline FK referencing a compound PK points at the table-level form
ADR-0043 D4 residual: an inline column-level FK (`<col> REFERENCES P(a,b)`)
is single-column by construction, so referencing a parent's compound PK
gave the generic arity error ("1 foreign-key column(s) on the child side,
but `P`'s key has 2..."). It now points the user at the table-level form:
"an inline column reference can only name one column ... Use the table-level
form instead: FOREIGN KEY (<columns>) REFERENCES P (a, b)".

- Adds `inline: bool` to SqlForeignKey, set by the grammar's single shared
  builder consume_fk_reference (true for the inline path, false for the
  table-level and ALTER paths).
- resolve_fk_parent_columns takes `inline` and tailors the arity-mismatch
  message when an inline FK meets a compound key.

Tests: parse-layer (inline=true / table-level=false) + end-to-end worker
refusal wording. 2209 pass / 0 fail / 1 ignored. Clippy clean.
2026-06-10 11:49:33 +00:00
claude@clouddev1 0a7612efe2 feat: comprehensive logging across parser, app, persistence, runtime (X1)
Completes the X1 full sweep started in a8ad0c6 (db.rs). Closes X1 -> [x].

- persistence/mod.rs: debug! on every yaml/CSV/history write -- the
  silent-failure-prone disk paths (write_schema, write_table_data incl.
  the empty->delete branch, append_history/_failure).
- runtime.rs: debug! on execute_command_typed dispatch (one per executed
  command, complements the db.rs executor logs).
- app.rs: debug! on submit (route + submission mode), dispatch_app_command,
  and the ADR-0044 diagram-vs-prose render-mode choice.
- dsl/parser.rs: trace! on parse begin/outcome at the parse_command_inner
  choke point -- trace, not debug, because the live overlay/completion
  re-parse per keystroke (hot path).
- logging.rs: documented level discipline (error/warn/info/debug/trace) so
  the convention survives across sessions.

Levels verified end-to-end through the real worker thread + logging::init.
~75 -> 135 tracing sites total. Tests: 2207 pass / 0 fail / 1 ignored.
Clippy clean.
2026-06-10 11:38:22 +00:00
claude@clouddev1 a8ad0c6cc3 feat(db): comprehensive logging across worker + executors (X1)
Instrument db.rs to the CLAUDE.md "log liberally" bar (X1). 26 -> 67
tracing sites:

- Entry-level debug! on all 34 do_* executors (DDL, DML, relationship,
  index, read paths), matching the existing do_sql_delete/do_run_select
  style -- so the route through delegating executors (e.g. add_column ->
  add_constrained_column_via_rebuild) is visible in the log sequence.
- Decision-point logs: rebuild_table primitive (begin/commit; FK-check
  failure and foreign_keys re-enable failure as warn), do_insert autofill
  summary, do_delete cascade summary, do_create_table FK resolution.
- Worker lifecycle (start/exit) raised debug! -> info! so it shows at the
  default level.

Levels per the X1 discipline: debug for per-command detail (off by
default, opt-in via RDBMS_PLAYGROUND_LOG=debug), info for lifecycle, warn
for fallbacks. Loops log summary counts, never per-row.

Tests: 2207 pass / 0 fail / 1 ignored (unchanged). Clippy clean.
2026-06-10 11:26:45 +00:00
claude@clouddev1 619c200ea1 Merge branch 'main' into website (V1 relationship visualization)
Brings main's relationship-visualization feature (ADR-0044 in the main
namespace) and Gitea-migration cleanup onto the website branch, so the
docs can be written against the new diagram output:

- show relationship <name> / show table <T> render two-table connector
  diagrams (child-FK-left, parent-right, n…1 cardinality)
- compound-FK bus routing + pairing line
- ~2000 lines across src/{app,db,event,output_render,runtime,ui}.rs,
  new insta snapshots, tests/it/{show_list,compound_fk}.rs

Merged clean — no conflicts. The prior commit moved the website ADR out
of docs/adr/ into its own namespace, so main's ADR-0044
(relationship-visualization) lands with no collision.

Tests on the merged tree: 2207 passed, 0 failed, 0 skipped
(1 ignored doctest, inherited from main).
2026-06-10 11:06:14 +00:00
claude@clouddev1 dfb5f0b1b1 docs: move website ADR + plan into a dedicated docs/website/ namespace
The website subproject drew ADR numbers from the same global integer pool
as main, so every merge risked a collision — this already happened twice
(drafted 0042, bumped to 0044, both landing on numbers main had taken; main
has now used 0044 for relationship visualization). Give the website its own
ADR namespace so the two never compete again.

- docs/adr/0044-public-website-...md
    -> docs/website/adr/20260604-adr-website-001.md  (id: ADR-website-001)
- docs/plans/20260604-adr-0044-website.md
    -> docs/website/plans/20260604-website-implementation-plan.md
- new docs/website/adr/README.md index (dated <date>-adr-website-<NNN> seq)
- docs/adr/README.md: drop the 0044 entry, add a namespace pointer in the
  intro (keeps the list tail == merge-base, so main's 0044 merges cleanly)
- ADR-0000: record the subproject-ADR-namespace convention
- update references in STYLE.md, astro.config.mjs, the plan body

Handoff files left untouched as point-in-time history.
2026-06-10 11:04:55 +00:00
claude@clouddev1 39e97ac3f9 docs: website-branch session handoff (website-1)
First handoff for the website work, on a branch-scoped name sequence
(…-website-handoff-N.md) to avoid colliding with main's handoff-NN files.
Captures stack/layout, the five-section structure, binding conventions
(no DSL / no engine name / fence + prompt + copy rules), the canonical
library schema, a verified-syntax cheat-sheet, the dev-server IPv4 gotcha,
next-work priorities (fill the 6 Reference stubs, iterate guides, Phase B
landing, deferred casts), and process pins.
2026-06-10 10:41:45 +00:00
claude@clouddev1 1152b0dc14 docs: session handoff 60 — Gitea migration cleanup + V1 relationship visualization (ADR-0044) 2026-06-10 10:40:48 +00:00
claude@clouddev1 936d9254c0 feat: add "Using the playground" section + Reference skeleton
Restructure the docs into five top-level sections, splitting the
application you drive from the database language you build with.

- New "Using the playground" section: command-line options; the assistive
  editor (completion, highlighting, [ERR]/[WRN] indicator, hints, in-line
  editing); the output pane (scrolling); projects (save/load/new/rebuild);
  undo/redo & history; export & import; clipboard; getting help. Grounded in
  the in-app help/usage and ADR-0003/0022/0027.
- Reference: seed the remaining topic pages (Columns, Relationships,
  Indexes, Constraints, Inserting & editing data, Querying & inspecting)
  with real syntax synopses; worked examples to follow.
- Surface the assistive editor on the landing page and in Getting started;
  restore cross-links now that targets exist.

Plan + STYLE updated to the five-section structure. 24 pages, build green,
links resolve, content clean; planned features carry "planned" callouts.
2026-06-10 10:40:07 +00:00
claude@clouddev1 0a343036d8 feat: compound-FK bus routing + complete V1 relationship visualization (ADR-0044)
Completes requirement V1. A compound (multi-column) FK now routes a
bus connector — each paired endpoint's stub merges into a shared
vertical channel that splits to the other side — plus an explicit
"(a, b) ▶ P.(x, y)" pairing line; the bus generalises the single-column
jog (reproducing it exactly, so prior snapshots are unchanged).
Self-referential FKs render as two same-named boxes.

- output_render.rs: gutter_seg routes all endpoint pairs via a
  junction() bus; pairing line for compound FKs; compound, self-ref,
  and compound-from-data (build_diagram_table glue) tests + snapshots
- compound_fk.rs: worker test that show_relationship carries both
  paired column lists into the diagram payload
- db.rs: document do_show_one's now-app-superseded relationship prose
  branch (retained as a worker-API/text fallback; could back a future
  non-visual display option, cf. ADR-0044 OOS-7)

Second /runda pass over the implementation: confirmed ADR-compliance,
UTF-8/byte-range safety, and edge-case routing. The ADR §3 last-resort
helper line was considered and rejected (vertical fallback + ratatui
truncation cover all realistic cases). ADR-0044 marked implemented;
requirements.md V1 -> [x].

Full suite 2207 pass / 0 fail / 1 ignored; clippy nursery clean.
2026-06-10 10:17:09 +00:00
claude@clouddev1 a0ee32393f feat: show table renders relationships as compact diagrams (ADR-0044)
show table <T> and add/drop relationship echoes now render the focal
structure box plus a Relationships section of compact stacked
connector diagrams (child-left/parent-right, n…1, actions); incidental
DDL echoes keep the prose References:/Referenced by: form. Selected by
command in handle_dsl_success via the "relationship-relevant" reach.

- output_render.rs: render_structure refactored into section helpers
  (box/prose/index/constraint), byte-identical output; new
  render_structure_with_diagrams + compact-box rendering
- app.rs: handle_dsl_success routes ShowTable/Add/DropRelationship to
  the diagram path, others to prose
- fixes: eager widths[1] index on compact (1-col) boxes; body-cell
  padding under title-widening (name wider than columns)

Tests: unit + snapshot + integration; add-relationship echo test
updated to the diagram form. Full suite 2203 pass / 0 fail / 1 ignored;
clippy clean. V1 still [/] (compound routing + self-ref remain).
2026-06-10 06:56:35 +00:00
claude@clouddev1 44390e765d feat: simple-mode code-block highlighting, prompt, and copy rules
Add a custom Shiki grammar for the simple-mode command language
(src/grammars/rdbms.mjs), registered with Expressive Code. Two language ids
share it: rdbms (real commands) and rdbms-syntax (abstract templates).
Simple-mode blocks now highlight; advanced examples keep sql.

Separation + copy ergonomics via CSS (global.css): a decorative, copy-safe
"> " prompt on rdbms command lines (not in the copy buffer), and the copy
button hidden on multi-command rdbms blocks and on rdbms-syntax templates
(the app input is single-line, so a multi-command paste is not runnable);
single-command, sql, and sh blocks keep copy.

Content: convert 22 simple-mode fences to rdbms; lead the simplest examples
(first project, Tables reference) with bare "with pk" (the beginner default
that creates a ready-made id key), pointing to the named form. Record the
fence + prompt conventions in STYLE.md.
2026-06-09 22:30:44 +00:00
claude@clouddev1 995c0ba8eb docs: reconcile website doc inventory with merged main scope
The merge from main added user-facing surface the pre-merge inventory had
listed as planned. Mark them documented-as-shipped: show tables /
relationships / indexes + show relationship/index <name> (V5/V5a),
help [<command>] + help types (H3), compound-primary-key foreign-key
references (T3, ADR-0043), and friendlier parse-error messaging (H1a).
Refresh the test count to 2193 and note requirements.md now uses a [/]
partial marker (trust the code, not the marker).
2026-06-09 22:30:44 +00:00
claude@clouddev1 cad90ec4a5 feat: show relationship <name> renders a styled two-table diagram (ADR-0044)
The first wired slice of relationship visualization (V1). `show
relationship <name>` now renders the relationship as two full
structure boxes joined by a width-jogging connector (child-left /
parent-right, n…1 cardinality, on delete/update actions), styled
App-side, with a vertical-stack fallback for narrow terminals.

- db.rs: RelationshipDiagramData + show_relationship worker path
  (structured data: the relationship + both endpoint TableDescriptions)
- runtime.rs: named relationships route to the structured outcome
  (boxed); other show <kind> forms stay prose
- app.rs/event.rs/ui.rs: DslShowRelationshipSucceeded rendered App-side;
  new diagram OutputStyleClass variants; App::last_output_width from ui.rs
- output_render.rs: styled Seg layout engine (boxes, connector routing,
  side-by-side + vertical), composing the ADR-0016 box primitives

Tests: 4 unit + 4 integration; full suite 2201 pass / 0 fail / 1 ignored;
clippy nursery clean. requirements.md V1 stays [/] (show table diagrams,
compound routing, DDL-echo wiring remain).
2026-06-09 22:27:39 +00:00
claude@clouddev1 bb02dfb752 docs: ADR-0044 relationship visualization (V1); accepted
Two-table connector diagrams (Style A) for relationships, resolving
ADR-0016 OOS-1 and the open half of requirements.md V1. Reach is
'relationship-relevant' (show relationship / show table / relationship
DDL echoes; incidental echoes keep prose). App-side rendering, width-
adaptive side-by-side vs vertical, compound-FK pair routing, bold box
title rows. Revised after a /runda DA pass corrected three inverted-
architecture claims (App-side rendering, untracked output width,
prose-in-worker show-relationship).

Index updated per ADR-0000.
2026-06-09 21:47:35 +00:00
claude@clouddev1 c72c624daa chore: bind website dev/preview server to IPv4 loopback (127.0.0.1)
Astro/Vite's default localhost bind resolves to IPv6 ::1 on this host,
which silently breaks `ssh -L 4321:127.0.0.1:4321` tunnels (they target
IPv4). Pin server.host to 127.0.0.1 so dev/preview is reachable over an
IPv4 loopback forward. Loopback-only — no network exposure.
2026-06-09 21:44:43 +00:00
claude@clouddev1 9e774b2dfa docs: ADR numbering discipline — assign numbers at merge-to-main
Codifies the fix for the ADR-0042 cross-branch collision (resolved this
merge by renumbering the website ADR to 0044): ADR numbers are assigned
when a branch merges to main, not at creation. On a branch, draft under
a placeholder (ADR-XXXX title / draft-<slug>.md filename); main's
docs/adr/README.md is the single source of truth for the next free
number.

- ADR-0000: new "Numbering discipline" section.
- CLAUDE.md: pointer to it from the documentation-discipline note.
2026-06-09 20:30:36 +00:00
claude@clouddev1 40de389bcb Merge branch 'main' into website (Gitea migration + ADR renumber)
Brings website up to date with main (18 commits): H1a parse-error
pedagogy, V5/H3/V5a show+help commands, ADR-0043 compound-PK FK,
handoffs 58-59, and the GitHub->Gitea doc scrub (Cargo.toml repository,
CLAUDE.md, ADR-0001 amendment, requirements).

Conflict: docs/adr/README.md. main and website had each created an
ADR-0042 (main: H1a parse-error pedagogy; website: public website &
docs site). Renumbered the website ADR to 0044 (next free after main's
0042/0043) and updated all references (ADR file, plan file, STYLE.md,
astro.config.mjs, README index). Website build verified green.
2026-06-09 20:28:27 +00:00
claude@clouddev1 b17148b467 docs: scrub GitHub-specifics after Gitea migration; add tea issue conventions
- Cargo.toml: repository -> git.lazyeval.net/oli/rdbms-playground
- requirements.md: backlog now tracked as Gitea issues
- ADR-0001 Amendment 1: distribution channel reopened post-migration
  (Decision text preserved per supersede-don't-rewrite)
- CLAUDE.md: issue-tracking working method + Gitea/tea operational section
2026-06-09 20:07:40 +00:00
claude@clouddev1 e9b7f58fbc docs: session handoff 59 — tracking reconciliation + V5/H3/V5a sweep + T3 compound-PK FK (ADR-0043) 2026-06-09 18:45:58 +00:00
claude@clouddev1 4752ba29a0 feat: compound-PK foreign-key references — grammar + tests (ADR-0043)
Multi-column FK parsing on both surfaces: DSL from P.(a, b) to
C.(x, y) (parenthesized endpoint; single bare form unchanged) and
SQL FOREIGN KEY (a, b) REFERENCES P(x, y) incl. bare-reference
auto-expand. consume_fk_reference + the table-level/ALTER FK
parsers collect column lists; the from P. completion now offers
( (snapshots updated). 12 integration tests in
tests/it/compound_fk.rs cover parse (both surfaces), engine-enforced
FK, arity + partial-PK + per-pair-type-mismatch refusal,
--create-fk per-column, save->rebuild round-trip, undo (one step),
and single-column preservation. Mark T3 [x]; ADR-0043 implemented.
2026-06-09 18:44:37 +00:00
claude@clouddev1 b14f0199e9 refactor: relationship model to column lists for compound FK (ADR-0043)
Move the FK column fields String->Vec<String> through all six
layers (AddRelationship/SqlForeignKey AST, RelationshipSchema,
metadata, project.yaml, ReadForeignKey, RelationshipEnd). Metadata
stores comma-joined lists in the existing TEXT cells; project.yaml
endpoints now columns: [a, b] (house style). Executor logic is
multi-column ready: resolve_fk_parent_columns (full-PK F-A +
auto-expand F-D), per-pair type-compat, schema_to_ddl multi-column
emission, pragma FK read grouped by id, auto-name + --create-fk
per-column, multi-column teaching echo. Single-column behaviour
preserved (one-element vecs); all 2181 tests green. The grammar to
parse multi-column input lands next.
2026-06-09 18:25:40 +00:00
claude@clouddev1 b688592b4c docs: ADR-0043 implementation-readiness notes from /runda DA pass
DA pass found three change sites the first sketch missed
(teaching-echo renderers, --create-fk per-column creation, the
auto-name generator) and made explicit the rules the forks left
implicit: SQLite FK precondition (compound PK provides the unique
index), explicit parent cols must be the PK set (any order,
positional), arity/empty/inline-rejection wording, single-in-parens
accepted, --create-fk per-column typed to fk_target_type. Expanded
the test plan to cover enforcement, auto-expand, undo, round-trip.
Fixed a stale 'legacy yaml loads' test line (no back-compat).
2026-06-09 17:11:01 +00:00
claude@clouddev1 274e2b17b7 docs: ADR-0043 compound-PK foreign-key references (T3); accepted
Audit found single-column FK woven through ~15-20 sites; earns an
ADR. Decision: reference the parent's full compound PK, matched
positionally to an equal-length child list, per-pair type compat.
DSL `from P.(a,b) to C.(x,y)`; SQL `FOREIGN KEY (x,y) REFERENCES
P(a,b)` with bare-FK auto-expansion. Storage follows the existing
primary_key: [...] list convention (yaml columns: [a,b], uniform
JSON in unchanged metadata TEXT cols); back-compat not required,
so no migration. Also marks T3's verified scope.
2026-06-09 17:01:38 +00:00
claude@clouddev1 1d898adf00 feat: V5a show relationship/index <name> detail views
Fold the singular per-item forms into Command::ShowList { kind,
name: Option<String> } (name: Some = one item). Two grammar
branches reuse the relationship/index completion sources; worker
do_show_one renders a labelled detail block or a friendly
"No ... named X." line, reusing the V5 render path. Help +
parse-usage entries, two ADR-0042 near-miss rows, 5 integration
tests. Mark V5a [x] — V5's [<name>] clause now complete.
2026-06-07 14:04:00 +00:00
claude@clouddev1 757711f2bf feat: H3 help <command> per-command detail + general reference
HELP node takes an optional single-word topic (BarePath);
AppCommand::Help { topic }. note_help_topic renders the help
block(s) of every command sharing that entry word (so `help
create` covers both create forms), plus `help types` and a
friendly "no help for X" pointer for unknown topics. Full help
gains a detail-hint footer. Catalogued help.detail_hint /
help.unknown_topic; parse-error matrix updated (help now takes a
topic, so the near-miss is the multi-word case). 9 integration
tests in tests/it/help_command.rs. Mark H3 [x].
2026-06-07 13:32:18 +00:00
claude@clouddev1 8dec784080 feat: V5 show tables / relationships / indexes list commands
Add the list-all show family as one Command::ShowList { kind }
variant. A read-only worker show_list formats count-headed lists
(reusing do_list_tables / read_all_relationships /
read_table_indexes, so it never drifts from the items panel);
internal __rdbms_* tables excluded. Help + parse-usage entries
added; 10 integration tests in tests/it/show_list.rs.

Mark V5 [x]. Split the singular show relationship/index <name>
detail forms (the [<name>] half) into a new tracked V5a [ ] item
rather than leaving them as an untracked footnote.
2026-06-07 13:20:52 +00:00
claude@clouddev1 28e75961aa docs: reconcile requirements tracking with verified code state
Audit of all 35 [ ] items vs source found ~46% mis-marked. Add a
[/] partial marker; promote 7 shipped-but-open items to [x]
(S1/S4/S5/I1a/I3/I4/C1) and 9 substantially-built ones to [/]
with gap notes (S3/A1/V1/V2/V5/T3/H3/DOC1/X1). Fix CLAUDE.md's
false "Tier 4 is wired" claim — no PTY tests exist.
2026-06-07 12:31:16 +00:00
claude@clouddev1 ca158e8b25 docs: session handoff 58 — H1a done via ADR-0042 systematic pass 2026-06-06 12:29:47 +00:00
claude@clouddev1 c305dc7282 docs: mark H1a done via the ADR-0042 systematic pass
requirements.md H1a → [x]: the per-command near-miss matrix (entry words,
missing clauses, committed multi-forms, both modes) plus the gap fixes
(G1 `1:n relationship`, G2 select projection gloss, G3 mode-aware usage
showing all valid forms, G4 `with` CTE template, CROSS JOIN ON teaching
message) close the systematic pass. The advanced-SQL items the survey
flagged (INSERT…SELECT count, RETURNING scope) were verified already
present. One low-priority residual is deferred by decision (submit-time
expression first-set at non-projection positions).

ADR-0042: record the pre-existing `SELECT *` arity caveat (INSERT…SELECT
with a star projection isn't expanded for pre-flight arity; engine
catches it at execution — adjacent to ADR-0019 §OOS-2).
2026-06-06 07:44:55 +00:00
claude@clouddev1 0fcb7b1105 docs: website docs structure + first content pages
Phase D foundation. Configures the pragmatic four-section sidebar
(Getting started / Guides / Reference / Concepts) and replaces the
template example pages with grounded content built on the shared
"library" example database (authors/books/members/loans):

- Getting started: installation, first project, simple vs advanced,
  the example library.
- Reference: Types (all ten + serial/shortid + advanced aliases),
  Tables (create/drop, compound PK, advanced CREATE TABLE).
- Concepts: projects & storage (readable files, derived database,
  autosave, temp projects).
- Guides: Build the library (draft, to be refined for teaching).

Command syntax grounded in en-US.yaml usage/help, command.rs, and
types.rs (verified against tests). Records the settled doc decisions
in STYLE.md. Build green (10 pages, Pagefind); content clean of
"DSL"/engine-name.
2026-06-06 07:34:57 +00:00