mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-31 14:22:27 +00:00
shell tweaks, better handling for windows (#5455)
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -14,11 +14,10 @@ import { Permission } from "@/permission"
|
||||
import { fileURLToPath } from "url"
|
||||
import { Flag } from "@/flag/flag.ts"
|
||||
import path from "path"
|
||||
import { iife } from "@/util/iife"
|
||||
import { Shell } from "@/shell/shell"
|
||||
|
||||
const MAX_OUTPUT_LENGTH = Flag.OPENCODE_EXPERIMENTAL_BASH_MAX_OUTPUT_LENGTH || 30_000
|
||||
const DEFAULT_TIMEOUT = Flag.OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS || 2 * 60 * 1000
|
||||
const SIGKILL_TIMEOUT_MS = 200
|
||||
|
||||
export const log = Log.create({ service: "bash-tool" })
|
||||
|
||||
@@ -53,32 +52,7 @@ const parser = lazy(async () => {
|
||||
// TODO: we may wanna rename this tool so it works better on other shells
|
||||
|
||||
export const BashTool = Tool.define("bash", async () => {
|
||||
const shell = iife(() => {
|
||||
const s = process.env.SHELL
|
||||
if (s) {
|
||||
const basename = path.basename(s)
|
||||
if (!new Set(["fish", "nu"]).has(basename)) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
return "/bin/zsh"
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
// Let Bun / Node pick COMSPEC (usually cmd.exe)
|
||||
// or explicitly:
|
||||
return process.env.COMSPEC || true
|
||||
}
|
||||
|
||||
const bash = Bun.which("bash")
|
||||
if (bash) {
|
||||
return bash
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
const shell = Shell.acceptable()
|
||||
log.info("bash tool using shell", { shell })
|
||||
|
||||
return {
|
||||
@@ -261,51 +235,23 @@ export const BashTool = Tool.define("bash", async () => {
|
||||
let aborted = false
|
||||
let exited = false
|
||||
|
||||
const killTree = async () => {
|
||||
const pid = proc.pid
|
||||
if (!pid || exited) {
|
||||
return
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
await new Promise<void>((resolve) => {
|
||||
const killer = spawn("taskkill", ["/pid", String(pid), "/f", "/t"], { stdio: "ignore" })
|
||||
killer.once("exit", resolve)
|
||||
killer.once("error", resolve)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
process.kill(-pid, "SIGTERM")
|
||||
await Bun.sleep(SIGKILL_TIMEOUT_MS)
|
||||
if (!exited) {
|
||||
process.kill(-pid, "SIGKILL")
|
||||
}
|
||||
} catch (_e) {
|
||||
proc.kill("SIGTERM")
|
||||
await Bun.sleep(SIGKILL_TIMEOUT_MS)
|
||||
if (!exited) {
|
||||
proc.kill("SIGKILL")
|
||||
}
|
||||
}
|
||||
}
|
||||
const kill = () => Shell.killTree(proc, { exited: () => exited })
|
||||
|
||||
if (ctx.abort.aborted) {
|
||||
aborted = true
|
||||
await killTree()
|
||||
await kill()
|
||||
}
|
||||
|
||||
const abortHandler = () => {
|
||||
aborted = true
|
||||
void killTree()
|
||||
void kill()
|
||||
}
|
||||
|
||||
ctx.abort.addEventListener("abort", abortHandler, { once: true })
|
||||
|
||||
const timeoutTimer = setTimeout(() => {
|
||||
timedOut = true
|
||||
void killTree()
|
||||
void kill()
|
||||
}, timeout + 100)
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
|
||||
Reference in New Issue
Block a user