diff --git a/packages/cli/src/serve/server.test.ts b/packages/cli/src/serve/server.test.ts index 77ba324a8bd..d5cc3a95715 100644 --- a/packages/cli/src/serve/server.test.ts +++ b/packages/cli/src/serve/server.test.ts @@ -6036,6 +6036,68 @@ describe('createServeApp', () => { expect(managed.body.features).toContain('scheduled_task_session_reuse'); }); + it('advertises workspace runtime stop only with the full managed stop wiring', async () => { + const bridge = Object.assign(fakeBridge(), { + stopWorkspaceRuntime: vi.fn(), + getRuntimeStopCompletion: vi.fn(), + getRuntimeStopSnapshot: vi.fn(), + }); + const workspaceRegistry = createWorkspaceRegistry([ + makeWorkspaceRuntimeForTest({ + workspaceId: 'primary-id', + workspaceCwd: WS_BOUND, + primary: true, + bridge, + }), + ]); + const runtimeRemoval = { + beginDrain: vi.fn(), + cancelDrain: vi.fn(), + completeDrain: vi.fn(), + disposeRuntime: vi.fn().mockResolvedValue(undefined), + getActivity: vi.fn(() => ({ + pendingSessionStarts: 0, + channelWorkers: 0, + voiceSessions: 0, + })), + }; + const wiredDeps = { + bridge, + workspaceRegistry, + managedChildProcesses: { + registry: new ProcessRegistry(), + policy: createChildHeapPolicy({ + budget: resolveDaemonMemoryBudget({ availableMemoryMb: 2048 }), + mode: 'admit', + }), + }, + workspaceRuntimeRemoval: runtimeRemoval, + voiceCoordinator: new WorkspaceVoiceCoordinator(), + getSessionBridges: () => [bridge], + manageScheduledTaskSessions: true, + }; + + // Every leg of the boot-time conjunction is present: the capabilities + // route must advertise the stop surface from that production wiring. + const wired = await request( + createServeApp(baseOpts, undefined, wiredDeps), + ) + .get('/capabilities') + .set('Host', `127.0.0.1:${baseOpts.port}`); + expect(wired.body.features).toContain('workspace_runtime_stop'); + + // Drop exactly one required leg and the same route must stop + // advertising it, so a regression in any single leg is observable. + const { manageScheduledTaskSessions: _dropped, ...partialDeps } = + wiredDeps; + const missingLeg = await request( + createServeApp(baseOpts, undefined, partialDeps), + ) + .get('/capabilities') + .set('Host', `127.0.0.1:${baseOpts.port}`); + expect(missingLeg.body.features).not.toContain('workspace_runtime_stop'); + }); + it('refuses scheduled task sessions in the Hosted Harness profile', () => { expect(() => createServeApp(