Skip to content

Commit 3ff930e

Browse files
authored
Merge branch 'main' into fix/hardcoded-snowflake-dialect
2 parents 5a41dbe + 5d0ada3 commit 3ff930e

120 files changed

Lines changed: 14796 additions & 427 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
description: Add a new database driver to Altimate Code. Scaffolds the driver, registers it across all 23 integration points, writes E2E tests, and updates docs. Usage - /add-database-driver <database-name>
3+
---
4+
5+
# Add Database Driver
6+
7+
Scaffold and fully integrate a new database/warehouse driver into Altimate Code. This command handles all 23 integration points — driver code, registry, discovery, finops, tests, and documentation.
8+
9+
## Input
10+
11+
`$ARGUMENTS` = the database name (e.g., `cockroachdb`, `timescaledb`, `cassandra`, `neo4j`).
12+
13+
If empty, ask: "Which database should I add support for?"
14+
15+
## Step 0: Research
16+
17+
Before writing any code, research the database:
18+
19+
1. **Find the official Node.js/TypeScript client package** on npm. Search for `@{database}/client`, `{database}-js`, or similar.
20+
2. **Check supported server versions** — which versions are not EOL?
21+
3. **Identify auth methods** — password, token, TLS/certificate, connection string, cloud-specific?
22+
4. **Check SQL dialect** — standard SQL? Custom syntax? LIMIT vs TOP vs FETCH FIRST? System tables for schemas/tables/columns?
23+
5. **Find Docker image** — official image on Docker Hub for E2E testing?
24+
6. **Check if dbt adapter exists** — search for `dbt-{database}` on PyPI.
25+
26+
Present findings to the user before proceeding:
27+
```
28+
## Research: {Database}
29+
30+
- **npm package**: `{package}` (v{version})
31+
- **Server versions**: {non-EOL versions}
32+
- **Auth methods**: {list}
33+
- **SQL dialect**: {notes on LIMIT, system tables, parameterized queries}
34+
- **Docker image**: `{image}:{tag}`
35+
- **dbt adapter**: {exists/not found}
36+
37+
Proceed with implementation?
38+
```
39+
40+
## Step 1: Read Reference Document
41+
42+
Read the comprehensive checklist:
43+
```bash
44+
cat packages/drivers/ADDING_A_DRIVER.md
45+
```
46+
47+
This document has all 23 integration points with exact file paths and code patterns.
48+
49+
## Step 2: Read Existing Driver for Pattern
50+
51+
Read a similar existing driver as a template. Choose based on database type:
52+
53+
- **SQL database with password auth** → read `packages/drivers/src/mysql.ts`
54+
- **Cloud warehouse with token auth** → read `packages/drivers/src/databricks.ts`
55+
- **Database with connection string support** → read `packages/drivers/src/postgres.ts`
56+
- **HTTP-based client** → read `packages/drivers/src/clickhouse.ts`
57+
- **Document database (non-SQL)** → read `packages/drivers/src/mongodb.ts`
58+
59+
Also read:
60+
- `packages/drivers/src/normalize.ts` — for alias pattern
61+
- `packages/opencode/src/altimate/native/connections/registry.ts` — for registration pattern
62+
- `packages/opencode/test/altimate/drivers-docker-e2e.test.ts` — for E2E test pattern
63+
64+
## Step 3: Implement (23 integration points)
65+
66+
Work through all 9 phases from the checklist. Use parallel edits where possible.
67+
68+
### Phase 1: Core Driver (4 files)
69+
70+
1. **Create `packages/drivers/src/{database}.ts`**
71+
- Follow the Connector interface: `connect()`, `execute()`, `listSchemas()`, `listTables()`, `describeTable()`, `close()`
72+
- Lazy-import the npm package
73+
- Use parameterized queries for schema introspection
74+
- Handle LIMIT injection with DML guard: `!hasDML` check before appending LIMIT
75+
- Handle TLS detection from connection strings
76+
77+
2. **Add export to `packages/drivers/src/index.ts`**
78+
79+
3. **Add optionalDependency to `packages/drivers/package.json`**
80+
81+
4. **Add aliases to `packages/drivers/src/normalize.ts`**
82+
83+
### Phase 2: Registry (4 files in registry.ts)
84+
85+
5. Add to `DRIVER_MAP`
86+
6. Add to import switch statement
87+
7. Add to `PASSWORD_DRIVERS` (if applicable)
88+
8. Remove from `KNOWN_UNSUPPORTED` (if listed)
89+
90+
### Phase 3: Discovery (4 files)
91+
92+
9. Docker discovery — `docker-discovery.ts` (IMAGE_MAP, ENV_MAP, DEFAULT_PORTS, DEFAULT_USERS)
93+
10. Env var detection — `project-scan.ts` (detectEnvVars warehouses array)
94+
11. dbt adapter — `dbt-profiles.ts` (ADAPTER_TYPE_MAP)
95+
12. dbt lineage — `dbt/lineage.ts` (detectDialect dialectMap)
96+
97+
### Phase 4: FinOps (1 file)
98+
99+
13. Query history — `finops/query-history.ts` (SQL template + handler if database has system query log)
100+
101+
### Phase 5: Build (1 file)
102+
103+
14. Peer deps — `script/publish.ts` (driverPeerDependencies)
104+
105+
### Phase 6: Tool Descriptions (1 file)
106+
107+
15. warehouse_add — `tools/warehouse-add.ts` (config description + error message)
108+
109+
### Phase 7: Tests (2 new files + 1 edit)
110+
111+
16. E2E tests — `test/altimate/drivers-{database}-e2e.test.ts`
112+
17. Normalization tests — add to `test/altimate/driver-normalize.test.ts`
113+
18. Verify existing tests pass
114+
115+
### Phase 8: Documentation (5 files)
116+
117+
19. `docs/docs/configure/warehouses.md` — config section + update count
118+
20. `docs/docs/drivers.md` — support matrix + installation + auth + update count
119+
21. `docs/docs/data-engineering/tools/warehouse-tools.md` — env vars + Docker
120+
22. `README.md` — warehouse list
121+
23. `docs/docs/getting-started/index.md` — homepage list
122+
123+
### Phase 9: Optional
124+
125+
- Guide page at `docs/docs/data-engineering/guides/{database}.md`
126+
- Update `mkdocs.yml` nav and `guides/index.md`
127+
- Check fingerprint regex in `fingerprint/index.ts`
128+
129+
## Step 4: Run Quality Gates
130+
131+
```bash
132+
# Tests (from packages/opencode/)
133+
cd packages/opencode && bun test test/altimate/driver-normalize.test.ts test/altimate/connections.test.ts test/altimate/drivers-{database}-e2e.test.ts
134+
135+
# Typecheck (from repo root)
136+
cd "$(git rev-parse --show-toplevel)" && bun turbo typecheck
137+
138+
# Marker check (from repo root)
139+
bun run script/upstream/analyze.ts --markers --base main --strict
140+
```
141+
142+
All three must pass before proceeding.
143+
144+
## Step 5: Run Code Review
145+
146+
Run `/consensus:code-review` to get the implementation reviewed by multiple models before committing.
147+
148+
## Step 6: Summary
149+
150+
Present final summary:
151+
```
152+
## {Database} Driver Added
153+
154+
### Files Created
155+
- packages/drivers/src/{database}.ts
156+
- packages/opencode/test/altimate/drivers-{database}-e2e.test.ts
157+
- docs/docs/data-engineering/guides/{database}.md (if created)
158+
159+
### Files Modified
160+
- {list all modified files}
161+
162+
### Test Results
163+
- {N} normalization tests pass
164+
- {N} connection tests pass
165+
- Typecheck: pass
166+
- Marker check: pass
167+
168+
### E2E Test Coverage
169+
- {list of test suites and server versions}
170+
171+
Ready to commit.
172+
```
173+
174+
## Rules
175+
176+
1. **Read before writing.** Always read existing drivers and the reference doc before creating new code.
177+
2. **Don't skip integration points.** All 23 points exist for a reason — missing one causes inconsistencies users will hit.
178+
3. **Use parameterized queries** for `listTables` and `describeTable` — never interpolate user input into SQL.
179+
4. **Test multiple server versions** — at minimum: latest stable + oldest non-EOL LTS.
180+
5. **Run all quality gates** before presenting the summary.
181+
6. **Don't modify finops tools** (credit-analyzer, warehouse-advisor, unused-resources) unless the database has equivalent cost/credit APIs.

.github/meta/commit.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
fix: remove flaky `setTimeout` in todo bus event test
2-
3-
`Bus.publish` is synchronous — the event is delivered immediately,
4-
no 50ms delay needed. Removes resource contention risk in parallel CI.
5-
6-
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1+
feat: add ClickHouse warehouse driver

.github/workflows/ci.yml

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jobs:
4646
- 'packages/opencode/test/altimate/drivers-e2e.test.ts'
4747
- 'packages/opencode/test/altimate/drivers-docker-e2e.test.ts'
4848
- 'packages/opencode/test/altimate/drivers-mongodb-e2e.test.ts'
49+
- 'packages/opencode/test/altimate/drivers-clickhouse-e2e.test.ts'
4950
- 'packages/opencode/test/altimate/connections.test.ts'
5051
dbt-tools:
5152
- 'packages/dbt-tools/**'
@@ -84,13 +85,45 @@ jobs:
8485
run: bun install
8586

8687
- name: Run tests
87-
run: bun test --timeout 30000
8888
working-directory: packages/opencode
8989
# Cloud E2E tests (Snowflake, BigQuery, Databricks) auto-skip when
9090
# ALTIMATE_CODE_CONN_* env vars are not set. Docker E2E tests auto-skip
9191
# when Docker is not available. No exclusion needed — skipIf handles it.
9292
# --timeout 30000: matches package.json "test" script; prevents 5s default
9393
# from cutting off tests that run bun install or bootstrap git instances.
94+
#
95+
# Bun 1.3.x has a known segfault during process cleanup after all tests
96+
# pass (exit code 143/SIGTERM or 134/SIGABRT). We capture test output and
97+
# check for real failures vs Bun crashes to avoid false CI failures.
98+
shell: bash
99+
run: |
100+
# Redirect bun output to file, then cat it for CI visibility.
101+
# This avoids tee/pipe issues where SIGTERM kills tee before flush.
102+
bun test --timeout 30000 > /tmp/test-output.txt 2>&1 || true
103+
cat /tmp/test-output.txt
104+
105+
# Extract pass/fail counts from Bun test summary (e.g., " 5362 pass")
106+
PASS_COUNT=$(awk '/^ *[0-9]+ pass$/{print $1}' /tmp/test-output.txt || true)
107+
FAIL_COUNT=$(awk '/^ *[0-9]+ fail$/{print $1}' /tmp/test-output.txt || true)
108+
109+
echo ""
110+
echo "--- Test Summary ---"
111+
echo "pass=${PASS_COUNT:-none} fail=${FAIL_COUNT:-none}"
112+
113+
# Real test failures — always fail CI
114+
if [ -n "$FAIL_COUNT" ] && [ "$FAIL_COUNT" != "0" ]; then
115+
echo "::error::$FAIL_COUNT test(s) failed"
116+
exit 1
117+
fi
118+
119+
# Tests passed (we have a pass count and zero/no failures)
120+
if [ -n "$PASS_COUNT" ] && [ "$PASS_COUNT" -gt 0 ] 2>/dev/null; then
121+
exit 0
122+
fi
123+
124+
# No test summary at all — Bun crashed before running tests
125+
echo "::error::No test results found in output — Bun may have crashed before running tests"
126+
exit 1
94127
95128
# ---------------------------------------------------------------------------
96129
# Driver E2E tests — only when driver code changes.
@@ -166,6 +199,19 @@ jobs:
166199
--health-timeout 5s
167200
--health-retries 10
168201
202+
clickhouse:
203+
image: clickhouse/clickhouse-server:latest
204+
env:
205+
CLICKHOUSE_DB: testdb
206+
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
207+
ports:
208+
- 18123:8123
209+
options: >-
210+
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1"
211+
--health-interval 5s
212+
--health-timeout 5s
213+
--health-retries 15
214+
169215
steps:
170216
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
171217

@@ -213,6 +259,13 @@ jobs:
213259
TEST_MONGODB_HOST: 127.0.0.1
214260
TEST_MONGODB_PORT: "27017"
215261

262+
- name: Run ClickHouse driver E2E
263+
run: bun test test/altimate/drivers-clickhouse-e2e.test.ts
264+
working-directory: packages/opencode
265+
env:
266+
TEST_CLICKHOUSE_HOST: 127.0.0.1
267+
TEST_CLICKHOUSE_PORT: "18123"
268+
216269
# Cloud tests NOT included — they require real credentials
217270
# Run locally with:
218271
# ALTIMATE_CODE_CONN_SNOWFLAKE_TEST='...' bun test test/altimate/drivers-snowflake-e2e.test.ts
@@ -297,6 +350,55 @@ jobs:
297350
DBT_E2E_VERSIONS: "1.8,1.10,1.11"
298351
DBT_RESOLVE_SCENARIOS: "venv,uv,system"
299352

353+
# ---------------------------------------------------------------------------
354+
# Verdaccio sanity suite — tests the real `npm install -g` flow.
355+
# Only on push to main (too slow for PRs, needs Docker Compose).
356+
# Catches publish-pipeline bugs: missing files, broken symlinks, wrong bin
357+
# field, dependency resolution failures, postinstall script issues.
358+
# ---------------------------------------------------------------------------
359+
sanity-verdaccio:
360+
name: Sanity (Verdaccio)
361+
needs: changes
362+
if: github.event_name == 'push'
363+
runs-on: ubuntu-latest
364+
timeout-minutes: 30
365+
steps:
366+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
367+
368+
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
369+
with:
370+
bun-version: "1.3.10"
371+
372+
- name: Cache Bun dependencies
373+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
374+
with:
375+
path: ~/.bun/install/cache
376+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
377+
restore-keys: |
378+
bun-${{ runner.os }}-
379+
380+
- name: Install dependencies
381+
run: bun install
382+
383+
- name: Build CLI binary
384+
# target-index=1 = linux-x64 (see release.yml matrix)
385+
run: bun run packages/opencode/script/build.ts --target-index=1
386+
env:
387+
OPENCODE_VERSION: 0.0.0-sanity-${{ github.sha }}
388+
OPENCODE_RELEASE: "1"
389+
MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json
390+
391+
- name: Build dbt-tools
392+
run: bun run build
393+
working-directory: packages/dbt-tools
394+
395+
- name: Run Verdaccio sanity suite
396+
run: |
397+
docker compose -f test/sanity/docker-compose.verdaccio.yml up \
398+
--build --abort-on-container-exit --exit-code-from sanity
399+
env:
400+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
401+
300402
marker-guard:
301403
name: Marker Guard
302404
runs-on: ubuntu-latest

.github/workflows/release.yml

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,54 @@ jobs:
125125
path: packages/opencode/dist/
126126
compression-level: 1
127127

128+
# ---------------------------------------------------------------------------
129+
# Verdaccio sanity suite — tests the real `npm install -g` flow BEFORE
130+
# publishing to npm. Catches broken symlinks, missing files, postinstall
131+
# failures, and dependency resolution issues that smoke tests miss.
132+
# ---------------------------------------------------------------------------
133+
sanity-verdaccio:
134+
name: Sanity (Verdaccio)
135+
needs: build
136+
runs-on: ubuntu-latest
137+
timeout-minutes: 30
138+
steps:
139+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
140+
141+
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
142+
with:
143+
bun-version: "1.3.10"
144+
145+
- name: Cache Bun dependencies
146+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
147+
with:
148+
path: ~/.bun/install/cache
149+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
150+
restore-keys: |
151+
bun-${{ runner.os }}-
152+
153+
- name: Install dependencies
154+
run: bun install
155+
156+
- name: Download linux-x64 build artifact
157+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
158+
with:
159+
name: dist-linux-x64
160+
path: packages/opencode/dist/
161+
162+
- name: Build dbt-tools
163+
run: bun run build
164+
working-directory: packages/dbt-tools
165+
166+
- name: Run Verdaccio sanity suite
167+
run: |
168+
docker compose -f test/sanity/docker-compose.verdaccio.yml up \
169+
--build --abort-on-container-exit --exit-code-from sanity
170+
env:
171+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
172+
128173
publish-npm:
129174
name: Publish to npm
130-
needs: build
175+
needs: [build, sanity-verdaccio]
131176
runs-on: ubuntu-latest
132177
timeout-minutes: 60
133178
permissions:

.opencode/skills/dbt-analyze/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ If no manifest is available:
111111
1. Run `lineage_check` on the changed SQL
112112
2. Show column-level data flow
113113
3. Note: downstream impact requires a manifest
114-
4. Suggest: `altimate-dbt build-project` to generate one
114+
4. Suggest: `altimate-dbt build` to generate one
115115

116116
## Common Mistakes
117117

0 commit comments

Comments
 (0)