// Isolated production IPC/persistence, real file tools, Gateway, SDK MCP and actual OMP. import fs from 'node:fs/promises' import path from 'node:path' import assert from 'node:assert/strict' import { pathToFileURL } from 'node:url' import { createServer } from 'node:http' import { build } from 'esbuild' const directory = await fs.mkdtemp(path.resolve('.tmp/mode-policy-')) const userData = path.join(directory, 'data'), cwd = path.join(directory, 'workspace'), ompHome = path.join(directory, 'omp-home') await Promise.all([userData, cwd, ompHome].map(p => fs.mkdir(p))) await fs.writeFile(path.join(cwd, 'seed.txt'), 'MODE_READ_PROOF') await Promise.all(['.git', 'node_modules'].map(p => fs.mkdir(path.join(cwd, p)))) const checks = [], requests = [], engineResults = [], handlers = new Map() const state = globalThis.__YCODE_MODE_QA__ = { userData, cwd, handlers, expertWrites: 0, activations: 0 } const previousOmpHome = process.env.YCODE_OMP_HOME process.env.YCODE_OMP_HOME = ompHome const check = (name, actual, expected = true) => { assert.deepEqual(actual, expected, name); checks.push(name) } const electronSource = `const s=globalThis.__YCODE_MODE_QA__;export const app={getPath:n=>n==='home'?s.cwd:s.userData,getName:()=>'YCode',getVersion:()=>'0.1.0'};export const safeStorage={isEncryptionAvailable:()=>false,encryptString:v=>Buffer.from(v),decryptString:v=>v.toString()};export const ipcMain={handle:(n,f)=>s.handlers.set(n,f)};export const dialog={showOpenDialog:async()=>({canceled:true,filePaths:[]})};export const shell={openPath:async()=>''};export class BrowserWindow{};export class WebContentsView{}` const plugins = [{ name: 'isolated-electron', setup(b) { b.onResolve({ filter: /^electron$/ }, () => ({ path: 'electron', namespace: 'mode-qa' })) b.onLoad({ filter: /.*/, namespace: 'mode-qa' }, () => ({ contents: electronSource, loader: 'js' })) b.onResolve({ filter: /^\.\/terminal-host$/ }, () => ({ path: 'terminal', namespace: 'mode-no-terminal' })) b.onLoad({ filter: /.*/, namespace: 'mode-no-terminal' }, () => ({ contents: `const no=()=>{throw Error('Unexpected native terminal')};export const createTerminal=no,getTerminal=no,writeTerminal=no,resizeTerminal=no,clearTerminal=no,closeTerminal=no,rebindTerminal=no,disposeTerminalHosts=no`, loader: 'js' })) // Expert activation is controlled here; production mode validation and atomic session writes run unchanged. b.onResolve({ filter: /(?:^\.\/capabilities\/experts$|^\.\/experts$)/ }, () => ({ path: 'experts', namespace: 'mode-experts' })) b.onLoad({ filter: /.*/, namespace: 'mode-experts' }, () => ({ contents: `const s=globalThis.__YCODE_MODE_QA__;export async function activateExpert(id){s.activations++;return{id}};export function expertManagerDocument(){return{content:'Controlled manager'}};export const expertManagerAdapter=()=>'',expertManagerResource=()=>'';export async function expertPackageOperation(){s.expertWrites++;return{success:true}};export const expertTurnContext=async()=>undefined;export const listExperts=async()=>[],readExpert=async()=>({}),removeExpert=async()=>{},expertPackageOperationTool=()=>{},disposeExperts=async()=>{},subscribeExperts=()=>()=>{},installExpertFromPath=async()=>{},openExpertPath=async()=>{}`, loader: 'js' })) } }] await build({ stdin: { contents: `export {registerIpc,disposeOmpKernels} from './src/main/ipc';export * as sessions from './src/main/sessions';export * as config from './src/main/config';export * as workspaces from './src/main/workspaces';export * as mcp from './src/main/capabilities/mcp';export {createCapabilitySnapshot} from './src/main/capabilities/runtime';export {runTurn} from './src/main/agent/loop';export {runOmpTurn} from './src/main/agent/omp-turn';export {executeConversationTool,executeTurnTool} from './src/main/agent/conversation-tools';export * as policy from './src/main/agent/mode-policy';export {Gateway} from './src/main/gateway';export {OmpKernel,detectOmpPath} from './src/main/omp';export {prepareOmpModel} from './src/main/omp-model'`, resolveDir: process.cwd() }, outfile: path.join(directory, 'runtime.mjs'), bundle: true, platform: 'node', format: 'esm', packages: 'external', plugins, logLevel: 'silent' }) const api = await import(pathToFileURL(path.join(directory, 'runtime.mjs')).href) let upstream, kernel const invoke = (name, ...args) => handlers.get(name)({}, ...args) try { await api.config.setWorkspaceRoot(cwd) api.registerIpc(() => ({ webContents: { send() {} } })) const session = await invoke('session:create', 'mode fixture', { agentMode: 'plan' }) check('IPC create persists plan', session.agentMode, 'plan') check('plan creation clears expert', session.expertId, null) await assert.rejects(invoke('session:create', 'bad', { agentMode: 'unknown' }), /无效的对话模式/); checks.push('invalid create mode rejected') await assert.rejects(invoke('session:update-context', session.id, { agentMode: null }), /无效的对话模式/); checks.push('invalid IPC update rejected') check('invalid mode leaves old mode', (await api.sessions.getSessionContext(session.id)).agentMode, 'plan') await invoke('session:update-context', session.id, { expertId: 'controlled-expert' }) check('expert selection restores craft', (await api.sessions.getSessionContext(session.id)).agentMode, 'craft') await invoke('session:update-context', session.id, { agentMode: 'ask' }) const askContext = await api.sessions.getSessionContext(session.id) check('existing conversation enters ask and clears expert atomically', [askContext.agentMode, askContext.expertId], ['ask', null]) await Promise.all([invoke('session:update-context', session.id, { agentMode: 'plan' }), invoke('session:update-context', session.id, { agentMode: 'ask' })]) check('serialized mode mutations keep latest request', (await api.sessions.getSessionContext(session.id)).agentMode, 'ask') const disk = JSON.parse(await fs.readFile(path.join(userData, 'sessions.json'), 'utf8')) check('mode and expert clear reach real sessions JSON', [disk.sessions[0].agentMode, disk.sessions[0].expertId], ['ask', null]) const refreshed = await import(pathToFileURL(path.join(directory, 'runtime.mjs')).href + '?reload=1') check('fresh module hydrates persisted mode', (await refreshed.sessions.getSessionContext(session.id)).agentMode, 'ask') const listing = await invoke('resources:list', session.id, 'intentionally-invalid-workspace') check('resources list prioritizes session root', listing.some(x => x.name === 'seed.txt')) check('resources list excludes hidden dependency roots', !listing.some(x => ['.git', 'node_modules'].includes(x.name))) await assert.rejects(invoke('resources:list', undefined, 'invalid-id'), /空间不存在/); checks.push('resource registry id cannot become arbitrary root') await assert.rejects(invoke('resources:list', 'invalid-session', undefined), /会话不存在/); checks.push('invalid session cannot fall back to a global resource root') const ctx = { runId: 'mode-qa', toolCallId: 'mode-tool', workspaceRoot: cwd, permissionMode: 'full-access', signal: new AbortController().signal, emit() {} } for (const agentMode of ['plan', 'ask']) { check(agentMode + ' reads real file', (await api.executeConversationTool('read_file', { path: 'seed.txt' }, { ...ctx, agentMode })).content.includes('MODE_READ_PROOF')) for (const name of ['write_file', 'edit_file', 'execute_command', 'mcp_unknown', 'ycode_expert_package', 'unknown_tool']) { const result = await api.executeConversationTool(name, { path: 'seed.txt', content: 'BAD', oldText: 'MODE_READ_PROOF', newText: 'BAD', command: 'echo BAD', action: 'write' }, { ...ctx, agentMode }) check(agentMode + ' execution denies ' + name, result.ok, false) } check(agentMode + ' todo policy', (await api.executeConversationTool('create_plan', { steps: ['Inspect'] }, { ...ctx, agentMode })).ok, agentMode === 'plan') } check('readonly tool denials leave real source file unchanged', await fs.readFile(path.join(cwd, 'seed.txt'), 'utf8'), 'MODE_READ_PROOF') const saved = await api.mcp.saveMcpServer({ name: 'mode-fixture', transport: 'stdio', command: process.execPath, args: [path.resolve('scripts/test-mcp-server.mjs'), 'stdio', path.join(directory, 'mcp-events.jsonl')] }) await api.mcp.trustMcpServer(saved.id, saved.configHash); await api.mcp.setMcpEnabled(saved.id, true) const craftSnapshot = await api.createCapabilitySnapshot(['builtin:expert-manager'], cwd, { sessionId: session.id, agentMode: 'craft' }) const mcpName = craftSnapshot.specs.find(x => x.function.name.startsWith('mcp_echo_')).function.name for (const agentMode of ['plan', 'ask']) { const snap = await api.createCapabilitySnapshot([], cwd, { sessionId: session.id, agentMode }) check(agentMode + ' hides SDK MCP and expert package tool', !snap.specs.some(x => x.function.name === mcpName || x.function.name === 'ycode_expert_package')) check(agentMode + ' direct capability invocation blocked despite forged craft ctx', (await snap.execute(mcpName, { text: 'BAD' }, { ...ctx, agentMode: 'craft' })).ok, false) check(agentMode + ' blocks craft snapshot before dynamic dispatch', (await api.executeTurnTool(mcpName, { text: 'BAD' }, { ...ctx, agentMode }, craftSnapshot)).ok, false) check(agentMode + ' blocks expert package register before dispatch', (await api.executeTurnTool('ycode_expert_package', { id: 'bad', action: 'register' }, { ...ctx, agentMode }, craftSnapshot)).ok, false) } check('expert package mutation never reached service', state.expertWrites, 0) const noCalls = (await fs.readFile(path.join(directory, 'mcp-events.jsonl'), 'utf8')).trim().split('\n').map(JSON.parse) check('restricted requests never reached actual SDK callTool', noCalls.filter(x => x.type === 'call').length, 0) let phase = '', round = 0 const attackCalls = () => [ { name: 'read_file', args: { path: 'seed.txt' } }, { name: 'write_file', args: { path: 'forbidden.txt', content: 'BAD' } }, { name: 'execute_command', args: { command: 'echo BAD > shell-forbidden.txt' } }, { name: mcpName, args: { text: 'BAD' } }, { name: 'todo_write', args: { todos: [{ content: 'Inspect inputs' }] } } ] upstream = createServer(async (request, response) => { let raw = ''; for await (const chunk of request) raw += chunk const body = JSON.parse(raw), names = (body.tools ?? []).map(x => x.function.name) requests.push({ phase, path: request.url, tools: names, modeContext: JSON.stringify(body.messages).includes(`mode=\\"${phase.split('-').at(-1)}\\"`) }) const calls = round++ === 0 ? attackCalls() : undefined const delta = calls ? { tool_calls: calls.map((c, index) => ({ index, id: 'mode-call-' + index, type: 'function', function: { name: c.name, arguments: JSON.stringify(c.args) } })) } : { content: 'MODE_DONE' } response.writeHead(200, { 'content-type': 'text/event-stream' }) const chunk = d => ({ id: 'mode-fixture', object: 'chat.completion.chunk', created: 1700000000, model: body.model, choices: [{ index: 0, delta: d, finish_reason: null }] }) const end = chunk({}); end.choices[0].finish_reason = calls ? 'tool_calls' : 'stop' response.end('data: ' + JSON.stringify(chunk(delta)) + '\n\ndata: ' + JSON.stringify(end) + '\n\ndata: [DONE]\n\n') }) await new Promise(resolve => upstream.listen(0, '127.0.0.1', resolve)) const config = { baseUrl: `http://127.0.0.1:${upstream.address().port}/v1`, model: 'mode-fixture', apiKey: '', authMode: 'none', temperature: 0, maxToolRounds: 5 } for (const mode of ['plan', 'ask']) { phase = 'gateway-' + mode; round = 0 const result = await api.runTurn({ runId: phase, agentMode: mode, history: [], userText: 'Controlled mode QA', signal: ctx.signal, emit() {}, gateway: new api.Gateway(config), model: config.model, maxToolRounds: 5, workspaceRoot: cwd, permissionMode: 'full-access', capabilityTools: craftSnapshot }) engineResults.push({ phase, tools: result.tools.map(({ name, status, output }) => ({ name, status, output })) }) check(phase + ' real Gateway returns terminal', result.content, 'MODE_DONE') check(phase + ' actual tool results enforce mode', result.tools.map(x => x.status), ['ok', 'error', 'error', 'error', mode === 'plan' ? 'ok' : 'error']) } const exe = api.detectOmpPath() assert.ok(exe, 'Actual OMP must be available; no simulated engine PASS') const prepared = await api.prepareOmpModel({ id: 'mode-fixture', config, profile: { id: 'mode-fixture', name: 'Mode fixture', model: config.model, providerId: 'openai', baseUrl: config.baseUrl, authMode: 'none', supportsToolCall: true, supportsImages: false, supportsReasoning: false, maxInputTokens: 32000, maxOutputTokens: 2048, hasApiKey: false, keyStorage: 'none' } }) for (const mode of ['plan', 'ask']) { phase = 'omp-' + mode; round = 0 kernel = new api.OmpKernel(exe, cwd, prepared.profile, path.join(directory, mode + '.jsonl'), prepared.model, prepared.env) await kernel.start() const result = await api.runOmpTurn({ runId: phase, agentMode: mode, kernel, userText: 'Controlled mode QA', signal: ctx.signal, emit() {}, workspaceRoot: cwd, permissionMode: 'full-access', capabilityTools: craftSnapshot }) engineResults.push({ phase, tools: result.tools.map(({ name, status, output }) => ({ name, status, output })) }) check(phase + ' actual OMP terminal', result.status, 'done') check(phase + ' actual OMP final reply', result.content, 'MODE_DONE') check(phase + ' readonly read succeeds', result.tools.some(x => x.name === 'read_file' && x.status === 'ok')) const hidden = result.tools.filter(x => ['write_file', 'execute_command', mcpName].includes(x.name)) check(phase + ' all three forbidden attempts are observed', hidden.length, 3) check(phase + ' hidden harmful calls fail', hidden.every(x => x.status === 'error')) check(phase + ' planning tool follows current mode', result.tools.find(x => x.name === 'todo_write')?.status, mode === 'plan' ? 'ok' : 'error') await kernel.dispose(); kernel = undefined } for (const mode of ['plan', 'ask']) { const matching = requests.filter(r => r.phase.endsWith(mode)) check(mode + ' tool visibility filtered in both actual engines', matching.every(r => r.tools.includes('read_file') && !r.tools.includes('write_file') && !r.tools.includes('execute_command') && !r.tools.includes(mcpName) && (mode === 'plan' || !r.tools.includes('todo_write')))) check(mode + ' honest mode instruction reaches both actual engines', matching.length >= 4 && matching.every(r => r.modeContext)) } check('no hidden write produced a file', await fs.stat(path.join(cwd, 'forbidden.txt')).then(() => true, () => false), false) check('no hidden shell command ran', await fs.stat(path.join(cwd, 'shell-forbidden.txt')).then(() => true, () => false), false) check('neither actual engine reached MCP callTool in restricted mode', (await fs.readFile(path.join(directory, 'mcp-events.jsonl'), 'utf8')).trim().split('\n').map(JSON.parse).filter(x => x.type === 'call').length, 0) check('craft still permits real write', (await api.executeTurnTool('write_file', { path: 'craft.txt', content: 'CRAFT_OK' }, { ...ctx, agentMode: 'craft' }, craftSnapshot)).ok) check('craft SDK MCP retains actual execution', (await api.executeTurnTool(mcpName, { text: 'CRAFT_OK' }, { ...ctx, agentMode: 'craft' }, craftSnapshot)).content, 'stdio:CRAFT_OK') const report = { result: 'PASS', checks, requests, engineResults, directory, limitations: ['Electron transport is controlled IPC registration; real session persistence and tool implementations.', 'Actual OMP executable and actual Gateway hit only a loopback SSE fixture; no remote model or native UI tested.', 'MCP uses an actual SDK stdio fixture. No WorkBuddy/OMP native mode equivalence claimed.'] } await fs.writeFile(path.join(directory, 'report.json'), JSON.stringify(report, null, 2)) console.log(JSON.stringify({ result: 'PASS', checks: checks.length, directory })) } catch (error) { await fs.writeFile(path.join(directory, 'report.json'), JSON.stringify({ result: 'FAIL', checks, requests, engineResults, error: String(error), directory }, null, 2)); throw error } finally { await kernel?.dispose(); await api.mcp.disposeMcpServers(); await api.disposeOmpKernels() if (upstream) { upstream.closeAllConnections(); await new Promise(resolve => upstream.close(resolve)) } if (previousOmpHome === undefined) delete process.env.YCODE_OMP_HOME; else process.env.YCODE_OMP_HOME = previousOmpHome }