diff --git a/src/adapters/codex.ts b/src/adapters/codex.ts index 27e7ba8..2623ef0 100644 --- a/src/adapters/codex.ts +++ b/src/adapters/codex.ts @@ -269,7 +269,9 @@ export class CodexAdapter implements AgentAdapter { promptFilePath = await writePromptFile(opts.prompt); promptFd = await openPromptFd(promptFilePath); } else { - args.push(opts.prompt); + // Use -- separator to prevent prompts starting with dashes (e.g. YAML + // frontmatter "---") from being interpreted as CLI options by codex. + args.push("--", opts.prompt); } const env = buildSpawnEnv(undefined, opts.env); diff --git a/src/adapters/opencode-launch.test.ts b/src/adapters/opencode-launch.test.ts index d917eaa..af44da2 100644 --- a/src/adapters/opencode-launch.test.ts +++ b/src/adapters/opencode-launch.test.ts @@ -74,7 +74,13 @@ describe("OpenCodeAdapter launch", () => { const modelIdx = args.indexOf("--model"); const promptIdx = args.indexOf("fix the bug"); expect(modelIdx).toBeLessThan(promptIdx); - expect(args).toEqual(["run", "--model", "deepseek-r1", "fix the bug"]); + expect(args).toEqual([ + "run", + "--model", + "deepseek-r1", + "--", + "fix the bug", + ]); }); it("omits --model flag when opts.model is not set", async () => { @@ -87,6 +93,22 @@ describe("OpenCodeAdapter launch", () => { expect(spawnCalls).toHaveLength(1); const args = spawnCalls[0].args; expect(args).not.toContain("--model"); - expect(args).toEqual(["run", "fix the bug"]); + expect(args).toEqual(["run", "--", "fix the bug"]); + }); + + it("inserts -- before prompts that start with dashes (e.g. YAML frontmatter)", async () => { + const dashPrompt = "---\ntitle: My Spec\n---\nBuild this."; + await adapter.launch({ + adapter: "opencode", + prompt: dashPrompt, + cwd: tmpDir, + }); + + expect(spawnCalls).toHaveLength(1); + const args = spawnCalls[0].args; + // -- must appear immediately before the prompt positional + const separatorIdx = args.indexOf("--"); + expect(separatorIdx).toBeGreaterThan(-1); + expect(args[separatorIdx + 1]).toBe(dashPrompt); }); }); diff --git a/src/adapters/opencode.ts b/src/adapters/opencode.ts index 3fca28f..9f2e6d7 100644 --- a/src/adapters/opencode.ts +++ b/src/adapters/opencode.ts @@ -357,7 +357,9 @@ export class OpenCodeAdapter implements AgentAdapter { promptFilePath = await writePromptFile(opts.prompt); promptFd = await openPromptFd(promptFilePath); } else { - args.push(opts.prompt); + // Use -- separator to prevent prompts starting with dashes (e.g. YAML + // frontmatter "---") from being interpreted as CLI options by opencode. + args.push("--", opts.prompt); } const env = buildSpawnEnv(undefined, opts.env); diff --git a/src/adapters/pi-rust.ts b/src/adapters/pi-rust.ts index 3e0877f..0178ff4 100644 --- a/src/adapters/pi-rust.ts +++ b/src/adapters/pi-rust.ts @@ -342,7 +342,9 @@ export class PiRustAdapter implements AgentAdapter { const args = useTempFile ? ["--print", "--mode", "json"] - : ["--print", "--mode", "json", opts.prompt]; + : // Use -- separator to prevent prompts starting with dashes from being + // interpreted as CLI options by pi-rust. + ["--print", "--mode", "json", "--", opts.prompt]; if (useTempFile) { promptFilePath = await writePromptFile(opts.prompt);