From 4b3fd38c50a573efb0475c65c5324082499126f6 Mon Sep 17 00:00:00 2001 From: caroline-li-studio Date: Tue, 30 Jun 2026 16:02:33 +0800 Subject: [PATCH] fix(cli): preserve positional prompt arguments --- packages/cli/src/cli-args.ts | 4 +++- packages/cli/src/tests/cli-args.test.ts | 30 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/cli-args.ts b/packages/cli/src/cli-args.ts index b86eda4..38b4159 100644 --- a/packages/cli/src/cli-args.ts +++ b/packages/cli/src/cli-args.ts @@ -140,6 +140,8 @@ export async function parseArguments(argv?: string[]): Promise { }); const parsed = y.parseSync() as Record; + const queryRaw = parsed.query as string | string[] | undefined; + const positionalPrompt = Array.isArray(queryRaw) ? queryRaw.join(" ") : queryRaw; const resumeRaw = parsed.resume as string | undefined; let resume: ParsedCliArgs["resume"]; @@ -152,7 +154,7 @@ export async function parseArguments(argv?: string[]): Promise { } return { - prompt: parsed.prompt as string | undefined, + prompt: (parsed.prompt as string | undefined) ?? positionalPrompt, resume, version: parsed.version === true, help: parsed.help === true, diff --git a/packages/cli/src/tests/cli-args.test.ts b/packages/cli/src/tests/cli-args.test.ts index fe90eee..ddb67d4 100644 --- a/packages/cli/src/tests/cli-args.test.ts +++ b/packages/cli/src/tests/cli-args.test.ts @@ -28,6 +28,18 @@ test("parseArguments returns prompt after --prompt", async () => { assert.equal(r.prompt, "hello world"); }); +test("parseArguments returns prompt from positional query", async () => { + const r = await parseArguments(["hello world"]); + assert.ok(!("message" in r)); + assert.equal(r.prompt, "hello world"); +}); + +test("parseArguments joins multi-word positional query", async () => { + const r = await parseArguments(["hello", "world"]); + assert.ok(!("message" in r)); + assert.equal(r.prompt, "hello world"); +}); + test("parseArguments returns undefined prompt when -p is not present", async () => { const r = await parseArguments(["--resume"]); assert.ok(!("message" in r)); @@ -140,6 +152,13 @@ test("parseArguments handles -p before --resume ", async () => { assert.equal(r.prompt, "hello"); }); +test("parseArguments handles --resume combined with positional query", async () => { + const r = await parseArguments(["--resume", "0a5cb7a5-c39d-4c39-a11b-05f8b22b8df6", "hello", "again"]); + assert.ok(!("message" in r)); + assert.equal(r.resume, "0a5cb7a5-c39d-4c39-a11b-05f8b22b8df6"); + assert.equal(r.prompt, "hello again"); +}); + test("parseArguments --version takes precedence over --help", async () => { const r = await parseArguments(["--version", "--help"]); assert.ok(!("message" in r)); @@ -199,6 +218,17 @@ test("parseArguments exits on empty -p value", async () => { }); }); +test("parseArguments exits when positional query is combined with -p", async () => { + await withMockedExit(async (exitSpy) => { + try { + await parseArguments(["hello", "-p", "world"]); + } catch { + /* expected */ + } + assert.ok(exitSpy.calls.length >= 1); + }); +}); + test("parseArguments exits on invalid --resume session ID", async () => { await withMockedExit(async (exitSpy) => { try {