/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.
Claude Code
$ npx -y skills add exmergo/dex --skill transform --agent claude-code
Codex
$ npx skills add exmergo/dex --skill transform -a codex -y
Cursor
$ npx skills add exmergo/dex --skill transform -a cursor -y
Gemini CLI
$ npx skills add exmergo/dex --skill transform -a gemini-cli -y
GitHub Copilot
$ npx skills add exmergo/dex --skill transform -a github-copilot -y
OpenCode
$ npx skills add exmergo/dex --skill transform -a opencode -y
Windsurf
$ npx skills add exmergo/dex --skill transform -a windsurf -y
SKILL.md
transform.SKILL.mdname: 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
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
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
More skills from other plugins.
paddleocr-doc-parsing
Use this skill to extract structured Markdown/JSON from PDFs and document images—tables with cell-level precision, formulas as…
13c-metabolic-flux
Estimates intracellular metabolic fluxes from steady-state carbon-13 isotope-tracing measurements using validated atom maps,…
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.

