From 33f7f593eeba84de34c52779a42b24b4edfa652a Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Thu, 30 Apr 2026 22:45:41 -0500 Subject: [PATCH 1/3] fix: tui list jank issue (#25219) --- .../opencode/src/cli/cmd/tui/component/dialog-provider.tsx | 2 +- .../src/cli/cmd/tui/component/dialog-session-list.tsx | 2 +- packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx index ebc28847f..d6cbda413 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx @@ -51,7 +51,7 @@ export function createDialogProviderOptions() { }[provider.id], footer: consoleManaged ? sync.data.console_state.activeOrgName : undefined, category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other", - gutter: connected && onboarded() ? : undefined, + gutter: connected && onboarded() ? () => : undefined, async onSelect() { if (consoleManaged) return diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx index 72d60767b..04c6b9945 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx @@ -168,7 +168,7 @@ export function DialogSessionList() { value: x.id, category, footer, - gutter: isWorking ? : undefined, + gutter: isWorking ? () => : undefined, } }) }) diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx index b6c937f41..4d68c4430 100644 --- a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx +++ b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx @@ -42,7 +42,7 @@ export interface DialogSelectOption { categoryView?: JSX.Element disabled?: boolean bg?: RGBA - gutter?: JSX.Element + gutter?: () => JSX.Element margin?: JSX.Element onSelect?: (ctx: DialogContext) => void } @@ -407,7 +407,7 @@ function Option(props: { active?: boolean current?: boolean footer?: JSX.Element | string - gutter?: JSX.Element + gutter?: () => JSX.Element onMouseOver?: () => void }) { const { theme } = useTheme() @@ -422,7 +422,7 @@ function Option(props: { - {props.gutter} + {props.gutter?.()} Date: Thu, 30 Apr 2026 23:47:15 -0400 Subject: [PATCH 2/3] Preapprove agent tmp directory access (#25226) --- packages/core/src/global.ts | 5 +++++ packages/opencode/src/agent/agent.ts | 6 +++++- packages/opencode/src/tool/bash.ts | 2 ++ packages/opencode/src/tool/bash.txt | 2 ++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/core/src/global.ts b/packages/core/src/global.ts index 42e0f1030..1acc3f47f 100644 --- a/packages/core/src/global.ts +++ b/packages/core/src/global.ts @@ -11,6 +11,7 @@ const data = path.join(xdgData!, app) const cache = path.join(xdgCache!, app) const config = path.join(xdgConfig!, app) const state = path.join(xdgState!, app) +const tmp = path.join(os.tmpdir(), app) const paths = { get home() { @@ -22,6 +23,7 @@ const paths = { cache, config, state, + tmp, } export const Path = paths @@ -32,6 +34,7 @@ await Promise.all([ fs.mkdir(Path.data, { recursive: true }), fs.mkdir(Path.config, { recursive: true }), fs.mkdir(Path.state, { recursive: true }), + fs.mkdir(Path.tmp, { recursive: true }), fs.mkdir(Path.log, { recursive: true }), fs.mkdir(Path.bin, { recursive: true }), ]) @@ -44,6 +47,7 @@ export interface Interface { readonly cache: string readonly config: string readonly state: string + readonly tmp: string readonly bin: string readonly log: string } @@ -55,6 +59,7 @@ export function make(input: Partial = {}): Interface { cache: Path.cache, config: Flag.OPENCODE_CONFIG_DIR ?? Path.config, state: Path.state, + tmp: Path.tmp, bin: Path.bin, log: Path.log, ...input, diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts index 2a090b0ee..b38b0cc5d 100644 --- a/packages/opencode/src/agent/agent.ts +++ b/packages/opencode/src/agent/agent.ts @@ -81,7 +81,11 @@ export const layer = Layer.effect( Effect.fn("Agent.state")(function* (ctx) { const cfg = yield* config.get() const skillDirs = yield* skill.dirs() - const whitelistedDirs = [Truncate.GLOB, ...skillDirs.map((dir) => path.join(dir, "*"))] + const whitelistedDirs = [ + Truncate.GLOB, + path.join(Global.Path.tmp, "*"), + ...skillDirs.map((dir) => path.join(dir, "*")), + ] const defaults = Permission.fromConfig({ "*": "allow", diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts index c50b259f7..fe3e45d66 100644 --- a/packages/opencode/src/tool/bash.ts +++ b/packages/opencode/src/tool/bash.ts @@ -14,6 +14,7 @@ import { AppFileSystem } from "@opencode-ai/core/filesystem" import { fileURLToPath } from "url" import { Config } from "@/config/config" import { Flag } from "@opencode-ai/core/flag/flag" +import { Global } from "@opencode-ai/core/global" import { Shell } from "@/shell/shell" import { BashArity } from "@/permission/arity" @@ -587,6 +588,7 @@ export const BashTool = Tool.define( return { description: DESCRIPTION.replaceAll("${directory}", instance.directory) + .replaceAll("${tmp}", Global.Path.tmp) .replaceAll("${os}", process.platform) .replaceAll("${shell}", name) .replaceAll("${chaining}", chain) diff --git a/packages/opencode/src/tool/bash.txt b/packages/opencode/src/tool/bash.txt index c2fe87379..04e935fe7 100644 --- a/packages/opencode/src/tool/bash.txt +++ b/packages/opencode/src/tool/bash.txt @@ -4,6 +4,8 @@ Be aware: OS: ${os}, Shell: ${shell} All commands run in the current working directory by default. Use the `workdir` parameter if you need to run a command in a different directory. AVOID using `cd && ` patterns - use `workdir` instead. +Use `${tmp}` for temporary work outside the workspace. This directory is pre-approved for external directory access. + IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead. Before executing the command, please follow these steps: From 3615d8e226a5dae909139d306e2a684a92680ccf Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Thu, 30 Apr 2026 23:48:48 -0400 Subject: [PATCH 3/3] core: clarify that temp directory already exists for AI agents The bash tool description now explicitly states that the temp directory has already been created and exists, preventing agents from unnecessarily trying to create it before use. --- packages/opencode/src/tool/bash.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/tool/bash.txt b/packages/opencode/src/tool/bash.txt index 04e935fe7..a131ed7e6 100644 --- a/packages/opencode/src/tool/bash.txt +++ b/packages/opencode/src/tool/bash.txt @@ -4,7 +4,7 @@ Be aware: OS: ${os}, Shell: ${shell} All commands run in the current working directory by default. Use the `workdir` parameter if you need to run a command in a different directory. AVOID using `cd && ` patterns - use `workdir` instead. -Use `${tmp}` for temporary work outside the workspace. This directory is pre-approved for external directory access. +Use `${tmp}` for temporary work outside the workspace. This directory has already been created, already exists, and is pre-approved for external directory access. IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead.