fix(cli): address review feedback on agent-view supervisor (#7799)

This commit is contained in:
qwen-code-ci-bot 2026-07-28 17:10:33 +00:00
parent d4c3f0f7e1
commit 214a1cffd1
5 changed files with 45 additions and 29 deletions

View file

@ -378,8 +378,15 @@ export function subscribeAgentViewSupervisor(
let response: AgentViewSupervisorResponse;
try {
response = parseSupervisorResponse(line);
} catch {
continue;
} catch (parseError) {
notifySubscriptionError(
new AgentViewSupervisorClientError(
`Invalid subscription response: ${parseError instanceof Error ? parseError.message : String(parseError)}`,
'invalid_response',
),
);
socket.destroy();
return;
}
if (!response.ok) {
notifySubscriptionError(

View file

@ -144,16 +144,16 @@ class AgentViewSupervisorProcessHandler
}
async tickIdleHibernation(): Promise<AgentViewSupervisorMaintenanceResult> {
if (this.options.hibernationPolicy?.enabled === false) {
return { hibernated: [], shutdownRequested: false };
}
const states = await listAgentViewSessionStates(this.store);
if (this.shouldAutoExit(states)) {
void this.options.onShutdown?.();
return { hibernated: [], shutdownRequested: true };
}
if (this.options.hibernationPolicy?.enabled === false) {
return { hibernated: [], shutdownRequested: false };
}
return { hibernated: [], shutdownRequested: false };
}

View file

@ -167,6 +167,12 @@ describe('Agent View supervisor runner', () => {
result: { subscribed: true },
})}\n`,
);
socket.write(
`${JSON.stringify({
type: 'changed',
at: '2026-07-17T00:00:00.000Z',
})}\n`,
);
}),
dispatch: vi.fn(() => ({ sessionId: 'session-2' })),
adopt: vi.fn(() => ({ sessionId: 'session-2', adopted: true })),
@ -199,8 +205,14 @@ describe('Agent View supervisor runner', () => {
]);
expect(handler.list).toHaveBeenCalledWith({ cwd: '/workspace/project' });
const subscription = handle.subscribe(() => {});
const eventCallback = vi.fn();
const subscription = handle.subscribe(eventCallback);
await waitFor(() => handler.subscribe.mock.calls.length === 1);
await waitFor(() => eventCallback.mock.calls.length === 1);
expect(eventCallback).toHaveBeenCalledWith({
type: 'changed',
at: '2026-07-17T00:00:00.000Z',
});
subscription.dispose();
await expect(

View file

@ -502,27 +502,13 @@ function normalizeWorker(
return {
...raw,
schemaVersion: 1,
...(numberValue(raw['hostPid'])
? { hostPid: numberValue(raw['hostPid']) }
: {}),
...(numberValue(raw['workerPid'])
? { workerPid: numberValue(raw['workerPid']) }
: {}),
...(stringValue(raw['endpoint'])
? { endpoint: stringValue(raw['endpoint']) }
: {}),
...(stringValue(raw['hostEndpoint'])
? { hostEndpoint: stringValue(raw['hostEndpoint']) }
: {}),
...(stringValue(raw['hostAuthToken'])
? { hostAuthToken: stringValue(raw['hostAuthToken']) }
: {}),
...(stringValue(raw['tokenDigest'])
? { tokenDigest: stringValue(raw['tokenDigest']) }
: {}),
...(stringValue(raw['lastHeartbeatAt'])
? { lastHeartbeatAt: stringValue(raw['lastHeartbeatAt']) }
: {}),
hostPid: numberValue(raw['hostPid']),
workerPid: numberValue(raw['workerPid']),
endpoint: stringValue(raw['endpoint']),
hostEndpoint: stringValue(raw['hostEndpoint']),
hostAuthToken: stringValue(raw['hostAuthToken']),
tokenDigest: stringValue(raw['tokenDigest']),
lastHeartbeatAt: stringValue(raw['lastHeartbeatAt']),
protocolVersion: numberValue(raw['protocolVersion']) ?? 1,
platform: platformValue(raw['platform']),
recentOutputBytes: numberValue(raw['recentOutputBytes']) ?? 0,
@ -609,8 +595,18 @@ function terminalValue(value: unknown): AgentViewLaunchFile['terminal'] {
};
}
const KNOWN_PLATFORMS: ReadonlySet<string> = new Set([
'aix',
'darwin',
'freebsd',
'linux',
'openbsd',
'sunos',
'win32',
]);
function platformValue(value: unknown): NodeJS.Platform {
return typeof value === 'string'
return typeof value === 'string' && KNOWN_PLATFORMS.has(value)
? (value as NodeJS.Platform)
: process.platform;
}

View file

@ -121,6 +121,7 @@ async function pumpInputToPty(
}
await pty.write(toBuffer(next.value));
}
detached = true;
return 'detached';
} finally {
const returned = iterator.return?.();