FN-5811: respect persisted CLI onboarding completion marker
Ensure CLI onboarding only auto-runs once by honoring a valid persisted completion timestamp. - add `isCliOnboardingComplete` helper to validate non-empty `cliOnboardingCompletedAt` marker values - use the helper in `runOnboard` so reruns are blocked unless `--force` is provided - extend onboard tests to cover marker validation and verify the rerun guidance log Files changed: packages/cli/src/commands/__tests__/onboard.test.ts | 10 ++++++++++ packages/cli/src/commands/onboard.ts | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-5811 Fusion-Task-Lineage: 1547fd85-d06f-4ad0-adca-3a22709447fa
This commit is contained in:
@@ -85,6 +85,14 @@ function makeProviderAuth() {
|
||||
}
|
||||
|
||||
describe("onboard", () => {
|
||||
it("isCliOnboardingComplete handles marker presence correctly", () => {
|
||||
expect(__testUtils.isCliOnboardingComplete({})).toBe(false);
|
||||
expect(__testUtils.isCliOnboardingComplete({ cliOnboardingCompletedAt: "" })).toBe(false);
|
||||
expect(__testUtils.isCliOnboardingComplete({ cliOnboardingCompletedAt: "2026-06-01T00:00:00.000Z" })).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
for (const key of Object.keys(globalSettingsState)) delete globalSettingsState[key];
|
||||
@@ -166,9 +174,11 @@ describe("onboard", () => {
|
||||
it("re-runs only with force when marker already exists", async () => {
|
||||
const providerAuth = makeProviderAuth();
|
||||
mockProviderAuthFactory.mockReturnValue(providerAuth);
|
||||
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
|
||||
globalSettingsState.cliOnboardingCompletedAt = "2026-06-01T00:00:00.000Z";
|
||||
|
||||
await runOnboard({ input: inputFrom(["y", "3", "y", "y", "n", "y"]) });
|
||||
expect(logSpy).toHaveBeenCalledWith("Onboarding already completed. Re-run with --force to run it again.");
|
||||
expect(providerAuth.setApiKey).not.toHaveBeenCalled();
|
||||
expect(mockRunInit).not.toHaveBeenCalled();
|
||||
|
||||
|
||||
@@ -150,12 +150,19 @@ async function runSkippableStep(
|
||||
return true;
|
||||
}
|
||||
|
||||
export function isCliOnboardingComplete(settings: { cliOnboardingCompletedAt?: string }): boolean {
|
||||
return (
|
||||
typeof settings.cliOnboardingCompletedAt === "string" &&
|
||||
settings.cliOnboardingCompletedAt.trim().length > 0
|
||||
);
|
||||
}
|
||||
|
||||
export async function runOnboard(options: OnboardOptions = {}): Promise<void> {
|
||||
const globalSettingsStore = new GlobalSettingsStore();
|
||||
await globalSettingsStore.init();
|
||||
const settings = await globalSettingsStore.getSettings();
|
||||
|
||||
if (settings.cliOnboardingCompletedAt && !options.force) {
|
||||
if (isCliOnboardingComplete(settings) && !options.force) {
|
||||
console.log("Onboarding already completed. Re-run with --force to run it again.");
|
||||
return;
|
||||
}
|
||||
@@ -267,5 +274,6 @@ export const __testUtils = {
|
||||
createPromptSession,
|
||||
validateMaxConcurrent,
|
||||
runSkippableStep,
|
||||
isCliOnboardingComplete,
|
||||
PROMPT_CANCELLED_ERROR,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user