Skip to content

feat: add altimate-dbt CLI for dbt project operations#145

Closed
suryaiyer95 wants to merge 10000 commits intomainfrom
feat/dbt-tools-cli
Closed

feat: add altimate-dbt CLI for dbt project operations#145
suryaiyer95 wants to merge 10000 commits intomainfrom
feat/dbt-tools-cli

Conversation

@suryaiyer95
Copy link
Copy Markdown
Contributor

Summary

  • New packages/dbt-tools/ TypeScript package wrapping @altimateai/dbt-integration to provide one-shot dbt CLI operations
  • 16 commands covering the full dbt workflow: compile, build, run, test, execute SQL, introspect columns/DAG, manage packages
  • Config auto-detected via altimate-dbt init, stored at ~/.altimate-code/dbt.json
  • Prerequisite validation (doctor) checks Python, dbt-core, and project health before loading the heavy adapter
  • Structured JSON output with actionable error + fix fields for all failure modes
  • Patch for [email protected] to fix bluebird.promisifyAll crash with class private fields
  • Builds with bun build --target node for Node.js runtime (workaround for Bun IPC channel bug)
  • /dbt-cli skill teaching AI agents when and how to invoke each command

Architecture

altimate-dbt CLI (packages/dbt-tools/)
  ├── bin/altimate-dbt          # #!/usr/bin/env node shebang
  ├── src/index.ts              # CLI entry: argv dispatch, error handling, JSON output
  ├── src/config.ts             # Read/write ~/.altimate-code/dbt.json
  ├── src/adapter.ts            # Wire DBTProjectIntegrationAdapter (10 parsers, 4 factories)
  ├── src/check.ts              # Prerequisite validation (Python, dbt, project)
  ├── src/commands/             # 9 command files implementing 16 commands
  └── test/                     # 11 tests (config round-trip, CLI dispatch, error paths)

.opencode/skills/dbt-cli/       # AI skill with workflow patterns and invocation guidance
patches/[email protected]  # Fix bluebird.promisifyAll crash

Commands

Category Commands
Setup init, doctor
Info info
Compile compile, compile-query
Build build, run, test, build-project
Execute execute
Introspect columns, columns-source, column-values, children, parents
Packages deps, add-packages

Test plan

  • bun test --cwd packages/dbt-tools — 11/11 tests pass
  • bun turbo typecheck — 0 type errors in dbt-tools
  • altimate-dbt init --project-root <path> — writes config, runs health checks
  • altimate-dbt doctor — returns structured check results
  • altimate-dbt info — returns project info via adapter
  • /dbt-cli skill loads and guides AI to run correct commands
  • Full compile/build/execute flow requires dbt_core_integration Python module

🤖 Generated with Claude Code

kulvirgit and others added 30 commits March 2, 2026 15:27
Replace broken `[email protected]` npm reference
(package doesn't exist) with a direct in-tree implementation in
`src/plugin/anthropic.ts`, matching the pattern used by Codex and Copilot.

- Add `AnthropicAuthPlugin` supporting Claude Pro/Max OAuth, API key
  creation via OAuth, and manual API key entry
- Clear `BUILTIN` array and add `AnthropicAuthPlugin` to `INTERNAL_PLUGINS`
- Skip old `opencode-anthropic-auth` / `altimate-code-anthropic-auth`
  entries in user plugin configs to avoid duplicate loading

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
feat: port Anthropic OAuth plugin in-tree
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Restore .trim() on models API JSON to prevent syntax error in
  generated models-snapshot.ts
- Fix archive path for scoped package names (@altimate/cli-*) in
  release tarball/zip creation
- Remove gh release upload from build.ts (handled by github-release job)
- Add CHANGELOG.md entry for v0.1.5

Co-authored-by: Claude Opus 4.6 <[email protected]>
- Redesign M as 5-wide with visible V-valley to distinguish from A
- Change E top from full bar to open-right, distinguishing from T
- Fix T with full-width crossbar and I as narrow column
- Fix D shape in CODE
- Render CODE in theme.accent (purple) instead of theme.primary (peach)

Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- publish.ts: change glob from `*/package.json` to `**/package.json` to
  find scoped package directories (@altimate/cli-*) which are 2 levels deep
- release.yml: add skip-existing to PyPI publish so it doesn't fail when
  the engine version hasn't changed between releases

Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
The npm org is @AltimateAI, not @Altimate. Update all package names,
workspace dependencies, imports, and documentation to use the correct
scope so npm publish succeeds.

Name mapping:
- @altimate/cli → @altimateai/altimate-code
- @altimate/cli-sdk → @altimateai/altimate-code-sdk
- @altimate/cli-plugin → @altimateai/altimate-code-plugin
- @altimate/cli-util → @altimateai/altimate-code-util
- @altimate/cli-script → @altimateai/altimate-code-script

Also updates publish.ts to emit the wrapper package as @altimateai/altimate-code
(no -ai suffix) and hardcodes the bin entry to altimate-code.

Co-authored-by: Claude Opus 4.6 <[email protected]>
Two issues:
1. TypeScript permission-task tests: test fixture wrote config to
   `opencode.json` but the config loader only looks for
   `altimate-code.json`. Updated fixture to use correct filename.

2. Python tests: `pytest: command not found` because pyproject.toml
   had no `dev` optional dependency group. Added `dev` extras with
   pytest and ruff.

Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: rename opencode references to altimate-code in all test files

Update test files to use the correct names after the config loader
was renamed from opencode to altimate-code:

- `opencode.json` → `altimate-code.json`
- `.opencode/` → `.altimate-code/`
- `.git/opencode` → `.git/altimate-code`
- `OPENCODE_*` env vars → `ALTIMATE_CLI_*`
- Cache dir `opencode` → `altimate-code`
- Schema URL `opencode.ai` → `altimate-code.dev`

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: resolve remaining test failures and build import issue

- Fix build.ts solid-plugin import to use bare specifier for monorepo hoisting
- Update agent tests: "build" → "builder", "plan" → "analyst" for disabled fallback
- Fix well-known config mock URL in config.test.ts
- Fix message-v2 test: "OpenCode" → "Altimate CLI"
- Fix retry.test.ts: replace unsupported test.concurrent with test
- Fix read.test.ts: update agent name to "builder"
- Fix agent-color.test.ts: update config keys to "builder"
- Fix registry.test.ts: remove unpublished plugin dep from test fixture
- Skip adding plugin dependency in local dev mode (installDependencies)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address Sentry review comments and Python CI deps

- Update theme schema URL from opencode.ai to altimate-code.dev (33 files)
- Rename opencode references in ACP README.md and AGENTS.md docs
- Update test fixture tmp dir prefix to altimate-code-test-
- Install warehouse extras in Python CI for duckdb/boto3 test deps

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: Python CI — SqlGuardResult allows None data, restrict pytest to tests/

- Allow SqlGuardResult.data to be None (fixes lineage.check Pydantic error)
- Set testpaths = ["tests"] in pyproject.toml to exclude src/test_local.py
  from pytest collection (it's a source module, not a test)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: resolve ruff lint errors in Python engine

- Remove unused imports in server.py (duplicate imports, unused models)
- Remove unused `json` import in schema/cache.py
- Remove unused `os` import in sql/feedback_store.py
- Add noqa for keyring availability check import

Co-Authored-By: Claude Opus 4.6 <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Use import.meta.resolve to find the @opentui/core package directory
instead of hardcoding node_modules path, which fails with monorepo
hoisting.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…aming

- Build: output binary as altimate-code instead of opencode
- Bin wrapper: look for @altimateai/altimate-code-* scoped packages
- Postinstall: resolve @AltimateAI scoped platform packages
- Publish: update Docker/AUR/Homebrew refs to AltimateAI/altimate-code
- Publish: make Docker/AUR/Homebrew non-fatal (infra not set up yet)
- Dockerfile: update binary paths and names

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
…sion (#15762)

Co-authored-by: Test User <[email protected]>
Co-authored-by: Shoubhit Dash <[email protected]>
kulvirgit and others added 20 commits March 6, 2026 20:59
fix: resolve GitlabAuthPlugin type incompatibility
* chore: use ARC self-hosted runner for CI

* chore: use ARC self-hosted runner for release workflow

* fix: harden ARC runner migration with security and reliability safeguards

- Fall back to `ubuntu-latest` for fork PRs to prevent untrusted code
  execution on self-hosted ARC runners
- Add `timeout-minutes: 60` to all CI and release jobs (self-hosted
  runners have no default timeout unlike GitHub-hosted 6h limit)
- Write `NPM_TOKEN` to `$RUNNER_TEMP/.npmrc` instead of `~/.npmrc` to
  prevent secret persistence on self-hosted runners
- Set `NPM_CONFIG_USERCONFIG` to point publish step to temp `.npmrc`
- Add `concurrency` group to CI workflow to cancel superseded runs

---------

Co-authored-by: anandgupta42 <[email protected]>
ci: switch Windows tests to ARC self-hosted runner
…onfig

fix: restore TUI crash after upstream merge
fix: correct TEAM_MEMBERS ref from 'dev' to 'main' in pr-standards workflow
- Add `AltimateApi` client for datamate CRUD and integration resolution
- Add `datamate` tool with 9 operations: list, show, create, update, delete,
  add (MCP connect), remove (MCP disconnect), list-integrations, status
- Extract shared MCP config utilities (`resolveConfigPath`, `addMcpToConfig`,
  `removeMcpFromConfig`, `listMcpInConfig`) to `mcp/config.ts`
- Add `/datamate-setup` skill for guided datamate onboarding
- Register datamate tool in tool registry and TUI sync context
- Add test suite for `AltimateApi` credential loading and API methods
feat: datamate manager — dynamic MCP server management
Replace arc-runner-altimate-code with ubuntu-latest across all
workflows to eliminate security risk on public repo.

Closes #109

Co-authored-by: Claude Opus 4.6 <[email protected]>
* feat: add `/feedback` command and `feedback_submit` tool (#86)

- Add `feedback_submit` tool at `src/altimate/tools/feedback-submit.ts`
  with `try-catch` around all `Bun.$` calls (ENOENT safety) and
  buffer-based stdout/stderr capture for better error reporting
- Add `/feedback` slash command with guided flow template
- Register `FeedbackSubmitTool` in tool registry
- Register feedback command in `command/index.ts`
- Add 49 tests (tool + command integration)
- Fix CI `pr-standards.yml`: change `ref: 'dev'` to `ref: 'main'`
  and wrap TEAM_MEMBERS lookup in `try-catch` for rebase resilience
- Add `/feedback` to docs `commands.md`

* fix: address code review findings in feedback-submit tool

- Fix misleading error: `gh auth status` catch now returns `gh_auth_check_failed`
  instead of `gh_not_installed` (gh IS installed at that point)
- Fix fragile version check: use `startsWith("gh version")` instead of
  `includes("not found")` for cross-platform correctness
- Add `trim().min(1)` validation to `title` and `description` zod schemas
  to reject empty/whitespace-only inputs
- Check `issueResult.exitCode !== 0` before stdout URL check on issue creation
- Restore `Bun.$` in `afterAll` to prevent mock leaking across test files
- Remove trailing `$ARGUMENTS` from end of feedback.txt template (duplicated
  from Step 1 pre-fill logic; could confuse model)
- Add 8 new tests: empty/whitespace validation, `gh_auth_check_failed` path,
  non-zero exitCode with stdout scenario, and updated "not found" test name

* test: fix Windows CI failures in install and bridge tests

- Replace `/bin/echo` with `process.execPath` in bridge test — /bin/echo
  does not exist on Windows, causing ENOENT on spawn; process.execPath
  (the current Bun binary) exists on all platforms and exits quickly
  without speaking JSON-RPC as expected
- Add `unixtest` guard to postinstall, bin-wrapper, and integration tests
  — on Windows, postinstall.mjs takes a different early-exit path that
  skips hard-link setup; dummy binaries are Unix shell scripts that
  cannot be executed on Windows; skip all Unix-specific test paths using
  the same `process.platform !== "win32" ? test : test.skip` pattern
  already used in fsmonitor.test.ts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

---------

Co-authored-by: Claude Sonnet 4.6 <[email protected]>
- Bump engine version to 0.2.5
- Update CHANGELOG.md with v0.2.5 release notes
…eam rebase

The upstream OpenCode rebase changed the package name from
`@altimateai/altimate-code` to `opencode`, causing npm publish to fail
with E403 (trying to publish to unscoped `opencode-*` packages).

- Restore `name` field in `packages/opencode/package.json`
- Remove upstream `opencode` bin entry
- Update workspace reference in `packages/web/package.json`
npm v7+ silences postinstall stdout, so the `printWelcome()` banner was
never visible to users despite running correctly.

**Fixes:**
- Postinstall now writes a `.installed-version` marker to `XDG_DATA_HOME`
- CLI reads the marker on startup, displays a styled welcome banner, then
  removes it — works regardless of npm's output suppression
- Fixed double-v bug (`vv0.2.4`) in `printWelcome()` version display

**Tests (10 new):**
- Postinstall: marker file creation, v-prefix stripping, missing version
- Welcome module: marker cleanup, empty marker, fs error resilience
) (#133)

After 20+ minutes idle, OAuth tokens expire and subsequent prompts show
unhelpful "Error" with no context or retry. This commit fixes the issue
across Anthropic and Codex OAuth plugins:

- Add 3-attempt retry with backoff for token refresh (network/5xx only)
- Fail fast on 4xx auth errors (permanent failures like revoked tokens)
- Add 30-second proactive refresh buffer to prevent mid-request expiry
- Update `currentAuth.expires` after successful refresh
- Classify token refresh failures as `ProviderAuthError` for actionable
  error messages with recovery instructions
- Make auth errors retryable at session level with user-facing guidance
- Improve generic `Error` display (no more bare "Error" in TUI)

Co-authored-by: Claude Opus 4.6 <[email protected]>
* chore: rebrand all user-facing references from OpenCode to Altimate Code

Comprehensive rebranding of user-facing surfaces while preserving
internal code names for upstream compatibility:

- URLs: `opencode.ai` → `altimate.ai`
- GitHub org: `anomalyco/opencode` → `AltimateAI/altimate-code`
- Product name: "OpenCode" → "Altimate Code" in UI, prompts, docs
- CLI binary: `opencode` → `altimate-code` in install scripts, nix
- npm package: `opencode-ai` → `@altimateai/altimate-code`
- Extensions: VSCode rebranded
- Social: X handle → `@Altimateinc`
- Brew tap: `AltimateAI/tap/altimate-code`
- Container registry: `ghcr.io/AltimateAI`
- All 20 localized READMEs

Preserved internal names: `@opencode-ai/` scope, `packages/opencode/`
dir, `OPENCODE_*` env vars, `.opencode/` config paths

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: additional user-facing branding fixes missed from upstream rebase

- `.github/workflows/beta.yml`: "Install OpenCode" → "Install Altimate Code",
  `bun i -g opencode-ai` → `bun i -g @altimateai/altimate-code`
- `.github/actions/setup-git-committer/action.yml`: descriptions updated
  from "OpenCode GitHub App" → "Altimate Code GitHub App"
- `github/index.ts`: `spawn('opencode')` → `spawn('altimate-code')`

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat: add upstream merge automation tooling

Comprehensive automation for merging upstream OpenCode releases into
the Altimate Code fork, inspired by Kilo-Org/kilocode's approach.

Key scripts:
- `merge.ts` — 11-step merge orchestration with auto-conflict resolution,
  branding transforms, version preservation, and `--continue` support
- `analyze.ts` — `altimate_change` marker integrity audit + branding
  leak detection (CI-friendly exit codes)
- `list-versions.ts` — upstream tag listing with merge status indicators
- `verify-restructure.ts` — branch comparison verification

Transforms (10 files):
- Core branding engine with preservation-aware product name handling
- `keepOurs` / `skipFiles` / lock file conflict auto-resolution
- Specialized transforms for `package.json`, Nix, Tauri, i18n,
  extensions, web docs, workflows, and build scripts

Configuration:
- All branding rules in TypeScript (`utils/config.ts`) for type safety
- URL, GitHub, registry, email, app ID, social, npm, brew mappings
- Preserve patterns protect internal refs (`@opencode-ai/`, `OPENCODE_`)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* chore: remove upstream-only packages, workflows, and artifacts (Kilo-style cleanup)

Remove upstream platform packages (app, console, containers, desktop,
desktop-electron, docs, enterprise, extensions, function, identity,
slack, storybook, ui, web), translated READMEs, upstream-only workflows,
nix packaging (nix/, flake.nix, flake.lock), SST infra (sst.config.ts,
sst-env.d.ts), specs/, and .signpath/ config.

- Update workspaces from `packages/*` glob to explicit package list
- Remove unused catalog entries and devDependencies (sst, @aws-sdk/client-s3)
- Remove unused scripts (dev:desktop, dev:web, dev:storybook)
- Remove `electron` from trustedDependencies
- Remove `@opencode-ai/app#test` task from turbo.json
- Update merge-config.json and config.ts skipFiles with new patterns

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* chore: remove upstream SST `infra/` directory and add to skipFiles

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* docs: rewrite upstream merge README as a practical runbook

Reorganized around the step-by-step workflow someone would follow
when doing an upstream merge. Covers fork strategy, prerequisites,
the full merge process, configuration reference, and troubleshooting.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* test: add comprehensive branding, build integrity, and upstream merge guard tests

Add 141 tests across 3 test files to prevent regressions:

- `branding.test.ts` (33 tests): Verify all user-facing surfaces show
  Altimate branding — package metadata, CLI entry points, logo, welcome
  banner, install script, GitHub Action, VSCode extension, postinstall,
  and a full codebase leak scanner for `opencode.ai`/`anomalyco`/`opncd.ai`
- `build-integrity.test.ts` (19 tests): Verify workspace config, turbo.json
  validity, package dependencies, binary entry points, skip/keepOurs
  consistency, and no orphaned package references
- `upstream-guard.test.ts` (89 tests): Verify skipFiles/keepOurs config
  completeness, deleted upstream packages stay deleted, branding rules
  coverage, preserve patterns, and no upstream artifacts reappear

Fix 14 upstream branding leaks found by the tests:
- Replace `opencode.ai` URLs with `altimate.ai` in config.ts, retry.ts,
  dialog-provider.tsx, oauth-provider.ts, migrate-tui-config.ts
- Replace `opncd.ai` with `altimate.ai` in share-next.ts and import.ts
- Replace "OpenCode Go" with "Altimate Code Go" in dialog-provider.tsx

Add CI enforcement:
- New `branding-check.yml` workflow with branding audit + test jobs
- Add `branding` job to existing `ci.yml` for PR checks

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* chore: remove separate branding CI workflow — tests run with `bun test`

The branding unit tests already run as part of the existing `typescript`
CI job via `bun test`. A separate workflow and branding audit on every
commit is overkill — the `analyze.ts --branding` audit is a merge-time
tool, not a per-commit check.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: persist version snapshot in merge state for `--continue` flow

The `--continue` handler was re-snapshotting versions after the merge
commit, capturing upstream versions instead of our pre-merge versions.
Now the snapshot is saved in `.upstream-merge-state.json` and restored
when resuming.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address code review — XSS, branding leaks, regex safety

- Fix XSS in OAuth error page: escape HTML in error parameter
- Fix branding: `client_name` and HTML titles/text in OAuth pages
  now show "Altimate Code" instead of "OpenCode"
- Fix Anthropic plugin regex: add word boundaries (`\b`) to prevent
  replacing "opencode" inside URLs, paths, and identifiers

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* ci: retry CI run

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
New `packages/dbt-tools/` TypeScript package wrapping `@altimateai/dbt-integration`
to provide one-shot dbt CLI operations (compile, build, test, execute, introspect).

- 16 commands: init, doctor, info, compile, compile-query, build, run, test,
  build-project, execute, columns, columns-source, column-values, children,
  parents, deps, add-packages
- Config at `~/.altimate-code/dbt.json`, auto-detected via `altimate-dbt init`
- Prerequisite validation (`doctor`) checks Python, dbt-core, and project health
- Structured JSON output to stdout, logs to stderr, `--format text` for humans
- Graceful error handling with actionable `error` + `fix` fields
- Patch `[email protected]` to fix `bluebird.promisifyAll` crash
- Build with `bun build --target node` for Node.js runtime (Bun IPC bug workaround)
- 11 tests covering config round-trip, CLI dispatch, error paths
- `/dbt-cli` skill teaching AI agents when and how to invoke each command

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@github-actions
Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

Comment on lines +157 to +160
result = (await import("./commands/graph")).children(adapter, rest)
break
case "parents":
result = (await import("./commands/graph")).parents(adapter, rest)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The children and parents command results are not awaited in index.ts. This causes them to return a Promise that serializes to an empty object {}.
Severity: HIGH

Suggested Fix

Add the await keyword to the calls for the children and parents commands within the switch statement in index.ts. This will ensure the Promise resolves before the result is assigned and serialized.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: packages/dbt-tools/src/index.ts#L157-L160

Potential issue: The `children` and `parents` commands in `graph.ts` are not declared as
`async` but return Promises from the underlying adapter methods. In `index.ts`, the
calls to these functions are not awaited, unlike other commands. Consequently, the
`result` variable holds a Promise object. When this object is serialized with
`JSON.stringify()`, it results in an empty object `{}`. This causes the `altimate-dbt
children` and `altimate-dbt parents` CLI commands to always return `{}` instead of the
expected model dependency data, breaking their functionality.

Did we get this right? 👍 / 👎 to inform future reviews.

const model = flag(args, "model") ?? ""
const raw = flag(args, "limit")
const limit = raw ? parseInt(raw, 10) : undefined
if (limit) return adapter.immediatelyExecuteSQLWithLimit(sql, model, limit)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The execute command uses a falsy check if (limit), causing --limit 0 to be ignored and the query to run without any limit.
Severity: MEDIUM

Suggested Fix

Change the condition from if (limit) to if (limit !== undefined). This correctly checks for the presence of the limit argument, including 0, ensuring that LIMIT 0 is properly applied to the SQL query.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: packages/dbt-tools/src/commands/execute.ts#L9

Potential issue: In the `execute` command, the code checks `if (limit)` to determine
whether to apply a SQL limit. When a user passes `--limit 0`, the `limit` variable
becomes the number `0`. In JavaScript, `0` is a falsy value, so the condition `if
(limit)` evaluates to false. As a result, the code incorrectly executes the branch for
running the SQL query without a limit, ignoring the user's explicit instruction to
return zero rows. This behavior is incorrect as `LIMIT 0` is a valid SQL operation.

Did we get this right? 👍 / 👎 to inform future reviews.

… bridge

`bun build` bundles all JS into a single `dist/index.js`, causing
`import.meta.url` to resolve to the bundle location instead of the
original `@altimateai/dbt-integration/dist/` directory. This meant
`PYTHONPATH` pointed to a nonexistent `altimate_python_packages/` dir,
breaking `dbt_core_integration` imports.

- Add `script/copy-python.ts` post-build step that copies
  `altimate_python_packages/` from the npm package into `dist/`
- Remove developer-only build instructions from `/dbt-cli` skill

Co-Authored-By: Claude Opus 4.6 <[email protected]>
}

function format(result?: CommandProcessResult) {
if (result?.stderr) return { error: result.stderr, stdout: result.stdout }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The format function incorrectly uses stderr to detect errors instead of checking the exitCode, causing successful dbt commands to be reported as failures.
Severity: HIGH

Suggested Fix

Update the format function to check for a non-zero exitCode to identify an error, rather than checking for the existence of stderr. The condition should be changed to if (result?.exitCode !== 0).

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: packages/dbt-tools/src/commands/deps.ts#L16

Potential issue: The `format` function in `deps.ts` and `build.ts` incorrectly
determines command failure by checking for the presence of `result?.stderr`. However,
dbt commands like `dbt deps` can write informational progress messages to `stderr` even
during successful runs. The standard practice for determining success or failure is to
check the command's `exitCode`. Due to this flawed logic, successful dbt operations that
produce any `stderr` output will be incorrectly reported as failures. This causes the
CLI tool to exit with a non-zero status code, which can break automated scripts or CI/CD
pipelines that depend on the exit code to determine the outcome.

@dev-punia-altimate
Copy link
Copy Markdown

🤖 Behavioral Analysis — 3 Finding(s)

🔴 Critical (1)

  • F1 packages/dbt-tools/src/index.ts:157 [Missing await — Promise stored as result]
    The children and parents switch cases assign result without await, unlike every other command in the same switch. graph.children() and graph.parents() are not declared async but return the Promise from adapter.getChildrenModels() / adapter.getParentModels(). Without await, result holds an unresolved Promise. (1) output(result) calls JSON.stringify(promise) which serializes to {}, so both commands always print {} instead of actual graph data. (2) The finally { await adapter.dispose() } block tears down the Python bridge while the underlying operation is still in flight. All other commands in the switch correctly use result = await (await import(...)).fn(adapter, rest). — Auto-fixable: Add await before both graph calls: result = await (await import('./commands/graph')).children(adapter, rest) and same for parents.

🟡 Warnings (1)

  • F2 packages/dbt-tools/src/commands/build.ts:30 [stderr presence used as error signal — false positives on successful dbt runs]
    The format() helper in both build.ts (line 30) and deps.ts (line 16) uses if (result?.stderr) to decide whether a command failed. dbt consistently writes progress output to stderr on success — lines like 'Running with dbt=1.8.0', 'Found N models', 'Completed successfully'. Any successful build/run/test/deps invocation that produces any stderr will be incorrectly reported as a failure: CLI returns { error: <stderr> } and exits with code 1, breaking any CI pipeline checking exit codes. The correct signal is a non-zero exitCode.

🔵 Nits (1)

  • F3 packages/dbt-tools/src/commands/execute.ts:9 — The parsed limit is checked with if (limit). JavaScript treats 0 as falsy, so --limit 0 silently falls back to the unlimited query path. Negative limits (e.g. --limit -1) are truthy and passed to the adapter unchecked.

Analysis run | Powered by QA Autopilot

@dev-punia-altimate
Copy link
Copy Markdown

✅ Tests — All Passed

TypeScript — passed

Python — passed

Tested at bf3da562 | Run log | Powered by QA Autopilot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.