vccs
Vue 3용 차트 컴포넌트 모음, Recharts에서 포팅
Claude Code와 모든 에이전트를 위한 분석 엔지니어링, 데이터 웨어하우스 탐색·dbt 변환·시맨틱 모델링·스키마 드리프트 관리
Analytics engineering for Claude Code and any agent: data warehouse exploration, dbt transformation and semantic modeling, and schema-drift maintenance on dbt.
데이터Python · ShellGitHub @exmergo온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Dex is the agent-native analytics engineering toolkit. Point it at your warehouse and your dbt project. It learns the landscape, authors your transformations, and tells you exactly what to fix when the schema drifts. Built for analytics engineers and data engineers who want more out of their coding agent.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Built by Exmergo · The AI Stack for Your Data Stack.
Run these commands inside Claude Code one at a time
Update later with /plugin marketplace update exmergo. The skills appear as
/dex:explore, /dex:transform, and /dex:maintain and auto-trigger on matching
intent. Ask it to warm dex once after installing, so the first real command does
not wait for the engine to install (see Prerequisite: uv).README 전문 보기 ↗Analytics engineering for your coding agent, with guardrails and lifecycle built into the engine.
Dex lets your agent build your analytics: data warehouse exploration, dbt data transformation and semantic modeling, and schema-drift maintenance.
Built by Exmergo
Any agent (run in your terminal):
npx skills add exmergo/dex
Claude Code (run these inside Claude Code, one at a time):
/plugin marketplace add exmergo/exmergo-agent-plugins
/plugin install dex@exmergo
Codex:
npx skills add exmergo/dex --agent codex
[!IMPORTANT] Dex needs
uvon yourPATH. No agent installs it for you. Runbrew install uvorpipx install uv, or see the uv installation docs for other platforms.uvsupplies Python and the engine. Use uv 0.13.4 or later (uv self update): earlier releases still trust the emSign CA roots withdrawn after their keys were compromised.
In Claude Code the skills appear as /dex:explore, /dex:transform, and
/dex:maintain and trigger on matching intent. Update later with
/plugin marketplace update exmergo. Codex also gets a native plugin, with no MCP
server needed. Any other agent can be pointed at AGENTS.md.
Run Dex from your project directory, so it finds your .dex/config.yml and keeps
its cache next to your project. Dex needs an agent with a local shell, so it does
not run in claude.ai chat.
[!TIP] Skip the first-run wait. The first command installs the engine, which takes tens of seconds on a cold
uvcache. Ask your agent to warm Dex once after installing, or run the command below in a CI or container build step. Add--connector snowflake(or any connector) to warm one before a project exists.
uv run --no-project --script skills/<skill>/scripts/run.py --warm
What you get:
Your source data is never written to, and builds run on a dev target only. Cost quoted before any spend. Every change is a diff you review. Works in Claude Code, Codex, or any agent that loads Agent Skills.
Most deadly errors arise from obsolete assumptions.
Frank Herbert, Children of Dune
A general coding agent is a good SQL author and a poor analytics engineer. It:
Dex owns exactly that loop, and enforces its rules in the engine rather than in a prompt.
No warehouse, no credentials, no cloud account, no network.
pip install "exmergo-dex-core[duckdb]"
dex demo
dex explore map
dex demo writes a small e-commerce DuckDB warehouse (dex_demo.duckdb, 7 tables,
29,512 rows) and a .dex/config.yml into the current directory, so every command
after it runs with no flags. It refuses rather than overwrite anything. The data
comes from a pinned seed, so what you see is what is written here.
explore map maps all 7 tables, infers 5 joins, flags 6 columns as personal data,
and reports 6 data-quality findings. Every command answers with one JSON envelope.
An excerpt, for one table:
{
"identifier": "dex_demo.main.order_items",
"row_count": 14000,
"grain": null,
"data_quality": [
"order_item_id is not unique: 13000 distinct over 14000 rows (1000 rows would have to be removed for it to be unique, so it is unique for 92.9% of rows); joins on it will fan out"
]
}
A first run that reports a clean bill of health teaches you nothing, so the demo ships with real defects. Dig into them:
dex explore profile order_items products
dex explore relationships --verify
dex explore query "select email from customers"
order_item_id is unique for only 92.9% of rows. Dex reports the duplicates and leaves the grain unknown rather than guessing a key.sku is 90% numeric, 10% 32-character hexadecimal (md5-shaped). Cast it to a number and you silently drop 10% of products.web_events.customer_id shares a name with the CRM's key, but verification finds 100% of its values have no match.customers.email into context. select count(distinct email) from customers runs, because a statistic is not a value.There is also a table an interrupted load left empty, two columns whose declared
type contradicts their content, and two designed PII false positives. See the
dex demo reference.
[!NOTE] DuckDB is free and local, so nothing here asks you to confirm a spend. On a metered warehouse the same commands return an estimate first and run only once you agree to it.
flowchart LR
Agent[Coding agent] --> Skills[Dex skills]
Skills --> Engine[exmergo-dex-core engine]
Engine -->|SELECT-only SQL, cost-capped| Warehouse[(Your warehouse)]
Engine -->|dbt builds, dev target only| Warehouse
Engine -->|one sanitized JSON envelope| Agent
Engine -->|plans as diffs| Repo[Your repository: dbt project + semantic layer]
Engine <--> Cache[.dex/ cache and snapshot]
The skills are thin. All the logic, and every guardrail, lives in one engine
(exmergo-dex-core) behind a small command contract.
Your repository is the source of truth on two independent axes: the transformation
project (dbt) and the semantic layer. The .dex/ directory is only a cache.
Rank what matters, profile selectively, infer and verify joins, answer ad-hoc questions through a PII-aware query firewall, read and query the semantic layer, and draw the map as a Mermaid ER diagram. Fully read-only. Skill · methodology · commands
Author and refactor dbt models from staging to marts, with tests and docs, plus the semantic layer on top. Every change is a stored plan you review, then apply. Builds run against a dev target only. Skill · what Dex writes · commands
Diff the warehouse, the project, and the semantic layer against the last snapshot,
rank the drift by blast radius, and propose the reconciling edits. maintain verify
checks a project as it stands, with no baseline needed.
Skill · commands
.dex/Dex keeps its working state in .dex/. Most of it is safe to commit; the
exception is any file that can carry data values. Commit the lockfile and the
config, and keep the exploration cache out of a repo that must not publish
data values:
| File | Commit? | Can it contain data values? |
|---|---|---|
.dex/config.yml | Yes | No: connector targets, pii_overrides (column names, not values), budgets and limits. Credentials live in environment variables or dbt profiles, never in this file. |
.dex/snapshot.json | Yes, like a lockfile | Yes: when snapshotted from a cache it pins the cache's datasets wholesale, including each non-PII column's capped value domain and min/max. A metadata-only baseline (no cache) carries schema and volume only. PII-flagged columns never carry value domains. |
.dex/cache.json | Only if values may be public | Yes: column profiles with capped value domains (actual values with counts). Never for PII-flagged columns. |
.dex/plans/*.json | Optional, as an audit trail | No warehouse values: the proposed contents of project files. |
.dex/queries.jsonl | Optional, as a ledger | SQL text, which may hold literals. |
.dex/drift.json | No: regenerate with maintain check | Aggregates only: counts, names and schema metadata in drift findings. |
For a repo that must not publish data values, ignore the rest:
# Dex state that can publish data values, or is local-only output.
.dex/cache.json
.dex/dex.db
.dex/dex.db-journal
.dex/queries.jsonl
.dex/drift.json
.dex/spend.jsonl
.dex/spend.lock
.dex/dex.db is the SQLite backend's equivalent of cache.json, so it gets
the same caution. .dex/spend.jsonl is the billed-command ledger: byte
counts, job ids and statement hashes only, never SQL values or credentials,
but it is local spend history, so there is no reason to commit it.
| Connector | Type | Self-hostable | Extra / --connector | Cost surfaced as | Credentials from |
|---|---|---|---|---|---|
| Snowflake | Cloud warehouse | ❌ | snowflake | Warehouse-seconds, with credits | connections.toml, SNOWFLAKE_* env, or a dbt profile |
| BigQuery | Cloud warehouse | ❌ | bigquery | Bytes scanned | Application Default Credentials |
| Databricks | Cloud warehouse | ❌ | databricks | Warehouse-seconds, with DBUs | databricks auth login, DATABRICKS_* env, or a dbt profile |
| Amazon Redshift | Cloud warehouse, Serverless-first | ❌ | redshift | Compute-seconds, with RPU-hours | The AWS credential chain or REDSHIFT_* env |
| ClickHouse | Analytical database | ✅ | clickhouse | Compute-seconds on Cloud, database-seconds self-hosted | CLICKHOUSE_URL, CLICKHOUSE_* env, or a dbt profile |
| Trino | Federated query engine | ✅ |
Credentials are discovered, never asked for, and never enter the agent's context. Every scan is estimated, confirmed, and capped server-side, and settled spend is recorded in a local ledger (cost controls). Self-hosted databases bill no dollars and are still gated, because an unbounded scan on a production Postgres primary is a real cost too.
Coming next: MotherDuck, Starburst Galaxy, Microsoft Fabric.
The semantic layer is its own axis, chosen once per repository in .dex/config.yml.
With Ossie or SLayer, it needs no dbt project at all. (overview)
| Semantic layer | Hosted | Queryable | vendor / deployment | Read through | Documentation |
|---|---|---|---|---|---|
| Apache Ossie (incubating) | ❌ | ❌ | ossie / local | Native documents in the repository, no dbt or MetricFlow in the path | Docs |
| dbt | ✅ | ✅ | dbt / local or dbt_cloud | MetricFlow locally, run through the Dex connector and its cost guard, or the hosted dbt Cloud Semantic Layer API | Docs |
| SLayer | ❌ | ✅ | slayer / local | SLayer model files, validated by one pinned release; SLayer renders, Dex runs it under the cost guard | Docs |
Coming next: Cube, Snowflake Semantic Views, Looker / LookML, and Databricks Metric Views.
github-repo-analytics is a template that tracks GitHub traffic, stars, downloads and contributors for your open-source projects, free on GitHub Actions.
Every model and metric was built and is maintained with Dex. Its audit trail holds the raw envelopes, including the drift Dex blocked.
The engine is a plain Python package, exmergo-dex-core:
pip install exmergo-dex-core # or: uv add exmergo-dex-core
Drive the same loop from Python instead of parsing CLI output:
from exmergo_dex_core import DexEngine
with DexEngine(connector="duckdb", path="shop.duckdb") as eng:
mapped = eng.map() # a DexCache, not a JSON blob
rows = eng.query("select status, count(*) from orders group by status")
print(mapped.relationship_count, rows.cells)
Every guarantee the CLI makes holds here, because it is the same code. An
unconfirmed billed call raises ConfirmationRequiredError carrying the estimate.
By default nothing is written to disk; DexEngine.from_repo("path/to/repo") opts in
to a project on disk, the way the CLI does.
For hosts embedding Dex:
ConnectionSource so each request reaches the warehouse as its own principal.More in the package README.
We run Dex on two public analytics-engineering benchmarks and commit every run's raw per-task results, including the ones that flatter us least.
| Benchmark | Setup | Result | Details |
|---|---|---|---|
| data-eng-bench (Snowflake, 103 tasks) | Dex + Claude Sonnet 5 | 57.3% resolved, 89.7% of assertions pass | README |
| ADE-bench (dbt Labs, 75 tasks) | Dex + Claude Sonnet 5 | 76% resolved, at 2.5x lower cost than Fable 5 | README |
We believe that benchmarks are important, but not as important as user/agent experience.
Trust in a diff, cost surfaced before spend, and sensitive data kept out of context. We optimize for that experience
and treat these scores as guide posts. (evaluation)
uv downloads the pinned engine (and a Python 3.11 to 3.14 if you have none) from PyPI or your configured index.DO_NOT_TRACK=1 for every dbt process it starts. transform deps downloads the packages your packages.yml declares..dex/. dbt writes its usual target/ and logs/.[!IMPORTANT] Dex sends nothing to Exmergo. No telemetry, analytics, license check, or update ping. See the Dex privacy policy and the Dex terms of service.
AGENTS.md: how any agent drives the engine.dex/config.yml as a confirmed diffreferences/: the same material as Markdown, for agents and offline readingDex Enterprise runs Dex as automated workflows in your own CI. It turns tickets into
draft pull requests with explore and transform, and runs maintain on a schedule
to turn drift into draft pull requests for your engineers to review. No Exmergo
service sits in the request path, and everything in this repository stays
Apache-2.0. Learn more.
| Integration | Maintainer | What it does |
|---|---|---|
| dagster-dex | CatInCloud Labs | Explore and maintain your Dagster assets with Dex, using the asset graph in place of a dbt project. |
Join the agent-native data/analytics community!
See CONTRIBUTING.md for local setup, linting, the pre-commit
hook, and changelog fragments. Every pull request into main must pass Lint and
CI, and adds a fragment under changelog.d/ unless no user can
see the change. Please also read the code of conduct.
Apache-2.0. See LICENSE and NOTICE. The licence governs the software. Exmergo's distribution, documentation, support, and trademarks are covered by the Dex terms of service.
trino| Cluster-seconds |
TRINO_URL, TRINO_* env, or a dbt profile |
| DuckDB | Embedded analytical | ✅ | duckdb | Free and local | None, just a file path |
| Postgres | Operational database | ✅ | postgres | Database-seconds | pg_service.conf, DATABASE_URL, PG* env, or a dbt profile |