/** Offline integration only. NEVER imports/runs the installed Claude SDK or opens a network port. */ import assert from 'node:assert/strict' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' import { pathToFileURL } from 'node:url' import { build } from 'esbuild' const temp = await mkdtemp(join(tmpdir(), 'ycode-claude-bridge-offline-')) const queries = [], leases = [], kernels = [] let queryFailure = false, runtimeFailure = false, grantFailure = false, acquireGate const deferred = () => { let resolve; const promise = new Promise(r => { resolve = r }); return { promise, resolve } } const tick = () => new Promise(r => setImmediate(r)) const mocks = { electron: { app: { getPath: () => temp, getAppPath: () => temp } }, '@anthropic-ai/claude-agent-sdk': { createSdkMcpServer: config => config, tool: (name, description, schema, handler) => ({ name, description, schema, handler }), query: request => { if (queryFailure) throw new Error('mock SDK startup failure') const ended = deferred() const instance = { closeCount: 0, interrupt: async () => {}, close() { this.closeCount++; ended.resolve() }, async *[Symbol.asyncIterator]() { await ended.promise }, applyFlagSettings: async () => { if (grantFailure) throw new Error('mock grant replay failure') }, setPermissionMode: async () => {}, getContextUsage: async () => ({ categories: [] }) } queries.push({ ...request, instance }) return instance } }, 'private-runtimes': { privateRuntimeEnvironment: async env => { if (runtimeFailure) throw new Error('mock runtime failure'); return env } }, 'agent/tools/browser': { browserTool: { description: 'inert browser', run: () => { throw new Error('Unexpected browser execution') } } }, 'capabilities/claude-capabilities': { createClaudeCapabilityRuntime: () => ({ server: {}, setRequestSelection() {} }) }, 'model-bridge': { acquireModelBridge: async model => { const id = leases.length + 1 const lease = { model: structuredClone(model), baseUrl: `http://127.0.0.1:${24000 + id}/lease-${id}`, apiKey: `mock-local-token-${id}`, closeCount: 0, async close() { this.closeCount++ } } leases.push(lease) if (acquireGate) await acquireGate.promise return lease } } } const portKeys = new Map(Object.keys(mocks).map(key => [key === 'electron' || key.startsWith('@') ? key : resolve('src/main', key), key])) globalThis.__claudeBridgeOfflineMocks = mocks let checks = 0 const check = async (name, body) => { await body(); checks++; console.log(`PASS ${name}`) } function model(api = 'openai-completions', suffix = '') { return { profile: { id: `offline${suffix}`, name: 'Offline', providerId: 'offline', model: `model${suffix}`, baseUrl: 'https://invalid.example/v1', authMode: 'api-key', apiPreference: api, protocol: api === 'anthropic-messages' ? 'anthropic' : 'openai', contextWindowTokens: 100000 }, config: { api, model: `model${suffix}`, baseUrl: 'https://invalid.example/v1', apiKey: `FAKE-NOT-A-CREDENTIAL${suffix}` } } } const options = (id, value = model()) => ({ sessionId: id, workspaceRoot: temp, model: value, permissionMode: 'default-sandbox', agentMode: 'craft', onSessionId() {} }) try { const bundle = join(temp, 'kernel.mjs') await build({ stdin: { contents: "export * from './src/main/agent/claude/claude-kernel'; export { rememberSessionGrant } from './src/main/agent/claude/session-grants'", resolveDir: process.cwd(), loader: 'ts' }, outfile: bundle, bundle: true, platform: 'node', format: 'esm', logLevel: 'warning', metafile: true, plugins: [{ name: 'strict-offline-ports', setup(b) { b.onResolve({ filter: /.*/ }, args => { const path = args.path.startsWith('.') ? resolve(args.resolveDir, args.path).replace(/\.(ts|js)$/, '').replace(/\/index$/, '') : args.path const key = portKeys.get(path) if (key) return { path: key, namespace: 'offline' } if (args.path.includes('claude-agent-sdk')) throw new Error('Actual SDK resolution forbidden') }) b.onLoad({ filter: /.*/, namespace: 'offline' }, args => ({ contents: Object.keys(mocks[args.path]).map(name => `export const ${name} = globalThis.__claudeBridgeOfflineMocks[${JSON.stringify(args.path)}][${JSON.stringify(name)}]`).join('\n'), loader: 'js' })) } }] }).then(result => { assert(!Object.keys(result.metafile.inputs).some(path => path.includes('node_modules/@anthropic-ai/')), 'real SDK must never enter bundle') assert(!Object.keys(result.metafile.inputs).some(path => /src\/main\/model-bridge\//.test(path) && !path.endsWith('/model-bridge/paths.ts')), 'real network bridge must never enter bundle') }) const { ClaudeKernel, getClaudeKernel, disposeClaudeKernels, rememberSessionGrant } = await import(pathToFileURL(bundle).href) const make = opts => { const kernel = new ClaudeKernel(opts); kernels.push(kernel); return kernel } let baseline await check('both OpenAI APIs use isolated bridge env, not upstream credentials', async () => { for (const api of ['openai-completions', 'openai-responses']) { const value = model(api), kernel = make(options(api, value)), before = leases.length await kernel.ensureStarted() const lease = leases.at(-1), request = queries.at(-1) assert.equal(leases.length, before + 1) assert.deepEqual(lease.model, { ...value, config: { ...value.config, thinkingLevel: 'off' } }) assert.equal(request.options.env.ANTHROPIC_BASE_URL, lease.baseUrl) assert.equal(request.options.env.ANTHROPIC_API_KEY, lease.apiKey) assert(!JSON.stringify(request.options.env).includes(value.config.apiKey)) assert.equal(request.options.model, value.config.model) baseline ??= request.options await kernel.close(); assert.equal(lease.closeCount, 1) await kernel.close(); assert.equal(lease.closeCount, 1) } }) await check('bridge lease receives effective low/off thinking without mutating resolved config', async () => { for (const api of ['openai-completions', 'openai-responses']) { for (const [requested, reasoning, expected] of [['low', true, 'low'], ['off', true, 'off'], [undefined, false, 'off']]) { const value = model(api) value.profile.supportsReasoning = reasoning value.profile.supportedEfforts = ['low', 'high'] value.config.thinkingLevel = 'high' const kernel = make({ ...options(`thinking-${api}-${requested}`, value), thinkingLevel: requested }) await kernel.ensureStarted() assert.equal(leases.at(-1).model.config.thinkingLevel, expected) assert.equal(value.config.thinkingLevel, 'high', 'bridge-specific effective level must not mutate resolved model') await kernel.close() } } }) await check('Anthropic remains direct and permission/tool hooks remain identical', async () => { const before = leases.length, value = model('anthropic-messages') const kernel = make(options('anthropic', value)); await kernel.ensureStarted() const opts = queries.at(-1).options assert.equal(leases.length, before) assert.equal(opts.env.ANTHROPIC_BASE_URL, 'https://invalid.example') assert.equal(opts.env.ANTHROPIC_API_KEY, value.config.apiKey) for (const key of ['permissionMode', 'permissionPrompts', 'settingSources', 'strictMcpConfig', 'tools', 'allowedTools', 'disallowedTools', 'plugins', 'agents', 'skills']) assert.deepEqual(opts[key], baseline[key], key) assert.equal(opts.permissionMode, 'default'); assert.equal(opts.permissionPrompts, 'host') assert.deepEqual(Object.keys(opts.hooks), ['PreToolUse']) assert.equal(typeof opts.canUseTool, 'function') for (const policy of [opts, baseline]) { const result = await policy.hooks.PreToolUse[0].hooks[0]({ hook_event_name: 'PreToolUse', tool_name: 'Bash', tool_input: {}, tool_use_id: 'inactive' }) assert.equal(result.hookSpecificOutput.permissionDecision, 'deny') } await kernel.close() }) await check('two simultaneous sessions have separate leases and independent cleanup', async () => { const a = make(options('dual-a', model('openai-completions', '-a'))), b = make(options('dual-b', model('openai-responses', '-b'))) const before = leases.length await Promise.all([a.ensureStarted(), b.ensureStarted()]) const [la, lb] = leases.slice(before) assert.notEqual(la.apiKey, lb.apiKey); assert.notEqual(la.baseUrl, lb.baseUrl) await a.close(); assert.equal(la.closeCount, 1); assert.equal(lb.closeCount, 0) await b.close(); assert.equal(lb.closeCount, 1) }) await check('concurrent ensureStarted acquires exactly one lease and SDK query', async () => { const kernel = make(options('concurrent')), before = leases.length, q = queries.length acquireGate = deferred() const starts = Array.from({ length: 6 }, () => kernel.ensureStarted()) await tick(); acquireGate.resolve(); acquireGate = undefined await Promise.all(starts) assert.equal(leases.length, before + 1); assert.equal(queries.length, q + 1) await kernel.close(); assert.equal(leases.at(-1).closeCount, 1) }) await check('API/model/base URL/key configuration changes retire old leases', async () => { let opts = options('fingerprint'), kernel = await getClaudeKernel(opts) await kernel.ensureStarted(); assert.equal(await getClaudeKernel(opts), kernel) for (const patch of [{ api: 'openai-responses' }, { model: 'changed-model' }, { baseUrl: 'https://other.invalid/v1' }, { apiKey: 'FAKE-CHANGED-KEY' }]) { const oldLease = leases.at(-1) opts = { ...opts, model: { ...opts.model, config: { ...opts.model.config, ...patch } } } const next = await getClaudeKernel(opts); assert.notEqual(next, kernel) assert.equal(oldLease.closeCount, 1); await next.ensureStarted(); kernel = next } await kernel.close() }) await check('failed SDK startup releases lease and permits clean retry', async () => { const kernel = make(options('failed')) queryFailure = true await assert.rejects(kernel.ensureStarted(), /mock SDK startup failure/) queryFailure = false assert.equal(leases.at(-1).closeCount, 1) await kernel.ensureStarted(); assert.equal(leases.at(-1).closeCount, 0) await kernel.close(); assert.equal(leases.at(-1).closeCount, 1) }) await check('failed session grant replay releases producer and bridge before retry', async () => { const kernel = make(options('grant-replay')) rememberSessionGrant('grant-replay', { rules: ['Read(**)'], updates: [] }, temp) grantFailure = true await assert.rejects(kernel.ensureStarted(), /mock grant replay failure/) grantFailure = false; await tick() assert.equal(leases.at(-1).closeCount, 1) await kernel.ensureStarted(); await kernel.close() assert.equal(leases.at(-1).closeCount, 1) }) await check('runtime environment failure cannot strand a bridge lease', async () => { const kernel = make(options('runtime-failure')), before = leases.length runtimeFailure = true await assert.rejects(kernel.ensureStarted(), /mock runtime failure/) runtimeFailure = false for (const lease of leases.slice(before)) assert.equal(lease.closeCount, 1) await kernel.close() }) await check('close during asynchronous acquisition releases lease without SDK startup', async () => { const kernel = make(options('close-during-start')), q = queries.length acquireGate = deferred() const start = kernel.ensureStarted().catch(error => error) await tick() const closing = kernel.close() acquireGate.resolve(); acquireGate = undefined await Promise.all([start, closing]) assert.equal(queries.length, q); assert.equal(leases.at(-1).closeCount, 1) }) await check('unsupported Gemini fails before bridge or SDK creation', async () => { const value = model('google-generative-ai'); value.profile.protocol = 'gemini' const kernel = make(options('unsupported', value)), before = leases.length, q = queries.length await assert.rejects(kernel.ensureStarted(), /协议/) assert.equal(leases.length, before); assert.equal(queries.length, q) await kernel.close() }) await check('resolved model snapshot cannot be mutated after kernel creation', async () => { const value = model(), kernel = make(options('snapshot', value)) value.config.apiKey = 'FAKE-MUTATED'; value.config.model = 'mutated-model' await kernel.ensureStarted() assert.equal(leases.at(-1).model.config.apiKey, 'FAKE-NOT-A-CREDENTIAL') assert.equal(queries.at(-1).options.model, 'model') await kernel.close() }) await check('bridge preserves full-access tool preauthorization and question approval boundary', async () => { const kernel = make({ ...options('hook-policy'), permissionMode: 'full-access' }), controller = new AbortController() const run = kernel.runTurn({ runId: 'hook-run', userMessageId: 'user', prompt: 'offline', emit() {}, interactions: {}, signal: controller.signal }) const rejected = assert.rejects(run, error => error.name === 'AbortError') await tick() const opts = queries.at(-1).options, hook = opts.hooks.PreToolUse[0].hooks[0] assert.equal(opts.permissionMode, 'default') for (const [name, decision] of [['Bash', 'allow'], ['AskUserQuestion', 'ask']]) { const result = await hook({ hook_event_name: 'PreToolUse', tool_name: name, tool_input: {}, tool_use_id: name }) assert.equal(result.hookSpecificOutput.permissionDecision, decision) } controller.abort(); await rejected; await kernel.close() }) await check('unexpected producer termination releases bridge lease', async () => { const kernel = make(options('producer-end')) await kernel.ensureStarted(); const lease = leases.at(-1) queries.at(-1).instance.close(); await tick() assert.equal(lease.closeCount, 1) await kernel.close(); assert.equal(lease.closeCount, 1) }) await check('cancellation during bridge acquisition releases newly started producer', async () => { const kernel = make(options('cancel-start')), controller = new AbortController() acquireGate = deferred() const run = kernel.runTurn({ runId: 'cancel-start-run', userMessageId: 'user', prompt: 'offline', emit() {}, interactions: {}, signal: controller.signal }) const rejected = assert.rejects(run, error => error.name === 'AbortError') await tick(); controller.abort(); acquireGate.resolve(); acquireGate = undefined await rejected; await tick() assert.equal(leases.at(-1).closeCount, 1) await kernel.close() }) await check('turn cancellation retires producer and releases its bridge lease', async () => { const kernel = make(options('cancel')), controller = new AbortController() const run = kernel.runTurn({ runId: 'cancel-run', userMessageId: 'user', prompt: 'offline', emit() {}, interactions: {}, signal: controller.signal }) const rejected = assert.rejects(run, error => error.name === 'AbortError') await tick(); assert.equal(kernel.busy, true) const lease = leases.at(-1) controller.abort(); await rejected; await tick() assert.equal(lease.closeCount, 1) await kernel.close(); assert.equal(lease.closeCount, 1) }) await disposeClaudeKernels() assert(leases.every(lease => lease.closeCount === 1), 'all leases released exactly once') console.log(`PASS ${checks} offline Claude/bridge host groups; no actual SDK startup, network or credentials`) } finally { acquireGate?.resolve() await Promise.all(kernels.map(kernel => kernel.close().catch(() => {}))) delete globalThis.__claudeBridgeOfflineMocks await rm(temp, { recursive: true, force: true }) }