@altimateai/altimate-code 0.9.3 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.4] - 2026-07-31
9
+
10
+ Onboarding UX + first-run OAuth reliability. Ships the CLI's first-run scan + activation menu (Altimate LLM Gateway top of picker; bundled jaffle-shop DuckDB sample for users with no warehouse yet), then hardens the sign-in flow that path leads into.
11
+
12
+ ### Added
13
+
14
+ - **First-run scan + activation menu.** Fresh installs land on a curated 6-provider picker with Altimate LLM Gateway on top, then a Yes/No "Scan your environment?" gate that reads local config files (`.dbt/profiles.yml`, `dbt_project.yml`, `.git/config`) and routes into one of four branches — warehouse found, dbt-only, git-repo-no-dbt, nothing yet. The last branch offers to materialize a bundled jaffle-shop DuckDB sample dbt project (`~/altimate-sample-dbt/` by default; a suffixed variant if the name is taken) so a user with no warehouse can try Altimate against real data, real dbt models, without touching production. Every branch ends on a numbered "What would you like to do?" menu wired to real skills. (#1001)
15
+ - **Bundled jaffle-shop DuckDB sample project.** Ships with a pre-compiled `target/manifest.json` so `/discover` and `/review` work without dbt-core / dbt-duckdb installed. `dbt build` needs `pip install dbt-duckdb duckdb-cli` (or `pipx install --include-deps dbt-duckdb` / `uv tool install dbt-core --with dbt-duckdb` if you hit PEP 668). (#1001)
16
+
17
+ ### Fixed
18
+
19
+ - **Loopback OAuth sign-in is resilient to port collisions and long-SSO windows.** The Altimate LLM Gateway callback server now walks 7317-7325 on `EADDRINUSE` (a squatting dev tool on 7317 no longer wedges sign-in) and reports the actual bound port in the redirect. The pending-flow window extended from 5 min to 15 min so corporate SSO + MFA can finish. Two `authorize()` calls arriving concurrently now share one startup promise — both see the actually-bound port instead of one racing past on a stale/undefined value. (#1053)
20
+ - **CI test-isolation leak that turned six `permission/next.test.ts` tilde-expansion tests red.** `mcp/lifecycle.test.ts` was spying on `os.homedir()` in `beforeEach` with no `mockRestore`; the mock leaked forward into the next test file bun loaded, poisoning the tilde-expansion suite with a tmp path. Captured the spy handle and restored it in `afterEach`. Root-fix on the class, not the symptom. (#1053)
21
+ - **`HOME` recovery message is portable and doesn't tell users to write as root.** The prior text pointed at `/Users/you altimate-code` (macOS-only) and suggested `sudo HOME=…` which writes root-owned files a normal-user run then can't modify. Primary guidance is now "re-run without sudo" (install to a per-user prefix, or use nvm/asdf); secondary is `sudo -E HOME="$HOME" altimate-code` with an explicit `chown` recovery hint. (#1053)
22
+ - **PEP 668 install fallbacks actually expose a `dbt` binary.** `pipx install dbt-duckdb` and `uv tool install dbt-duckdb` both succeed but neither publishes the `dbt` entry point (it ships with `dbt-core`, a dependency). Users who followed the fallback after `pip` refused with `externally-managed-environment` hit a second dead end at their point of maximum frustration. Fixed to `pipx install --include-deps dbt-duckdb` and `uv tool install dbt-core --with dbt-duckdb`. The venv option also now asks for the absolute path — `~/.venvs/dbt/bin/dbt` wouldn't expand under the CLI's single-quoted validation. (#1053)
23
+ - **Scan disclosure is honest about telemetry.** The first-run scan's docs previously claimed "nothing leaves your computer". The scan itself doesn't send credentials, model contents, queries, or schema — but it does emit an anonymous environment summary (dbt-detected, warehouse-configured, etc.) through the standard telemetry pipeline if telemetry is enabled. Disclosure updated; `OPENCODE_DISABLE_TELEMETRY=1` remains the offline-strict switch. (#1053)
24
+ - **`sample_setup` error metadata no longer collides with success shape.** The unreachable `suffix: -1` sentinel was reverted to `0`; `success: false` is the disambiguator for metadata consumers, and the error `output` string separately begins `status: error` for the LLM template's failure branch. (#1053)
25
+ - **The auth plugin no longer leaks state-bearing authorize URLs into log files.** An earlier revision wrote the authorize URL to `process.stderr` as a fallback for SSH/tmux users; the auth plugin runs inside a TUI worker whose stdio is redirected to the log file (`packages/opencode/src/cli/tui/worker.ts`), so the write never reached the terminal it was written for. Removed. The TUI's auth dialog already renders the URL as a clickable link and binds `c` to copy it to the clipboard. (#1053)
26
+
27
+ ### Changed
28
+
29
+ - **`useConnected` and the home-tips visibility gate now share one predicate.** The "is any provider connected?" logic was duplicated in `component/use-connected.tsx` and `feature-plugins/home/tips.tsx`; both now call `isAnyProviderConnected` from `packages/tui/src/util/connected.ts` so a future edit to one can't drift them apart. Behavior unchanged (a semantically identical refactor). Non-`opencode` providers count as connected regardless of `cost` metadata (BYOK / self-hosted / custom-registration path); the `opencode` provider still requires a nonzero-cost model to count. (#1053)
30
+
8
31
  ## [0.9.3] - 2026-07-24
9
32
 
10
33
  Focused polish on the `altimate review` dbt PR reviewer — plus TUI startup UX
package/package.json CHANGED
@@ -7,20 +7,20 @@
7
7
  "scripts": {
8
8
  "postinstall": "bun ./postinstall.mjs || node ./postinstall.mjs"
9
9
  },
10
- "version": "0.9.3",
10
+ "version": "0.9.4",
11
11
  "license": "MIT",
12
12
  "dependencies": {
13
13
  "@altimateai/altimate-core": "0.5.1"
14
14
  },
15
15
  "optionalDependencies": {
16
- "@altimateai/altimate-code-darwin-x64-baseline": "0.9.3",
17
- "@altimateai/altimate-code-linux-arm64": "0.9.3",
18
- "@altimateai/altimate-code-darwin-x64": "0.9.3",
19
- "@altimateai/altimate-code-windows-x64-baseline": "0.9.3",
20
- "@altimateai/altimate-code-linux-x64": "0.9.3",
21
- "@altimateai/altimate-code-linux-x64-baseline": "0.9.3",
22
- "@altimateai/altimate-code-darwin-arm64": "0.9.3",
23
- "@altimateai/altimate-code-windows-x64": "0.9.3"
16
+ "@altimateai/altimate-code-darwin-x64-baseline": "0.9.4",
17
+ "@altimateai/altimate-code-linux-arm64": "0.9.4",
18
+ "@altimateai/altimate-code-darwin-x64": "0.9.4",
19
+ "@altimateai/altimate-code-windows-x64-baseline": "0.9.4",
20
+ "@altimateai/altimate-code-linux-x64": "0.9.4",
21
+ "@altimateai/altimate-code-linux-x64-baseline": "0.9.4",
22
+ "@altimateai/altimate-code-darwin-arm64": "0.9.4",
23
+ "@altimateai/altimate-code-windows-x64": "0.9.4"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "pg": ">=8",
@@ -0,0 +1,81 @@
1
+ # Jaffle Shop — altimate-code starter sample
2
+
3
+ Everything below runs against a local DuckDB file — no cloud warehouse, no
4
+ credentials, no network calls.
5
+
6
+ ## What's in here
7
+
8
+ ```
9
+ dbt_project.yml dbt project config
10
+ profiles.yml DuckDB profile — path is project-relative
11
+ sample-manifest.json version metadata used by altimate-code to detect
12
+ stale copies on upgrade
13
+ models/
14
+ staging/
15
+ stg_customers.sql renames raw customer columns to snake_case
16
+ stg_orders.sql renames raw order columns
17
+ schema.yml column descriptions + unique/not_null tests
18
+ marts/
19
+ customers.sql one row per customer, joins in order counts
20
+ orders.sql one row per order, joins in customer names
21
+ schema.yml column descriptions + tests + relationships
22
+ seeds/
23
+ raw_customers.csv 3 rows of test data
24
+ raw_orders.csv 4 rows of test data
25
+ target/
26
+ manifest.json PRE-COMPILED dbt manifest — ships with the sample so
27
+ altimate-code's static workflows (/discover, /review)
28
+ work without dbt-core / dbt-duckdb installed
29
+ ```
30
+
31
+ ## What to try
32
+
33
+ **If you got here via altimate-code's activation menu**, the chat is already
34
+ offering you a numbered menu — pick a number (or say what else you want to
35
+ do). Every option is wired to a real workflow:
36
+
37
+ - **See what breaks downstream before you change a model** — try `customers`
38
+ or `orders`.
39
+ - **Review the SQL in this project with every finding explained** — targets
40
+ the mart models.
41
+ - **Build & query it** — altimate-code detects whether dbt-core + dbt-duckdb
42
+ are installed, offers to reuse an existing dbt binary if you paste its
43
+ path, and walks you through the run. Auto-registers the DuckDB file as a
44
+ warehouse so `sql_execute` connects to the database dbt just built.
45
+
46
+ **If you `cd`'d into `~/altimate-sample-dbt/` from a different shell** — no
47
+ activation menu, no LLM in the loop. You can drive dbt yourself:
48
+
49
+ ```bash
50
+ # Three PyPI packages that do different jobs:
51
+ # - dbt-core: provides the `dbt` binary (the entry point)
52
+ # - dbt-duckdb: adapter — teaches dbt-core how to talk to DuckDB
53
+ # - duckdb-cli: standalone `duckdb` binary the ad-hoc query line uses
54
+ # `pip install dbt-duckdb` pulls dbt-core as a dependency, so pip is fine.
55
+ # `pipx install dbt-duckdb` does NOT — pipx only exposes entry points from the
56
+ # named package, and dbt-duckdb has none. Use `--include-deps` if you go pipx.
57
+ pip install dbt-duckdb duckdb-cli # PEP 668 alternatives below
58
+ cd ~/altimate-sample-dbt # wherever you materialized the sample
59
+ dbt seed # load the CSVs into DuckDB
60
+ dbt build # run models + tests
61
+ duckdb target/jaffle.duckdb -c 'select * from customers'
62
+ ```
63
+
64
+ If plain `pip` fails with `externally-managed-environment` (PEP 668, common
65
+ on modern macOS Homebrew and Debian/Ubuntu Python), use one of these instead:
66
+
67
+ ```bash
68
+ pipx install --include-deps dbt-duckdb && pipx install duckdb-cli
69
+ # or
70
+ uv tool install dbt-core --with dbt-duckdb && uv tool install duckdb-cli
71
+ ```
72
+
73
+ Once `dbt` is discoverable (venv, pipx, conda, uv, poetry, homebrew — the CLI
74
+ walks every common Python env manager), altimate-code's "Build & query"
75
+ option surfaces the same actions inside the chat.
76
+
77
+ ## Bringing your own project
78
+
79
+ When you're ready to switch to your real dbt project, `cd` into it and run
80
+ altimate-code again. The scan will pick up your `dbt_project.yml` and offer
81
+ to connect its warehouse.
@@ -0,0 +1,16 @@
1
+ name: "jaffle_shop"
2
+ version: "1.0.0"
3
+
4
+ profile: "jaffle_shop"
5
+
6
+ model-paths: ["models"]
7
+ seed-paths: ["seeds"]
8
+ target-path: "target"
9
+ clean-targets: ["target", "dbt_packages"]
10
+
11
+ models:
12
+ jaffle_shop:
13
+ staging:
14
+ +materialized: view
15
+ marts:
16
+ +materialized: table
@@ -0,0 +1,9 @@
1
+ select
2
+ c.customer_id,
3
+ c.first_name,
4
+ c.last_name,
5
+ count(o.order_id) as order_count,
6
+ coalesce(sum(o.amount), 0) as total_amount
7
+ from {{ ref('stg_customers') }} c
8
+ left join {{ ref('stg_orders') }} o on c.customer_id = o.customer_id
9
+ group by c.customer_id, c.first_name, c.last_name
@@ -0,0 +1,8 @@
1
+ select
2
+ o.order_id,
3
+ o.customer_id,
4
+ c.first_name || ' ' || c.last_name as customer_name,
5
+ o.order_date,
6
+ o.amount
7
+ from {{ ref('stg_orders') }} o
8
+ join {{ ref('stg_customers') }} c on o.customer_id = c.customer_id
@@ -0,0 +1,32 @@
1
+ version: 2
2
+
3
+ models:
4
+ - name: customers
5
+ description: One row per customer with total order count and revenue.
6
+ columns:
7
+ - name: customer_id
8
+ description: Primary key.
9
+ data_tests:
10
+ - unique
11
+ - not_null
12
+ - name: order_count
13
+ description: Number of orders placed by the customer (0 when none).
14
+ data_tests:
15
+ - not_null
16
+ - name: total_amount
17
+ description: Sum of all order amounts (0 when none).
18
+ data_tests:
19
+ - not_null
20
+
21
+ - name: orders
22
+ description: One row per order with a joined customer name.
23
+ columns:
24
+ - name: order_id
25
+ description: Primary key.
26
+ data_tests:
27
+ - unique
28
+ - not_null
29
+ - name: customer_id
30
+ description: Foreign key to `stg_customers`.
31
+ data_tests:
32
+ - not_null
@@ -0,0 +1,27 @@
1
+ version: 2
2
+
3
+ models:
4
+ - name: stg_customers
5
+ description: Renamed customer columns from the raw seed.
6
+ columns:
7
+ - name: customer_id
8
+ description: Primary key of the customer.
9
+ data_tests:
10
+ - unique
11
+ - not_null
12
+
13
+ - name: stg_orders
14
+ description: Renamed order columns from the raw seed.
15
+ columns:
16
+ - name: order_id
17
+ description: Primary key of the order.
18
+ data_tests:
19
+ - unique
20
+ - not_null
21
+ - name: customer_id
22
+ description: Foreign key to `stg_customers`.
23
+ data_tests:
24
+ - not_null
25
+ - relationships:
26
+ to: ref('stg_customers')
27
+ field: customer_id
@@ -0,0 +1,5 @@
1
+ select
2
+ id as customer_id,
3
+ first_name,
4
+ last_name
5
+ from {{ ref('raw_customers') }}
@@ -0,0 +1,6 @@
1
+ select
2
+ id as order_id,
3
+ customer_id,
4
+ order_date,
5
+ amount
6
+ from {{ ref('raw_orders') }}
@@ -0,0 +1,14 @@
1
+ # DuckDB profile — everything runs locally against a single file at
2
+ # `target/jaffle.duckdb` (created on first `dbt build`). No cloud credentials.
3
+ # `path:` is unqualified, so dbt-duckdb resolves it against the PROCESS
4
+ # working directory at build time — NOT the project directory. Run
5
+ # `dbt build` from the materialized sample dir (`cd <sample-path>`) and
6
+ # the database lands at `<sample-path>/target/jaffle.duckdb`.
7
+ # Run it from anywhere else and dbt writes to `$PWD/target/jaffle.duckdb`.
8
+ jaffle_shop:
9
+ target: dev
10
+ outputs:
11
+ dev:
12
+ type: duckdb
13
+ path: "target/jaffle.duckdb"
14
+ threads: 1
@@ -0,0 +1,27 @@
1
+ {
2
+ "$comment": "Metadata about this sample project. Distinct from dbt's target/manifest.json — this is our own version stamp for conflict detection on the materialized copy at ~/altimate-sample-dbt/. If you edit any source file below, run ./regenerate.sh and commit the refreshed target/manifest.json alongside your change.",
3
+ "name": "jaffle-shop-duckdb",
4
+ "version": "1.0.0",
5
+ "kind": "altimate-starter-sample",
6
+ "source": "packages/opencode/sample-projects/jaffle-shop-duckdb",
7
+ "requires": {
8
+ "dbt-core": ">=1.7 <2.0",
9
+ "dbt-duckdb": ">=1.7 <2.0"
10
+ },
11
+ "notes": [
12
+ "Renamed profile from the original test fixture: `test_jaffle_shop` → `jaffle_shop`.",
13
+ "DuckDB target file resolves project-relative at `target/jaffle.duckdb`; no host paths bake into the profile.",
14
+ "target/manifest.json ships pre-compiled so static workflows (/discover, /review) work without dbt installed."
15
+ ],
16
+ "$assets_comment": "Single source of truth for the file list shipped to end users. `packages/opencode/src/altimate/onboarding/materialize.ts` copies these into the user's home; `packages/opencode/script/publish.ts` copies the same list into the wrapper npm package at release time; `packages/opencode/test/altimate/onboarding/publish-parity.test.ts` cross-checks both consumers use the same list. Adding a new sample file? Add it here — everything else picks it up automatically.",
17
+ "assets": [
18
+ { "from": "README.md", "kind": "file", "required": true },
19
+ { "from": "dbt_project.yml", "kind": "file", "required": true },
20
+ { "from": "profiles.yml", "kind": "file", "required": true },
21
+ { "from": "sample-manifest.json", "kind": "file", "required": true },
22
+ { "from": ".gitignore", "kind": "file", "required": false },
23
+ { "from": "models", "kind": "dir", "required": true },
24
+ { "from": "seeds", "kind": "dir", "required": true },
25
+ { "from": "target/manifest.json", "kind": "file", "required": true }
26
+ ]
27
+ }
@@ -0,0 +1,4 @@
1
+ id,first_name,last_name
2
+ 1,Alice,Smith
3
+ 2,Bob,Jones
4
+ 3,Carol,White
@@ -0,0 +1,5 @@
1
+ id,customer_id,order_date,amount
2
+ 1,1,2024-01-15,100
3
+ 2,1,2024-02-20,200
4
+ 3,2,2024-01-10,150
5
+ 4,3,2024-03-05,300