Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 21 additions & 33 deletions core/tools/implementations/runTerminalCommand.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import iconv from "iconv-lite";
import childProcess from "node:child_process";
import os from "node:os";
import util from "node:util";
import { ContinueError, ContinueErrorReason } from "../../util/errors";
// Automatically decode the buffer according to the platform to avoid garbled Chinese
function getDecodedOutput(data: Buffer): string {
Expand Down Expand Up @@ -44,7 +43,25 @@ import {
} from "../../util/processTerminalStates";
import { getBooleanArg, getStringArg } from "../parseArgs";

const asyncExec = util.promisify(childProcess.exec);
/**
* Resolves the working directory from workspace dirs.
* Falls back to home directory or temp directory if no workspace is available.
*/
function resolveWorkingDirectory(workspaceDirs: string[]): string {
const fileWorkspaceDir = workspaceDirs.find((dir) =>
dir.startsWith("file:/"),
);
if (fileWorkspaceDir) {
return fileURLToPath(fileWorkspaceDir);
}
// Default to user's home directory with fallbacks
try {
return process.env.HOME || process.env.USERPROFILE || process.cwd();
} catch {
// Final fallback if even process.cwd() fails - use system temp directory
return os.tmpdir();
}
}

// Add color-supporting environment variables
const getColorEnv = () => ({
Expand Down Expand Up @@ -82,20 +99,7 @@ export const runTerminalCommandImpl: ToolImpl = async (args, extras) => {
if (extras.onPartialOutput) {
try {
const workspaceDirs = await extras.ide.getWorkspaceDirs();

// Handle case where no workspace is available
let cwd: string;
if (workspaceDirs.length > 0) {
cwd = fileURLToPath(workspaceDirs[0]);
} else {
// Default to user's home directory with fallbacks
try {
cwd = process.env.HOME || process.env.USERPROFILE || process.cwd();
} catch (error) {
// Final fallback if even process.cwd() fails - use system temp directory
cwd = os.tmpdir();
}
}
const cwd = resolveWorkingDirectory(workspaceDirs);

return new Promise((resolve, reject) => {
let terminalOutput = "";
Expand Down Expand Up @@ -281,23 +285,7 @@ export const runTerminalCommandImpl: ToolImpl = async (args, extras) => {
} else {
// Fallback to non-streaming for older clients
const workspaceDirs = await extras.ide.getWorkspaceDirs();

// Handle case where no workspace is available
let cwd: string;
const fileWorkspaceDir = workspaceDirs.find((dir) =>
dir.startsWith("file:/"),
);
if (fileWorkspaceDir) {
cwd = fileURLToPath(fileWorkspaceDir);
} else {
// Default to user's home directory with fallbacks
try {
cwd = process.env.HOME || process.env.USERPROFILE || process.cwd();
} catch (error) {
// Final fallback if even process.cwd() fails - use system temp directory
cwd = os.tmpdir();
}
}
const cwd = resolveWorkingDirectory(workspaceDirs);

if (waitForCompletion) {
// Standard execution, waiting for completion
Expand Down
Loading