From 6a2f9fae5fbdd5fa79b066c9827c58433c6be3db Mon Sep 17 00:00:00 2001 From: Dax Date: Sat, 11 Jul 2026 15:05:08 +0000 Subject: [PATCH] fix(cli): avoid duplicate Zsh positional completion --- packages/cli/test/completions.test.ts | 15 ++++++++++++++ patches/effect@4.0.0-beta.83.patch | 28 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 packages/cli/test/completions.test.ts diff --git a/packages/cli/test/completions.test.ts b/packages/cli/test/completions.test.ts new file mode 100644 index 000000000000..f0826db26383 --- /dev/null +++ b/packages/cli/test/completions.test.ts @@ -0,0 +1,15 @@ +import { expect, test } from "bun:test" +import path from "node:path" + +test("zsh completion does not define the first positional twice", async () => { + const proc = Bun.spawn([process.execPath, path.join(import.meta.dir, "../src/index.ts"), "--completions", "zsh"], { + stdout: "pipe", + stderr: "pipe", + }) + const output = await new Response(proc.stdout).text() + const error = await new Response(proc.stderr).text() + + expect(await proc.exited, error).toBe(0) + expect(output).toContain("'1:command:->command'") + expect(output).not.toContain("':Directory to start OpenCode in:'") +}) diff --git a/patches/effect@4.0.0-beta.83.patch b/patches/effect@4.0.0-beta.83.patch index 11030bc6ab7f..c2ae36e31157 100644 --- a/patches/effect@4.0.0-beta.83.patch +++ b/patches/effect@4.0.0-beta.83.patch @@ -55,3 +55,31 @@ index f2920365cf0328146523ce2e2dba04d6a8809a4a..5482d635cdf01a72063ff683d244fab8 /** * Creates a streaming `Uint8Array` success response schema. * +diff --git a/dist/unstable/cli/internal/completions/zsh.js b/dist/unstable/cli/internal/completions/zsh.js +--- a/dist/unstable/cli/internal/completions/zsh.js ++++ b/dist/unstable/cli/internal/completions/zsh.js +@@ -102,9 +102,7 @@ const generateFunction = (descriptor, parentPath, lines) => { + lines.push(` ${spec}`); + } + } +- for (const arg of descriptor.arguments) { +- lines.push(` ${argSpec(arg)}`); +- } ++ // Positional specs conflict with the explicit first-position subcommand dispatcher in Zsh. + lines.push(` '1:command:->command'`); + lines.push(` '*::arg:->args'`); + lines.push(` )`); +diff --git a/src/unstable/cli/internal/completions/zsh.ts b/src/unstable/cli/internal/completions/zsh.ts +--- a/src/unstable/cli/internal/completions/zsh.ts ++++ b/src/unstable/cli/internal/completions/zsh.ts +@@ -133,9 +133,7 @@ const generateFunction = ( + lines.push(` ${spec}`) + } + } +- for (const arg of descriptor.arguments) { +- lines.push(` ${argSpec(arg)}`) +- } ++ // Positional specs conflict with the explicit first-position subcommand dispatcher in Zsh. + lines.push(` '1:command:->command'`) + lines.push(` '*::arg:->args'`) + lines.push(` )`)