This commit is contained in:
LukeParkerDev 2026-04-21 11:21:30 +10:00
parent cc392859a9
commit 6da5cec12e
3 changed files with 11 additions and 9 deletions

View file

@ -48,6 +48,8 @@ type ShellOption = {
acceptable: boolean
}
const AUTO_SHELL_VALUE = "__opencode_auto_shell__"
// To prevent audio from overlapping/playing very quickly when navigating the settings menus,
// delay the playback by 100ms during quick selection changes and pause existing sounds.
const stopDemoSound = () => {
@ -179,7 +181,8 @@ export const SettingsGeneral: Component = () => {
const globalSdk = useGlobalSDK()
const [shells] = createResource<ShellOption[]>(() => globalSdk.client.pty.shells().then((res) => res.data || []))
const auto = { value: "", label: "Auto (Default)" }
const auto = { value: AUTO_SHELL_VALUE, label: "Auto (Default)" }
const currentShell = createMemo(() => globalSync.data.config.shell || AUTO_SHELL_VALUE)
const shellOptions = createMemo(() => {
const list = shells() || []
@ -293,12 +296,12 @@ export const SettingsGeneral: Component = () => {
<Select
data-action="settings-shell"
options={shellOptions()}
current={shellOptions().find((o) => o.value === globalSync.data.config.shell) ?? auto}
current={shellOptions().find((o) => o.value === currentShell()) ?? auto}
value={(o) => o.value}
label={(o) => o.label}
onSelect={(option) => {
if (!option) return
globalSync.updateConfig({ shell: option.value })
globalSync.updateConfig({ shell: option.value === AUTO_SHELL_VALUE ? "" : option.value })
}}
variant="secondary"
size="small"

View file

@ -90,7 +90,7 @@ function resolve(file: string) {
function win() {
return Array.from(
new Set(
[Bun.which("pwsh"), Bun.which("powershell"), gitbash(), process.env.COMSPEC || "cmd.exe"]
[which("pwsh"), which("powershell"), gitbash(), process.env.COMSPEC || "cmd.exe"]
.filter((item): item is string => Boolean(item))
.map(full),
),
@ -98,10 +98,8 @@ function win() {
}
async function unix() {
const file = Bun.file("/etc/shells")
if (await file.exists()) {
return Array.from(new Set((await file.text()).split("\n").filter((line) => line.trim() && !line.startsWith("#"))))
}
const text = await Filesystem.readText("/etc/shells").catch(() => "")
if (text) return Array.from(new Set(text.split("\n").filter((line) => line.trim() && !line.startsWith("#"))))
return ["/bin/bash", "/bin/zsh", "/bin/sh"]
}

View file

@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test"
import path from "path"
import { Shell } from "../../src/shell/shell"
import { Filesystem } from "../../src/util"
import { which } from "../../src/util/which"
const withShell = async (shell: string | undefined, fn: () => void | Promise<void>) => {
const prev = process.env.SHELL
@ -77,7 +78,7 @@ describe("shell", () => {
})
test("resolves bare PowerShell shells", async () => {
const shell = Bun.which("pwsh") || Bun.which("powershell")
const shell = which("pwsh") || which("powershell")
if (!shell) return
await withShell(path.win32.basename(shell), async () => {
expect(Shell.preferred()).toBe(shell)