mirror of
https://github.com/vercel/eve.git
synced 2026-09-20 05:35:39 +08:00
fix(eve): simplify add failure results (#3495)
Signed-off-by: owenkephart <owen.kephart@vercel.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"eve": patch
|
||||
---
|
||||
|
||||
Keep registry installation error traces visible in the dev TUI after an `/add` failure, alongside the per-item recovery guidance.
|
||||
@@ -17,7 +17,8 @@ describe("formatRegistrySessionResult", () => {
|
||||
failures: [
|
||||
{
|
||||
title: "Slack",
|
||||
message: "Vercel CLI is not authenticated.\nRun /deploy, then try again.",
|
||||
message:
|
||||
"Vercel CLI is not authenticated. Try again with `eve add channel/slack --skip-install`.",
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -30,7 +31,7 @@ describe("formatRegistrySessionResult", () => {
|
||||
" Configured MCP connection.\n\n" +
|
||||
" ⨯ Slack\n" +
|
||||
" Vercel CLI is not authenticated.\n" +
|
||||
" Run /deploy, then try again.",
|
||||
" Try again with `eve add channel/slack --skip-install`.",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@ function joinedTitles(titles: readonly string[]): string {
|
||||
return `${titles.slice(0, -1).join(", ")}, and ${titles.at(-1)}`;
|
||||
}
|
||||
|
||||
function formatFailureMessage(message: string): string {
|
||||
return message.replace(" Try again with `", "\nTry again with `");
|
||||
}
|
||||
|
||||
function resultHeadline(
|
||||
outcomes: readonly { kind: "installed" | "failed" | "cancelled" }[],
|
||||
installedTitles: readonly string[],
|
||||
@@ -67,7 +71,11 @@ export function formatRegistrySessionResult(result: RegistrySessionResult): stri
|
||||
continue;
|
||||
}
|
||||
if (outcome.kind === "failed") {
|
||||
lines.push(...outcome.message.split("\n").map((line) => ` ${line}`));
|
||||
lines.push(
|
||||
...formatFailureMessage(outcome.message)
|
||||
.split("\n")
|
||||
.map((line) => ` ${line}`),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (outcome.facts.length === 0 && outcome.output.length === 0) {
|
||||
|
||||
@@ -118,6 +118,31 @@ describe("runRegistryFlow", () => {
|
||||
expect(flow.browseRegistryCatalog).not.toHaveBeenCalled();
|
||||
expect(flow.installRegistryItem).toHaveBeenCalledOnce();
|
||||
});
|
||||
it("reports an installation failure without another decision prompt", async () => {
|
||||
const flow = deps();
|
||||
flow.installRegistryItem = vi.fn(async () => {
|
||||
throw new Error("Dependency installation failed.");
|
||||
});
|
||||
const fake = createFakePrompter();
|
||||
|
||||
await expect(
|
||||
runRegistryFlow({
|
||||
appRoot: "/agent",
|
||||
initialAddress: "connection/linear",
|
||||
prompter: fake.prompter,
|
||||
deps: flow,
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
kind: "done",
|
||||
result: {
|
||||
failures: [{ title: "connection/linear", message: "Dependency installation failed." }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(fake.prompter.log.error).not.toHaveBeenCalled();
|
||||
expect(fake.selectMessages).toEqual([]);
|
||||
});
|
||||
|
||||
it("cancels before installing anything", async () => {
|
||||
const flow = deps();
|
||||
const fake = createFakePrompter({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { RegistryCatalogItem } from "#cli/commands/registry.js";
|
||||
import { HumanActionRequiredError } from "#setup/human-action.js";
|
||||
import type { Prompter, SingleSelectOptions } from "#setup/prompter.js";
|
||||
import type { Prompter } from "#setup/prompter.js";
|
||||
import { WizardCancelledError } from "#setup/step.js";
|
||||
import { withSpinner } from "#setup/with-spinner.js";
|
||||
|
||||
@@ -120,20 +120,7 @@ export async function runRegistryFlow(input: {
|
||||
if (error instanceof HumanActionRequiredError) throw error;
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
const failureMessage = message.trim() || "Installation failed.";
|
||||
const summary = failureMessage.split("\n").find((line) => line.trim() !== "");
|
||||
activeSession.addFailure(label(item), failureMessage);
|
||||
const request: SingleSelectOptions<"skip" | "cancel"> = {
|
||||
message: `Couldn't add ${label(item)}`,
|
||||
options: [
|
||||
{ value: "skip", label: `Skip ${label(item)}` },
|
||||
{ value: "cancel", label: "Cancel setup" },
|
||||
],
|
||||
};
|
||||
if (summary !== undefined) request.description = summary;
|
||||
const action = await input.prompter.select(request);
|
||||
if (action === "cancel") {
|
||||
return { kind: "done", result: { ...activeSession.result(), cancelled: true } };
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user