diff --git a/src/configure.ts b/src/configure.ts index eddf9a3..312158b 100644 --- a/src/configure.ts +++ b/src/configure.ts @@ -47,6 +47,8 @@ interface PromptOption { export interface SelectParams { readonly message: string; readonly options: readonly PromptOption[]; + /** Which option the cursor starts on. Omit to let the prompt library fall back to its own default (the first option) — pass this explicitly whenever the safest or most common answer isn't the first one listed, so the on-screen reading order and the default-on-Enter answer can differ deliberately rather than being forced to match. */ + readonly initialValue?: Value; } /** Parameters for a multi-select prompt. */ @@ -103,6 +105,7 @@ export const realPromptsPort: PromptsPort = { .select({ message: params.message, options: toClackOptions(params.options), + ...(params.initialValue === undefined ? {} : { initialValue: params.initialValue }), }) .then((value): Value | symbol => { if (typeof value === "symbol" || isKnownOptionValue(value, params.options)) { diff --git a/src/identityManager.test.ts b/src/identityManager.test.ts index 3e974fe..0476edc 100644 --- a/src/identityManager.test.ts +++ b/src/identityManager.test.ts @@ -218,6 +218,25 @@ describe("identityManager", () => { expect(readIdentity(paths, "joseph.mearman@exadev.io")).toBeDefined(); expect(readActiveIdentity(paths)).toBe("joseph.mearman@exadev.io"); }); + + it("defaults the profile-creation prompt's cursor to skip, so a bare Enter creates no profile", async () => { + const selectCalls: SelectParams[] = []; + const base = scriptedIdentityPrompts(["create", "skip"]); + const spying: PromptsPort = { + ...base, + select: (params) => { + selectCalls.push(params); + return base.select(params); + }, + }; + + await runIdentityWizard(spying, paths, "work"); + + const profilePrompt = selectCalls.find((call) => call.message.includes("configuration profile")); + expect(profilePrompt?.initialValue).toBe("skip"); + // The option order stays create-then-skip regardless — initialValue moves the default answer without reordering what's read on screen. + expect(profilePrompt?.options.map((option) => option.value)).toEqual(["create", "skip"]); + }); }); describe("isIdentityDirectoryName", () => { diff --git a/src/identityManager.ts b/src/identityManager.ts index 9cdf6b4..8b63c1e 100644 --- a/src/identityManager.ts +++ b/src/identityManager.ts @@ -114,6 +114,8 @@ export async function runIdentityWizard(prompts: PromptsPort, paths: LayoutPaths { value: "create", label: "Create and configure a profile" }, { value: "skip", label: "Skip for now" }, ], + // Most identities need no profile of their own at all — they're meant to fall through to whatever the global default (or a directory rule) already resolves to, and a profile only earns its keep once an identity genuinely needs to diverge from that. Defaulting the cursor to "skip" makes the common, no-profile-needed case the one a bare Enter confirms, without reordering the options and making "skip" read as the first, most prominent choice on screen. + initialValue: "skip", }); if (!prompts.isCancel(profileChoice) && profileChoice === "create") { const result = await runProfileWizard(prompts, { paths, defaultNewName: name });