diff --git a/src/lib/init/local-ops.ts b/src/lib/init/local-ops.ts index 429bea2f..ec201091 100644 --- a/src/lib/init/local-ops.ts +++ b/src/lib/init/local-ops.ts @@ -141,6 +141,19 @@ function safePath(cwd: string, relative: string): string { return resolved; } +/** + * Pre-compute directory listing before the first API call. + * Uses the same parameters the server's discover-context step would request. + */ +export function precomputeDirListing(directory: string): LocalOpResult { + return listDir({ + type: "local-op", + operation: "list-dir", + cwd: directory, + params: { path: ".", recursive: true, maxDepth: 3, maxEntries: 500 }, + }); +} + export async function handleLocalOp( payload: LocalOpPayload, options: WizardOptions diff --git a/src/lib/init/wizard-runner.ts b/src/lib/init/wizard-runner.ts index ea38246f..842e1329 100644 --- a/src/lib/init/wizard-runner.ts +++ b/src/lib/init/wizard-runner.ts @@ -21,7 +21,7 @@ import { } from "./constants.js"; import { formatError, formatResult } from "./formatters.js"; import { handleInteractive } from "./interactive.js"; -import { handleLocalOp } from "./local-ops.js"; +import { handleLocalOp, precomputeDirListing } from "./local-ops.js"; import type { InteractivePayload, LocalOpPayload, @@ -153,9 +153,22 @@ export async function runWizard(options: WizardOptions): Promise { let result: WorkflowRunResult; try { - spin.start("Connecting to wizard..."); + spin.start("Scanning project..."); + const listing = precomputeDirListing(directory); + const dirListing = + ( + listing.data as { + entries: Array<{ + name: string; + path: string; + type: "file" | "directory"; + }>; + } + )?.entries ?? []; + + spin.message("Connecting to wizard..."); result = (await run.startAsync({ - inputData: { directory, force, yes, dryRun, features }, + inputData: { directory, force, yes, dryRun, features, dirListing }, tracingOptions, })) as WorkflowRunResult; } catch (err) {