fix(qa): use built plugin tools server (#116442)

This commit is contained in:
Dallin Romney
2026-07-31 14:49:24 +08:00
committed by GitHub
parent 8d7ff3c04c
commit fa5ee0798b
2 changed files with 45 additions and 6 deletions
@@ -124,7 +124,7 @@ describe("qa suite runtime agent tools helpers", () => {
).resolves.toEqual("done");
});
it("calls plugin-tools MCP through the resolved node executable", async () => {
it("falls back to the source plugin-tools MCP entry", async () => {
listToolsMock.mockResolvedValueOnce({
tools: [{ name: "plugin.echo" }] as never[],
});
@@ -180,6 +180,35 @@ describe("qa suite runtime agent tools helpers", () => {
expect(closeMock).toHaveBeenCalled();
});
it("prefers the built plugin-tools MCP entry", async () => {
const builtRepoRoot = await makeTempDir("qa-built-repo-");
const distEntry = path.join(builtRepoRoot, "dist", "mcp", "plugin-tools-serve.js");
await fs.mkdir(path.dirname(distEntry), { recursive: true });
await fs.writeFile(distEntry, "// built MCP entry\n", "utf8");
listToolsMock.mockResolvedValueOnce({
tools: [{ name: "plugin.echo" }] as never[],
});
await callPluginToolsMcp({
env: {
gateway: {
tempRoot: gatewayTempRoot,
runtimeEnv: { PATH: "/usr/bin" },
},
repoRoot: builtRepoRoot,
} as never,
toolName: "plugin.echo",
args: {},
});
expect(stdioTransportMock).toHaveBeenCalledWith(
expect.objectContaining({
command: "/usr/bin/node",
args: [distEntry],
}),
);
});
it("reports available plugin-tools MCP names when the requested tool is missing", async () => {
listToolsMock.mockResolvedValueOnce({
tools: [{ name: "plugin.beta" }, { name: "plugin.alpha" }] as never[],
@@ -22,6 +22,20 @@ const requireFromHere = createRequire(import.meta.url);
const MCP_STDERR_TAIL_LIMIT = 8_192;
const MCP_REQUEST_TIMEOUT_MS = 180_000;
async function resolvePluginToolsMcpArgs(repoRoot: string) {
const distEntry = path.join(repoRoot, "dist", "mcp", "plugin-tools-serve.js");
try {
await fs.access(distEntry);
return [distEntry];
} catch {
return [
"--import",
requireFromHere.resolve("tsx"),
path.join(repoRoot, "src", "mcp", "plugin-tools-serve.ts"),
];
}
}
function findSkill(skills: QaSkillStatusEntry[], name: string) {
return skills.find((skill) => skill.name === name);
}
@@ -73,11 +87,7 @@ async function callPluginToolsMcp(params: {
const nodeExecPath = await resolveQaNodeExecPath();
const transport = new StdioClientTransport({
command: nodeExecPath,
args: [
"--import",
requireFromHere.resolve("tsx"),
path.join(params.env.repoRoot, "src/mcp/plugin-tools-serve.ts"),
],
args: await resolvePluginToolsMcpArgs(params.env.repoRoot),
stderr: "pipe",
cwd: params.env.repoRoot,
env: transportEnv,