From dex
Author and refactor a dbt project: bootstrap, write SQL models, add tests/docs, and define the semantic layer (MetricFlow) with reviewable diffs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dex:transformThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Author and refactor the dbt project: both the SQL transformations (staging to
Author and refactor the dbt project: both the SQL transformations (staging to marts, tests, docs) and the semantic layer on top (entities, dimensions, measures, metrics). Both are the same job, writing reviewable diffs to the dbt project, which is the source of truth. This is the building half of the loop. It writes only to the repo, as reviewable diffs, and runs against a dev target only.
uv run "${CLAUDE_SKILL_DIR}/scripts/run.py" <subcommand> [flags]
You author the dbt file content; the engine validates it, computes the diffs,
and stores the proposal as a plan. Hand content over with --edits-file <path>
(or - to read stdin), a JSON payload:
{"edits": [
{"path": "models/staging/stg_orders.sql", "kind": "model_sql", "content": "..."},
{"path": "models/staging/stg_orders.yml", "kind": "schema_yml", "content": "..."}
]}
kind is model_sql, schema_yml, or semantic_yml (optional on
semantic define|update|plan, which imply it). Model SQL must be a single
read-only SELECT once its jinja is stripped; semantic YAML is validated against
MetricFlow's schemas, cross-reference-checked, and (when dbt is available)
parsed by dbt itself before the plan is accepted.
If no dbt project exists in the repo, offer transform init before anything
else: transform plan needs a project to edit. Ask the user for the project
name and confirm the connector with them, then run:
uv run "${CLAUDE_SKILL_DIR}/scripts/run.py" transform init "<name>" --connector <c>
The engine renders the whole skeleton (dbt_project.yml, models/staging/ and
models/marts/, a profiles.yml with a single dev target and no secrets) and
records connector, dbt_project_dir, and dbt_target: dev in
.dex/config.yml; do not hand-write these files yourself. Init never assumes a
connector: it errors rather than defaulting, so always pass the user's confirmed
choice (a connector: already committed in .dex/config.yml also counts).
Every connector is supported: DuckDB, BigQuery, Snowflake, Databricks, and
Postgres. DuckDB needs a warehouse path (--path, or the duckdb.path
config). BigQuery needs a GCP project (usually bigquery.project in
.dex/config.yml; confirm it with the user) and writes builds to a dedicated
dev dataset (bigquery.dev_dataset, default dbt_dev); auth is Application
Default Credentials, so if credentials are missing tell the user to run
gcloud auth application-default login, never ask for a key. Snowflake
writes builds to a dedicated snowflake.dev_database/dev_schema on the
pinned warehouse; Databricks writes builds to a dedicated
databricks.dev_catalog/dev_schema on the pinned SQL warehouse (if
credentials are missing tell the user to run databricks auth login, never
ask for a token); Postgres writes builds to a dedicated postgres.dev_schema
(default dbt_dev), with the password reaching dbt only through the
PGPASSWORD environment variable. All of them discover their connections and
refuse with the fix named when none resolves. Init refuses if any dbt project
already exists.
transform plan "<intent>" --edits-file <path|-> validates the edits and
returns them as diffs with a plan id. Nothing is applied yet. Add
--scaffold <table> (repeatable) to generate a staging skeleton
(stg_<table>.sql plus per-model YAML with key tests and PII meta) from the
.dex/ cache instead of, or on top of, hand-authored edits.transform apply [plan-id] writes the plan into the dbt project (the latest
unapplied plan when no id is given; any plan kind, semantic included). The
result is still a reviewable git diff for the user. If a human edited a file
after the plan was made, nothing is written: the divergence comes back as
diffs with needs_confirmation, and you should re-plan against current state
(or, only when the user says so, re-run with --confirm).transform plans lists stored plans (pending and applied, newest first), so
you never need to browse .dex/plans/ by hand.transform build --target dev runs dbt build against a dev target. The
engine surfaces a cost preflight first and runs only with --confirm (plus a
--budget on billed connectors). On BigQuery there is no upfront estimate
(dbt has no dry-run), so always get an explicit byte budget from the user and
pass it as --budget <bytes>; never invent one. Each statement dbt runs is
capped server-side by the profile's maximum_bytes_billed, and the envelope
reports billed bytes afterward. Production-looking targets are refused
outright; --confirm cannot override that. dbt runs with its working
directory pinned to the project dir, so relative paths in profiles.yml
resolve against the project. When the project declares packages
(packages.yml) and dbt_packages/ is missing, the engine runs dbt deps
automatically before the build.transform deps installs dbt packages explicitly (also the refresh path when
dbt_packages/ exists but is stale). No confirmation needed: deps writes only
inside the project and never touches the warehouse.Before the cost gate, and for free, transform build refuses two things and
names the fix for each. Neither costs anything to check, so both surface on the
unconfirmed call rather than after a budget has been agreed.
Config that has drifted from the profile. transform init renders
.dex/config.yml into the project's profiles.yml, and dbt reads only the
profile from then on. If a later config edit never reached it (a retargeted
dev_database, a different warehouse), the build refuses and names both values
and both files. Edit one to match the other. The engine never rewrites
profiles.yml, which you may legitimately have hand-edited.
A dev target that does not exist. On Snowflake, dbt creates schemas but never
databases, so a missing dev_database is refused with the CREATE DATABASE
statement to run; dex will not create it for you, because its only writes are
reviewable diffs inside the repo. On DuckDB the dev target is a database file,
and dbt would happily create an empty one, then fail every source() relation
with a confusing catalog error. The convention there: copy the shared source
warehouse to the dev target path (for example
cp shared/f1.duckdb <project>/dev.duckdb), or point the dev target at an
existing file. Projects without sources just get a warning and an empty
database, which is fine for model-only builds.
semantic define ... --edits-file <path|-> and semantic update ... author
and evolve the dbt semantic models (entities, dimensions, measures, metrics)
as plans. define refuses names that already exist (use update); update
refuses names that do not (use define). For one logical change that mixes
both (evolve existing metrics and add the helpers they depend on), use
semantic plan ...: it accepts mixed intent and classifies each name, and the
envelope reports the split as defined and updated.create_metric: true, and the error names that fix); and
finally the emitted YAML is run through dbt's own parser against a
throwaway copy of the project. A plan that fails parse is refused, not stored.
If dbt is not installed the parse degrades to a warning; --no-parse skips it
explicitly.transform apply [plan-id] writes
its YAML into the dbt project (no id applies the latest unapplied plan).time_spine: config) in the same or a separate plan.viz preview is not yet implemented (it returns not_implemented); the Viz
integration arrives later.meta),
never example values.npx claudepluginhub exmergo/exmergo-agent-plugins --plugin dexBuilds and modifies dbt models with SQL transformations using ref() and source(), creates tests, validates results with dbt show. For dbt projects: modeling, debugging errors, data exploration, testing, change evaluation.
Provides dbt patterns for model organization in staging, intermediate, and marts layers, including project structure, sources, configs, SQL examples, and testing setups. Useful for data transformation projects.
Provides patterns for building dbt models, adding tests, and designing data models including dimensional modeling, staging/intermediate/marts organization, naming conventions, and testing strategies.