mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(setup): configure every detected client
This commit is contained in:
@@ -437,7 +437,8 @@ try {
|
||||
)
|
||||
throw new Error("packaged stale-skill upgrade was not isolated");
|
||||
|
||||
await writeFile(cursorConfig, "malformed");
|
||||
await writeFile(claudeConfig, "malformed");
|
||||
await writeFile(cursorConfig, "{}\n");
|
||||
const failedExecution = await runWithStatus(
|
||||
cli,
|
||||
["setup", "--yes", "--json"],
|
||||
@@ -447,10 +448,17 @@ try {
|
||||
if (
|
||||
failed.status !== "needs_human" ||
|
||||
failedExecution.status !== 1 ||
|
||||
(await readFile(cursorConfig, "utf8")) !== "malformed"
|
||||
failed.clients?.claude_desktop?.status !== "failed" ||
|
||||
failed.clients?.cursor?.status !== "configured" ||
|
||||
!failed.appliedActions.includes("configured_cursor") ||
|
||||
(await readFile(claudeConfig, "utf8")) !== "malformed" ||
|
||||
json(await readFile(cursorConfig, "utf8")).mcpServers?.rea?.command !==
|
||||
cli
|
||||
)
|
||||
throw new Error("packaged setup failure recovery did not preserve input");
|
||||
await writeFile(cursorConfig, '{"existing":true}\n');
|
||||
throw new Error(
|
||||
`packaged setup did not continue after an earlier client failure: ${JSON.stringify(failed)}`,
|
||||
);
|
||||
await writeFile(claudeConfig, "{}\n");
|
||||
const recoveredExecution = await runWithStatus(
|
||||
cli,
|
||||
["setup", "--yes", "--json"],
|
||||
|
||||
@@ -16,7 +16,7 @@ const failedConfigurationMessage = (
|
||||
return "Agent configuration could not be verified after writing. Repair the configuration file or restore its `.rea.backup`, then rerun setup.";
|
||||
};
|
||||
|
||||
/** Configure each detected agent, stopping after the first failed transaction. */
|
||||
/** Configure every detected agent and report the first failed transaction. */
|
||||
export const configureDetectedClients = async (options: {
|
||||
readonly host: SetupHost;
|
||||
readonly detectedClients: readonly SetupClient[];
|
||||
@@ -25,6 +25,7 @@ export const configureDetectedClients = async (options: {
|
||||
readonly clients: Record<string, ClientConfigurationResult>;
|
||||
readonly appliedActions: string[];
|
||||
}): Promise<string | undefined> => {
|
||||
let failure: string | undefined;
|
||||
for (const client of options.detectedClients) {
|
||||
const result = await options.host.configureClient(
|
||||
client,
|
||||
@@ -33,9 +34,9 @@ export const configureDetectedClients = async (options: {
|
||||
);
|
||||
options.clients[client.name] = result;
|
||||
if (result.status === "failed")
|
||||
return failedConfigurationMessage(result.reason);
|
||||
if (result.status === "configured")
|
||||
failure ??= failedConfigurationMessage(result.reason);
|
||||
else if (result.status === "configured")
|
||||
options.appliedActions.push(`configured_${client.name}`);
|
||||
}
|
||||
return undefined;
|
||||
return failure;
|
||||
};
|
||||
|
||||
@@ -301,6 +301,31 @@ describe("setup workflow", () => {
|
||||
expect(result.remediation).not.toContain("internal_client_key");
|
||||
});
|
||||
|
||||
it("records every detected client outcome after an earlier failure", async () => {
|
||||
const host = new FakeSetupHost();
|
||||
host.hopper = "/Applications/Hopper";
|
||||
host.clients = [
|
||||
{ name: "first", configPath: "/first.json" },
|
||||
{ name: "second", configPath: "/second.json" },
|
||||
{ name: "third", configPath: "/third.json" },
|
||||
];
|
||||
host.clientResults.set("first", { status: "failed", reason: "write" });
|
||||
host.clientResults.set("second", { status: "configured" });
|
||||
host.clientResults.set("third", { status: "failed", reason: "readback" });
|
||||
|
||||
const result = await runSetup(options(true), host);
|
||||
|
||||
expect(host.configurations).toBe(3);
|
||||
expect(result.clients).toEqual({
|
||||
first: { status: "failed", reason: "write" },
|
||||
second: { status: "configured" },
|
||||
third: { status: "failed", reason: "readback" },
|
||||
});
|
||||
expect(result.appliedActions).toEqual(["configured_second"]);
|
||||
expect(result.status).toBe("needs_human");
|
||||
expect(result.remediation).toContain("could not be updated");
|
||||
});
|
||||
|
||||
it("explains skill installation recovery", async () => {
|
||||
const host = new FakeSetupHost();
|
||||
host.hopper = "/Applications/Hopper";
|
||||
|
||||
Reference in New Issue
Block a user