140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import { access, mkdir, readFile } from "node:fs/promises";
|
|
import { userInfo } from "node:os";
|
|
import { isAbsolute, join, relative, sep } from "node:path";
|
|
import { parse } from "jsonc-parser";
|
|
|
|
import { expect } from "vitest";
|
|
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
|
|
cliTest(
|
|
"setup dry run resolves empty home values without writing to the cwd",
|
|
async ({ cli }) => {
|
|
const directory = await createTestTempDirectory("rea-empty-home-dry-run-");
|
|
const workingDirectory = join(directory, "cwd");
|
|
await mkdir(workingDirectory);
|
|
const hostHome = userInfo().homedir;
|
|
const result = await cli.run({
|
|
arguments: [
|
|
"setup",
|
|
"--client",
|
|
"cursor",
|
|
"--skill=false",
|
|
"--dry-run",
|
|
"--json",
|
|
],
|
|
cwd: workingDirectory,
|
|
environment: {
|
|
HOME: "",
|
|
USERPROFILE: "",
|
|
HOMEDRIVE: "",
|
|
HOMEPATH: "",
|
|
XDG_CONFIG_HOME: "",
|
|
},
|
|
});
|
|
|
|
expect(result.exitCode, result.stdout).toBe(0);
|
|
const output = result.json as {
|
|
plannedActions?: Array<{ kind?: unknown; target?: unknown }>;
|
|
status?: unknown;
|
|
};
|
|
expect(["planned", "ready"]).toContain(output.status);
|
|
const configTargets = (output.plannedActions ?? [])
|
|
.filter((action) => action.kind === "configure_client")
|
|
.map((action) => action.target);
|
|
for (const target of configTargets) {
|
|
expect(typeof target).toBe("string");
|
|
if (typeof target !== "string") continue;
|
|
expect(isAbsolute(target)).toBe(true);
|
|
const relativeTarget = relative(hostHome, target);
|
|
expect(
|
|
relativeTarget === "" ||
|
|
(!relativeTarget.startsWith(`..${sep}`) && relativeTarget !== ".."),
|
|
).toBe(true);
|
|
}
|
|
expect(configTargets).not.toContain(
|
|
join(workingDirectory, ".cursor", "mcp.json"),
|
|
);
|
|
await expect(
|
|
access(join(workingDirectory, ".cursor", "mcp.json")),
|
|
).rejects.toMatchObject({
|
|
code: "ENOENT",
|
|
});
|
|
},
|
|
);
|
|
|
|
cliTest.skipIf(process.platform === "win32")(
|
|
"setup, doctor, and uninstall use the nonempty fallback home when HOME is empty",
|
|
async ({ cli }) => {
|
|
const directory = await createTestTempDirectory(
|
|
"rea-empty-home-lifecycle-",
|
|
);
|
|
const home = join(directory, "fallback-home");
|
|
const workingDirectory = join(directory, "cwd");
|
|
await mkdir(home);
|
|
await mkdir(workingDirectory);
|
|
const environment = {
|
|
HOME: "",
|
|
USERPROFILE: home,
|
|
XDG_CONFIG_HOME: join(home, ".config"),
|
|
};
|
|
const run = (arguments_: readonly string[]) =>
|
|
cli.run({
|
|
arguments: arguments_,
|
|
cwd: workingDirectory,
|
|
environment,
|
|
});
|
|
|
|
const setup = await run(["setup", "--client", "cursor", "--yes", "--json"]);
|
|
expect(setup.exitCode, setup.stderr).toBe(0);
|
|
expect(setup.json).toMatchObject({ status: "ready" });
|
|
await access(join(home, ".cursor", "mcp.json"));
|
|
await access(
|
|
join(home, ".agents", "skills", "reverse-engineer-anything", "SKILL.md"),
|
|
);
|
|
await expect(
|
|
access(join(workingDirectory, ".cursor", "mcp.json")),
|
|
).rejects.toMatchObject({
|
|
code: "ENOENT",
|
|
});
|
|
await expect(
|
|
access(join(workingDirectory, ".agents", "skills")),
|
|
).rejects.toMatchObject({ code: "ENOENT" });
|
|
|
|
const doctor = await run([
|
|
"doctor",
|
|
"--client",
|
|
"cursor",
|
|
"--skill",
|
|
"--json",
|
|
]);
|
|
expect(doctor.exitCode, doctor.stdout).toBe(0);
|
|
expect(doctor.json).toMatchObject({ healthy: true });
|
|
|
|
const uninstall = await run(["uninstall", "--json"]);
|
|
expect(uninstall.exitCode, uninstall.stderr).toBe(0);
|
|
expect(uninstall.json).toMatchObject({ status: "complete" });
|
|
const remainingConfig = parse(
|
|
await readFile(join(home, ".cursor", "mcp.json"), "utf8"),
|
|
);
|
|
expect(remainingConfig).not.toHaveProperty("mcpServers.rea");
|
|
await expect(
|
|
access(
|
|
join(
|
|
home,
|
|
".agents",
|
|
"skills",
|
|
"reverse-engineer-anything",
|
|
"SKILL.md",
|
|
),
|
|
),
|
|
).rejects.toMatchObject({ code: "ENOENT" });
|
|
await expect(
|
|
access(join(workingDirectory, ".cursor", "mcp.json")),
|
|
).rejects.toMatchObject({
|
|
code: "ENOENT",
|
|
});
|
|
},
|
|
);
|