src/orchestrator/plugin.ts — the VxPlugin interface + installer
Purpose
Section titled “Purpose”The integration seam. A plugin declares a name plus at least one
capability; defineWorkspace({ plugins: [...] }) activates it. Core
consults capabilities at fixed points and otherwise ignores plugins —
behavior lives in the plugin package (vite-style), not in core.
Capabilities
Section titled “Capabilities”| Capability | Consulted by | Contract |
|---|---|---|
backend(ctx) | cli/run.ts | return a RunBackend or decline |
cache(ctx) | run setup | return a CacheLayer wrapper or decline |
telemetry(ctx) | telemetry-host.ts | return sink(s) or decline |
eventSink(ctx) | plugin-host.ts | raw WireEvent consumer |
setup(ctx) | installPlugins | validate config; throw UserError |
teardown() | end-of-run | flush/close; crash-isolated, 3s-bounded |
Invariants
Section titled “Invariants”- Decline-fast: every capability must return
undefinedcheaply when unconfigured — a plain run with declared-but-unconfigured plugins is zero-overhead (measured ~116ms unchanged). setupthrows fail the run with a clean error naming the plugin; everything else is crash-isolated (observability never breaks a run).teardown()andEventSink.flush()ARE invoked at end-of-run (since 2026-07) — plugins may rely on them to drain buffers.