|
1 | 1 | import iconv from "iconv-lite"; |
2 | 2 | import childProcess from "node:child_process"; |
3 | 3 | import os from "node:os"; |
4 | | -import util from "node:util"; |
5 | 4 | import { ContinueError, ContinueErrorReason } from "../../util/errors"; |
6 | 5 | // Automatically decode the buffer according to the platform to avoid garbled Chinese |
7 | 6 | function getDecodedOutput(data: Buffer): string { |
@@ -44,7 +43,25 @@ import { |
44 | 43 | } from "../../util/processTerminalStates"; |
45 | 44 | import { getBooleanArg, getStringArg } from "../parseArgs"; |
46 | 45 |
|
47 | | -const asyncExec = util.promisify(childProcess.exec); |
| 46 | +/** |
| 47 | + * Resolves the working directory from workspace dirs. |
| 48 | + * Falls back to home directory or temp directory if no workspace is available. |
| 49 | + */ |
| 50 | +function resolveWorkingDirectory(workspaceDirs: string[]): string { |
| 51 | + const fileWorkspaceDir = workspaceDirs.find((dir) => |
| 52 | + dir.startsWith("file:/"), |
| 53 | + ); |
| 54 | + if (fileWorkspaceDir) { |
| 55 | + return fileURLToPath(fileWorkspaceDir); |
| 56 | + } |
| 57 | + // Default to user's home directory with fallbacks |
| 58 | + try { |
| 59 | + return process.env.HOME || process.env.USERPROFILE || process.cwd(); |
| 60 | + } catch { |
| 61 | + // Final fallback if even process.cwd() fails - use system temp directory |
| 62 | + return os.tmpdir(); |
| 63 | + } |
| 64 | +} |
48 | 65 |
|
49 | 66 | // Add color-supporting environment variables |
50 | 67 | const getColorEnv = () => ({ |
@@ -82,20 +99,7 @@ export const runTerminalCommandImpl: ToolImpl = async (args, extras) => { |
82 | 99 | if (extras.onPartialOutput) { |
83 | 100 | try { |
84 | 101 | const workspaceDirs = await extras.ide.getWorkspaceDirs(); |
85 | | - |
86 | | - // Handle case where no workspace is available |
87 | | - let cwd: string; |
88 | | - if (workspaceDirs.length > 0) { |
89 | | - cwd = fileURLToPath(workspaceDirs[0]); |
90 | | - } else { |
91 | | - // Default to user's home directory with fallbacks |
92 | | - try { |
93 | | - cwd = process.env.HOME || process.env.USERPROFILE || process.cwd(); |
94 | | - } catch (error) { |
95 | | - // Final fallback if even process.cwd() fails - use system temp directory |
96 | | - cwd = os.tmpdir(); |
97 | | - } |
98 | | - } |
| 102 | + const cwd = resolveWorkingDirectory(workspaceDirs); |
99 | 103 |
|
100 | 104 | return new Promise((resolve, reject) => { |
101 | 105 | let terminalOutput = ""; |
@@ -281,23 +285,7 @@ export const runTerminalCommandImpl: ToolImpl = async (args, extras) => { |
281 | 285 | } else { |
282 | 286 | // Fallback to non-streaming for older clients |
283 | 287 | const workspaceDirs = await extras.ide.getWorkspaceDirs(); |
284 | | - |
285 | | - // Handle case where no workspace is available |
286 | | - let cwd: string; |
287 | | - const fileWorkspaceDir = workspaceDirs.find((dir) => |
288 | | - dir.startsWith("file:/"), |
289 | | - ); |
290 | | - if (fileWorkspaceDir) { |
291 | | - cwd = fileURLToPath(fileWorkspaceDir); |
292 | | - } else { |
293 | | - // Default to user's home directory with fallbacks |
294 | | - try { |
295 | | - cwd = process.env.HOME || process.env.USERPROFILE || process.cwd(); |
296 | | - } catch (error) { |
297 | | - // Final fallback if even process.cwd() fails - use system temp directory |
298 | | - cwd = os.tmpdir(); |
299 | | - } |
300 | | - } |
| 288 | + const cwd = resolveWorkingDirectory(workspaceDirs); |
301 | 289 |
|
302 | 290 | if (waitForCompletion) { |
303 | 291 | // Standard execution, waiting for completion |
|
0 commit comments