v0.1.4
Tycoon v0.1.4
Released: 2026-04-30
Headline
v0.1.4 closes the four open issues that survived v0.1.3 (#7, #12, #17,
plus the late-add #18 / #19 / #20), adds a comprehensive MkDocs Material
docs site with tycoon docs serve, and ships a long list of small UX
improvements (-h alias, hygiene fixes, dbt profile flags, non-interactive
register surfaces).
The two themes worth opening with:
-
tycoon data sync— cloud → local DuckDB snapshots (#12).
Snapshot one or moremd:(or local) DuckDBs into a single local
file you can point dbt-dev / notebooks / agents at instead of prod.
Three modes (replace / append / skip-existing), optionalsync:
block intycoon.yml, deliberate v1 non-goals (no reverse, no
incremental). -
First-class observability metadata in dbt + Nao (#20). Tycoon
already accumulated rich run history in.tycoon/metadata.duckdb—
v0.1.4 makes that history visible to the rest of the stack. Every
scaffolded dbt project ATTACHes the metadata DB astycoon_metaand
ships ninestg_tycoon__*staging models (plus adim_runsmart
union'ing dlt + dbt timelines).tycoon ask syncthen exposes them
to Nao automatically — no extra plumbing.
What landed
tycoon data sync — cloud → local snapshots ✅ (#12)
tycoon data sync --from md:my_catalog --to ./data/local.duckdb
tycoon data sync --schema mart --tables 'dim_*'
tycoon data sync --mode skip-existing
tycoon data sync # uses tycoon.yml's sync blockNew module src/tycoon/sync.py (DuckDB ATTACH-based core, sources always
READ_ONLY) + src/tycoon/commands/sync_cmd.py (CLI surface) +
SyncSourceSpec / SyncConfig pydantic models on TycoonProject.
v1 deliberate non-goals: no reverse sync, no incremental, only md: +
local DuckDB sources, full replace per table. 16 new tests in
test_sync.py.
One-command MotherDuck + Nao + LM Studio setup ✅ partial (#7)
Four of six sub-asks landed:
- §4
tycoon ask initpre-creates all eight directoriesnao sync
walks (databases/,queries/,docs/,semantics/,repos/,
agent/{tools,mcps,skills}). Eliminates the "No such file or
directory: 'repos'" crash class. - §5 New
tycoon ask init --llm <provider>flag with shortcuts
forlm-studio/ollama/openai/anthropic/gemini/
mistral. Thelm-studioshortcut expands to OpenAI-compat config
pointed athttp://localhost:1234/v1— users don't have to discover
that "openai + custom base_url" is the LM Studio idiom. - §6
tycoon ask doctorhealth check — validatesnao_config.yaml,
the eight required dirs, MotherDuck auth, and LM Studio reachability.
Renders an OK/WARN/FAILstatus_table; exits non-zero on any FAIL. - §7 Auto-generated
.tycoon/nao/.gitignorekeeps PII row-previews- sync artifacts (
databases/,repos/,db.sqlite*) out of git.
- sync artifacts (
§3 (smart include_schemas defaults) and §5b (init-wizard LLM prompt)
are deferred to v0.2.0's init redesign (#14) — no point adding LLM
prompting to a wizard that's about to be reworked.
Legacy NYC pipelines fixed ✅ (#17)
nyc_dot_pipeline, mta_pipeline, and mta_bus_speeds_pipeline were
reaching into the global config singleton (config.raw_db) instead of
using the raw_db_path the runner threads through. Fine in real CLI
processes; broke under cli_runner.invoke because monkeypatch.setattr
only rebinds the command's reference.
_run_legacy now passes raw_db_path through; the three pipeline
modules dropped their global-config import. Test runs in 2.57s.
tycoon register dbt profile flags ✅ (#18)
Three new flags mirror dbt's own CLI options:
tycoon register dbt ../my-dbt --profiles-dir ~/.dbt --profile prod_p --target prodPersisted into tycoon.yml as dbt_profiles_dir / dbt_profile /
dbt_target so subsequent tycoon data transform runs reuse them
without re-passing flags. The warehouse-alignment branch of
register dbt now reads the right adapter config when these are set.
tycoon register warehouse non-interactive flags ✅ (#19)
Companion to #18. Five new flags make the command scriptable in CI:
tycoon register warehouse --type duckdb --path data/wh.duckdb --no-prompt
tycoon register warehouse --type motherduck --catalog my_demo --no-prompt
tycoon register warehouse --type duckdb --path data/new.duckdb --force --no-prompt--type accepts both canonical (duckdb, motherduck) and
conversational (local, cloud) values for either UX preference.
Observability metadata in dbt + Nao ✅ (#20)
The headline architectural change. Three sub-pieces compose:
1. ATTACH at scaffold time. Every scaffolded dbt profile gains a
tycoon_meta ATTACH entry pointing at .tycoon/metadata.duckdb,
READ_ONLY. dbt models can now SELECT * FROM tycoon_meta.main.<table>
directly, without copying data. The metadata DB is pre-created with the
empty observability schema at scaffold time so the first dbt run
doesn't trip on a missing file.
2. Nine staging models + a dim_runs mart. New tycoon data observability scaffold writes:
dbt_project/models/_tycoon/
├── stg_tycoon__dlt_runs.sql # views over each metadata table
├── stg_tycoon__dlt_rows_by_table.sql
├── stg_tycoon__dlt_trace_runs.sql
├── stg_tycoon__dlt_trace_steps.sql
├── stg_tycoon__dlt_trace_jobs.sql
├── stg_tycoon__dbt_runs.sql
├── stg_tycoon__dbt_nodes.sql
├── stg_tycoon__dbt_manifest_snapshots.sql
├── stg_tycoon__dbt_schema_changes.sql
├── dim_runs.sql # UNION dlt + dbt timelines
└── _tycoon__schema.yml
All materialized: view so they don't double-store data. Pull with
tycoon data transform run --select _tycoon.
3. Nao gets it for free. Once the staging views exist, tycoon ask sync introspects them as part of the warehouse — no extra plumbing.
tycoon ask context --schema _tycoon cats the synced columns.md /
preview.md just like any other schema.
tycoon init wires all three for new projects automatically.
tycoon register dbt wires them for existing projects unless
--no-attach-metadata is passed. tycoon data observability scaffold
is the standalone retrofit command (idempotent).
MkDocs Material docs site ✅
Comprehensive docs site at docs/. ~30 pages, ~25K words, including:
- Getting started — installation, first project, six core concepts
- Commands — full reference per command surface (init, register,
doctor, docs, data sources, data transform, data sync, data query,
data history, data analyze, data status, data run-all, ask, start,
stop, run) - Reference —
tycoon.ymlschema, templates catalog, observability
tables, environment variables - Recipes — CSV-to-dashboard, MotherDuck cloud sync, LM Studio local
LLM, adopt tycoon for an existing dbt project - Releases — links every release narrative
New tycoon docs serve command (and tycoon docs build --strict) wraps
MkDocs so contributors have one command to read the docs locally:
tycoon docs serve # http://127.0.0.1:8000 with hot reload
tycoon docs build --strict # fail on warnings — CI-friendlyNew [docs] extra pulls in mkdocs==1.6.1 + mkdocs-material==9.5.49.
-h short-alias for --help
tycoon -h
tycoon data sync -h
tycoon ask doctor -hConfigured once on the root typer app via context_settings; click
propagates it to every sub-command.
Hygiene fixes
-
Drop the noisy "Tables" column from
tycoon data sources list.
Always rendered(all)for the source types most users have
(rest_api / filesystem) — meaningless. The underlying field still
appears intycoon data sources show <name>where there's space. -
Drop the
dbt-fusioncheck fromtycoon doctor. Got its own
panel and warned whendbtfwas on$PATH, but the warning's premise
didn't survive scrutiny —dbtfis a separate binary, doesn't shadow
dbt, they coexist fine. Singling out one specific competitor was
disproportionate.tycoon doctoris more useful when every line on
it represents a real check. -
Fix repo
.gitignoredata/pattern. The pattern was matching
anydata/subdirectory anywhere in the tree (intended only for the
repo-rootdata/). Causeddocs/commands/data/pages to be silently
uncommitted across two earlier docs commits. Anchored to root. -
Add
_tycoon_*artifact ignores to the same.gitignore. The
CLI source repo's ownrill/directory accumulates auto-generated
observability dashboards when tycoon is invoked against itself during
testing. Same exclusion bucket as the existing
"this is the CLI source repo, not a tycoon project" block.
GitHub Actions Node 24 prep
Bumped at branch cut so the deprecation warning is gone from the cycle:
actions/checkoutv4 → v6actions/upload-artifactv4 → v7actions/download-artifactv4 → v8astral-sh/setup-uvv4 → v7 (the latest moving major-tag alias —
v8is published as specific tags only, no moving alias)
GitHub flips the runner default to Node 24 on June 2 2026 and
removes Node 20 entirely on September 16 2026.
CI/CD automation — release pre-flight + nightly e2e
Three additions to the GitHub Actions surface, each removing a step
from the manual-before-each-release checklist:
ci.yml gains three jobs alongside the existing pytest + ruff:
build—uv build+ install the produced wheel into a fresh
venv + runtycoon --version/-h. Catches packaging regressions
(manifest typos, broken extras, console-script wiring drift) on
every PR rather than the next release.docs—uv run mkdocs build --strict. Broken internal links
or missing nav targets block the merge.template-smoke(matrix over the four built-in templates) —
scaffolds a fresh project from each template, runstycoon doctor,
asserts noERRORlines. Catches template-side regressions
(missing files, bad placeholder substitution) without spinning up
the full e2e ingestion suite.
New nightly-e2e.yml runs on a daily cron (08:00 UTC) and
exercises the no-credential live-API tests (nyc-transit +
weather-station). On failure, the workflow opens a GitHub issue
labeled ci,upstream-flake so upstream API drift is visible against
a triage queue rather than surprising us during a release. Skips
issue creation when an open one already exists, so the bug-tracker
doesn't get pinged daily for the same outage.
publish.yml gains a preflight job that gates every other
publish step. Reads the tag, the version pins from pyproject.toml
and src/tycoon/__init__.py, the ## [<version>] - YYYY-MM-DD
entry in CHANGELOG.md, and the _Released: line in
docs/releases/v<version>.md — and fails fast if any disagree.
Eliminates the "tagged the wrong version / forgot to date the
CHANGELOG" failure mode without relying on a manual checklist.
The combined effect: most of what was a Claude-driven manual
pre-release checklist now happens automatically. v0.1.4's own
publish exercises all three new layers as the first end-to-end
verification.
Deferred
Carried forward to a future minor or to v0.2.0:
- Smart
include_schemasdefaults for Nao (#7 §3) — defer to v0.2.0
init redesign - Init-wizard LLM provider prompt (#7 §5b) — same
tycoon initredesign around required dbt-or-dlt + git remote
(#14) — explicitly v0.2.0- Rill 0.86 DuckLake live-connector migration — revisit when Rill
ships shared-lock support, or when a Postgres-backed catalog story
is acceptable
Upgrade notes
pip install -U database-tycoonNo breaking changes for code. Five things worth knowing:
tycoon ask initpre-creates 8 nao directories now — fresh
projects no longer need a separatenao initstep. Existing
projects re-runningask initwill see the dirs appear.tycoon initandtycoon register dbtnow wiretycoon_meta
into the dbt profile by default. The firstdbt runon a fresh
project builds the newmodels/_tycoon/views automatically. Pass
tycoon register dbt --no-attach-metadataif you don't want this on
an existing project.- The
dbt_profiles_dir/dbt_profile/dbt_targetkeys are new
intycoon.yml. Optional — only set whentycoon register dbt
was passed the matching CLI flag. No effect on existing projects
that don't have them. - The repo's
.gitignoredata/pattern is now anchored to root
(/data/). If you forked tycoon and your fork added subdirectories
underdata/elsewhere expecting them to be ignored, anchor your
pattern explicitly. - GH Actions versions bumped. Forks running their own CI should
re-validate.
Tests / validation
uv run pytest -q → 385 passed, 1 skipped, 3 deselected. All
previously-existing tests still green; +44 new across the cycle
(observability scaffolding, sync command, register flags, ask
doctor / context / init flags, AGENTS.md, etc.).
uv run mkdocs build --strict clean.