feat: telemetry for the workspace engine
Closes #1512
Stacked on #1511 (usage rows), itself on #1509; review the commit above #1511.
What
The rows that say whether the workspace engine is there for a linked project, and what gets in the way, per the shared event contract.
workspace_engine_attachwhen a session's attach outcome settles and differs from the last one recorded for that session:attached(withavailable,declaredandmissingcounts andengine_version),engine_missing,engine_too_old(found_version),connect_failed(anerror_class),disabled,unbound. A repeated turn boundary with the same outcome reports nothing.workspace_engine_install_prompt:shownonce per offer with the surface that took it (headless,dialog,bus,toast) and whether Node was found to install with (node_detected,node_major); thenaccepted,installed,install_failed,copiedordeclinedfrom the TUI dialog.workspace_engine_precedencewhen a session's precedence snapshot changes: on or off with the reason, counts of shadowed integration types and connections, extensions, and whether the escape hatch is set.workspace_engine_redirectwhen adatamate_managercall is refused because the project is linked (the workspace's engine owns its integrations).workspace_engine_errorwith a stage (attach,install,precedence) and a masked message when the overlay, an install or a precedence derivation throws.
The builders live in altimate/workspace/engine-telemetry.ts; each hook is one call at an existing decision point (the overlay's record, offerOrNotify, the dialog's actions, refresh, refusal). Nothing awaits the network and no tracker can throw into its caller.
Not here: an attach duration (the outcome settles across turn boundaries, so there is no single start to measure from), and a redirect row for a datamate call that runs on the engine (that is an ordinary MCP call, reported as tool_call.via_workspace by #1511).
Why
Linking and usage (#1509, #1511) say a workspace reached the CLI and was used. These rows say whether the engine that serves its integrations was actually available, how the install offer lands, and where it fails: the "what gets in the way" stage of the funnel.
Verification
- New tests: the builders (outcome mapping, change signatures, the install prompt's node fields, the precedence snapshot, masking and bounds), and each hook through the existing fixtures: an attach reported once and again on change, a too-old engine's version, a probe throw as an attach-stage error, the headless and bus
shownevents with node detection, the precedence snapshot deduped per session, the refusal's redirect row. - Workspace, tool and telemetry suites pass;
tsgo --noEmit, oxlint and the marker guard clean.
Review log (claims and residuals Codex reviews against): https://github.com/AltimateAI/altimate-code/pull/1513#issuecomment-6191206918
š¤ Generated with Claude Code
https://claude.ai/code/session_011AhtJPr3nmT1Po92ZQk4VE
Summary by cubic
Adds telemetry for the workspace engine to see whether the engine that serves a linked project's integrations was available, how the install offer lands, and where it fails, alongside the usage rows from #1511.
New events
workspace_engine_attachā one row per session when the attach outcome settles or changes, with counts, the engine version, and the reason when it did not attach. Dedupe uses the account-scoped workspace identity, so a relink or the same id under another account reports again. An unbound row names no workspace explicitly. The in-session retry sentinel reports nothing, and a retry add that throws settles as a connect failure.workspace_engine_install_promptāshownis reported by the surface that rendered the offer (the dialog when it renders, the headless and toast paths when they actually show it, and an attached run that prints the offer it read off the bus), then the user's action, and whether Node was available to install with; an install that throws pastinstallEnginereports the same rows as a reported failure. The bus path'sshownrow carries no node fields, as the probe stays off the publish path.copiedis tracked only when a writer exists and a write-read-back confirms the clipboard holds the command.workspace_engine_precedenceā one row per session when the snapshot changes, with the types the session can route through the engine, the local connections the engine shadows, extensions, and the escape hatch flag; a change in shadowed connection count re-reports it, and dedupe uses the account-scoped workspace identity. A disabled snapshot's row names the linked workspace instead of its own binding.workspace_engine_redirectā adatamate_managercall refused because the project is linked.workspace_engine_errorā attach, install, or precedence failures with masked, bounded messages, including turn-hook attach failures; a precedence error names the refreshed session.
All tracking is fire-and-forget: no tracker awaits the network or throws into its caller, and repeated identical outcomes are not re-reported per session.