Repository navigation
Commit dd7d1e5
committed
feat(workspace): attach the bound workspace's integration engine
Integrations are served by the local datamate engine — the same process the VS
Code extension spawns as `datamate start-stdio`. Altimate Code could reuse an
entry an IDE had already written, but could not acquire an engine on its own:
with no entry present it fell through to the hosted SSE endpoint, which runs in
multi-user mode and serves a DIFFERENT tool set (no connection validation, no
extension-bridge tools, server-side cwd). A terminal session in a bound project
therefore had either the IDE's tools or the wrong ones.
`workspace/engine-sync.ts` closes that gap with `ensure(sessionID)`, idempotent
per session and gated on the workspace pilot flag. Its rules, in order:
**Reuse.** A connected `datamate` MCP entry wins — that is an IDE-written or
previously persisted entry, and attaching to it is free. If it is down, what it
is decides what happens next. A URL entry is an IDE's in-process engine or the
hosted endpoint; neither can be revived from here, so with a binding and a
usable engine on PATH we spawn locally and report what was replaced. The IDE's
own config is never touched. A command entry that failed is retried once, then
reported — spawning a second engine beside a failing one is the duplicate-process
problem the single-gateway design exists to avoid.
**Opportunistic use, never an install.** A `datamate` on PATH whose `--version`
clears the floor is spawned as `datamate start-stdio --datamate <id>`, pinned to
the bound workspace and persisted to the project config so later sessions start
it at boot. With no engine present the user is told which workspace tools are
unavailable and how to install one; the CLI ships as a self-contained binary
with no Node runtime, so it must not pull one in.
**Never fall back to hosted on failure.** The local and hosted tool sets diverge
in both directions, so a silent fallback would change the workspace's declared
contract. A failed engine is reported, not routed around.
**Report what was declared but not delivered.** The engine intersects the
workspace allowlist with what it managed to build and says nothing about the
difference; this diffs declared keys against the tools that actually arrived and
surfaces the gap.
**First-turn readiness.** A turn resolves its tool list before the per-turn work
that starts the attach, so a session that spawned its own engine listed the
engine's tools one turn late — the model saw `datamate_manager` alone on the
first turn and the integration tools only from the second. The attach now starts
ahead of tool resolution and `whenAttached` gives it a bounded window, so those
tools make the first tool list. A cold attach measures ~6.5s (≈1s to probe
`--version`, ≈1s for the declared allowlist, ≈4.5s for the engine to boot,
handshake and build its tools), against a 15s cap set well clear of that and far
below MCP's own 30s connect timeout. Past the cap the turn proceeds and
`tools/list_changed` delivers the tools when they land. Unbound and disabled
sessions settle without I/O and wait for nothing.
`datamate_manager list-integrations` now hides extension-type integrations,
which are RPC into a live VS Code host and have no meaning on the CLI surface,
and reports how many it hid rather than pretending they do not exist.
Inert without a local binding. 21 unit tests cover the decision logic through
the `syncInternals` seams.1 parent 8e76c90 commit dd7d1e5
5 files changed
Lines changed: 814 additions & 3 deletions
File tree
- packages/opencode
- src
- altimate
- api
- tools
- workspace
- session
- test/altimate/workspace
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
40 | 45 | | |
41 | 46 | | |
42 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
141 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
142 | 149 | | |
143 | 150 | | |
144 | 151 | | |
145 | | - | |
| 152 | + | |
146 | 153 | | |
147 | 154 | | |
148 | 155 | | |
| |||
151 | 158 | | |
152 | 159 | | |
153 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
154 | 169 | | |
155 | 170 | | |
156 | | - | |
| 171 | + | |
157 | 172 | | |
158 | 173 | | |
159 | 174 | | |
| |||
0 commit comments