diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index 949bcf02..933d2875 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -29,6 +29,7 @@ type ProfileCliOptions = { type WebCliOptions = { command: "start" | "ui" | "web"; + daemon: boolean; daemonChild: boolean; ensureGatewayRunning: boolean; help: boolean; @@ -101,6 +102,13 @@ async function main(): Promise { printWebHelp(0); return; } + if (options.daemon) { + await startService({ + ...options, + command: "start" + }); + return; + } await runWebServer(options); return; } @@ -130,6 +138,7 @@ async function main(): Promise { if (profile.agent === "codex" && resolvedSurface === "app" && profileOptions.agentArgs.length === 0) { const state = await startService({ command: "start", + daemon: false, daemonChild: false, ensureGatewayRunning: true, help: false, @@ -158,6 +167,7 @@ async function main(): Promise { profileGatewayLease ??= createProfileGatewayLease(); await startService({ command: "start", + daemon: false, daemonChild: false, ensureGatewayRunning: true, help: false, @@ -313,6 +323,7 @@ function parseStopArgs(args: string[]): StopCliOptions { function parseWebArgs(args: string[], command: WebCliOptions["command"], defaultOpen = false): WebCliOptions { const options: WebCliOptions = { command, + daemon: false, daemonChild: false, ensureGatewayRunning: false, help: false, @@ -342,8 +353,12 @@ function parseWebArgs(args: string[], command: WebCliOptions["command"], default options.startGateway = false; continue; } - if (arg === "--daemon-child") { - options.daemonChild = true; + if (arg === "--daemon" || arg === "--daemon-child") { + if (arg === "--daemon") { + options.daemon = true; + } else { + options.daemonChild = true; + } continue; } if (arg === "--profile-managed") { @@ -569,9 +584,9 @@ function printHelp(exitCode: number): void { const command = cliCommandName(); const output = [ "Usage:", - ` ${command} start [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, - ` ${command} ui [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, - ` ${command} serve [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, + ` ${command} start [--daemon] [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, + ` ${command} ui [--daemon] [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, + ` ${command} serve [--daemon] [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, ` ${command} stop`, ` ${command} [cli|app] [-- ]`, "", @@ -598,9 +613,10 @@ function printStartHelp(exitCode: number): void { const command = cliCommandName(); const output = [ "Usage:", - ` ${command} start [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, + ` ${command} start [--daemon] [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, "", "Options:", + " --daemon Run the management server in the background (default for start).", " --host Management server host. Defaults to CCR_WEB_HOST or 127.0.0.1.", " --port Management server port. Defaults to CCR_WEB_PORT or 3458.", " --open Open the management page in the default browser.", @@ -622,11 +638,12 @@ function printUiHelp(exitCode: number): void { const command = cliCommandName(); const output = [ "Usage:", - ` ${command} ui [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, + ` ${command} ui [--daemon] [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, "", "Starts the background CCR service if needed and opens the management UI in the default browser.", "", "Options:", + " --daemon Run the management server in the background (default for ui).", " --host Management server host. Defaults to CCR_WEB_HOST or 127.0.0.1.", " --port Management server port. Defaults to CCR_WEB_PORT or 3458.", " --open Open the management page (default).", @@ -661,11 +678,12 @@ function printWebHelp(exitCode: number): void { const command = cliCommandName(); const output = [ "Usage:", - ` ${command} serve [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, + ` ${command} serve [--daemon] [--host ] [--port ] [--open|--no-open] [--gateway|--no-gateway]`, "", - `Runs in the foreground. ${command} web is an alias.`, + `Runs in the foreground by default. ${command} web is an alias.`, "", "Options:", + " --daemon Start the management server in the background instead of the foreground.", " --host Management server host. Defaults to CCR_WEB_HOST or 127.0.0.1.", " --port Management server port. Defaults to CCR_WEB_PORT or 3458.", " --open Open the management page in the default browser.", diff --git a/packages/cli/test/integration/cli-help.test.mjs b/packages/cli/test/integration/cli-help.test.mjs index e8a330bb..5d9bdea2 100644 --- a/packages/cli/test/integration/cli-help.test.mjs +++ b/packages/cli/test/integration/cli-help.test.mjs @@ -34,6 +34,18 @@ test("every service command exposes its package-owned command help", () => { } }); +test("built CLI accepts --daemon on service commands", () => { + for (const args of [ + ["start", "--daemon", "--help"], + ["ui", "--daemon", "--help"], + ["serve", "--daemon", "--help"] + ]) { + const result = runCli(args); + assert.equal(result.status, 0, `${args.join(" ")}: ${result.stderr}`); + assert.match(result.stdout, /--daemon/, args.join(" ")); + } +}); + test("built CLI rejects missing, out-of-range, and unknown service options", () => { const cases = [ [["serve", "--host"], /--host requires a value/],