返回 CodeWhale
raw-dsh-mcp.test.mjs
根目录 / crates / tui / extension-host / test / raw-dsh-mcp.test.mjs
1 // Real HostRoot/Loader; Core admission is a recorded fake. Rust pool tests are separate.
2 import {test} from 'node:test'
3 import assert from 'node:assert/strict'
4 import {join} from 'node:path'
5 import {mkdtempSync,writeFileSync,rmSync} from 'node:fs'
6 import {tmpdir} from 'node:os'
7 import {startHost,activate,owner,sha256File,FIXTURES} from './harness.mjs'
8 const directory=join(FIXTURES,'raw-dsh-mcp')
9 const entry=tag=>{const path=join(directory,'native',`${tag}.mjs`);return {path,sha256:sha256File(path)}}
10 function plugin(t,body){const dir=mkdtempSync(join(tmpdir(),'cw-mcp-proposal-'));t.after(()=>rmSync(dir,{recursive:true,force:true}));const path=join(dir,'index.mjs');writeFileSync(path,`export const inject=['mcp'];export function apply(ctx){${body}}`);return path}
11
12 test('raw MCP and skills mount with all authored registries under exact sibling scopes',async t=>{
13 const host=await startHost();t.after(()=>host.stop());const ref=owner('raw-dsh-mcp')
14 for(const tag of ['a','b']) {const e=entry(tag);const result=await activate(host,'raw-dsh-mcp',e.path,{owner:ref,scope:e});assert.equal(result.result.status,'ok',result.result.diagnostic)}
15 const registered=host.registry.filter(r=>r.op==='register')
16 assert.deepEqual([...new Set(registered.map(r=>r.kind))].sort(),['command','hook','mcp_server','prompt_section','skill_root','tool'])
17 for(const tag of ['a','b']) {
18 const scoped=registered.filter(r=>r.scope.path===entry(tag).path);assert.equal(scoped.length,6)
19 const mcp=scoped.find(r=>r.kind==='mcp_server');assert.equal(mcp.spec.name,'scoped')
20 assert.deepEqual(JSON.parse(mcp.spec.description),{type:'stdio',command:'node',args:['peer.mjs',tag],env:{},cwd:'source',extensions:{'net.codewhale':{execute_timeout:5}}})
21 assert.equal(scoped.find(r=>r.kind==='skill_root').spec.name,'source/skills')
22 }
23 await host.call('ext/deactivate',{owner:ref,entry:entry('a')})
24 const disposed=new Set(host.registry.filter(r=>r.op==='unregister').map(r=>r.handle))
25 for(const item of registered) assert.equal(disposed.has(item.handle),item.scope.path===entry('a').path)
26 const remaining=registered.find(r=>r.scope.path===entry('b').path&&r.kind==='tool')
27 const result=await host.call('tool/call',{handle:remaining.handle,input:{},call_id:'sibling',deadline_ms:5000});assert.equal(result.content[0].text,'b')
28 })
29
30 test('Core MCP refusal rolls back every mixed graph proposal before failed activation',async t=>{
31 const host=await startHost({admit:spec=>spec.name==='scoped'?{refused:'fixture reviewed definition refused'}:undefined});t.after(()=>host.stop())
32 const e=entry('a');const {ref,result}=await activate(host,'raw-dsh-mcp',e.path,{scope:e})
33 assert.equal(result.status,'failed');assert.match(result.diagnostic,/fixture reviewed definition refused/)
34 await host.call('ext/deactivate',{owner:ref,entry:e})
35 for(const item of host.registry.filter(r=>r.op==='register'&&r.kind!=='mcp_server'))assert.ok(host.registry.some(r=>r.op==='unregister'&&r.handle===item.handle))
36 })
37
38 test('literal credentials and duplicate namespaces fail before transport or credential protocol',async t=>{
39 const host=await startHost();t.after(()=>host.stop())
40 const path=plugin(t,`ctx.mcp.registerServer({serverName:'bad',server:{type:'streamable-http',url:'https://example.invalid/mcp',headers:{Authorization:'fixture-canary'}}})`)
41 const {result}=await activate(host,'credential-refused',path);assert.equal(result.status,'failed');assert.match(result.diagnostic,/Rust authentication authority/)
42 assert.equal(host.registry.length,0);assert.equal(host.coreCalls.length,0);assert.ok(!host.logs.some(r=>r.msg.includes('fixture-canary')))
43 const duplicate=plugin(t,`const definition={serverName:'echo',server:{type:'streamable-http',url:'https://example.invalid/mcp'}};ctx.mcp.registerServer(definition);ctx.mcp.registerServer(definition)`)
44 const failed=await activate(host,'duplicate-mcp',duplicate);assert.equal(failed.result.status,'failed');assert.match(failed.result.diagnostic,/already registered/)
45 await host.call('ext/deactivate',{owner:failed.ref});assert.ok(host.registry.some(r=>r.op==='unregister'))
46 })
47
48 test('a raw Native module cannot install a competing runtimeLoop service',async t=>{
49 const host=await startHost();t.after(()=>host.stop())
50 const path=plugin(t,`ctx.provide('runtimeLoop',{turn(){}})`)
51 const {result}=await activate(host,'runtime-refused',path)
52 assert.equal(result.status,'failed');assert.match(result.diagnostic,/runtimeLoop.*core owns/)
53 assert.equal(host.coreCalls.length,0);assert.equal(host.registry.length,0)
54 })
55
55 lines Plain Text