Download src/server/services/mcpHostPreflight.test.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 4.89 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/server/services/mcpHostPreflight.test.ts
- Command line
-
hf download hf://chenbhao/codev/src/server/services/mcpHostPreflight.test.ts
-
curl -L -o mcpHostPreflight.test.ts https://huggingface.co/chenbhao/codev/resolve/main/src/server/services/mcpHostPreflight.test.ts
4.89 kB
| import { afterEach, beforeEach, describe, expect, it } from 'bun:test' | |
| import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises' | |
| import { tmpdir } from 'node:os' | |
| import path from 'node:path' | |
| import { resetMcpStdioEnvironmentCacheForTests } from '../../utils/mcpStdioEnvironment.js' | |
| import { inspectMcpHostCommand } from './mcpHostPreflight.js' | |
| let tmpDir: string | |
| let originalEnv: { | |
| HOME?: string | |
| PATH?: string | |
| SHELL?: string | |
| ZDOTDIR?: string | |
| CC_HAHA_DISABLE_TERMINAL_SHELL_ENV?: string | |
| } | |
| async function writeExecutable(filePath: string, content: string) { | |
| await writeFile(filePath, content, { mode: 0o755 }) | |
| } | |
| async function writeFakeZsh(filePath: string) { | |
| await writeExecutable( | |
| filePath, | |
| [ | |
| '#!/bin/sh', | |
| 'command=', | |
| 'while [ "$#" -gt 0 ]; do', | |
| ' if [ "$1" = "-c" ]; then', | |
| ' shift', | |
| ' command="$1"', | |
| ' break', | |
| ' fi', | |
| ' shift', | |
| 'done', | |
| 'if [ -f "$HOME/.zshrc" ]; then', | |
| ' . "$HOME/.zshrc" </dev/null >/dev/null 2>/dev/null || true', | |
| 'fi', | |
| 'exec /bin/sh -c "$command"', | |
| '', | |
| ].join('\n'), | |
| ) | |
| } | |
| describe('MCP host preflight', () => { | |
| beforeEach(async () => { | |
| tmpDir = await mkdtemp(path.join(tmpdir(), 'mcp-host-preflight-test-')) | |
| originalEnv = { | |
| HOME: process.env.HOME, | |
| PATH: process.env.PATH, | |
| SHELL: process.env.SHELL, | |
| ZDOTDIR: process.env.ZDOTDIR, | |
| CC_HAHA_DISABLE_TERMINAL_SHELL_ENV: | |
| process.env.CC_HAHA_DISABLE_TERMINAL_SHELL_ENV, | |
| } | |
| delete process.env.CC_HAHA_DISABLE_TERMINAL_SHELL_ENV | |
| resetMcpStdioEnvironmentCacheForTests() | |
| }) | |
| afterEach(async () => { | |
| for (const [key, value] of Object.entries(originalEnv)) { | |
| if (value === undefined) { | |
| delete process.env[key] | |
| } else { | |
| process.env[key] = value | |
| } | |
| } | |
| resetMcpStdioEnvironmentCacheForTests() | |
| await rm(tmpDir, { recursive: true, force: true }) | |
| }) | |
| it('finds npx from user shell PATH when the desktop process PATH is minimal', async () => { | |
| const shellPath = path.join(tmpDir, 'zsh') | |
| const nodeBin = path.join(tmpDir, 'node-bin') | |
| const npxPath = path.join(nodeBin, 'npx') | |
| await mkdir(nodeBin, { recursive: true }) | |
| await writeFakeZsh(shellPath) | |
| await writeExecutable(npxPath, '#!/bin/sh\nexit 0\n') | |
| await writeFile( | |
| path.join(tmpDir, '.zshrc'), | |
| `export PATH="${nodeBin}:$PATH"\n`, | |
| ) | |
| process.env.HOME = tmpDir | |
| process.env.SHELL = shellPath | |
| process.env.PATH = '/usr/bin:/bin' | |
| delete process.env.ZDOTDIR | |
| await expect(inspectMcpHostCommand('npx', tmpDir, {})).resolves.toEqual({ | |
| ok: true, | |
| resolvedCommand: npxPath, | |
| }) | |
| }) | |
| it('finds commands from the desktop process PATH before shell fallback', async () => { | |
| const processBin = path.join(tmpDir, 'process-bin') | |
| const toolPath = path.join(processBin, 'mcp-tool') | |
| await mkdir(processBin, { recursive: true }) | |
| await writeExecutable(toolPath, '#!/bin/sh\nexit 0\n') | |
| process.env.HOME = tmpDir | |
| process.env.SHELL = '/bin/zsh' | |
| process.env.PATH = processBin | |
| await expect( | |
| inspectMcpHostCommand('mcp-tool', tmpDir, {}), | |
| ).resolves.toEqual({ | |
| ok: true, | |
| resolvedCommand: toolPath, | |
| }) | |
| }) | |
| it('uses explicit MCP PATH to resolve host commands', async () => { | |
| const configuredBin = path.join(tmpDir, 'configured-bin') | |
| const toolPath = path.join(configuredBin, 'mcp-tool') | |
| await mkdir(configuredBin, { recursive: true }) | |
| await writeExecutable(toolPath, '#!/bin/sh\nexit 0\n') | |
| process.env.HOME = tmpDir | |
| process.env.SHELL = '/bin/zsh' | |
| process.env.PATH = '/usr/bin:/bin' | |
| await expect( | |
| inspectMcpHostCommand('mcp-tool', tmpDir, { PATH: configuredBin }), | |
| ).resolves.toEqual({ | |
| ok: true, | |
| resolvedCommand: toolPath, | |
| }) | |
| }) | |
| it('does not fall back to shell PATH when MCP PATH is explicit', async () => { | |
| const shellPath = path.join(tmpDir, 'zsh') | |
| const nodeBin = path.join(tmpDir, 'node-bin') | |
| const emptyBin = path.join(tmpDir, 'empty-bin') | |
| const npxPath = path.join(nodeBin, 'npx') | |
| await mkdir(nodeBin, { recursive: true }) | |
| await mkdir(emptyBin, { recursive: true }) | |
| await writeFakeZsh(shellPath) | |
| await writeExecutable(npxPath, '#!/bin/sh\nexit 0\n') | |
| await writeFile( | |
| path.join(tmpDir, '.zshrc'), | |
| `export PATH="${nodeBin}:$PATH"\n`, | |
| ) | |
| process.env.HOME = tmpDir | |
| process.env.SHELL = shellPath | |
| process.env.PATH = '/usr/bin:/bin' | |
| delete process.env.ZDOTDIR | |
| await expect( | |
| inspectMcpHostCommand('npx', tmpDir, { PATH: emptyBin }), | |
| ).resolves.toEqual({ | |
| ok: false, | |
| message: | |
| 'Host command "npx" is not available in PATH. This STDIO MCP runs on the host machine. Install Node.js on this machine so "npx" is available in PATH, then retry.', | |
| }) | |
| }) | |
| }) | |