← All Releases

v0.2.35

2026-07-18

THE FIELD-BUG SWEEP, DASHBOARDS, AND MARTIN STREAMS

A release forged in the trial fleet: every generate-sources failure reproduced against real engines and fixed at the root, four field bugs down (including one that silently hid bucket sources), sources.yml generation promoted to a first-class CLI command, DVT Dashboards live on :46108 fed by your saved chat assets, and Martin now streams his work as it happens — with automatic recovery when your gateway's model catalog shifts under him. Rolls up 0.2.34 and 0.2.35.

ADDED

  • dvt generate-sources <connection> — the project kick-start, now a real CLI command: no UI, no Martin, zero AI tokens. Walks the connection's information schema live and writes <model-root>/<connection>_sources.yml with meta.connection on every source and a timestamped .bak when the file exists. Consistent flags: -s/--select and -x/--exclude take schema or schema.table patterns with wildcards ('sales', 'sales.*', '*.orders'), --print previews without writing, -o overrides the path (still jailed to your model-paths), and running it bare lists the project's connections.
  • DVT Dashboards on :46108 — the saved answers, on a wall. Every asset you SAVE in Chat with Martin appears as a card; RERUN LIVE executes its SQL through the same guarded virtualization path the chat uses — never a stale number — rendering the saved chart or a table. Deliberately basic v1: the chat is where assets are born, this is where they live. Part of dvt serve, standalone as dvt dashboards, stoppable with dvt kill -s dashboards; rerun and remove answer loopback-only.
  • MARTIN'S WORK streams live: each tool call appears in the chat the moment it finishes — run_sql, get_columns, the lot — then the answer lands whole. (Streaming shaped for an agent whose reply is a structured contract: you watch the work, not raw JSON.)
  • Martin survives the vanishing model: gateway catalogs shift as auth sessions rotate, and a pinned model can disappear mid-conversation. Instead of stranding you, Martin retries once on the gateway's default route and says so in MARTIN'S WORK — with a nudge to re-pick via /model.

FIXED

  • generate-sources on SQL Server: the metadata query carried an ORDER BY that SQL Server refuses inside the derived table Sling wraps it in. No metadata query orders anymore — sorting was always the renderer's job.
  • generate-sources on Oracle: the system-schema blocklist was hiding the connection's own tables when the profile connects as an Oracle-maintained account (XE trials routinely materialize as SYSTEM — and saw zero tables). The walk now always includes the connection's target schema, pruning Oracle's furniture (LOGMNR, MVIEW$, recycle-bin BIN$...) by name, plus every real user schema via oracle_maintained='N'.
  • Bucket sources were unreachable — and worse, sometimes silently empty: the extraction path glued the connection's JSON config blob onto the object path. MinIO refused loudly ('Object name contains unsupported characters'); Azure just listed nothing, so real data impersonated an empty source. Reads now use the connection's true object base — verified by pulling real rows from a MinIO parquet that no query could touch before.
  • The catalog keeps your real column-name case: dvt docs generate lowercased every identifier, breaking mixed-case engines downstream (Oracle's uppercase columns, quoted mixed-case in Postgres). Root cause fixed at generation; the profiler's self-heal stays as belt-and-braces.
  • dvt run --select with a selection matching nothing now says so — 'Nothing to do: the selection matched no models' — instead of exiting 0 in silence. (Adapter warnings sprayed onto stdout were being counted as model names, so the empty check never fired.)
  • Empty sources behave like empty tables in live queries: a 0-row source (Sling writes no file for those) is fabricated as an empty relation over the columns your query reads, so aggregates and joins return honest empty results instead of a 502. A SELECT * over an empty source still errors — with guidance to name the columns.
  • dvt sync now proves the Sling ENGINE answers, not just the wrapper: the sling pip package downloads its ~100MB engine lazily on first invocation, so a fresh environment's first real query could stall behind a multi-minute download that every per-connection timeout kept killing. Sync probes the binary and, when the engine isn't cached, runs the download itself — visibly, with a real budget and an honest failure message.

Get it: pip install dvt-core==0.2.35 · wheels on PyPI for macOS (arm64 + x86_64) and Linux, Python 3.10–3.12.