diff --git a/apps/cli/src/shared/output/output.layer.ts b/apps/cli/src/shared/output/output.layer.ts index 65c18177d..b8763b562 100644 --- a/apps/cli/src/shared/output/output.layer.ts +++ b/apps/cli/src/shared/output/output.layer.ts @@ -305,7 +305,7 @@ export const textOutputLayer = Layer.effect( cancel("Operation cancelled."); return yield* Effect.interrupt; } - return value.trim(); + return typeof value === "string" ? value.trim() : ""; }), promptConfirm: (message: string, opts?: { defaultValue?: boolean }) => Effect.gen(function* () { diff --git a/apps/cli/src/shared/output/output.layer.unit.test.ts b/apps/cli/src/shared/output/output.layer.unit.test.ts index 7592e6789..0a6d7f049 100644 --- a/apps/cli/src/shared/output/output.layer.unit.test.ts +++ b/apps/cli/src/shared/output/output.layer.unit.test.ts @@ -297,6 +297,15 @@ describe("Output", () => { }).pipe(Effect.provide(layer)); }); + it.effect("promptPassword treats an undefined response as blank input", () => { + mockClack.password.mockResolvedValue(undefined); + return Effect.gen(function* () { + const out = yield* Output; + const result = yield* out.promptPassword("Enter password"); + expect(result).toBe(""); + }).pipe(Effect.provide(layer)); + }); + it.effect("promptConfirm interrupts on cancel", () => { mockClack.confirm.mockResolvedValue(Symbol.for("clack:cancel")); mockClack.isCancel.mockReturnValue(true);