| 112 | } |
| 113 | |
| 114 | export async function run(cmd: string[], opts: RunOptions = {}): Promise<Result> { |
| 115 | const proc = spawn(cmd, { |
| 116 | cwd: opts.cwd, |
| 117 | env: opts.env, |
| 118 | stdin: opts.stdin, |
| 119 | shell: opts.shell, |
| 120 | abort: opts.abort, |
| 121 | kill: opts.kill, |
| 122 | timeout: opts.timeout, |
| 123 | stdout: "pipe", |
| 124 | stderr: "pipe", |
| 125 | }) |
| 126 | |
| 127 | if (!proc.stdout || !proc.stderr) throw new Error("Process output not available") |
| 128 | |
| 129 | const out = await Promise.all([proc.exited, buffer(proc.stdout), buffer(proc.stderr)]) |
| 130 | .then(([code, stdout, stderr]) => ({ |
| 131 | code, |
| 132 | stdout, |
| 133 | stderr, |
| 134 | })) |
| 135 | .catch((err: unknown) => { |
| 136 | if (!opts.nothrow) throw err |
| 137 | return { |
| 138 | code: 1, |
| 139 | stdout: Buffer.alloc(0), |
| 140 | stderr: Buffer.from(errorMessage(err)), |
| 141 | } |
| 142 | }) |
| 143 | if (out.code === 0 || opts.nothrow) return out |
| 144 | throw new RunFailedError(cmd, out.code, out.stdout, out.stderr) |
| 145 | } |
| 146 | |
| 147 | // Duplicated in `packages/sdk/js/src/process.ts` because the SDK cannot import |
| 148 | // `opencode` without creating a cycle. Keep both copies in sync. |