mirror of
https://github.com/ruvnet/RuView.git
synced 2026-10-22 06:32:35 -05:00
- harness/ruview-umbrella -> npm `ruview` 0.8.0: one CLI and one MCP server for the operator harness, Homecore and the vitals kernel. `ruview homecore ...`, `ruview kernel <doctor|info|selftest|parity|synth|analyze|bench>`, `ruview capabilities`; everything else delegates to @ruvnet/ruview. MCP serves ruview_* + homecore_* tools and the ui:// console (stdio + HTTP). - @ruvnet/ruview 0.8.0: bin renamed `ruview-harness` (the umbrella owns `ruview`; a clean tarball install showed the bin collision). New exports (cli, cli-ui, mcp, mcp-http, ui, esphome, kernel); injectable MCP handler; kernel as optional peer + setKernelImporter so the kernel resolves from the umbrella's tree under linked/pnpm installs. - mmwave --source esphome: dependency-free read-only ESPHome native API client (private hosts only; encrypted/password APIs reported). Live Seeed MR60BHA2 kit: presence, distance, device-reported HR/BR (MEASURED). - monitor detects Ameba CSI buffer starvation; radar views in terminal UI and console widget. - homecore 0.1.0 and @ruvnet/ruview-kernel 0.1.0 gain ./cli exports. Gates: harness 166 + 89 security, homecore 27 + 23, kernel 21 + 12, umbrella 4; clean-dir tarball install smoke incl. live radar over HTTP MCP. Local publish is a one-off exception to ADR-265 D2, recorded in ADR-376. Co-Authored-By: claude-flow <ruv@ruv.net>
75 lines
4.0 KiB
JavaScript
75 lines
4.0 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { importKernelPackage, kernelSelfTest, KERNEL_PACKAGE, setKernelImporter } from '../src/kernel.js';
|
|
import { authorizeTool } from '../src/policy.js';
|
|
import { runTool } from '../src/tools.js';
|
|
|
|
const fakeKernel = (overrides = {}) => ({
|
|
loadKernel: ({ backend }) => ({ backend: backend === 'auto' ? 'wasm' : backend, requestedBackend: backend, fallbackReason: backend === 'auto' ? 'no addon' : null, integrity: 'verified', sha256: 'ab' }),
|
|
selfTest: (kernel, { seconds }) => ({ ok: true, evidence: 'SYNTHETIC', backend: kernel.backend, seconds }),
|
|
...overrides,
|
|
});
|
|
|
|
test('kernel self-test fails closed when the optional package is absent', async () => {
|
|
const result = await kernelSelfTest({}, { importer: async () => { const e = new Error('nope'); e.code = 'ERR_MODULE_NOT_FOUND'; throw e; } });
|
|
assert.equal(result.ok, false);
|
|
assert.equal(result.reason, 'kernel_not_installed');
|
|
assert.match(result.remedy, /@ruvnet\/ruview-kernel/);
|
|
});
|
|
|
|
test('kernel self-test only imports the fixed package name', async () => {
|
|
const seen = [];
|
|
const result = await kernelSelfTest({ backend: 'auto', seconds: 45 }, { importer: async (s) => { seen.push(s); return fakeKernel(); } });
|
|
assert.deepEqual(seen, [KERNEL_PACKAGE]);
|
|
assert.equal(result.ok, true);
|
|
assert.equal(result.backend, 'wasm');
|
|
assert.equal(result.requestedBackend, 'auto');
|
|
assert.equal(result.fallbackReason, 'no addon');
|
|
assert.equal(result.seconds, 45);
|
|
assert.equal(result.evidence, 'SYNTHETIC');
|
|
});
|
|
|
|
test('kernel self-test reports load failures and incompatible packages honestly', async () => {
|
|
const failing = fakeKernel({ loadKernel: () => { const e = new Error('no addon'); e.code = 'backend_unavailable'; throw e; } });
|
|
const r1 = await kernelSelfTest({ backend: 'napi' }, { importer: async () => failing });
|
|
assert.deepEqual([r1.ok, r1.reason, r1.requestedBackend], [false, 'backend_unavailable', 'napi']);
|
|
const r2 = await kernelSelfTest({}, { importer: async () => ({}) });
|
|
assert.deepEqual([r2.ok, r2.reason], [false, 'kernel_incompatible']);
|
|
});
|
|
|
|
test('kernel tool is read-only for MCP and rejects module/path injection', async () => {
|
|
assert.equal(authorizeTool('ruview_kernel_selftest', {}, { source: 'mcp', grants: [] }).ok, true);
|
|
for (const args of [{ module: 'fs' }, { wasm_path: '/tmp/x.wasm' }, { backend: 'python' }, { seconds: 5 }]) {
|
|
const result = await runTool('ruview_kernel_selftest', args, { source: 'mcp' });
|
|
assert.equal(result.reason, 'invalid_arguments', JSON.stringify(args));
|
|
}
|
|
});
|
|
|
|
// Cross-package end-to-end (ADR-368). CI installs the packed
|
|
// @ruvnet/ruview-kernel tarball with `npm install --no-save` before this runs;
|
|
// elsewhere the package is optional and the fail-closed path is covered above.
|
|
let installed = false;
|
|
try { await import(KERNEL_PACKAGE); installed = true; } catch { /* optional */ }
|
|
|
|
test('installed kernel passes its SYNTHETIC self-test through the harness tool', { skip: !installed && `${KERNEL_PACKAGE} not installed` }, async () => {
|
|
const result = await runTool('ruview_kernel_selftest', { backend: 'wasm', seconds: 45 }, { source: 'mcp', grants: [] });
|
|
assert.equal(result.ok, true, JSON.stringify(result.checks));
|
|
assert.equal(result.backend, 'wasm');
|
|
assert.equal(result.evidence, 'SYNTHETIC');
|
|
assert.equal(result.integrity, 'verified');
|
|
});
|
|
|
|
test('an embedding package can supply the kernel importer (ADR-376)', async () => {
|
|
const seen = [];
|
|
setKernelImporter(async (specifier) => { seen.push(specifier); return { loadKernel: () => { throw Object.assign(new Error('stub'), { code: 'backend_unavailable' }); }, selfTest: () => ({}) }; });
|
|
try {
|
|
await importKernelPackage();
|
|
const r = await kernelSelfTest({ backend: 'wasm' });
|
|
assert.deepEqual(seen, [KERNEL_PACKAGE, KERNEL_PACKAGE]);
|
|
assert.equal(r.reason, 'backend_unavailable');
|
|
assert.throws(() => setKernelImporter('not a function'), /importer must be a function/);
|
|
} finally {
|
|
setKernelImporter((specifier) => import(specifier));
|
|
}
|
|
});
|