Diff visualizer for Databricks bundle plans — resources and job DAGs
Project description
Dagshund
Colored diff summaries and interactive DAG visualizations for Databricks Asset Bundles. Requires a plan file from the direct deployment engine (databricks bundle plan -o json). See what changed, what's new, and what's being deleted, in your terminal or in the browser.
Install
Requires Python 3.12+.
# Run without installing (ephemeral)
uvx dagshund plan.json
# Persistent install
uv tool install dagshund
# Traditional pip
pip install dagshund
Usage
By default, dagshund prints a colored text diff to the terminal:
dagshund plan.json
Export an interactive HTML visualization with -o:
dagshund plan.json -o report.html
Open it in the browser automatically with -b:
dagshund plan.json -o report.html -b
Reads from stdin, so you can pipe directly from the Databricks CLI:
databricks bundle plan -o json | dagshund
databricks bundle plan -o json | dagshund -o report.html
Dagshund works anywhere, it just needs a plan JSON file. You don't need to run it from inside your bundle directory.
Filter the output to specific change types:
dagshund plan.json -c # changed resources only (hides unchanged)
dagshund plan.json -a # added only
dagshund plan.json -m # modified only
dagshund plan.json -a -r # added and removed
The filter flags (-a, -m, -r) compose freely. -c is shorthand for -a -m -r.
Use -f to filter by resource type, name, or diff status with the same search DSL as the browser UI:
dagshund plan.json -f 'type:jobs' # only jobs
dagshund plan.json -f 'status:added' # only new resources
dagshund plan.json -f '"etl_pipeline"' # exact name match
dagshund plan.json -f 'type:jobs pipeline' # jobs matching "pipeline"
dagshund plan.json -c -f 'type:volumes' # changed volumes only
All tokens in a filter expression AND together. -f composes with -c/-a/-m/-r — both must match.
Use -e for CI-friendly exit codes (see CI Exit Codes).
Interactive Visualization
The HTML report shows your resources as an interactive graph with diff highlighting. Resources are organized into visual groups:
- Workspace, jobs, alerts, experiments, pipelines, and other bundle resources
- Unity Catalog, catalogs, schemas, volumes, and registered models in their hierarchy
- Lakebase, database instances and synced tables (when present, flat resources move into an "Other Resources" group)
Click any node to open a detail panel with per-field structural diffs, old values in red, new values in green, unchanged fields for context.
Jobs with task dependencies get their own DAG view. Switch between the Resources and Jobs tabs to navigate between them.
Phantom Nodes
If your schema references a parent catalog that isn't in your bundle, dagshund infers it and adds it to the graph as a phantom node (shown with a dashed border). Hierarchy phantoms like these always display because they hold the tree together. Inferred leaf nodes (like a warehouse referenced by an alert) can be toggled on or off with the Inferred leaf nodes button in the toolbar.
Lateral Dependencies
Many resources reference each other across hierarchies, an alert might target a SQL warehouse, or a serving endpoint might bind to a registered model. These relationships are hidden by default to keep the graph clean. Toggle Lateral dependencies in the toolbar to see how your resources connect across group boundaries.
Search
The search bar uses the same filter DSL as the CLI's -f flag. Non-matching nodes dim so matches stand out.
- Type a name to filter:
warehouse,analytics - Wrap in quotes for exact match:
"analytics"finds only that node, notanalytics_pipeline - Prefix with
type:to filter by badge:type:wheelhighlights all wheel tasks - Prefix with
status:to filter by diff status:status:added,status:modified,status:removed - Press Escape to clear
The diff filter buttons (Added, Modified, Removed) compose with search, when both are active, only nodes matching both criteria stay highlighted. When exactly one node matches, the viewport auto-centers on it.
CI Exit Codes
Use --detailed-exitcode (or -e) for machine-readable exit codes in CI pipelines:
dagshund plan.json -e
| Exit Code | Meaning |
|---|---|
| 0 | Plan parsed, no changes detected |
| 1 | Error (bad input, missing file, etc.) |
| 2 | Plan parsed, changes detected |
# Check for drift
dagshund plan.json -e
if [ $? -eq 2 ]; then echo "Drift detected"; fi
# Generate report AND get exit code
dagshund plan.json -o report.html -e
Without -e, dagshund always exits 0 on success.
Agent Skill
Dagshund ships as a Claude Code plugin with an agent skill that teaches AI coding agents how to use it. Once installed, your agent can answer questions like "what's changing in my deploy?" by running dagshund automatically.
Install as a Claude Code plugin:
/plugin marketplace add https://gitlab.com/chinchy/dagshund.git
/plugin install dagshund@chinchy-dagshund
Or use the CLI to install the skill into any agent harness:
dagshund --install-skill .claude/skills # Claude Code
dagshund --install-skill .cursor/skills # Cursor
dagshund --install-skill .agents/skills # Codex / Gemini CLI
Contributing
Dagshund is a solo project and I'm not accepting pull requests at this time. If you run into a bug or have a feature request, please open an issue, I'm happy to hear what you need.
Development
Requires Bun 1.3+, uv, and just.
just install # Install dependencies
just dev # Dev server with hot reload (http://localhost:3000)
just build # JS template + Python wheel
just check # Lint + typecheck + all tests
For Claude Code LSP support (go-to-definition, type hover, find-references), install the language server binaries:
bun install -g pyright typescript-language-server typescript
The plugins are already configured in .claude/settings.json.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dagshund-0.5.0.tar.gz.
File metadata
- Download URL: dagshund-0.5.0.tar.gz
- Upload date:
- Size: 1.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5189c151892544c0db71f746d1600cee9b1f1d1d240e80bac28072933522501c
|
|
| MD5 |
6498b3274a485d070ef6088b9f730f08
|
|
| BLAKE2b-256 |
91ba310101ac64d8cc125eb643e24a670eaec7203b3d0e86b8e894aa6452c7cd
|
File details
Details for the file dagshund-0.5.0-py3-none-any.whl.
File metadata
- Download URL: dagshund-0.5.0-py3-none-any.whl
- Upload date:
- Size: 768.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5d59e86e15dd09d7ed51bae40069cf64b059e97606ddd69665487fcc184fee8
|
|
| MD5 |
2919cb23edabc9f66e48eddbfb2b38e9
|
|
| BLAKE2b-256 |
f61c4e04cffadb6b3cef856f71bb06af320e84658a5f5d3fa1eae948224a9db4
|