From 1616c997aed6a40b8a890b8b0b2f5e7a258e3be1 Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Wed, 26 Nov 2025 14:04:46 -0500 Subject: [PATCH 01/14] feat: tui.copy_on_select option --- packages/opencode/src/cli/cmd/tui/app.tsx | 21 ++++++++++++--------- packages/opencode/src/config/config.ts | 5 +++++ packages/sdk/go/config.go | 13 ++++++++----- packages/sdk/js/src/gen/types.gen.ts | 4 ++++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index f72dc8365719..7262de2a0184 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -440,15 +440,18 @@ function App() { onMouseUp={async () => { const text = renderer.getSelection()?.getSelectedText() if (text && text.length > 0) { - const base64 = Buffer.from(text).toString("base64") - const osc52 = `\x1b]52;c;${base64}\x07` - const finalOsc52 = process.env["TMUX"] ? `\x1bPtmux;\x1b${osc52}\x1b\\` : osc52 - /* @ts-expect-error */ - renderer.writeOut(finalOsc52) - await Clipboard.copy(text) - .then(() => toast.show({ message: "Copied to clipboard", variant: "info" })) - .catch(toast.error) - renderer.clearSelection() + const copyOnSelect = sync.data.config.tui?.copy_on_select ?? true + if (copyOnSelect) { + const base64 = Buffer.from(text).toString("base64") + const osc52 = `\x1b]52;c;${base64}\x07` + const finalOsc52 = process.env["TMUX"] ? `\x1bPtmux;\x1b${osc52}\x1b\\` : osc52 + /* @ts-expect-error */ + renderer.writeOut(finalOsc52) + await Clipboard.copy(text) + .then(() => toast.show({ message: "Copied to clipboard", variant: "info" })) + .catch(toast.error) + renderer.clearSelection() + } } }} > diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 0ea0e8fa23b4..a6d37d45eeff 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -456,6 +456,11 @@ export namespace Config { }) .optional() .describe("Scroll acceleration settings"), + copy_on_select: z + .boolean() + .optional() + .default(true) + .describe("Enable copying text to clipboard when selected with mouse"), }) export const Layout = z.enum(["auto", "stretch"]).meta({ diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index 02460fb5df9e..dc8ab0e8df11 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -1834,15 +1834,18 @@ func (r ConfigShare) IsKnown() bool { // TUI specific settings type ConfigTui struct { // TUI scroll speed - ScrollSpeed float64 `json:"scroll_speed"` - JSON configTuiJSON `json:"-"` + ScrollSpeed float64 `json:"scroll_speed"` + // Enable copying text to clipboard when selected with mouse + CopyOnSelect bool `json:"copy_on_select"` + JSON configTuiJSON `json:"-"` } // configTuiJSON contains the JSON metadata for the struct [ConfigTui] type configTuiJSON struct { - ScrollSpeed apijson.Field - raw string - ExtraFields map[string]apijson.Field + ScrollSpeed apijson.Field + CopyOnSelect apijson.Field + raw string + ExtraFields map[string]apijson.Field } func (r *ConfigTui) UnmarshalJSON(data []byte) (err error) { diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 6e3b8c07140e..12bfc6e8e0e0 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -995,6 +995,10 @@ export type Config = { */ enabled: boolean } + /** + * Enable copying text to clipboard when selected with mouse + */ + copy_on_select?: boolean } /** * Command configuration, see https://opencode.ai/docs/commands From ca973fe0eaa6bec3cb893738299f702f1f4c9f48 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 27 Nov 2025 03:21:28 +0000 Subject: [PATCH 02/14] chore: format code --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d4875c3a39cd..5cf3c465bca0 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 1b9dc0fcf37a..a0c125c68633 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From 5d637d9483ab217bcf5ca61ff85227e789494ded Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 27 Nov 2025 03:27:19 +0000 Subject: [PATCH 03/14] chore: format code --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d4875c3a39cd..5cf3c465bca0 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 1b9dc0fcf37a..a0c125c68633 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From 3b820122e6e93800bec2c2ab470eb17f6e3f4f44 Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Wed, 26 Nov 2025 23:44:04 -0500 Subject: [PATCH 04/14] tidy: minimize useless unnecessary changes. --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 5cf3c465bca0..d4875c3a39cd 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} +} \ No newline at end of file diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index a0c125c68633..1b9dc0fcf37a 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} +} \ No newline at end of file From fda245c88db17a7e4433c9234cca4363e59de0e4 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 27 Nov 2025 04:44:51 +0000 Subject: [PATCH 05/14] chore: format code --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d4875c3a39cd..5cf3c465bca0 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 1b9dc0fcf37a..a0c125c68633 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From 4c608726ec5cc173a68eba170b3b460a15fbd3de Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Wed, 26 Nov 2025 23:51:51 -0500 Subject: [PATCH 06/14] tidy: minimize useless unnecessary changes. --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 5cf3c465bca0..d4875c3a39cd 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} +} \ No newline at end of file diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index a0c125c68633..1b9dc0fcf37a 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} +} \ No newline at end of file From 57b4850c170d32cc9662bbf5df795c5ef842e378 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 27 Nov 2025 04:52:29 +0000 Subject: [PATCH 07/14] chore: format code --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d4875c3a39cd..5cf3c465bca0 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 1b9dc0fcf37a..a0c125c68633 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From fcbd6b702aa5dbeee4ad1e797c1bf657b597e0b7 Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Sun, 30 Nov 2025 02:05:35 -0500 Subject: [PATCH 08/14] style: nit-picky fiddling with whitespace --- packages/sdk/go/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index a9c61b71323d..ea7e20654e49 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -1834,9 +1834,9 @@ func (r ConfigShare) IsKnown() bool { // TUI specific settings type ConfigTui struct { // TUI scroll speed - ScrollSpeed float64 `json:"scroll_speed"` + ScrollSpeed float64 `json:"scroll_speed"` // Enable copying text to clipboard when selected with mouse - CopyOnSelect bool `json:"copy_on_select"` + CopyOnSelect bool `json:"copy_on_select"` // Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column DiffStyle string `json:"diff_style"` JSON configTuiJSON `json:"-"` From 4fc556821d796cf99c375c94fdd9cece5e6680f8 Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Sun, 30 Nov 2025 02:07:07 -0500 Subject: [PATCH 09/14] style: nit-picky fiddling with whitespace --- packages/sdk/go/config.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index ea7e20654e49..98eb2d11d4ea 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -1834,12 +1834,12 @@ func (r ConfigShare) IsKnown() bool { // TUI specific settings type ConfigTui struct { // TUI scroll speed - ScrollSpeed float64 `json:"scroll_speed"` + ScrollSpeed float64 `json:"scroll_speed"` // Enable copying text to clipboard when selected with mouse - CopyOnSelect bool `json:"copy_on_select"` + CopyOnSelect bool `json:"copy_on_select"` // Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column - DiffStyle string `json:"diff_style"` - JSON configTuiJSON `json:"-"` + DiffStyle string `json:"diff_style"` + JSON configTuiJSON `json:"-"` } // configTuiJSON contains the JSON metadata for the struct [ConfigTui] From b0744fc79c97fb734ca259a0f491e8b5df5ebd06 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 1 Dec 2025 11:54:42 +0000 Subject: [PATCH 10/14] chore: format code --- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 21ef2a744071..7248787e88e3 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -24,4 +24,4 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:" } -} \ No newline at end of file +} diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 9d3de8bb1002..651f061ae07f 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -26,4 +26,4 @@ "publishConfig": { "directory": "dist" } -} \ No newline at end of file +} From 8d4639fb01745f08b5c88076d9bcaaeb8c7350d9 Mon Sep 17 00:00:00 2001 From: Github Action Date: Mon, 1 Dec 2025 11:55:56 +0000 Subject: [PATCH 11/14] Update Nix flake.lock and hashes --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 3a6b887186db..05e9e841d76e 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1764527385, - "narHash": "sha256-nA5ywiGKl76atrbdZ5Aucd8SjF/v8ew9b9QsC+MKL14=", + "lastModified": 1764557259, + "narHash": "sha256-fhD/QUtJ0HKs3oLvfnD+/SrBV5Y7YEkCYnDjOVUjLys=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "23258e03aaa49b3a68597e3e50eb0cbce7e42e9d", + "rev": "0d70460758949966e91d9ecb823b821f963cefbb", "type": "github" }, "original": { From 17368aa3c3e5febeddbea8359b68a5373b004a93 Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Mon, 1 Dec 2025 21:47:37 -0500 Subject: [PATCH 12/14] fix: remove incorrect DiffStyle additions from copy-on-select branch --- packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 2 -- packages/opencode/src/config/config.ts | 4 ---- packages/sdk/go/config.go | 5 +---- packages/sdk/js/src/gen/types.gen.ts | 4 ---- 4 files changed, 1 insertion(+), 14 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index baa6631fbe71..2d78fce9ed1e 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -1477,8 +1477,6 @@ ToolRegistry.register({ const { theme, syntax } = useTheme() const view = createMemo(() => { - const diffStyle = ctx.sync.data.config.tui?.diff_style - if (diffStyle === "stacked") return "unified" // Default to "auto" behavior return ctx.width > 120 ? "split" : "unified" }) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index fd9109da8cb3..43516fc2ed69 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -461,10 +461,6 @@ export namespace Config { .optional() .default(true) .describe("Enable copying text to clipboard when selected with mouse"), - diff_style: z - .enum(["auto", "stacked"]) - .optional() - .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"), }) export const Layout = z.enum(["auto", "stretch"]).meta({ diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index 98eb2d11d4ea..dc8ab0e8df11 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -1834,11 +1834,9 @@ func (r ConfigShare) IsKnown() bool { // TUI specific settings type ConfigTui struct { // TUI scroll speed - ScrollSpeed float64 `json:"scroll_speed"` + ScrollSpeed float64 `json:"scroll_speed"` // Enable copying text to clipboard when selected with mouse CopyOnSelect bool `json:"copy_on_select"` - // Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column - DiffStyle string `json:"diff_style"` JSON configTuiJSON `json:"-"` } @@ -1846,7 +1844,6 @@ type ConfigTui struct { type configTuiJSON struct { ScrollSpeed apijson.Field CopyOnSelect apijson.Field - DiffStyle apijson.Field raw string ExtraFields map[string]apijson.Field } diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 725115ea75fd..d1cfe938adf3 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1016,10 +1016,6 @@ export type Config = { * Enable copying text to clipboard when selected with mouse */ copy_on_select?: boolean - /** - * Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column - */ - diff_style?: "auto" | "stacked" } /** * Command configuration, see https://opencode.ai/docs/commands From 39543657733ae673b37069d7741421ffba64f19e Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Mon, 1 Dec 2025 21:54:25 -0500 Subject: [PATCH 13/14] fix: remove incorrect DiffStyle additions from Go config --- packages/sdk/go/config.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index 98eb2d11d4ea..dc8ab0e8df11 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -1834,11 +1834,9 @@ func (r ConfigShare) IsKnown() bool { // TUI specific settings type ConfigTui struct { // TUI scroll speed - ScrollSpeed float64 `json:"scroll_speed"` + ScrollSpeed float64 `json:"scroll_speed"` // Enable copying text to clipboard when selected with mouse CopyOnSelect bool `json:"copy_on_select"` - // Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column - DiffStyle string `json:"diff_style"` JSON configTuiJSON `json:"-"` } @@ -1846,7 +1844,6 @@ type ConfigTui struct { type configTuiJSON struct { ScrollSpeed apijson.Field CopyOnSelect apijson.Field - DiffStyle apijson.Field raw string ExtraFields map[string]apijson.Field } From a7bcceb6c999152502cb337b5927dccd468e6c1f Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Mon, 1 Dec 2025 22:01:21 -0500 Subject: [PATCH 14/14] fix: restore diff_style functionality that was incorrectly removed --- packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 2 ++ packages/opencode/src/config/config.ts | 4 ++++ packages/sdk/js/src/gen/types.gen.ts | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 2d78fce9ed1e..baa6631fbe71 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -1477,6 +1477,8 @@ ToolRegistry.register({ const { theme, syntax } = useTheme() const view = createMemo(() => { + const diffStyle = ctx.sync.data.config.tui?.diff_style + if (diffStyle === "stacked") return "unified" // Default to "auto" behavior return ctx.width > 120 ? "split" : "unified" }) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 43516fc2ed69..fd9109da8cb3 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -461,6 +461,10 @@ export namespace Config { .optional() .default(true) .describe("Enable copying text to clipboard when selected with mouse"), + diff_style: z + .enum(["auto", "stacked"]) + .optional() + .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"), }) export const Layout = z.enum(["auto", "stretch"]).meta({ diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index d1cfe938adf3..725115ea75fd 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1016,6 +1016,10 @@ export type Config = { * Enable copying text to clipboard when selected with mouse */ copy_on_select?: boolean + /** + * Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column + */ + diff_style?: "auto" | "stacked" } /** * Command configuration, see https://opencode.ai/docs/commands