fix: list and count extension-type integrations when a live IDE bridge serves them
Issue for this PR
Closes AltimateAI/altimate-code#1235
Type of change
- Bug fix
- New feature
- Refactor / code improvement
- Documentation
What does this PR do?
Extension-type integrations were presented as categorically unusable from the CLI ("not available from the CLI"). They aren't: with VS Code + the Altimate extension open on the project, the workspace engine discovers the bridge over the ~/.altimate/extension-rpc/ sidecars, allowlists the extension tools into the session, and serves them. This PR makes the three presentation surfaces say what is actually true — no serving/allowlist/overlay behavior changes, only strings, listing rows, and metadata.
datamate_manager list-integrations— with a live bridge for this project, extension-type rows are listed, marked "(via VS Code)" and counted; without one they stay omitted, with copy that says they serve while VS Code with the Altimate extension is open on this project instead of "not available from the CLI".- Workspace attach announcement — appends "Plus N extension tools via the connected VS Code window" when the bridge is serving them. Their absence stays unwarned: that is the normal no-IDE case, never
missing. - New
liveBridge()probe (engine-probes) — a read-only mirror of the engine's sidecar discovery: cwd prefix match, else the sole live bridge; dead pids skipped, never unlinked (stale-sidecar GC stays with the engine and the extension). This works because presentation only needs the same answer the engine will reach at spawn time, without connecting.
Claims
- C1 —
list-integrationsoutput and metadata are bridge-conditional:bridge: truelists and counts extension rows;bridge: falseomits them with the "serve while VS Code … is open" copy. The absolute "not available from the CLI" copy is gone. - C2 — The bridge probe never mutates the sidecar directory: dead-pid and unreadable sidecars are skipped, not unlinked.
- C3 — Bridge resolution mirrors the engine's spawn-time discovery semantics: cwd-within-folder match first, else exactly one live bridge; two live non-matching bridges decline.
- C4 — The attach announcement counts extension tools as served only when they are present in the engine's tool list; declared-but-absent extension keys never enter
missing, never warn, and produce no "Plus…" clause. - C5 — A catalog with no extension-type rows never probes for a bridge.
- C6 — No behavioral change to tool serving, the allowlist, or the overlay: every change is presentation (strings, listing rows, metadata fields
bridge/hidden).
Residuals
- R1 —
liveBridge()path matching usespath.relativeprefix semantics, not the engine's platform-awarepathMatchnormalization (lowercase Windows drive letters). Presentation-only divergence; a Windows cwd/sidecar case mismatch shows the dormant copy while the engine still connects. - R2 — The probe reads the sidecar directory on every
list-integrationscall (no cache). The directory holds a handful of small files; not worth a TTL. - R3 — The awareness system-prompt section still projects only non-extension keys; teaching it bridge-served extension tools is follow-up scope, not presentation copy.
- R4 —
test/altimate/tracing-finalize-sync.test.tsflakes locally on the dev rig (mtime resolution; pre-existing, untouched by this diff).
How did you verify your code works?
End-to-end on a live rig (2026-09-03), which is also why the old copy is wrong: VS Code (WSL) + Altimate extension 0.8.12 + Power User for dbt 0.64.4 on a bound dbt project (snowflake profile), headless workspace-mode run:
- Engine discovered the sidecar, connected, registered 15 remote tools; the allowlist passed them into the session.
datamate_compile_modelreturned the compiled SQL;datamate_run_modelmaterialized the model on the warehouse (dbt 1.11.7 + snowflake 1.11.3,1 of 1 OK created sql view model DBT_CI_SCRATCH.answer … SUCCESS 1).- The workspace's server-side snowflake integration read the created view back in the same session:
[{"ANSWER": 42}].
Unit tests for every claim: liveBridge (cwd match incl. sibling-prefix negative, dead-pid skip + file preserved, single-bridge fallback vs two-bridge decline, garbage handling), list-integrations (bridged listing/marking/counting, unbridged copy, no-extension catalog never probes), overlay ("Plus 1 extension tool…" appended, absent extension key not missing, variant stays info). bun test test/altimate: my files green across three runs; tsgo --noEmit clean.
Screenshots / recordings
Not a UI change (CLI copy and toast text); before/after strings are quoted above.
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
🤖 Generated with Claude Code
https://claude.ai/code/session_01MaT4GH2aCGEmTg6bBPZBeU
Summary by CodeRabbit
-
New Features
- Extension integrations now appear when a live VS Code connection is detected for the project.
- Integration listings show connection status and identify tools provided through VS Code.
- Workspace tool summaries distinguish available extension tools from unavailable tools.
-
Bug Fixes
- Extension tools unavailable without a live connection are no longer incorrectly reported as missing.
- Stale, invalid, or ambiguous connection records are ignored when determining availability.
- Workspace and connection detection is more reliable across supported path formats.
-
Tests
- Added coverage for connection detection, integration visibility, status metadata, and workspace tool reporting.