fix(opencode): put altimate-dbt on PATH after npm install, with or without postinstall
Issue for this PR
Closes #982
Type of change
- Bug fix
- New feature
- Refactor / code improvement
- Documentation
What does this PR do?
After npm install -g altimate-code, altimate-dbt often isn't available. The agent then falls back to plain dbt and loses the manifest-aware tools (schema-verify, lineage, execute).
There are two causes:
script/publish.tsonly declaresaltimateandaltimate-codeasbinentries.altimate-dbtonly reaches the package'sbin/throughpostinstall.mjs, so it's missing whenever install scripts don't run:--ignore-scripts, pnpm/bun script allow-lists, or locked-down CI.- The app only adds that folder to PATH inside the bash tool (
ALTIMATE_BIN_DIR). The dbt-schema-verify validator spawnsaltimate-dbtwith the app's own PATH, so it couldn't find it even when postinstall did run.
The fix:
script/publish.ts: declare"altimate-dbt": "./dbt-tools/bin/altimate-dbt"in both generatedbinmaps. Package managers linkbinentries without running scripts, and npm creates the Windows.cmd/.ps1shims.bin/altimateandbin/altimate-code: prepend the packagebin/to the app's PATH. Also prepend../dbt-tools/binwhen postinstall didn't linkaltimate-dbt. Everything the app spawns inherits this, including the validators. It usespath.delimiter, finds the PATH key case-insensitively (Pathon Windows), and doesn't add duplicate entries.
postinstall.mjs and tool/bash.ts are unchanged.
How did you verify your code works?
- New tests.
test/install/dbt-tools-on-path.test.tschecks the publishbinentries. It also runs an end-to-endnpm packandnpm install -g --ignore-scripts, then runsaltimate-dbt doctorfrom PATH. That test has a control without the fix, and apostinstallthat exits 1 to prove scripts never ran.test/install/bin-wrapper.test.tscovers both launchers: the fallback, the postinstall-linked case, and no duplicate PATH entries. Without the fix, the publish test and 4 launcher tests fail. bun test test/install/ test/tool/bash.test.ts test/altimate/validators/: 1,091 pass, 0 fail.tsgo --noEmitis clean.- Manual, macOS (Apple silicon), v0.12.10, clean shell with nothing extra on PATH, both installed with
npm install -g --prefix <dir> --ignore-scripts:- stock:
bin/has onlyaltimateandaltimate-code. In Builder mode, the agent'swhich altimate-dbtgivesaltimate-dbt not found. - patched:
bin/also hasaltimate-dbt, andaltimate-dbt doctorpasses in a dbt + DuckDB project. In Builder mode, the agent'swhich altimate-dbtresolves to.../altimate-code/dbt-tools/bin/altimate-dbtthrough the launcher fallback.
- stock:
- Windows: not run on a Windows machine. I checked npm's generated
cmd-shimoutput for the new bin: the.cmdand.ps1shims both runnode <path>/dbt-tools/bin/altimate-dbt. Thedbt-tools/binfallback has no.cmd, so on Windows thebinentry is the fix.
Cost side effects
None. It changes package metadata and PATH setup at launch, and adds no model calls, queries or cloud resources.
Screenshots / recordings
N/A (not a UI change).
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
- I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"
Out of scope: the standalone installers (install, install.ps1) don't appear to ship altimate-dbt at all, which may be worth a separate look.
I diagnosed and patched this with help from Claude, and verified the behavior myself as described above.
Summary by cubic
Makes altimate-dbt available after npm install -g altimate-code, with or without lifecycle scripts, and on the PATH for everything the app spawns.
Previously altimate-dbt only reached the package's bin/ through postinstall.mjs, so it was missing when install scripts were skipped (--ignore-scripts, pnpm/bun allow-lists, locked-down CI), and the dbt-schema-verify validator spawned altimate-dbt with the app's own PATH, which never included it. The agent then silently fell back to plain dbt, losing schema-verify, lineage, and execute. Now the published package.json declares altimate-dbt as a bin (so package managers link it without running scripts), and both launchers put the package bin/ and the bundled dbt-tools/bin fallback at the front of the app's PATH, ahead of any existing entry, case-insensitively and without duplicates.
Bug Fixes
- Declares
altimate-dbtas a bin in both generatedpackage.jsonfiles inscript/publish.ts; npm also creates the Windows.cmd/.ps1shims. If another package already owns a globalaltimate-dbt, npm stops with EEXIST; remove or rename that shim or install with--force. - Puts the packaged tool dirs on PATH in
bin/altimateandbin/altimate-codeso validators and the agent inherit them, falling back todbt-tools/binwhen postinstall didn't linkaltimate-dbt. The dirs are moved ahead of the existing PATH, so an olderaltimate-dbtcan't shadow the bundled one. - Adds tests for the pack + global install with
--ignore-scriptsflow and the launcher PATH handling for both wrappers; npm calls are time-bounded so a stalled registry fails instead of hanging CI, and the launcher extends a mixed-casePathkey rather than adding a secondPATH.
Summary by CodeRabbit
- New Features
- The
altimate-dbtcommand is now available from both package variants, including after a global installation that skips install scripts.
- The
- Bug Fixes
- The app can locate the bundled
altimate-dbtexecutable when a post-install link is unavailable. The launcher prioritizes the relevant tool directories, avoids duplicate entries, and preserves existingPATHsettings.
- The app can locate the bundled