fix(dbt-tools): move to dbt-integration 0.3.15 so the dbt adapter starts under Bun
Issue for this PR
Closes #1367
Type of change
- Bug fix
What does this PR do?
Moves packages/dbt-tools from @altimateai/dbt-integration 0.2.14 to ^0.3.15. 0.2.x started its Python child through python-bridge, which fails under Bun (bluebird.promisifyAll on child_process throws Cannot access invalid private field (evaluating 'this.#stdin')), so the dbt-first path of sql_execute never ran. 0.3.x vendors the bridge and uses a plain fd-3 pipe; python-bridge and bluebird leave the lockfile. From 0.3.15, a bridge running inside a single-file executable writes its script to a temporary directory and removes it on exit, so the compiled binary starts the bridge too.
adapter.ts: 0.3.x'sDBTProjectIntegrationAdaptertakes aUnitTestParserand aSemanticModelParser; the Fusion integration no longer takes the cloud-variant detector (the Cloud integration still does).copy-python.ts/release.yml/publish.ts: the vendored bridge findsnode_python_bridge.pyfrom the bundle's own location at runtime (fileURLToPath(import.meta.url)), so thepython-bridge__dirnamepatch is gone. The build and the release smoke check now assert the new resolution instead of the patch.- Tests:
build-adversarial.test.tstested the removed patch. The checks in it that don't depend on the patch move tobuild-integrity.test.ts(no build-machine path in the bundle, Python packages copied,createRequire, byte-identical rebuilds). A new test runs the package aspublish.tslays it out, from another directory, and checks that it starts the bridge script next to its own bundle.
Claims
- C1: Under Bun, the dbt-first path of
sql_executestarts the dbt adapter and runs the query through dbt, from source and from the compiled binary. - C2: The compiled binary runs the bridge from a real directory, not from
/$bunfs. No Python process and no temporary bridge directory is left after the call. - C3:
altimate-dbt, laid out aspublish.tsships it and run by Node from another directory, starts thenode_python_bridge.pynext to its own bundle. The build and the release smoke check fail if a build-time path is baked into the bundle. - C4:
adapter.tsbuilds the adapter with what 0.3.x's constructors take: both new parsers, and the cloud-variant detector for dbt Cloud only.
Residuals
- R1: 0.3.15 was published on 2026-10-13 05:44Z, inside this repo's 3-day
minimumReleaseAge. In this repo,bun installresolves it again even with--frozen-lockfile, and the window blocks that, so CI can't install this branch until 2026-10-16 05:44Z. Every failing check fails at that install step. Nothing needs to change then: rerun CI. The lockfile already pins 0.3.15 with npm's integrity hash, and its dependencies are the same as 0.3.13's. - R2: When the adapter can't start (no dbt in the venv, a broken project),
sql_executestill falls back to the configured warehouse without saying why. That's unchanged by this PR.
How did you verify your code works?
sql_execute called through the real tool registry (debug agent build --tool sql_execute, no model turn), against a two-model dbt-core 1.11.7 / DuckDB project with its own venv, query select count(*) as n from customer_totals:
| before | this branch (ccc92cc431; since then only a test changed) | |
|---|---|---|
| compiled binary | v0.12.7 release: falls back, "No warehouse configured" | n = 2 via dbt |
| from source (Bun) | main (2026-09-29): falls back, "No warehouse configured" | n = 2 via dbt |
- Compiled binary: the bridge ran as
/tmp/altimate-dbt-integration-<random>/bridge.py. Python processes were sampled every 200 ms; none was left after the call, and neither was the temporary directory. - From source, the bridge ran from
@altimateai/dbt-integration@0.3.15/dist/node_python_bridge.py. altimate-dbtas npm ships it (publish.tslayout, Node 22, run from another directory),execute --query …:[{"n": 2}], as onmain.packages/dbt-toolson 97f6c2c4fd: typecheck clean, build verified, 185 tests pass. The relocation test fails when a fixed path is baked into the bundle. It compares against the install directory's real path, and passes withTMPDIRpointing at a symlink, which is howtmpdir()sits on macOS.packages/opencode: typecheck clean.
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
Appendix: complexity delta
✅ No touched function changed in complexity (2 touched, 0 new, all under 10). Advisory, not a gate.
🤖 Generated with Claude Code
https://claude.ai/code/session_0172qrhMa5TQgETASi5hxMqD
Summary by CodeRabbit
- New Features
- Added support for parsing dbt unit tests and semantic models.
- Bug Fixes
- Improved Python bridge location resolution so the CLI can find the bridge alongside its bundled files, including when run from a different directory.
- Improved package build checks to catch missing bridge files and references to local checkout or CI paths.