refactor: replace Bun shell execution with portable Process utilities (#18318)

This commit is contained in:
Dax
2026-03-19 21:17:06 -04:00
committed by GitHub
parent 37b8662a9d
commit 52a7a04ad8
2 changed files with 11 additions and 16 deletions
+4 -7
View File
@@ -11,6 +11,7 @@ import {
} from "@modelcontextprotocol/sdk/types.js" } from "@modelcontextprotocol/sdk/types.js"
import { Config } from "../config/config" import { Config } from "../config/config"
import { Log } from "../util/log" import { Log } from "../util/log"
import { Process } from "../util/process"
import { NamedError } from "@opencode-ai/util/error" import { NamedError } from "@opencode-ai/util/error"
import z from "zod/v4" import z from "zod/v4"
import { Instance } from "../project/instance" import { Instance } from "../project/instance"
@@ -166,14 +167,10 @@ export namespace MCP {
const queue = [pid] const queue = [pid]
while (queue.length > 0) { while (queue.length > 0) {
const current = queue.shift()! const current = queue.shift()!
const proc = Bun.spawn(["pgrep", "-P", String(current)], { stdout: "pipe", stderr: "pipe" }) const lines = await Process.lines(["pgrep", "-P", String(current)], { nothrow: true })
const [code, out] = await Promise.all([proc.exited, new Response(proc.stdout).text()]).catch( for (const tok of lines) {
() => [-1, ""] as const,
)
if (code !== 0) continue
for (const tok of out.trim().split(/\s+/)) {
const cpid = parseInt(tok, 10) const cpid = parseInt(tok, 10)
if (!isNaN(cpid) && pids.indexOf(cpid) === -1) { if (!isNaN(cpid) && !pids.includes(cpid)) {
pids.push(cpid) pids.push(cpid)
queue.push(cpid) queue.push(cpid)
} }
+7 -9
View File
@@ -32,7 +32,6 @@ import { Flag } from "../flag/flag"
import { ulid } from "ulid" import { ulid } from "ulid"
import { spawn } from "child_process" import { spawn } from "child_process"
import { Command } from "../command" import { Command } from "../command"
import { $ } from "bun"
import { pathToFileURL, fileURLToPath } from "url" import { pathToFileURL, fileURLToPath } from "url"
import { ConfigMarkdown } from "../config/markdown" import { ConfigMarkdown } from "../config/markdown"
import { SessionSummary } from "./summary" import { SessionSummary } from "./summary"
@@ -48,6 +47,7 @@ import { iife } from "@/util/iife"
import { Shell } from "@/shell/shell" import { Shell } from "@/shell/shell"
import { Truncate } from "@/tool/truncate" import { Truncate } from "@/tool/truncate"
import { decodeDataUrl } from "@/util/data-url" import { decodeDataUrl } from "@/util/data-url"
import { Process } from "@/util/process"
// @ts-ignore // @ts-ignore
globalThis.AI_SDK_LOG_WARNINGS = false globalThis.AI_SDK_LOG_WARNINGS = false
@@ -1812,15 +1812,13 @@ NOTE: At any point in time through this workflow you should feel free to ask the
template = template + "\n\n" + input.arguments template = template + "\n\n" + input.arguments
} }
const shell = ConfigMarkdown.shell(template) const shellMatches = ConfigMarkdown.shell(template)
if (shell.length > 0) { if (shellMatches.length > 0) {
const sh = Shell.preferred()
const results = await Promise.all( const results = await Promise.all(
shell.map(async ([, cmd]) => { shellMatches.map(async ([, cmd]) => {
try { const out = await Process.text([cmd], { shell: sh, nothrow: true })
return await $`${{ raw: cmd }}`.quiet().nothrow().text() return out.text
} catch (error) {
return `Error executing command: ${error instanceof Error ? error.message : String(error)}`
}
}), }),
) )
let index = 0 let index = 0