Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/cli/src/cli-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ export async function parseArguments(argv?: string[]): Promise<ParsedCliArgs> {
});

const parsed = y.parseSync() as Record<string, unknown>;
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"];
Expand All @@ -152,7 +154,7 @@ export async function parseArguments(argv?: string[]): Promise<ParsedCliArgs> {
}

return {
prompt: parsed.prompt as string | undefined,
prompt: (parsed.prompt as string | undefined) ?? positionalPrompt,
resume,
version: parsed.version === true,
help: parsed.help === true,
Expand Down
30 changes: 30 additions & 0 deletions packages/cli/src/tests/cli-args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -140,6 +152,13 @@ test("parseArguments handles -p before --resume <id>", async () => {
assert.equal(r.prompt, "hello");
});

test("parseArguments handles --resume <id> 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));
Expand Down Expand Up @@ -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 {
Expand Down