Add macOS companion node status and system.nodes APIs

This commit is contained in:
William Valentin
2026-02-16 12:41:58 -08:00
parent 8a0b4f3dbb
commit bea4c54f3b
14 changed files with 500 additions and 6 deletions
+57
View File
@@ -236,6 +236,8 @@ describe('GatewayServer integration', () => {
expect(methods).toContain('tools.invoke');
expect(methods).toContain('canvas.put');
expect(methods).toContain('canvas.list');
expect(methods).toContain('system.nodes');
expect(methods).toContain('node.status.set');
});
it('supports canvas artifact lifecycle via gateway RPC', async () => {
@@ -752,4 +754,59 @@ describe('GatewayServer node registration and capability negotiation', () => {
}
}
});
it('supports node.status.set and exposes registered nodes via system.nodes', async () => {
if (!LISTEN_ALLOWED) {
return;
}
const ws = await new Promise<WebSocket>((resolve, reject) => {
const c = new WebSocket(`ws://127.0.0.1:${NODE_PORT}`);
c.on('open', () => resolve(c));
c.on('error', reject);
});
try {
const registered = await sendAndReceive(ws, {
id: 20,
method: 'node.register',
params: {
nodeId: 'node-mac',
role: 'companion',
protocolVersion: 1,
capabilities: ['ui.canvas'],
},
});
expect(((registered as GatewayResponse).result as { registered: boolean }).registered).toBe(true);
const status = await sendAndReceive(ws, {
id: 21,
method: 'node.status.set',
params: {
platform: 'macos',
appVersion: '0.3.1',
deviceName: 'MacBook Pro',
batteryPct: 64,
powerSource: 'battery',
},
});
expect(((status as GatewayResponse).result as { updated: boolean }).updated).toBe(true);
const nodes = await sendAndReceive(ws, {
id: 22,
method: 'system.nodes',
params: { role: 'companion', platform: 'macos', limit: 10 },
});
const list = ((nodes as GatewayResponse).result as {
nodes: Array<{ nodeId: string; status?: { platform: string; appVersion?: string } }>;
}).nodes;
expect(list.length).toBeGreaterThanOrEqual(1);
expect(list.some((entry) => entry.nodeId === 'node-mac')).toBe(true);
expect(list.find((entry) => entry.nodeId === 'node-mac')?.status?.platform).toBe('macos');
} finally {
if (ws.readyState === WebSocket.OPEN) {
ws.close();
}
}
});
});