mirror of
https://github.com/ruvnet/RuView
synced 2026-07-30 18:41:42 +00:00
90b29595fb
Adds the accepted ADR-285 Homecore metaharness, WASM-first kernel, read-only MCP guidance, guarded local host adapters, reviewed memory, and provenance-only npm release gates.
86 lines
2.9 KiB
JavaScript
86 lines
2.9 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { spawn } from 'node:child_process';
|
|
import { dirname, resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { withToolBounds } from '../src/mcp-server.js';
|
|
|
|
const PACKAGE = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
|
test('tool calls fail closed on cancellation and timeout', async () => {
|
|
const controller = new AbortController();
|
|
const cancelled = withToolBounds(new Promise(() => {}), {
|
|
signal: controller.signal,
|
|
timeoutMs: 1_000,
|
|
});
|
|
controller.abort();
|
|
await assert.rejects(cancelled, (error) => error.rpcCode === -32800);
|
|
|
|
await assert.rejects(
|
|
withToolBounds(new Promise(() => {}), { timeoutMs: 10 }),
|
|
(error) => error.rpcCode === -32001,
|
|
);
|
|
});
|
|
|
|
test('MCP server initializes and lists the bounded tool surface', async () => {
|
|
const child = spawn(process.execPath, ['bin/cli.js', 'mcp', 'start'], {
|
|
cwd: PACKAGE,
|
|
env: {
|
|
...process.env,
|
|
METAHARNESS_KERNEL_BACKEND: 'wasm',
|
|
},
|
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
windowsHide: true,
|
|
});
|
|
let stdout = '';
|
|
let stderr = '';
|
|
child.stdout.on('data', (chunk) => { stdout += chunk; });
|
|
child.stderr.on('data', (chunk) => { stderr += chunk; });
|
|
|
|
child.stdin.write(`${'x'.repeat((256 * 1024) + 1)}\n`);
|
|
child.stdin.write('null\n');
|
|
child.stdin.write(`${JSON.stringify({ jsonrpc: '1.0', id: 0, method: 'ping' })}\n`);
|
|
child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', id: {}, method: 'ping' })}\n`);
|
|
child.stdin.write(`${JSON.stringify({
|
|
jsonrpc: '2.0',
|
|
id: 1,
|
|
method: 'initialize',
|
|
params: {
|
|
protocolVersion: '2024-11-05',
|
|
capabilities: {},
|
|
clientInfo: { name: 'test', version: '0' },
|
|
},
|
|
})}\n`);
|
|
child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} })}\n`);
|
|
child.stdin.end();
|
|
|
|
const code = await new Promise((resolveCode, reject) => {
|
|
const timer = setTimeout(() => {
|
|
child.kill();
|
|
reject(new Error(`MCP timeout\n${stderr}`));
|
|
}, 20_000);
|
|
child.once('error', reject);
|
|
child.once('close', (value) => {
|
|
clearTimeout(timer);
|
|
resolveCode(value);
|
|
});
|
|
});
|
|
assert.equal(code, 0, stderr);
|
|
const messages = stdout.trim().split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line));
|
|
assert.equal(messages.filter(({ error }) => error?.code === -32600).length, 3);
|
|
assert.equal(messages.find(({ id }) => id === 1).result.serverInfo.name, 'homecore');
|
|
const tools = messages.find(({ id }) => id === 2).result.tools;
|
|
assert.deepEqual(
|
|
tools.map(({ name }) => name),
|
|
[
|
|
'homecore_guidance',
|
|
'homecore_wasm_status',
|
|
'homecore_doctor',
|
|
'homecore_memory_search',
|
|
],
|
|
);
|
|
assert.equal(tools.some(({ name }) => name === 'homecore_verify'), false);
|
|
assert.match(stderr, /kernel wasm/);
|
|
assert.match(stderr, /oversized JSON-RPC line dropped/);
|
|
});
|