Skip to content
Data
Skill

/transform

Use this to author and change a dbt project or a semantic layer: bootstrap a project (`transform init`), write or refactor models from staging to marts, add tests and docs, and define semantic models, entities, dimensions, and metrics in MetricFlow, Apache Ossie or SLayer YAML.

From plugin
dex
1073 skills

Claude Code

$ npx -y skills add exmergo/dex --skill transform --agent claude-code

SKILL.md

transform.SKILL.md
name: transform
description: 'Use this to author and change a dbt project or a semantic layer: bootstrap a project (`transform init`), write or refactor models from staging to marts, add tests and docs, and define semantic models, entities, dimensions, and metrics in MetricFlow, Apache Ossie or SLayer YAML. Reach for it instead of editing model files by hand whenever a change spans more than one file or must stay consistent with the project: it validates the edit against the real schema, returns a reviewable diff with a plan id, and catches what otherwise fails at `dbt run`, such as wrong columns or broken refs. Bug-fix tickets count: "this model returns wrong numbers, fix it" is a transform task. Also for "build a staging model for this table", "define a revenue metric", "add a dimension to this entity". Warehouse builds are dev-target only, gated, and cost-surfaced first. If you have not verified the source tables'' columns or grain, use explore first. For a project that drifted from the warehouse, use maintain.'
compatibility: 'Needs a local shell and uv. On first use, uv builds the exmergo-dex-core engine from the source bundled with the plugin, or installs it from PyPI at the version scripts/run.py pins when no source is bundled. Runs in Claude Code or another agent that loads Agent Skills and has a shell, not in claude.ai chat.'

Transform

Author and refactor the dbt project, both the SQL (staging to marts, tests, docs) and the semantic layer on top. You write the file content; the engine validates it, computes the diffs, and stores a plan. Nothing reaches the project until `transform apply`, and any build runs against a dev target only.

<!-- dex:procedure:begin -->

Procedure

For project setup, run `dex init` (or `init` through an installed skill wrapper). It creates or adopts a project, installs managed README and agent instructions, and verifies the connection. It does not explore data or build models. Read its structured missing inputs and readiness before continuing; installing skills does not necessarily install a `dex` executable.

Dex works in one loop: explore, transform, maintain. `dex <command>` below is the `dex` CLI; where it is not installed, run the same command through the skill's `scripts/run.py` wrapper. Each command prints one JSON envelope: read it and decide the next step from it. Step 1 only reads. Steps 2 to 5 change the project, so take them only when the task asks for a change; a question about the data stops after step 1 and reports what it found. Explore and maintain report findings and hand repair work to transform; only the transform workflow performs the project edits, migrations and dev builds described below.

1. **Profile what the change reads.** Before writing or fixing SQL against a table whose columns, types, grain or join keys you have not verified in this session, run `dex explore profile <tables>` on every relation the change reads (`dex explore map` when you do not yet know which), and `dex explore relationships --verify` for the joins it will make. Answer data questions with `dex explore query`, never with a raw database client. 2. **Plan with a declaration.** Hand the SQL to `dex transform plan "<intent>" --edits-file <file>` with a declaration for every model you create or change, beside the edits:

   {"edits": [{"path": "models/marts/fct_orders.sql", "kind": "model_sql", "content": "..."}],
    "declarations": [{"model": "fct_orders", "description": "One row per order.",
      "grain": ["order_id"],
      "population": {"rule": "Placed orders; cancelled ones are excluded.",
                     "filters": [{"column": "status", "excludes": ["cancelled"]}]},
      "columns": {"order_id": {"role": "key"},
                  "amount": {"role": "measure", "aggregation": "sum",
                             "additivity": "additive", "unit": "currency:USD"}},
      "assumptions": [{"decision": "Which statuses count", "chosen": "all but cancelled",
                       "evidence": "precedent", "detail": "every sibling excludes cancelled"}]}]}

Use the conventional values, so tools can read them: `role` is `key`, `foreign_key`, `dimension`, `time`, `measure` or `attribute`; `additivity` is `additive`, `semi_additive` (a balance or a running total) or `non_additive` (a ratio, a share, a distinct count); `unit` is `currency:<ISO code>`, `fraction` (0 to 1), `percent` (0 to 100), `count` (any count of things), or a plain unit such as `days`; `aggregation` is how the column rolls up (a count rolls up with `sum`, a running total with `max`). A model that holds one row per entity of another model declares that parent too, `"population": {"parent": {"model": "stg_subscriptions", "key": {"subscription_id": "subscription_id"}}}`, so verification counts the parents missing from it. A model derived from a dbt snapshot's status history declares a `history` block (`skills/transform/references/declarations.md`): whether the first observation is a baseline or a transition, the NULL-status policy, the entities it holds, and whether its timestamp is business or capture time. A declaration is JSON in the payload, rendered into the model's YAML: it never adds, drops or renames an output column. 3. **Read the draft, supply the intent, plan again.** `data.declarations.<model>` holds `drafted` (what Dex measured: keys, running totals, units, value domains, and `precedent`, what sibling models do with the same columns), `missing` (the intent still owed) and `contradictions`. Read them with the `warnings` and, on an existing model, `data.row_attribution`. Correct the SQL or the declaration until both say what the request asks, then plan again. When the change should keep an existing model's results (a refactor, an extraction, a cleanup), run each `data.refactor_comparison_offer.per_model` command before applying, above all where `static_attributi

Read more
@exmergo
Ships withdex

Dex lets your agent build your analytics. Explore your data, build models and semantic layers, and keep them in sync as schemas change. Works with databases, data warehouses, lakehouses, and SQL engine endpoints through supported connectors. Built by Exmergo

Stars on GitHub

Momentum

stars in total
107
Star history of exmergo/dex on GitHub, a chart by star-history.com

Other skills on dex.

explore

explore

Use this whenever you need to know what is actually in a database, warehouse, or DuckDB file before you trust it: inventory,…

@exmergo@exmergoInstall Skill
maintain

maintain

Use this to find out whether an existing dbt project or semantic layer (dbt, Ossie, SLayer or Cube) is correct against its…

@exmergo@exmergoInstall Skill

More skills from other plugins.

context-loader
Auto-invoked

context-loader

Search memories from earlier Pi sessions in this repository. Use it when earlier work may already explain the code, error,…

mem06d69k
@mem0ai@mem0aiInstall Skill
analyzing-ai-citations

analyzing-ai-citations

Answer AI citation and answer engine optimization (AEO) questions in PostHog: whether AI answer engines (ChatGPT, Claude, and an…

posthog12d41k
@posthog@posthogInstall Skill

Questions about transform.

Which coding agents can use transform?
transform installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.