From 94ded4c898c0878830596f7e168fc1e79a21b87e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:27:37 +0000 Subject: [PATCH 1/3] Initial plan From bba34998011018d45af6e80c4eb3703f446380be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:33:32 +0000 Subject: [PATCH 2/3] Add configurable cwd setting to extension template Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --- bundled/tool/lsp_server.py | 24 ++++++++++++++++++++++-- package.json | 6 ++++++ src/common/settings.ts | 8 +++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/bundled/tool/lsp_server.py b/bundled/tool/lsp_server.py index 6abc0f8..57688fd 100644 --- a/bundled/tool/lsp_server.py +++ b/bundled/tool/lsp_server.py @@ -289,6 +289,26 @@ def on_shutdown(_params: Optional[Any] = None) -> None: jsonrpc.shutdown_json_rpc() +def get_cwd(settings: dict, document: Optional[workspace.Document]) -> str: + """Returns the working directory for running the tool. + + Supports the following variable substitutions: + - ``${fileDirname}``: resolved to the directory of the current document. + If no document is available, falls back to the workspace root. + - ``${workspaceFolder}``: pre-resolved by the TypeScript client before + the settings are sent to this server. + + Examples of supported patterns: ``${fileDirname}``, ``${fileDirname}/subdir``. + """ + cwd = settings.get("cwd", settings["workspaceFS"]) + if "${fileDirname}" in cwd: + if document and document.path: + cwd = cwd.replace("${fileDirname}", os.path.dirname(document.path)) + else: + cwd = settings["workspaceFS"] + return cwd + + def _get_global_defaults(): return { "path": GLOBAL_SETTINGS.get("path", []), @@ -393,7 +413,7 @@ def _run_tool_on_document( settings = copy.deepcopy(_get_settings_by_document(document)) code_workspace = settings["workspaceFS"] - cwd = settings["cwd"] + cwd = get_cwd(settings, document) use_path = False use_rpc = False @@ -498,7 +518,7 @@ def _run_tool(extra_args: Sequence[str]) -> utils.RunResult: settings = copy.deepcopy(_get_settings_by_document(None)) code_workspace = settings["workspaceFS"] - cwd = settings["workspaceFS"] + cwd = get_cwd(settings, None) use_path = False use_rpc = False diff --git a/package.json b/package.json index ffd3eea..bed4ceb 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,12 @@ "contributes": { "configuration": { "properties": { + ".cwd": { + "default": "${workspaceFolder}", + "description": "Sets the working directory for . Supported variables: `${workspaceFolder}` (workspace root) and `${fileDirname}` (directory of the current file).", + "scope": "resource", + "type": "string" + }, ".args": { "default": [], "description": "Arguments passed in. Each argument is a separate item in the array.", diff --git a/src/common/settings.ts b/src/common/settings.ts index 0259aff..2e59956 100644 --- a/src/common/settings.ts +++ b/src/common/settings.ts @@ -46,6 +46,11 @@ export function getInterpreterFromSetting(namespace: string, scope?: Configurati return config.get('interpreter'); } +function getCwd(config: WorkspaceConfiguration, workspace: WorkspaceFolder): string { + const cwd = config.get('cwd', '${workspaceFolder}'); + return resolveVariables([cwd], workspace)[0]; +} + export async function getWorkspaceSettings( namespace: string, workspace: WorkspaceFolder, @@ -62,7 +67,7 @@ export async function getWorkspaceSettings( } const workspaceSetting = { - cwd: workspace.uri.fsPath, + cwd: getCwd(config, workspace), workspace: workspace.uri.toString(), args: resolveVariables(config.get(`args`) ?? [], workspace), path: resolveVariables(config.get(`path`) ?? [], workspace), @@ -104,6 +109,7 @@ export async function getGlobalSettings(namespace: string, includeInterpreter?: export function checkIfConfigurationChanged(e: ConfigurationChangeEvent, namespace: string): boolean { const settings = [ `${namespace}.args`, + `${namespace}.cwd`, `${namespace}.path`, `${namespace}.interpreter`, `${namespace}.importStrategy`, From f3907a34f8aeb9e2c38ada4a35ee55f6b044b50b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:41:51 +0000 Subject: [PATCH 3/3] Improve get_cwd docstring and add call-site comment Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --- bundled/tool/lsp_server.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bundled/tool/lsp_server.py b/bundled/tool/lsp_server.py index 57688fd..50c6da8 100644 --- a/bundled/tool/lsp_server.py +++ b/bundled/tool/lsp_server.py @@ -292,11 +292,8 @@ def on_shutdown(_params: Optional[Any] = None) -> None: def get_cwd(settings: dict, document: Optional[workspace.Document]) -> str: """Returns the working directory for running the tool. - Supports the following variable substitutions: - - ``${fileDirname}``: resolved to the directory of the current document. - If no document is available, falls back to the workspace root. - - ``${workspaceFolder}``: pre-resolved by the TypeScript client before - the settings are sent to this server. + Resolves ``${fileDirname}`` to the directory of the current document. + If no document is available, falls back to the workspace root. Examples of supported patterns: ``${fileDirname}``, ``${fileDirname}/subdir``. """ @@ -413,6 +410,7 @@ def _run_tool_on_document( settings = copy.deepcopy(_get_settings_by_document(document)) code_workspace = settings["workspaceFS"] + # Pass document so get_cwd can resolve ${fileDirname} to this file's directory. cwd = get_cwd(settings, document) use_path = False