Repository navigation
Release 0.2.0: SDK 5.2.0, full-screen DQL lessons, tutorial, dql bench, shell .metrics, full profiles - #9
Open
Aaron LaBeau (biozal) wants to merge 12 commits into
Open
Aaron LaBeau (biozal) wants to merge 12 commits into
Aaron LaBeau (biozal) wants to merge 12 commits into
Conversation
- Bump @dittolive/ditto from 5.1.0 to 5.2.0 (same native platform matrix) - Update vite (8.3.6), source-map-js (1.2.2), and vitest (4.1.12) to resolve Dependabot/npm audit advisories in dev tooling - Bump package version to 0.2.0 and add releases/v0.2.0.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bring `dittosh dql --profile` to parity with the Ditto VS Code extension and surface every field the SDK 5.2.0 ~request_profile envelope returns: - parse #stats.yields (non-zero counters by reason), phaseTimes.stor, documentsSkipped, envelope directives, and nlJoin.inner subplans - render recv/send/stor and yields as per-operator detail lines, remaining operator attributes (truncated), skipped docs, labeled inner subtrees, Stor/Yields totals, and a db/request/flags/directives header line - count subplan exec time toward hotspot detection - regenerate the profile fixture from SDK 5.2.0 (spike-c now adds a join) - document the change in README, diagnostics testing doc, release notes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Enable the SDK's startup-gated system:metrics exporter when the session opens (DittoConfig systemParameters, SDK 5.2+), and add a REPL `.metrics` command that renders it as boxed tables, in parity with the Ditto VS Code extension's System Metrics panel: - store (backend/store/storage) and query (ditto.query.*, dql.* aliases deduped) sections by default; `.metrics <section>` or `all` for more - counters table (total since session open, change since last read) and timings table with a two-level header separating running Count/Avg/Peak from since-last-read New/p50/p90/p99/Max - namespace header rows, labelled breakdowns as `└ db=main`, unit-aware values (ns/µs/ms/s, B/KB/MB), shared name-column width, terminal fitting - clear messages for a disabled exporter, read failures, unknown sections - real SDK 5.2.0 system:metrics fixture; unit, mocked-session, and integration coverage; README, AGENTS, REPL testing doc, release notes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `dittosh tutorial` writes a hands-on Markdown walkthrough tailored to the install (CLI/SDK version, Homebrew or npm upgrade commands, platform), covering import/query/export, the shell and .metrics, datasets, explain/profile/advise, joins, what's new in DQL for SDK 5.2, and skills. Content is structured blocks; the e2e suite runs every runnable block in order and checks expected output. - `dittosh tutorial --interactive` starts a learn> shell with 27 lessons across beginner, intermediate, and advanced levels. Each teaches a concept (with an "if you know SQL" note), shows syntax, sets a task, and checks the answer by result, not text. Separate practice store, saved progress, .hint/.answer/.next/.back/.lessons/.level/.goto/.reset. - Advanced lessons and a tutorial section cover SDK 5.2 DQL changes (researched against 5.1.0 vs 5.2.0): ANY … SATISFIES with AND, USE IDS deletes/evicts, mixed-direction composite indexes, constant-first index ranges, system:sync_degradations, support bundles, new system_info keys, ditto.query.* metrics. - Every lesson answer verified against the real SDK (integration test); unit tests for rendering, command wiring, runner, eval, and check failures. - README, AGENTS, release notes, docs/testing-tutorial.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The interactive DQL lessons now open in a full-screen view built with Ink and React, lazy-loaded so no other command pays for them. A TutorialProvider supplies the lesson runner (which owns the Ditto session) and an output store to the components; the editor, layout, schema, help, and outline logic are pure modules with unit tests. `--plain`, or a window under 60x20, keeps the line-by-line node:repl shell. - Enter runs a statement (`;` optional); a `|` line only when the input looks unfinished. Each action starts with an empty results panel, and the latest ✓/✗ verdict stays above the prompt. - Left: a lesson outline with progress (Ctrl+B). Right: a slide-in help panel (?) and a data view (Ctrl+T, `.schema`) listing the fields of the lesson's collections from the live store. Ctrl+L lesson list, Ctrl+N/P, Ctrl+O for the whole lesson in a short window. - Lessons: syntax examples and hints no longer contain the answer (guarded by tests; every complete example runs against a real store), tasks reworded in plain English, full examples for CASE / BETWEEN / IS MISSING, lesson 13 shows the `details` object, INSERT uses VALUES, and lesson 1 explains that collection and field names are case-sensitive. A wrong-case name gets a case-sensitivity explanation instead of a generic failure. Ink 8 / React 19 are bundled in production mode into a separate chunk (about 23 MB more memory and 50 ms more startup, only for the lessons). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aaron LaBeau (biozal)
marked this pull request as ready for review
November 7, 2026 22:58
Five independent reviewers; fixed the 11 issues at least three agreed on. - Practice store guard: a blank -d now means the lessons' own store (never the default dql store), and the lessons refuse a directory they didn't create, since every lesson resets products/suppliers/orders. - Quitting the full-screen lessons waits for in-flight work before the session closes; plain-shell dot-commands queue behind a running statement, and submit() credits the lesson it started on. - Every lesson starts from fresh practice data, so skipped lessons or stray writes can't fail a correct answer later. - Input stops after a statement passes (the rest would be graded against the next lesson). - Indexes lesson checks for the named index; its setup drops the composite. - Full screen: input scrolls sideways around the cursor, long multi-line input collapses to its last lines, a too-small window shows a placeholder, every line of a multi-line chunk is kept, PgUp stops at the top, and stray control characters are dropped from typed text. - "Progress saved" goes to stderr. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tutorial teaches DQL on the bundled SDK, so it doesn't need to explain what changed between 5.1 and 5.2. - Lessons 21, 23, 26, and 27 lose their "New in SDK 5.2" notes; the badge and the lesson-list tag that showed them are removed. - The Markdown section "What's new in DQL (Ditto SDK 5.2)" becomes "Diagnostics and advanced DQL", with "now" / "Fixed:" / "earlier SDKs" wording replaced by plain descriptions. Same commands and checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…files - `dql bench <statement>` or `-f file.json` times DQL statements over `--runs` (default 50) with optional `--warmup` (bare: adaptive ~250 ms, or a fixed count) and reports mean, p50, p95, p99, min, max, stddev. - `--pre` runs once, `--before-each` (alias `--reset`) before every run untimed, `--post` once at the end even after a failure. - Benchmark files use the dql-metrics-benchmark benchmarks.json format (query, preQueries, resetQueries, postQueries); also a list or a single object. Unknown keys are rejected with typo suggestions. `--only` picks entries. - `--example <dataset>` writes a sample file from a dataset's catalog (plain read, indexed read, aggregate/join, a write that restores its data), each entry described. - `dataset run <query> --runs/--warmup` benchmarks a catalog query. - Stats and warmup sizing match the benchmark runners; a repeated write with no reset statements gets a warning. - Docs: docs/benchmarking.md, a "Benchmark a query" tutorial section, README, release notes, AGENTS.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moving to a lesson resets the practice data. A .goto issued while an answer was still being checked could evict the products under the check, so the correct answer failed (seen on the macOS CI runner). LessonRunner now queues start/submit/next/back/goto/level/reset so each finishes before the next starts; a failed action doesn't block later ones. Adds a deterministic unit test that fails without the queue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `dittosh doctor --report` writes one .tar.gz for GitHub issues: versions, OS/terminal details, doctor checks, paths and free space, dittosh settings (credentials only as set/not set), a store summary (no document contents), the last failed command, and the Ditto SDK 5.2 support bundle (EXECUTE FUNCTION system_request_support_bundle()). Home shows as ~ and the license token is never included. --no-store / --no-sdk-bundle opt out. - `dittosh dql support-bundle [-o file] [--list]` saves just the SDK bundle; past the SDK's 3-per-10-minutes limit it saves the newest existing one. - Failed commands are saved to <config dir>/last-error.json for the report. - `dittosh doctor` works without `dql`. - `--debug` / DITTOSH_DEBUG shows SDK debug logs and stack traces on stderr. - Keep Node's event loop alive while fetching an attachment: the native completion callback doesn't, so Node could exit mid-fetch and abort. - Bug-report issue template, docs/troubleshooting.md, tutorial section. - Silence a false-positive lint warning in the tutorial test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nitization) A cell ending in a backslash before a pipe (\|) could break the Markdown table; writing | as | can't be undone by a backslash and keeps Windows paths readable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Five independent reviewers; fixed what at least three agreed on, plus a credential leak two of them confirmed. - report.json: redact each string before JSON encoding, so Windows home paths (doubled backslashes) and secrets with quotes are caught. - Never write credentials: DITTOSH_GITHUB_TOKEN and any credential-like setting (TOKEN, SECRET, PASSWORD, API_KEY, …) shows only as set/not set, and those values are scrubbed from the whole report and last error. - --report: stage the archive in its own folder (report.md / report.json as names no longer fail), refuse an existing file (exit 2, before any checks), and write the default name inside a given directory. - Say plainly that the SDK support bundle is included as is and holds the database ID, full file paths, and peer keys (help, docs, issue template, release notes, tutorial, end-of-run summary). - Tests get a throwaway DITTOSH_CONFIG_DIR, so failing CLI runs in tests no longer write the developer's real last-error.json. - bench: the "no resetQueries" warning skips UPDATE (same work every run), so --example samples don't trigger it; result columns follow the requested --runs, so a failure doesn't change the JSON/CSV shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prepares the v0.2.0 release. Draft until review is done; tagging
v0.2.0after merge publishes to npm, GitHub, and Homebrew.What's in it
Ditto SDK 5.1.0 → 5.2.0
@dittolive/dittobumped to^5.2.0. Same native platform matrix (macOS arm64, Linux x64/arm64, Windows x64; still no Intel Mac), so the doctor/README/AGENTS platform text only changes the version.NO_COLORabort,system:collectionsfirst-read-only) are left as 5.1.0 — not yet re-checked on 5.2.0.--profileshows the full 5.2.0 profile (parity with the VS Code extension)recv/send/stortimes, yield counts by reason (budget,sender,receiver,heartbeat), skipped documents, and the operator's remaining attributes.nlJoin.innersubplans render as a labeled nested tree (previously a raw JSON attribute) and count toward hotspot detection.StorandYieldstotals; header shows db / request type / feature flags / directives.scripts/spike-c.mjsnow includes a join).New:
.metricsin the dql shellsystem:metricsexporter enabled (DittoConfigsystemParameters, SDK 5.2+), as the extension does..metricsrenders store + query (DQL) metrics as boxed tables;.metrics store|query|all|<section>selects sections.└ db=mainbreakdowns, unit-aware values, shared column widths, terminal-width fitting.dql.*aliases ofditto.query.*are hidden.SELECT * FROM system:metricsnow returns real data in anydittosh dqlcommand instead of the disabled placeholder.New:
dittosh tutorial(written walkthrough + interactive DQL lessons)dittosh tutorialwritesdittosh-tutorial.md, a hands-on walkthrough tailored to the install (CLI/SDK version, Homebrew vs npm upgrade commands, platform). Covers import/query/export, the shell and.metrics, datasets,--explain/--profile/--advise, joins, diagnostics and advanced DQL, and agent skills.--out,--force,--stdout.tests/e2e/tutorial.test.tsruns every runnable block in order against a fresh store and checks expected output (30 blocks), so the tutorial can't silently go stale.dittosh tutorial --interactiveteaches DQL in 27 lessons across beginner (8), intermediate (10), and advanced (9). Each lesson explains the concept (projection, predicates, scalar vs aggregate functions, MISSING vs NULL, joins, indexes, query plans…), adds an "if you know SQL" note, shows syntax, sets a task, and checks the answer by its result. Separate practice store (<config dir>/tutorial-store), saved progress,--level.Interactive lessons: full-screen UI (Ink)
less) built with Ink 8 + React 19: header with progress bar, lesson panel, results panel, a status line with the latest ✓/✗ verdict, thelearn>prompt, and a key bar.?) or the data view (Ctrl+T /.schema): the fields of the lesson's collections read from the live store, with types,n of mfor partial fields, examples, dot paths (details.origin) andlines[].skufor arrays of objects. Each lesson card says which collections it uses and that Ctrl+T shows them.;optional); a|line only when input looks unfinished. Each action starts with an empty results panel; long output opens at its top (PgUp/PgDn). Ctrl+L lesson picker, Ctrl+N/P, Ctrl+O for the whole lesson in a short window, ↑/↓ history, Tab hint. Over-wide tables are cut off with…rather than wrapped; the task line always stays visible.TutorialProvider(React context) supplies theLessonRunner— which owns the Ditto session — and a small output store; the SDK never enters React. Editor, layout, outline, help, and schema logic are pure modules. Tests drive the real screen through a fake TTY.await import) into their own chunk, bundled in production mode, so other commands are unaffected (cli.jssize unchanged). Measured: ~0.39 s vs 0.34 s to the first prompt, ~138 MB vs ~115 MB RSS (the Ditto SDK dominates both).--plain, or a window under 60×20, keeps the node:repl shell.Lesson content review
stock,fair-trade…). A unit test fails if any example or hint contains its lesson's answer, and an integration test runs every complete example against a real store.coffee, and show their names."). Full-statement examples for CASE, BETWEEN, IS MISSING; lesson 13 shows thedetailsobject's shape.VALUES(docs: equivalent toDOCUMENTS; verified on 5.2 with literals, multiple documents, andON ID CONFLICT) in the lessons and the Markdown tutorial.FROM Productssilently returns nothing), keywords aren't. Lesson 1 explains it, and a wrong-case collection or field name gets a specific "names are case-sensitive" verdict instead of a generic failure.ANY … SATISFIESwithAND,DELETE/EVICT … USE IDS, mixed ASC/DESC composite indexes, constant-first index ranges,system:sync_degradations, support bundles, newsystem:system_infokeys,ditto.query.*metrics. No 5.1 → 5.2 regressions found.tests/integration/lessons.test.ts), both in sequence and with each lesson started directly.New:
dittosh dql bench(benchmarking)Modeled on the
dql-metrics-benchmarkrunners so results are comparable.dql bench "<statement>"or-f file.json:--runs <n>timed runs (default 50), optional--warmup(bare = adaptive ~250 ms, clamped 1–1000, like the runners; or--warmup <n>). Reports mean, p50, p95, p99, min, max, stddev (true median, floor-indexed p95/p99, population stddev — same formulas asstats.rs/Stats.kt). One run shows just its time.--preruns once before warmup/timing;--before-each(alias--reset) runs untimed before every warmup and timed run;--postruns once at the end, even after a failure. All repeatable.benchmarks.jsonformat (query,preQueries,resetQueries,postQueries), so suite files run unchanged; a list or single object also works. Its oracle keys (category,qb,expected_count, …) are ignored; other unknown keys are a usage error with typo suggestions (prequeries→preQueries).--only a,bselects entries.--example <dataset>writes a sample file from the dataset's catalog (plain read, indexed read, aggregate/join, a write that restores its own data), keys in run order, each entry with a description. Integration test: every sample runs cleanly and leaves doc counts and indexes unchanged.dataset run <query> --runs <n> --warmupbenchmarks a catalog query with the same runner (existing--setup/--yesrules).evict_single) insert their fixture inpreQueries, so repeated runs time no-ops; pos does it right withresetQueries. The samples avoid those entries; fixing the catalogs is left for follow-up.-o,--format), progress to stderr; exit 1 if any benchmark or cleanup fails, 2 for usage errors.docs/benchmarking.md(options, order of steps, file format, how to build a file), a "Benchmark a query" section in the Markdown tutorial (run by e2e), README, release notes, AGENTS.md.New:
dittosh doctor --report(diagnostics for bug reports).tar.gzto attach to a GitHub issue:report.md+report.json(versions, build, install method, update status, OS/CPU/memory, terminal and locale, doctor checks, paths, store size and free disk space,DITTOSH_*and related settings, collection names with document counts and indexes, the last failed command and its error output) andditto-support-bundle.tar.EXECUTE FUNCTION system_request_support_bundle(), which returns an attachment token; fetched and copied out. Holds the SDK's debug logs (ditto-logs.log.gz, kept up to 15 MB / 15 days) andconfig_snapshot.json(secrets removed). Works offline. The SDK admits 3 requests per 10 minutes per store; past that, the newest bundle insystem:support_bundlesis saved instead, with the SDK's reason.~; no document contents.--no-store/--no-sdk-bundleopt out.<config dir>/last-error.json, so a report can be made after the fact.doctorandsupport-bundledon't overwrite it.dittosh dql support-bundle [-o file.tar] [--list]saves only the SDK bundle.dittosh doctornow works withoutdql.--debug/DITTOSH_DEBUG=1|verboseturns on the SDK's logs (the native logger writes to stderr, so stdout stays results-only) and prints stack traces..github/ISSUE_TEMPLATE/bug_report.yml),docs/troubleshooting.md, a "Report a problem" tutorial section (run by e2e), README, release notes, AGENTS.md, manual checklist indocs/testing-dql-doctor.md.Security (dev dependencies only — not in the installed CLI)
main).@vitest/coverage-v8→ 4.1.12 (moderatenpm auditadvisories).npm audit: 0 vulnerabilities.Adversarial review
Five independent reviewers went over the whole PR; the 11 issues at least three of them agreed on are fixed (
a35054d):-dnow means the lessons' own store (never the default dql store), and the lessons refuse a directory they didn't create — every lesson resetsproducts/suppliers/orders.submit()credits the lesson it started on.Raised by fewer than three reviewers and left for follow-up:
.breakon a|line,--comments in multi-line pastes,.metricswindow labels after a directsystem:metricsread, the composite-index lesson's setup pre-creating its index, a blank screen withCIset, and Update/Evict lessons accepting no WHERE.Second adversarial review (bench + diagnostics)
Five more independent reviewers went over the commits after
a35054d; everything at least three agreed on is fixed (4344fde), plus one credential leak two confirmed:doctor --reportcopied everyDITTOSH_*value, includingDITTOSH_GITHUB_TOKEN. That and any credential-like name (TOKEN,SECRET,PASSWORD,API_KEY, …) now shows only as set/not set, and those values are scrubbed from the whole report and the saved last error.report.json(5): redaction ran after JSON encoding doubled the backslashes; each string is now redacted first.--report report.mdfailed (5);--reportoverwrote files (4): the archive is staged in its own folder; an existing file is refused (exit 2, before any checks); a directory gets the default name inside it.last-error.json(3): tests now get a throwawayDITTOSH_CONFIG_DIR.--examplesamples triggered the reset warning (3): the warning skipsUPDATE, which does the same work every run.--runs.Left for follow-up (fewer than three): Ctrl-C during
benchskipspostQueries; the lessons' data drawer can read mid-reset;bench -oprints "Wrote…" on stdout;--debugcan't overrideDITTOSH_DEBUG=0; auto warmup ignores reset time;support-bundleopens the store before checking-o.Dependencies added
dist):ink8,react19,wrap-ansi10 (already present via Ink). Dev:@types/react.tsconfiggains"jsx": "react-jsx";tsupdefinesprocess.env.NODE_ENV=productionand keepsreact-devtools-core(Ink dev-only) external.Release prep
0.2.0inpackage.json/package-lock.json;releases/v0.2.0.mdadded.Testing
npm testwith dev credentials: 972 passing (907 unit + integration, 65 e2e).npm run coverage: ~94% statements / 89% branches (gate 85%);src/tutorial/ui~97%.npm run typecheck,npm run build,npm run release:checkpass.src,tests,scripts. Note:npm run lintfails onmaintoo becausebiome.jsonuses the 2.2.0 schema with Biome 2.5.11 installed (npx biome migratefixes it) — not addressed here.--profile,.metrics, and the interactive lessons in a real terminal; the full-screen UI was also driven in a pseudo-terminal at 80×24, 100×30, 110×26, and 120×30 and checked frame by frame. Manual checklist:docs/testing-tutorial.md.Before tagging
v0.2.0frommainperdocs/publishing.md🤖 Generated with Claude Code