Files
oh-my-pi/packages/coding-agent/test/discovery/opencode.test.ts
T
oldschoola a2854ba768 fix: migrate coding-agent tests from fs.rm to removeWithRetries
Migrate 203 test files (356 call sites) from fs.rm/fs.rmSync to
removeWithRetries/removeSyncWithRetries to reduce EBUSY test failures
on Windows. removeWithRetries is now exported from @oh-my-pi/pi-utils.

The migration uses a regex-based approach that:
- Replaces fs.rm(path, { recursive, force }) → removeWithRetries(path)
- Replaces fs.rmSync(path, { recursive, force }) → removeSyncWithRetries(path)
- Replaces fs.rm(path) → removeWithRetries(path) (no options)
- Skips fs.rm/fs.rmSync inside template literals (bun --eval scripts)
- Adds imports to existing @oh-my-pi/pi-utils import or creates new one
- Removes unused fs imports where fs.rm was the only fs usage (4 files)
2026-06-23 15:28:05 -07:00

98 lines
2.6 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { type MCPServer, mcpCapability } from "@oh-my-pi/pi-coding-agent/capability/mcp";
import { loadCapability } from "@oh-my-pi/pi-coding-agent/discovery";
import { removeWithRetries } from "@oh-my-pi/pi-utils";
async function loadOpenCodeMcpConfig(cwd: string): Promise<MCPServer[]> {
const result = await loadCapability<MCPServer>(mcpCapability.id, {
cwd,
providers: ["opencode"],
});
return result.items;
}
describe("OpenCode MCP discovery", () => {
let tempDir = "";
beforeEach(async () => {
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "omp-opencode-mcp-"));
});
afterEach(async () => {
await removeWithRetries(tempDir);
});
test("normalizes array commands and OpenCode environment fields", async () => {
await fs.writeFile(
path.join(tempDir, "opencode.json"),
JSON.stringify({
mcp: {
sequentialthinking: {
type: "local",
command: ["npx", "-y", "@modelcontextprotocol/server-sequential-thinking"],
enabled: true,
},
github: {
type: "local",
command: ["npx", "-y", "@modelcontextprotocol/server-github"],
environment: {
GITHUB_PERSONAL_ACCESS_TOKEN: "token",
},
enabled: true,
},
firecrawl: {
type: "local",
command: ["firecrawl-mcp"],
env: {
FIRECRAWL_API_KEY: "legacy-token",
},
},
},
}),
);
const servers = await loadOpenCodeMcpConfig(tempDir);
const byName = Object.fromEntries(servers.map(server => [server.name, server]));
expect(byName.sequentialthinking).toMatchObject({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-sequential-thinking"],
transport: "stdio",
});
expect(byName.github).toMatchObject({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: { GITHUB_PERSONAL_ACCESS_TOKEN: "token" },
transport: "stdio",
});
expect(byName.firecrawl).toMatchObject({
command: "firecrawl-mcp",
env: { FIRECRAWL_API_KEY: "legacy-token" },
transport: "stdio",
});
expect(byName.firecrawl?.args).toBeUndefined();
});
test("omits empty args for scalar OpenCode commands", async () => {
await fs.writeFile(
path.join(tempDir, "opencode.json"),
JSON.stringify({
mcp: {
plain: {
type: "local",
command: "server-bin",
},
},
}),
);
const [server] = await loadOpenCodeMcpConfig(tempDir);
expect(server?.command).toBe("server-bin");
expect(server?.args).toBeUndefined();
});
});