import { EventEmitter } from 'node:events' import { mkdir, mkdtemp, realpath, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { PassThrough } from 'node:stream' import { describe, expect, it, vi } from 'vitest' import { DEEPSEEK_HARNESS_CONTROL_PROTOCOL, DEEPSEEK_HARNESS_CONTROL_VERSION, DEEPSEEK_HARNESS_CREDENTIAL_REF, createDeepSeekHarnessUtilityLauncher, parseHarnessControlMessage } from './deepseek-harness-utility-launcher' class FakeUtility extends EventEmitter { readonly messages: unknown[] = [] readonly stderr = new PassThrough() readonly pid = 123 killed = false postMessage(message: unknown): void { this.messages.push(message) } kill(): boolean { this.killed = true return true } } async function fixture() { const root = await realpath( await mkdtemp(join(tmpdir(), 'goodbuddy-harness-launcher-')) ) const workspace = join(root, 'workspace') const dshHome = join(root, 'home') const hostPath = join( root, 'deepseek-harness-host-bootstrap.js' ) await Promise.all([ mkdir(workspace), mkdir(dshHome), writeFile(hostPath, '', 'utf8') ]) return { dshHome, hostPath, launchOptions: { cwd: workspace, signal: new AbortController().signal, baseUrl: 'https://gateway.example/openai/v1', model: 'qwen-plus', credentialRefs: [DEEPSEEK_HARNESS_CREDENTIAL_REF], skillPackages: [] } } } describe('DeepSeek Harness utility launcher', () => { it('accepts only strict control messages and secret-free config', () => { expect( parseHarnessControlMessage({ protocol: DEEPSEEK_HARNESS_CONTROL_PROTOCOL, version: DEEPSEEK_HARNESS_CONTROL_VERSION, type: 'ready' }) ).toMatchObject({ type: 'ready' }) expect( parseHarnessControlMessage({ protocol: DEEPSEEK_HARNESS_CONTROL_PROTOCOL, version: DEEPSEEK_HARNESS_CONTROL_VERSION, type: 'ready', apiKey: 'must-not-pass' }) ).toBeUndefined() }) it('waits for Host readiness and sends no credential value', async () => { const { dshHome, hostPath, launchOptions } = await fixture() const utility = new FakeUtility() const fork = vi.fn(() => utility as never) const launcher = createDeepSeekHarnessUtilityLauncher({ bundledHostPath: hostPath, dshHome, environment: { PATH: 'C:\\Tools' }, fork }) const launching = launcher(launchOptions) await vi.waitFor(() => expect(utility.messages).toHaveLength(1) ) expect(JSON.stringify(utility.messages[0])).not.toContain( 'secret' ) expect(utility.messages[0]).toMatchObject({ type: 'start', config: { baseUrl: 'https://gateway.example/openai/v1', model: 'qwen-plus', credentialRefs: [DEEPSEEK_HARNESS_CREDENTIAL_REF] } }) utility.emit('message', { protocol: DEEPSEEK_HARNESS_CONTROL_PROTOCOL, version: DEEPSEEK_HARNESS_CONTROL_VERSION, type: 'ready' }) await expect(launching).resolves.toMatchObject({ stdin: expect.any(WritableStream), stdout: expect.any(ReadableStream) }) expect(fork).toHaveBeenCalledWith( hostPath, [], expect.objectContaining({ cwd: launchOptions.cwd, stdio: ['ignore', 'ignore', 'pipe'] }) ) }) it('fails closed on an invalid Host startup message', async () => { const { dshHome, hostPath, launchOptions } = await fixture() const utility = new FakeUtility() const terminateProcess = vi.fn(() => { utility.killed = true }) const launcher = createDeepSeekHarnessUtilityLauncher({ bundledHostPath: hostPath, dshHome, environment: {}, fork: () => utility as never, terminateProcess }) const launching = launcher(launchOptions) await vi.waitFor(() => expect(utility.messages).toHaveLength(1) ) utility.emit('message', { type: 'ready' }) await expect(launching).rejects.toThrow('启动协议无效') expect(terminateProcess).toHaveBeenCalledOnce() }) it.each([ 'http://gateway.example/v1', 'https://user:secret@gateway.example/v1', 'https://gateway.example/v1?api-version=2025-01-01' ])('rejects unsafe endpoint %s before forking', async (baseUrl) => { const { dshHome, hostPath, launchOptions } = await fixture() const fork = vi.fn() const launcher = createDeepSeekHarnessUtilityLauncher({ bundledHostPath: hostPath, dshHome, environment: {}, fork }) await expect( launcher({ ...launchOptions, baseUrl }) ).rejects.toThrow('HTTPS') expect(fork).not.toHaveBeenCalled() }) })