diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 17c54e256..d11f5d424 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -16,12 +16,12 @@ import { const DEFAULT_PORT = 3000; const MAX_PORT_SCAN = 100; -/** Find the first available port starting from `start`, scanning upward. */ -async function findFreePort(start: number): Promise { +/** Find the first available port starting from `start`, scanning upward. Returns `null` if none found. */ +async function findFreePort(start: number): Promise { for (let port = start; port < start + MAX_PORT_SCAN; port++) { if (await isPortAvailable(port)) return port; } - return start; // fallback — will fail at bind time with a clear error + return null; } async function prompt( @@ -157,7 +157,7 @@ export function registerInit(program: Command): void { .option("--auto", "Auto-generate config with sensible defaults (no prompts)") .option( "--smart", - "Analyze project and generate custom rules (requires --auto, uses AI if available)", + "Analyze project and generate custom rules (coming soon — requires --auto)", ) .action(async (opts: { output: string; auto?: boolean; smart?: boolean }) => { const outputPath = resolve(opts.output); @@ -244,7 +244,15 @@ export function registerInit(program: Command): void { ); const worktreeDir = await prompt(rl, "Worktree directory", "~/.worktrees"); const freePort = await findFreePort(DEFAULT_PORT); - const portStr = await prompt(rl, "Dashboard port", String(freePort)); + if (freePort === null) { + console.log( + chalk.yellow( + `\n⚠ No free port found in range ${DEFAULT_PORT}–${DEFAULT_PORT + MAX_PORT_SCAN - 1}.`, + ), + ); + console.log(chalk.dim(" Please specify a port manually.\n")); + } + const portStr = await prompt(rl, "Dashboard port", String(freePort ?? DEFAULT_PORT)); const port = parseInt(portStr, 10); if (isNaN(port) || port < 1 || port > 65535) { console.error(chalk.red("\nInvalid port number. Must be 1-65535.")); @@ -303,6 +311,8 @@ export function registerInit(program: Command): void { ); const projectConfig: Record = { + name: projectId, + sessionPrefix: projectId.slice(0, 8), repo, path: projectPath, defaultBranch, @@ -444,10 +454,18 @@ async function handleAutoMode(outputPath: string, smart: boolean): Promise const defaultBranch = env.defaultBranch || "main"; const port = await findFreePort(DEFAULT_PORT); + if (port === null) { + console.log( + chalk.yellow( + ` ⚠ No free port found in range ${DEFAULT_PORT}–${DEFAULT_PORT + MAX_PORT_SCAN - 1}.`, + ), + ); + console.log(chalk.dim(" Set the port manually in the config before running ao start.\n")); + } const config: Record = { dataDir: "~/.agent-orchestrator", worktreeDir: "~/.worktrees", - port, + port: port ?? DEFAULT_PORT, defaults: { runtime: "tmux", agent: "claude-code", @@ -456,6 +474,8 @@ async function handleAutoMode(outputPath: string, smart: boolean): Promise }, projects: { [projectId]: { + name: projectId, + sessionPrefix: projectId.slice(0, 8), repo, path, defaultBranch,