Skip to content
2 changes: 2 additions & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@sigstore/bundle": "5.0.0",
"@sigstore/tuf": "5.0.0",
"@sigstore/verify": "4.1.2",
"ajv": "^8.20.0",
"electron-updater": "^6.8.9",
"node-pty": "^1.2.0-beta.15",
"qrcode": "^1.5.4",
Expand All @@ -84,6 +85,7 @@
"@types/react-dom": "^19.2.4",
"@types/ws": "^8.18.1",
"@vitejs/plugin-react": "^6.1.0",
"ai": "7.0.70",
"@xterm/addon-fit": "^0.11.0",
"@xterm/xterm": "^6.0.0",
"electron": "43.4.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,30 +544,29 @@ test('rolls back only candidate-owned IPC after a registration collision', async
assert.equal(host.closeCalls, 1);
});

test('closes the claimed Host connection when native capability construction fails', async () => {
test('does not drop the Host connection when a native tool schema is invalid', async () => {
// Per-tool isolation: one bad tool is skipped and the provider still
// constructs, so the Host connection stays alive.
const ipc = ipcHarness();
const host = connectionHarness('invalid-capability');
const invalidTool = {
...nativeTool(),
parameters: z.string(),
} as unknown as MakaTool;

await assert.rejects(
() =>
createDesktopRuntimeHostCandidate(
host.connection,
deps(ipc, {
browserTools: [invalidTool],
resolveBrowserUrl: () => 'https://example.com/',
releaseBrowserSession() {},
computerUseTools: emptyComputerUseTools(),
releaseComputerUseSession() {},
}),
),
/tool schema must be an object/,
const candidate = await createDesktopRuntimeHostCandidate(
host.connection,
deps(ipc, {
browserTools: [invalidTool],
resolveBrowserUrl: () => 'https://example.com/',
releaseBrowserSession() {},
computerUseTools: emptyComputerUseTools(),
releaseComputerUseSession() {},
}),
);

assert.equal(ipc.size, 0);
assert.equal(host.closeCalls, 0);
await candidate.close();
assert.equal(host.closeCalls, 1);
});

Expand Down
Loading
Loading