fix: list and count extension-type integrations when a live IDE bridge serves them

Merged
RA
2mo ago
+404-15

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-integrations output and metadata are bridge-conditional: bridge: true lists and counts extension rows; bridge: false omits 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 uses path.relative prefix semantics, not the engine's platform-aware pathMatch normalization (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-integrations call (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.ts flakes 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:

  1. Engine discovered the sidecar, connected, registered 15 remote tools; the allowlist passed them into the session.
  2. datamate_compile_model returned the compiled SQL; datamate_run_model materialized 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).
  3. 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.