diff --git a/packages/coding-agent/src/cli/args.ts b/packages/coding-agent/src/cli/args.ts index 284888d13..a35879807 100644 --- a/packages/coding-agent/src/cli/args.ts +++ b/packages/coding-agent/src/cli/args.ts @@ -92,11 +92,21 @@ export function parseArgs(args: string[]): Args { result.help = true; } else if (arg === "--version" || arg === "-v") { result.version = true; - } else if (arg === "--mode" && i + 1 < args.length) { - const mode = args[++i]; - if (mode === "text" || mode === "json" || mode === "rpc") { - result.mode = mode; + } else if (arg === "--mode") { + const mode = args[i + 1]; + if (mode === undefined || mode.startsWith("-")) { + result.diagnostics.push({ type: "error", message: "--mode requires text, json, or rpc" }); + continue; } + i++; + if (mode !== "text" && mode !== "json" && mode !== "rpc") { + result.diagnostics.push({ + type: "error", + message: `Invalid mode "${mode}". Valid values: text, json, rpc`, + }); + continue; + } + result.mode = mode; } else if (arg === "--continue" || arg === "-c") { result.continue = true; } else if (arg === "--resume" || arg === "-r") { diff --git a/packages/coding-agent/test/args.test.ts b/packages/coding-agent/test/args.test.ts index 710ed7b09..37e6407d5 100644 --- a/packages/coding-agent/test/args.test.ts +++ b/packages/coding-agent/test/args.test.ts @@ -115,16 +115,6 @@ describe("parseArgs", () => { expect(result.appendSystemPrompt).toEqual(["Context A", "Context B"]); }); - test("parses --mode", () => { - const result = parseArgs(["--mode", "json"]); - expect(result.mode).toBe("json"); - }); - - test("parses --mode rpc", () => { - const result = parseArgs(["--mode", "rpc"]); - expect(result.mode).toBe("rpc"); - }); - test("parses --session", () => { const result = parseArgs(["--session", "/path/to/session.jsonl"]); expect(result.session).toBe("/path/to/session.jsonl"); @@ -157,6 +147,48 @@ describe("parseArgs", () => { }); }); + // Issue #9045 + describe("--mode flag", () => { + test.each(["text", "json", "rpc"] as const)("parses --mode %s", (mode) => { + const result = parseArgs(["--mode", mode]); + expect(result.mode).toBe(mode); + expect(result.diagnostics).toEqual([]); + }); + + test.each(["yaml", ""])("rejects invalid --mode value %j", (mode) => { + const result = parseArgs(["--mode", mode, "--version"]); + expect(result.mode).toBeUndefined(); + expect(result.version).toBe(true); + expect(result.messages).toEqual([]); + expect(result.unknownFlags.size).toBe(0); + expect(result.diagnostics).toEqual([ + { type: "error", message: `Invalid mode "${mode}". Valid values: text, json, rpc` }, + ]); + }); + + test("reports a missing --mode value", () => { + const result = parseArgs(["--mode"]); + expect(result.mode).toBeUndefined(); + expect(result.unknownFlags.size).toBe(0); + expect(result.diagnostics).toEqual([{ type: "error", message: "--mode requires text, json, or rpc" }]); + }); + + test("does not consume another option as a --mode value", () => { + const result = parseArgs(["--mode", "--version"]); + expect(result.mode).toBeUndefined(); + expect(result.version).toBe(true); + expect(result.unknownFlags.size).toBe(0); + expect(result.diagnostics).toEqual([{ type: "error", message: "--mode requires text, json, or rpc" }]); + }); + + test("reports an invalid --mode value after a valid one", () => { + const result = parseArgs(["--mode", "json", "--mode", "yaml"]); + expect(result.diagnostics).toEqual([ + { type: "error", message: 'Invalid mode "yaml". Valid values: text, json, rpc' }, + ]); + }); + }); + describe("--name flag", () => { test("parses --name flag with value", () => { const result = parseArgs(["--name", "my-session"]);