Skip to content

Fix/wsl remote tool calling#12422

Closed
AeonDigital wants to merge 7 commits into
continuedev:mainfrom
AeonDigital:fix/wsl-remote-tool-calling
Closed

Fix/wsl remote tool calling#12422
AeonDigital wants to merge 7 commits into
continuedev:mainfrom
AeonDigital:fix/wsl-remote-tool-calling

Conversation

@AeonDigital
Copy link
Copy Markdown

@AeonDigital AeonDigital commented May 15, 2026

Summary

This PR is based almost entirely on the earlier work from PR #10786 by @shanevcantwell, titled: feat: shell integration-based terminal output capture for remote environments.

The original PR addressed the issue where the extension host runs on Windows with a remote workspace (SSH, WSL, Dev Container) and child process execution was incorrectly performed locally instead of on the remote machine. The existing fallback used ide.runCommand with no output capture, returning a hardcoded "Command completed" status with no actual remote output.

In addition to applying Shane's solution, this PR also updates the repository to work with Node 22.22.3, which required changes to the dependency installation and packaging workflow.

What this PR includes

  • Credit to @shanevcantwell for the remote terminal shell integration solution.
  • Implementation of a new runCommandWithOutput IDE method using VS Code Shell Integration API (1.93+) for remote terminal execution and output capture.
  • A fallback path when shell integration is unavailable that still executes commands via sendText without double-execution.
  • Packaging and install workflow updates to support Node 22.22.3 and Node SEA-based binary bundling.
  • Additional dependency manifest updates and generated lockfiles for the new environment.

Key changes

Remote shell integration support

  • Adds runCommandWithOutput to the IDE interface and protocol layers:
    • core/index.d.ts
    • core/protocol/ide.ts
    • core/protocol/messenger/messageIde.ts
    • core/protocol/messenger/reverseMessageIde.ts
  • Adds VS Code extension support for the new handler:
    • extensions/vscode/src/extension/VsCodeMessenger.ts
  • Implements the remote shell integration flow in the VS Code IDE adapter:
    • extensions/vscode/src/VsCodeIde.ts
  • Updates the remote fallback path in the terminal tool implementation to use the new method:
    • core/tools/implementations/runTerminalCommand.ts
  • Adds a stub fallback in the filesystem IDE implementation:
    • core/util/filesystem.ts
  • Enhances WSL/remote path handling for config storage:
    • core/util/paths.ts
  • Includes related type and protocol support updates:
    • core/config/types.ts
  • Adds test support/mocks for the new behavior:
    • core/tools/implementations/runTerminalCommand.vitest.ts

Node and install workflow updates

  • Updated the root package.json and binary/package.json for new devDependencies and runtime requirements.
  • Added support for Node SEA-based binary packaging in binary/utils/bundle-binary.js.
  • Adjusted binary build expectations in binary/build.js.
  • Updated the install script to validate Node version compatibility and support the new package workflow:
    • scripts/install-dependencies.sh
  • Hardened VS Code packaging dependency copying for @vscode/ripgrep and temporary install behavior:
    • extensions/vscode/scripts/install-copy-nodemodule.js

Tests and validation

  • Verified remote terminal integration behavior in the expected Shell Integration path.
  • Ensured fallback behavior still executes commands when shell integration is unavailable.
  • Confirmed Node 22.22.3 compatible install flow and packaging changes.
  • Updated any associated test harness expectations where needed.

Why this matters

The original issue affected remote development workflows where commands executed by the extension host were incorrectly routed to the local machine. This PR delivers the intended fix by capturing remote terminal output with VS Code shell integration, while preserving ANSI formatting and providing a safe fallback.

The Node 22.22.3 update is also important because it aligns the repository with the newer runtime and packaging expectations, and it required corresponding install and bundle adjustments.

Notes

  • This PR is intentionally built on top of Shane's original shell integration approach.

  • The Node upgrade is a complementary change needed to make the updated install and packaging flow work reliably.

  • The new output capture preserves ANSI colors and strips only VS Code internal OSC markers.

  • When shell integration is unavailable, the command still executes and the caller receives a sensible completion message without duplicate execution.

  • Some files were automatically updated by Prettier formatting as part of these changes. These formatting-only edits are non-functional and should be considered separate from the behavioral changes above.


Summary by cubic

Fixes remote tool execution in SSH/WSL/dev containers by running commands on the remote machine and capturing output via VS Code shell integration. Also upgrades to Node 22.22.3, switches the binary to Node SEA packaging, and adjusts @vscode/ripgrep handling for reliable builds.

  • Bug Fixes

    • Remote terminal tool now runs on the remote host and captures output using a new IDE method runCommandWithOutput (uses VS Code Shell Integration; falls back to sendText when unavailable).
    • Handles non‑zero exit codes, avoids double execution, and preserves ANSI colors. Improves WSL/remote path detection for config storage.
    • In remote VS Code sessions, always use the compiled GUI (not the localhost dev server) to ensure accessibility.
  • Migration

    • Requires Node 22.22.3 across the repo (.nvmrc, .node-version, engines updated).
    • Binary build switches to Node SEA; install/build scripts and dependencies updated (adds postject, ncp).
    • Adds @vscode/ripgrep and updates packaging: dev packaging writes placeholder rg/rg.exe to satisfy VS Code validation on Windows; copy/cleanup scripts adjusted.

Written for commit 88a39f0. Summary will update on new commits. Review in cubic

@AeonDigital AeonDigital requested a review from a team as a code owner May 15, 2026 23:21
@AeonDigital AeonDigital requested review from sestinj and removed request for a team May 15, 2026 23:21
@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label May 15, 2026
@github-actions
Copy link
Copy Markdown
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 104 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="extensions/vscode/src/diff/vertical/handler.ts">

<violation number="1" location="extensions/vscode/src/diff/vertical/handler.ts:377">
P1: Undo options are evaluated as a no-op comma expression inside the `edit` callback and are never passed to the VS Code API. `TextEditor.edit` expects options as its second argument, not inside the callback body. This breaks intended undo-grouping during Myers diff reapply.</violation>
</file>

<file name="binary/build.js">

<violation number="1" location="binary/build.js:221">
P1: Removed sqlite3 native module verification without completing dependency removal or updating the new SEA build path; builds may pass validation while failing at runtime when sqlite is exercised.</violation>
</file>

<file name="binary/utils/bundle-binary.js">

<violation number="1" location="binary/utils/bundle-binary.js:83">
P1: Cross-target binary packaging is broken: the SEA build always copies the host Node.js executable (`process.execPath`) regardless of the `target` parameter. The previous `pkg`-based build supported cross-compilation by using `pkgJson/${target}`, but Node SEA requires a platform/arch-matching base binary and the new code provides none. This causes all non-host targets to receive a host-architecture binary, producing broken artifacts.</violation>

<violation number="2" location="binary/utils/bundle-binary.js:149">
P1: Unsafe default LanceDB package fallback may bundle wrong native module for unmapped targets</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Fix all with cubic
Re-trigger cubic

await this.editor.edit((editBuilder) => {
editBuilder.replace(this.range, replaceContent),
{ undoStopAfter: false, undoStopBefore: false };
(editBuilder.replace(this.range, replaceContent),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Undo options are evaluated as a no-op comma expression inside the edit callback and are never passed to the VS Code API. TextEditor.edit expects options as its second argument, not inside the callback body. This breaks intended undo-grouping during Myers diff reapply.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/vscode/src/diff/vertical/handler.ts, line 377:

<comment>Undo options are evaluated as a no-op comma expression inside the `edit` callback and are never passed to the VS Code API. `TextEditor.edit` expects options as its second argument, not inside the callback body. This breaks intended undo-grouping during Myers diff reapply.</comment>

<file context>
@@ -374,8 +374,8 @@ export class VerticalDiffHandler implements vscode.Disposable {
     await this.editor.edit((editBuilder) => {
-      editBuilder.replace(this.range, replaceContent),
-        { undoStopAfter: false, undoStopBefore: false };
+      (editBuilder.replace(this.range, replaceContent),
+        { undoStopAfter: false, undoStopBefore: false });
     });
</file context>
Fix with Cubic

Comment thread binary/build.js
`${targetDir}/continue-binary${exe}`,
`${targetDir}/index.node`, // @lancedb
`${targetDir}/build/Release/node_sqlite3.node`,
`${targetDir}/rg${exe}`, // ripgrep binary
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Removed sqlite3 native module verification without completing dependency removal or updating the new SEA build path; builds may pass validation while failing at runtime when sqlite is exercised.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At binary/build.js, line 221:

<comment>Removed sqlite3 native module verification without completing dependency removal or updating the new SEA build path; builds may pass validation while failing at runtime when sqlite is exercised.</comment>

<file context>
@@ -218,7 +218,6 @@ async function buildWithEsbuild() {
       `${targetDir}/continue-binary${exe}`,
       `${targetDir}/index.node`, // @lancedb
-      `${targetDir}/build/Release/node_sqlite3.node`,
       `${targetDir}/rg${exe}`, // ripgrep binary
     );
   }
</file context>
Fix with Cubic

`node_modules/${TARGET_TO_LANCEDB[target]}/index.node`,
`${targetDir}/index.node`,
// 10. Source path
const lancedbPackage = TARGET_TO_LANCEDB[target] || "vectordb-linux-x64-gnu";
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Unsafe default LanceDB package fallback may bundle wrong native module for unmapped targets

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At binary/utils/bundle-binary.js, line 149:

<comment>Unsafe default LanceDB package fallback may bundle wrong native module for unmapped targets</comment>

<file context>
@@ -46,26 +47,159 @@ async function downloadNodeSqlite(target, targetDir) {
-    `node_modules/${TARGET_TO_LANCEDB[target]}/index.node`,
-    `${targetDir}/index.node`,
+  // 10. Source path
+  const lancedbPackage = TARGET_TO_LANCEDB[target] || "vectordb-linux-x64-gnu";
+  const lancedbSource = path.join(
+    __dirname,
</file context>
Suggested change
const lancedbPackage = TARGET_TO_LANCEDB[target] || "vectordb-linux-x64-gnu";
if (!TARGET_TO_LANCEDB[target]) {
throw new Error(`No LanceDB package mapped for target: ${target}`);
}
const lancedbPackage = TARGET_TO_LANCEDB[target];
Fix with Cubic


// 4. copy the current Node.js executable as the shell/base of the binary.
console.log(`[info] [SEA] Copiando executável base do Node...`);
fs.copyFileSync(process.execPath, finalBinaryPath);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Cross-target binary packaging is broken: the SEA build always copies the host Node.js executable (process.execPath) regardless of the target parameter. The previous pkg-based build supported cross-compilation by using pkgJson/${target}, but Node SEA requires a platform/arch-matching base binary and the new code provides none. This causes all non-host targets to receive a host-architecture binary, producing broken artifacts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At binary/utils/bundle-binary.js, line 83:

<comment>Cross-target binary packaging is broken: the SEA build always copies the host Node.js executable (`process.execPath`) regardless of the `target` parameter. The previous `pkg`-based build supported cross-compilation by using `pkgJson/${target}`, but Node SEA requires a platform/arch-matching base binary and the new code provides none. This causes all non-host targets to receive a host-architecture binary, producing broken artifacts.</comment>

<file context>
@@ -46,26 +47,159 @@ async function downloadNodeSqlite(target, targetDir) {
+
+  // 4. copy the current Node.js executable as the shell/base of the binary.
+  console.log(`[info] [SEA] Copiando executável base do Node...`);
+  fs.copyFileSync(process.execPath, finalBinaryPath);
+
+  // 5. Inject the code BLOB into the copied executable.
</file context>
Fix with Cubic

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="extensions/vscode/scripts/prepackage.js">

<violation number="1" location="extensions/vscode/scripts/prepackage.js:458">
P1: Unconditionally overwrites ripgrep binaries with placeholder text, destroying real executables installed by dependency setup and causing runtime spawn failures.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Fix all with cubic | Re-trigger cubic

Comment on lines +458 to +460
fs.writeFileSync(path.join(dir, "rg"), "placeholder-content-for-dev-build");
fs.writeFileSync(
path.join(dir, "rg.exe"),
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Unconditionally overwrites ripgrep binaries with placeholder text, destroying real executables installed by dependency setup and causing runtime spawn failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/vscode/scripts/prepackage.js, line 458:

<comment>Unconditionally overwrites ripgrep binaries with placeholder text, destroying real executables installed by dependency setup and causing runtime spawn failures.</comment>

<file context>
@@ -439,6 +439,29 @@ void (async () => {
+
+  ripgrepDirs.forEach((dir) => {
+    if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
+    fs.writeFileSync(path.join(dir, "rg"), "placeholder-content-for-dev-build");
+    fs.writeFileSync(
+      path.join(dir, "rg.exe"),
</file context>
Suggested change
fs.writeFileSync(path.join(dir, "rg"), "placeholder-content-for-dev-build");
fs.writeFileSync(
path.join(dir, "rg.exe"),
if (!fs.existsSync(path.join(dir, "rg"))) {
fs.writeFileSync(path.join(dir, "rg"), "placeholder-content-for-dev-build");
}
const rgExePath = path.join(dir, "rg.exe");
if (!fs.existsSync(rgExePath)) {
fs.writeFileSync(rgExePath, "placeholder-content-for-dev-build");
}
Fix with Cubic

@github-project-automation github-project-automation Bot moved this from Todo to Done in Issues and PRs May 16, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators May 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant