diff --git a/packages/dsh-plugin-browserskill/src/index.ts b/packages/dsh-plugin-browserskill/src/index.ts index 28c31f5..59ffe17 100644 --- a/packages/dsh-plugin-browserskill/src/index.ts +++ b/packages/dsh-plugin-browserskill/src/index.ts @@ -77,7 +77,14 @@ export function apply( }); registerTools({ ctx, runner, registry, config: resolved, observation }); - const removeRoutes = registerObservationRoutes(ctx, observation); + // Route registration rides ctx.inject: the webServer service may be provided + // AFTER this plugin loads, and in headless compositions it never appears (the + // callback simply never runs, leaving the rest of the plugin unaffected). + let removeRoutes: () => void = () => {}; + ctx.inject(["webServer"], (injected) => { + removeRoutes = registerObservationRoutes(injected, observation); + return () => removeRoutes(); + }); // Non-blocking install probe: warn early when bsk is missing instead of // failing the first tool call with a bare spawn error. diff --git a/packages/dsh-plugin-browserskill/tests/dispose.test.ts b/packages/dsh-plugin-browserskill/tests/dispose.test.ts index b392adb..6e820de 100644 --- a/packages/dsh-plugin-browserskill/tests/dispose.test.ts +++ b/packages/dsh-plugin-browserskill/tests/dispose.test.ts @@ -65,6 +65,8 @@ describe("dispose cleanup ownership", () => { const ctx = { tools: { register: (def: ToolDefinition) => tools.set(def.name, def) }, get: () => undefined, + // No webServer in this harness: the inject callback never runs. + inject: () => {}, effect: (fn: () => () => Promise) => { disposers.push(fn()); },