Files
reverse-engineering-anything/src/cliAmpRegistration.test.ts
T
morluto 69630c0362 fix(cli)!: own MCP client registration boundaries (#10102)
* fix(cli)!: own MCP client registration boundaries

* fix(cli): bind registration to native connection facts

* test(cli): isolate registration failure and fixture controls

* test(cli): distinguish native syntax and launcher alignment

* fix(cli): preserve registration selection and cancellation

* fix(cli): honor Goose and Zed native settings paths

* fix(cli): honor registration output controls

* fix(cli): reject disabled Junie global locations
2026-11-11 09:05:21 -05:00

102 lines
4.6 KiB
TypeScript

import { spawnSync } from "node:child_process";
import { mkdir, rm } from "node:fs/promises";
import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../tests/fixtures/temporaryDirectory.js";
it("admits exact Amp command facts and rejects invalid commands before publication", async () => {
const home = await createTestTempDirectory("rea-amp-source-command-");
try {
await mkdir(join(home, "config"));
const script = `
import { homedir } from 'node:os';
import { resolve, sep, join } from 'node:path';
import { mkdir, readFile, writeFile, rm, realpath } from 'node:fs/promises';
const home = process.env.HOME;
if (!home || await realpath(homedir()) !== await realpath(home))
throw Error('Fixture HOME was not selected before loading registration writers.');
for (const key of ['USERPROFILE','XDG_CONFIG_HOME','XDG_DATA_HOME','XDG_CACHE_HOME','XDG_STATE_HOME','APPDATA','LOCALAPPDATA']) {
const value = resolve(process.env[key] ?? '');
if (value !== home && !value.startsWith(home + sep))
throw Error('Fixture config location escapes selected HOME: ' + key);
}
const { createCli, closeCliResources } = await import(${JSON.stringify(new URL("./cli.ts", import.meta.url).href)});
const original = { 'amp.mcpServers': { rea: { command: 'stale-executable', args: ['stale-argument'], env: { KEEP: '1' }, disabled: false }, peer: { command: 'peer' } }, theme: 'dark' };
const directory = join(home, '.config', 'amp');
const path = join(directory, 'settings.json');
const cases = ['""', "'unclosed", 'fixture-server "unclosed', '"/fixture/server path" "" --mcp', String.raw\`'C:\\Program Files\\server.exe' 'C:\\data\\file'\`, 'fixture-server --mcp'];
const results = [];
try {
for (const command of cases) {
await rm(directory, { recursive: true, force: true });
await mkdir(directory, { recursive: true });
const before = JSON.stringify(original) + '\\n';
await writeFile(path, before);
let output = '', exitCode = 0;
await createCli(process.env).serve(['mcp','add','--agent','amp','--command',command,'--json'], { stdout(text) { output += text; }, exit(code) { exitCode = code; } });
const backup = await readFile(path + '.rea.backup', 'utf8').catch(error => { if (error.code === 'ENOENT') return null; throw error; });
results.push({ command, exitCode, output, before, after: await readFile(path, 'utf8'), backup });
}
} finally { await closeCliResources(); }
console.log(JSON.stringify(results));
`;
const child = spawnSync(
process.execPath,
["--import", "tsx", "--input-type=module", "--eval", script],
{
encoding: "utf8",
timeout: 20_000,
env: {
PATH: process.env.PATH,
SystemRoot: process.env.SystemRoot,
WINDIR: process.env.WINDIR,
TMPDIR: process.env.TMPDIR,
TMP: process.env.TMP,
TEMP: process.env.TEMP,
HOME: home,
USERPROFILE: home,
XDG_CONFIG_HOME: join(home, "config"),
XDG_DATA_HOME: join(home, "data"),
XDG_CACHE_HOME: join(home, "cache"),
XDG_STATE_HOME: join(home, "state"),
APPDATA: join(home, "appdata"),
LOCALAPPDATA: join(home, "localappdata"),
REA_LOG_LEVEL: "silent",
},
},
);
expect(child.error).toBeUndefined();
expect(child.status, child.stderr).toBe(0);
const results = JSON.parse(child.stdout);
expect(results).toHaveLength(6);
for (const result of results.slice(0, 3)) {
expect(result.exitCode, result.command).toBe(1);
expect(result.output).toContain("VALIDATION_ERROR");
expect(result.after).toBe(result.before);
expect(result.backup).toBeNull();
}
const expected = [
{ command: "/fixture/server path", args: ["", "--mcp"] },
{
command: String.raw`C:\Program Files\server.exe`,
args: [String.raw`C:\data\file`],
},
{ command: "fixture-server", args: ["--mcp"] },
];
for (const [index, result] of results.slice(3).entries()) {
expect(result.exitCode, result.output).toBe(0);
const original = JSON.parse(result.before);
expect(JSON.parse(result.after)).toEqual({
...original,
"amp.mcpServers": {
...original["amp.mcpServers"],
rea: { ...original["amp.mcpServers"].rea, ...expected[index] },
},
});
expect(result.backup).toBe(result.before);
}
} finally {
await rm(home, { recursive: true, force: true });
}
}, 30_000);