refactor: isolate legacy flags

This commit is contained in:
Dax Raad 2026-07-20 21:42:02 -04:00
commit 43c08387f1
65 changed files with 282 additions and 147 deletions

View file

@ -4,7 +4,6 @@ import { Deferred, Effect } from "effect"
import { Service, type Endpoint } from "@opencode-ai/client/effect/service"
import { OpenCode } from "@opencode-ai/client"
import { Global } from "@opencode-ai/core/global"
import { Flag } from "@opencode-ai/core/flag/flag"
import { ClipboardProvider, useClipboard } from "./context/clipboard"
import { LogProvider, useLog, type LogSink } from "./context/log"
import { ExitProvider, useExit } from "./context/exit"
@ -211,7 +210,7 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) {
useKittyKeyboard: {},
autoFocus: false,
openConsoleOnError: false,
useMouse: !Flag.OPENCODE_DISABLE_MOUSE && config.mouse,
useMouse: config.mouse,
consoleOptions: {
keyBindings: [{ name: "y", ctrl: true, action: "copy-selection" }],
},
@ -466,7 +465,7 @@ function App(props: { pair?: DialogPairCredentials; started: number }) {
const offSelectionKeys = keymap.intercept(
"key",
({ event }) => {
if (!Flag.OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT) return
if (config.data.terminal?.copy_on_select ?? process.platform !== "win32") return
Selection.handleSelectionKey(renderer, toast, event, clipboard)
},
{ priority: 1 },
@ -487,15 +486,16 @@ function App(props: { pair?: DialogPairCredentials; started: number }) {
renderer.clearSelection()
}
const terminalTitleEnabled = () => config.data.terminal?.title ?? true
const copyOnSelectEnabled = () => config.data.terminal?.copy_on_select ?? process.platform !== "win32"
const pasteSummaryEnabled = () => config.data.prompt?.paste !== "full"
createEffect(() => {
renderer.useMouse = !Flag.OPENCODE_DISABLE_MOUSE && config.data.mouse
renderer.useMouse = config.data.mouse
})
// Update terminal window title based on current route and session
createEffect(() => {
if (!terminalTitleEnabled() || Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return
if (!terminalTitleEnabled()) return
if (route.data.type === "home") {
renderer.setTerminalTitle("OpenCode")
@ -1090,7 +1090,7 @@ function App(props: { pair?: DialogPairCredentials; started: number }) {
flexDirection="column"
backgroundColor={themeV2.background.default}
onMouseDown={(evt) => {
if (!Flag.OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT) return
if (copyOnSelectEnabled()) return
if (evt.button !== MouseButton.RIGHT) return
if (!Selection.copy(renderer, toast, clipboard)) return
@ -1098,12 +1098,12 @@ function App(props: { pair?: DialogPairCredentials; started: number }) {
evt.stopPropagation()
}}
onMouseUp={
!Flag.OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT
copyOnSelectEnabled()
? () => Selection.copy(renderer, toast, clipboard)
: undefined
}
>
<Show when={Flag.OPENCODE_SHOW_TTFD}>
<Show when={config.data.debug?.timing}>
<TimeToFirstDraw />
</Show>
<box flexGrow={1} minHeight={0} flexDirection="row">

View file

@ -206,6 +206,14 @@ const settings: Setting[] = [
values: [false, true],
labels: ["off", "on"],
},
{
title: "Copy on select",
category: "Terminal",
path: ["terminal", "copy_on_select"],
default: process.platform !== "win32",
values: [false, true],
labels: ["off", "on"],
},
{
title: "DevTools",
category: "Debug",
@ -214,6 +222,14 @@ const settings: Setting[] = [
values: [false, true],
labels: ["off", "on"],
},
{
title: "Timing",
category: "Debug",
path: ["debug", "timing"],
default: false,
values: [false, true],
labels: ["off", "on"],
},
]
export function DialogConfig() {

View file

@ -12,7 +12,6 @@ import { registerOpencodeSpinner } from "../register-spinner"
import path from "path"
import { fileURLToPath } from "url"
import { useLocal } from "../../context/local"
import { Flag } from "@opencode-ai/core/flag/flag"
import { useTheme } from "../../context/theme"
import { tint } from "../../theme/color"
import { EmptyBorder, SplitBorder } from "../../ui/border"

View file

@ -92,6 +92,7 @@ export const Info = Schema.Struct({
terminal: Schema.optional(
Schema.Struct({
title: Schema.optional(Schema.Boolean).annotate({ description: "Update the terminal window title" }),
copy_on_select: Schema.optional(Schema.Boolean).annotate({ description: "Copy selected terminal text" }),
}),
).annotate({ description: "Terminal integration settings" }),
prompt: Schema.optional(
@ -129,6 +130,7 @@ export const Info = Schema.Struct({
debug: Schema.optional(
Schema.Struct({
devtools: Schema.optional(Schema.Boolean).annotate({ description: "Show the DevTools sidebar" }),
timing: Schema.optional(Schema.Boolean).annotate({ description: "Show time-to-first-draw diagnostics" }),
}),
).annotate({ description: "Debugging settings" }),
animations: Schema.optional(Schema.Boolean).annotate({ description: "Enable interface animations" }),

View file

@ -5,8 +5,8 @@ import { useTheme } from "../context/theme"
import { MouseButton, Renderable, RGBA } from "@opentui/core"
import { createStore } from "solid-js/store"
import { useToast } from "./toast"
import { Flag } from "@opencode-ai/core/flag/flag"
import { useClipboard } from "../context/clipboard"
import { useConfig } from "../config"
export function Dialog(
props: ParentProps<{
@ -197,6 +197,8 @@ export function DialogProvider(props: ParentProps) {
const renderer = useRenderer()
const toast = useToast()
const clipboard = useClipboard()
const config = useConfig()
const copyOnSelectEnabled = () => config.data.terminal?.copy_on_select ?? process.platform !== "win32"
function copySelection() {
const text = renderer.getSelection()?.getSelectedText()
@ -216,14 +218,14 @@ export function DialogProvider(props: ParentProps) {
position="absolute"
zIndex={3000}
onMouseDown={(evt: { button: number; preventDefault(): void; stopPropagation(): void }) => {
if (!Flag.OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT) return
if (copyOnSelectEnabled()) return
if (evt.button !== MouseButton.RIGHT) return
if (!copySelection()) return
evt.preventDefault()
evt.stopPropagation()
}}
onMouseUp={!Flag.OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT ? copySelection : undefined}
onMouseUp={copyOnSelectEnabled() ? copySelection : undefined}
>
<Show when={value.stack.length}>
<Dialog onClose={() => value.clear()} size={value.size} centered={value.centered}>