feat: configurable shell selection + desktop settings UI (#20602)
This commit is contained in:
@@ -11,6 +11,7 @@ import { Language, type Node } from "web-tree-sitter"
|
||||
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { fileURLToPath } from "url"
|
||||
import { Config } from "@/config"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Shell } from "@/shell/shell"
|
||||
|
||||
@@ -24,7 +25,6 @@ import { InstanceState } from "@/effect"
|
||||
|
||||
const MAX_METADATA_LENGTH = 30_000
|
||||
const DEFAULT_TIMEOUT = Flag.OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS || 2 * 60 * 1000
|
||||
const PS = new Set(["powershell", "pwsh"])
|
||||
const CWD = new Set(["cd", "push-location", "set-location"])
|
||||
const FILES = new Set([
|
||||
...CWD,
|
||||
@@ -278,8 +278,8 @@ const ask = Effect.fn("BashTool.ask")(function* (ctx: Tool.Context, scan: Scan)
|
||||
})
|
||||
})
|
||||
|
||||
function cmd(shell: string, name: string, command: string, cwd: string, env: NodeJS.ProcessEnv) {
|
||||
if (process.platform === "win32" && PS.has(name)) {
|
||||
function cmd(shell: string, command: string, cwd: string, env: NodeJS.ProcessEnv) {
|
||||
if (process.platform === "win32" && Shell.ps(shell)) {
|
||||
return ChildProcess.make(shell, ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", command], {
|
||||
cwd,
|
||||
env,
|
||||
@@ -296,7 +296,6 @@ function cmd(shell: string, name: string, command: string, cwd: string, env: Nod
|
||||
detached: process.platform !== "win32",
|
||||
})
|
||||
}
|
||||
|
||||
const parser = lazy(async () => {
|
||||
const { Parser } = await import("web-tree-sitter")
|
||||
const { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm" as string, {
|
||||
@@ -328,6 +327,7 @@ const parser = lazy(async () => {
|
||||
export const BashTool = Tool.define(
|
||||
"bash",
|
||||
Effect.gen(function* () {
|
||||
const config = yield* Config.Service
|
||||
const spawner = yield* ChildProcessSpawner
|
||||
const fs = yield* AppFileSystem.Service
|
||||
const trunc = yield* Truncate.Service
|
||||
@@ -408,7 +408,6 @@ export const BashTool = Tool.define(
|
||||
const run = Effect.fn("BashTool.run")(function* (
|
||||
input: {
|
||||
shell: string
|
||||
name: string
|
||||
command: string
|
||||
cwd: string
|
||||
env: NodeJS.ProcessEnv
|
||||
@@ -438,7 +437,7 @@ export const BashTool = Tool.define(
|
||||
|
||||
const code: number | null = yield* Effect.scoped(
|
||||
Effect.gen(function* () {
|
||||
const handle = yield* spawner.spawn(cmd(input.shell, input.name, input.command, input.cwd, input.env))
|
||||
const handle = yield* spawner.spawn(cmd(input.shell, input.command, input.cwd, input.env))
|
||||
|
||||
yield* Effect.forkScoped(
|
||||
Stream.runForEach(Stream.decodeText(handle.all), (chunk) => {
|
||||
@@ -567,7 +566,8 @@ export const BashTool = Tool.define(
|
||||
|
||||
return () =>
|
||||
Effect.gen(function* () {
|
||||
const shell = Shell.acceptable()
|
||||
const cfg = yield* config.get()
|
||||
const shell = Shell.acceptable(cfg.shell)
|
||||
const name = Shell.name(shell)
|
||||
const chain =
|
||||
name === "powershell"
|
||||
@@ -595,7 +595,7 @@ export const BashTool = Tool.define(
|
||||
throw new Error(`Invalid timeout value: ${params.timeout}. Timeout must be a positive number.`)
|
||||
}
|
||||
const timeout = params.timeout ?? DEFAULT_TIMEOUT
|
||||
const ps = PS.has(name)
|
||||
const ps = Shell.ps(shell)
|
||||
const root = yield* parse(params.command, ps)
|
||||
const scan = yield* collect(root, cwd, ps, shell)
|
||||
if (!Instance.containsPath(cwd)) scan.dirs.add(cwd)
|
||||
@@ -604,7 +604,6 @@ export const BashTool = Tool.define(
|
||||
return yield* run(
|
||||
{
|
||||
shell,
|
||||
name,
|
||||
command: params.command,
|
||||
cwd,
|
||||
env: yield* shellEnv(ctx, cwd),
|
||||
|
||||
Reference in New Issue
Block a user