From 8e5a7c2152a2e4e0baf88466900b258a9f2c28fd Mon Sep 17 00:00:00 2001 From: shanevcantwell <153727980+shanevcantwell@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:08:33 -0700 Subject: [PATCH] refactor: generalize remote URI handling and remove CLAUDE.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove WSL-specific check in favor of generic URI handling - Support all vscode-remote:// URI schemes (WSL, SSH, dev-container) - Prefer file:// URIs when available, fall back to remote URIs - Add tests for various remote URI formats - Remove CLAUDE.md per reviewer feedback (use AGENTS.md convention) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 52 ------------------- .../implementations/runTerminalCommand.ts | 26 +++++----- .../runTerminalCommand.vitest.ts | 52 +++++++++++++++++++ 3 files changed, 65 insertions(+), 65 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 4de463f01..000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,52 +0,0 @@ -# Continue Development Notes - -## WSL2 Development - -### Building VSIX from WSL2 - -The VS Code extension VSIX built on Linux contains Linux-only native binaries (sqlite3, LanceDB, ripgrep). When VS Code runs in WSL remote mode, extensions can run in either: - -- **Windows extension host** - needs Windows binaries -- **WSL extension host** - Linux binaries work - -If both hosts try to load the extension, the Windows host fails with: - -``` -Error: node_sqlite3.node is not a valid Win32 application -``` - -**Workaround for local testing:** - -1. Build VSIX normally: `npm run package` (in extensions/vscode) -2. Install: `code --install-extension extensions/vscode/build/continue-*.vsix` -3. Delete Windows installation to force WSL-only: - ```bash - rm -rf /mnt/c/Users//.vscode/extensions/continue.continue-* - ``` -4. Reload VS Code - -This forces Continue to run exclusively in WSL extension host where Linux binaries work. - -**Related:** GitHub Issue #9326 - -### File Count and Extension Activation - -Large file counts (300K+) from node_modules and build artifacts can cause extension activation issues. If Continue fails to load: - -1. Delete build artifacts: - ```bash - rm -rf */node_modules */*/node_modules node_modules - rm -rf */dist */*/dist */out */*/out */build - ``` -2. Reload VS Code -3. Rebuild only when needed for testing - -### Terminal Command Working Directory - -The `run_terminal_command` tool resolves workspace directories from VS Code URIs. In WSL2: - -- URIs are `vscode-remote://wsl+Ubuntu/path` (not `file://`) -- Must parse with `new URL()` and extract pathname -- Must `decodeURIComponent()` for paths with spaces/special chars - -See: `core/tools/implementations/runTerminalCommand.ts` diff --git a/core/tools/implementations/runTerminalCommand.ts b/core/tools/implementations/runTerminalCommand.ts index e80414f92..bed8aceb8 100644 --- a/core/tools/implementations/runTerminalCommand.ts +++ b/core/tools/implementations/runTerminalCommand.ts @@ -48,19 +48,6 @@ import { getBooleanArg, getStringArg } from "../parseArgs"; * Falls back to home directory or temp directory if no workspace is available. */ function resolveWorkingDirectory(workspaceDirs: string[]): string { - // Handle vscode-remote://wsl+distro/path URIs (WSL2 remote workspaces) - const wslWorkspaceDir = workspaceDirs.find((dir) => - dir.startsWith("vscode-remote://wsl"), - ); - if (wslWorkspaceDir) { - try { - const url = new URL(wslWorkspaceDir); - return decodeURIComponent(url.pathname); // e.g., "/home/user/project" - } catch { - // Fall through to other handlers - } - } - // Handle file:// URIs (local workspaces) const fileWorkspaceDir = workspaceDirs.find((dir) => dir.startsWith("file:/"), @@ -74,6 +61,19 @@ function resolveWorkingDirectory(workspaceDirs: string[]): string { } } + // Handle other URI schemes (vscode-remote://wsl, vscode-remote://ssh-remote, etc.) + const remoteWorkspaceDir = workspaceDirs.find( + (dir) => dir.includes("://") && !dir.startsWith("file:/"), + ); + if (remoteWorkspaceDir) { + try { + const url = new URL(remoteWorkspaceDir); + return decodeURIComponent(url.pathname); + } catch { + // Fall through to other handlers + } + } + // Default to user's home directory with fallbacks try { return process.env.HOME || process.env.USERPROFILE || process.cwd(); diff --git a/core/tools/implementations/runTerminalCommand.vitest.ts b/core/tools/implementations/runTerminalCommand.vitest.ts index 428cc8306..089c85502 100644 --- a/core/tools/implementations/runTerminalCommand.vitest.ts +++ b/core/tools/implementations/runTerminalCommand.vitest.ts @@ -553,6 +553,58 @@ describe("runTerminalCommandImpl", () => { // This demonstrates why the fix is needed - fileURLToPath throws on non-file URIs expect(() => fileURLToPath(nonFileUri)).toThrow(); }); + + it("should handle vscode-remote URIs by extracting pathname", async () => { + // Various remote URI formats that VS Code uses + const remoteUris = [ + "vscode-remote://wsl+Ubuntu/home/user/project", + "vscode-remote://ssh-remote+myserver/home/user/project", + "vscode-remote://dev-container+abc123/workspace", + ]; + + for (const uri of remoteUris) { + mockGetWorkspaceDirs.mockResolvedValue([uri]); + + // Should not throw - the generic URI handler extracts the pathname + await expect( + runTerminalCommandImpl( + { command: "echo test", waitForCompletion: false }, + createMockExtras(), + ), + ).resolves.toBeDefined(); + } + }); + + it("should decode URI-encoded characters in remote workspace paths", async () => { + // Path with spaces and special characters + const encodedUri = + "vscode-remote://wsl+Ubuntu/home/user/my%20project%20%28test%29"; + mockGetWorkspaceDirs.mockResolvedValue([encodedUri]); + + // Should handle without throwing - decodeURIComponent is applied + await expect( + runTerminalCommandImpl( + { command: "echo test", waitForCompletion: false }, + createMockExtras(), + ), + ).resolves.toBeDefined(); + }); + + it("should prefer file:// URIs over remote URIs when both present", async () => { + const workspaceDirs = [ + "vscode-remote://wsl+Ubuntu/home/user/remote-project", + "file:///home/user/local-project", + ]; + mockGetWorkspaceDirs.mockResolvedValue(workspaceDirs); + + // Should succeed, preferring the file:// URI + await expect( + runTerminalCommandImpl( + { command: "echo test", waitForCompletion: false }, + createMockExtras(), + ), + ).resolves.toBeDefined(); + }); }); describe("remote environment handling", () => {