Stop copying node-pty into Copilot CLI SDK (#310925)

* Stop copying node-pty into Copilot CLI SDK

* reanem

Co-authored-by: Copilot <copilot@github.com>

* resovle copilot comment

* recognize other sdk prebuilds NOT node-pty

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Anthony Kim
2026-04-20 21:25:55 -07:00
committed by GitHub
parent a1d3ff15f4
commit e8a7c6d6df
8 changed files with 43 additions and 246 deletions
+4 -5
View File
@@ -34,7 +34,7 @@ import * as cp from 'child_process';
import log from 'fancy-log';
import buildfile from './buildfile.ts';
import { fetchUrls, fetchGithub } from './lib/fetch.ts';
import { getCopilotExcludeFilter, copyCopilotNativeDeps, prepareBuiltInCopilotExtensionShims } from './lib/copilot.ts';
import { getCopilotExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts';
import jsonEditor from 'gulp-json-editor';
@@ -463,14 +463,13 @@ function patchWin32DependenciesTask(destinationFolderName: string) {
};
}
function copyCopilotNativeDepsTaskREH(platform: string, arch: string, destinationFolderName: string) {
function prepareCopilotRipgrepShimTaskREH(platform: string, arch: string, destinationFolderName: string) {
return async () => {
const outputDir = path.join(BUILD_ROOT, destinationFolderName);
const nodeModulesDir = path.join(outputDir, 'node_modules');
copyCopilotNativeDeps(platform, arch, nodeModulesDir);
const builtInCopilotExtensionDir = path.join(outputDir, 'extensions', 'copilot');
prepareBuiltInCopilotExtensionShims(platform, arch, builtInCopilotExtensionDir, nodeModulesDir);
prepareBuiltInCopilotRipgrepShim(platform, arch, builtInCopilotExtensionDir, nodeModulesDir);
};
}
@@ -523,7 +522,7 @@ function tweakProductForServerWeb(product: typeof import('../product.json')) {
gulp.task(`node-${platform}-${arch}`) as task.Task,
util.rimraf(path.join(BUILD_ROOT, destinationFolderName)),
packageTask(type, platform, arch, sourceFolderName, destinationFolderName),
copyCopilotNativeDepsTaskREH(platform, arch, destinationFolderName)
prepareCopilotRipgrepShimTaskREH(platform, arch, destinationFolderName)
];
if (platform === 'win32') {
+4 -5
View File
@@ -31,7 +31,7 @@ import minimist from 'minimist';
import { compileBuildWithoutManglingTask, compileBuildWithManglingTask } from './gulpfile.compile.ts';
import { compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileAllExtensionsBuildTask, compileExtensionMediaBuildTask, cleanExtensionsBuildTask, compileCopilotExtensionBuildTask } from './gulpfile.extensions.ts';
import { copyCodiconsTask } from './lib/compilation.ts';
import { getCopilotExcludeFilter, copyCopilotNativeDeps, prepareBuiltInCopilotExtensionShims } from './lib/copilot.ts';
import { getCopilotExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts';
import type { EmbeddedProductInfo } from './lib/embeddedType.ts';
import { useEsbuildTranspile } from './buildConfig.ts';
import { promisify } from 'util';
@@ -700,7 +700,7 @@ function patchWin32DependenciesTask(destinationFolderName: string) {
};
}
function copyCopilotNativeDepsTask(platform: string, arch: string, destinationFolderName: string) {
function prepareCopilotRipgrepShimTask(platform: string, arch: string, destinationFolderName: string) {
const outputDir = path.join(path.dirname(root), destinationFolderName);
return async () => {
@@ -711,10 +711,9 @@ function copyCopilotNativeDepsTask(platform: string, arch: string, destinationFo
? path.join(outputDir, `${product.nameLong}.app`, 'Contents', 'Resources', 'app')
: path.join(outputDir, versionedResourcesFolder, 'resources', 'app');
const appNodeModulesDir = path.join(appBase, 'node_modules');
copyCopilotNativeDeps(platform, arch, appNodeModulesDir);
const builtInCopilotExtensionDir = path.join(appBase, 'extensions', 'copilot');
prepareBuiltInCopilotExtensionShims(platform, arch, builtInCopilotExtensionDir, appNodeModulesDir);
prepareBuiltInCopilotRipgrepShim(platform, arch, builtInCopilotExtensionDir, appNodeModulesDir);
};
}
@@ -743,7 +742,7 @@ BUILD_TARGETS.forEach(buildTarget => {
compileNativeExtensionsBuildTask,
util.rimraf(path.join(buildRoot, destinationFolderName)),
packageTask(platform, arch, sourceFolderName, destinationFolderName, opts),
copyCopilotNativeDepsTask(platform, arch, destinationFolderName)
prepareCopilotRipgrepShimTask(platform, arch, destinationFolderName)
];
if (platform === 'win32') {
+17 -69
View File
@@ -46,8 +46,9 @@ function toNodePlatformArch(platform: string, arch: string): { nodePlatform: str
* for architectures other than the build target.
*
* For platforms the copilot SDK doesn't natively support (e.g. alpine, armhf),
* ALL platform packages are stripped - that's fine because the SDK doesn't ship
* binaries for those platforms anyway, and we replace them with VS Code's own.
* ALL platform packages are stripped - that's fine because the copilot CLI SDK
* resolves `node-pty` from the embedder (VS Code) first via `hostRequire`,
* falling back to its bundled copy only if the embedder can't provide it.
*/
export function getCopilotExcludeFilter(platform: string, arch: string): string[] {
const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch);
@@ -55,74 +56,30 @@ export function getCopilotExcludeFilter(platform: string, arch: string): string[
const nonTargetPlatforms = copilotPlatforms.filter(p => p !== targetPlatformArch);
// Strip wrong-architecture @github/copilot-{platform} packages.
// All copilot prebuilds are stripped by .moduleignore; VS Code's own
// node-pty is copied into the prebuilds location by a post-packaging task.
// All copilot prebuilds are stripped by .moduleignore; the copilot CLI SDK
// resolves `node-pty` from VS Code's own node_modules via `hostRequire`.
const excludes = nonTargetPlatforms.map(p => `!**/node_modules/@github/copilot-${p}/**`);
return ['**', ...excludes];
}
/**
* Copies VS Code's own node-pty binaries into the copilot SDK's
* expected locations so the copilot CLI subprocess can find them at runtime.
* The copilot-bundled prebuilds are stripped by .moduleignore;
* this replaces them with the same binaries VS Code already ships, avoiding
* new system dependency requirements.
*
* This works even for platforms the copilot SDK doesn't natively support
* (e.g. alpine, armhf) because the SDK's native module loader simply
* looks for `prebuilds/{process.platform}-{process.arch}/pty.node` - it
* doesn't validate the platform against a supported list.
*
* Failures are logged but do not throw, to avoid breaking the build on
* platforms where something unexpected happens.
*
* @param nodeModulesDir Absolute path to the node_modules directory that
* contains both the source binaries (node-pty) and the copilot SDK
* target directories.
*/
export function copyCopilotNativeDeps(platform: string, arch: string, nodeModulesDir: string): void {
const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch);
const platformArch = `${nodePlatform}-${nodeArch}`;
const copilotBase = path.join(nodeModulesDir, '@github', 'copilot');
if (!fs.existsSync(copilotBase)) {
console.warn(`[copyCopilotNativeDeps] @github/copilot not found at ${copilotBase}, skipping`);
return;
}
const nodePtySource = path.join(nodeModulesDir, 'node-pty', 'build', 'Release');
if (!fs.existsSync(nodePtySource)) {
console.warn(`[copyCopilotNativeDeps] node-pty source not found at ${nodePtySource}, skipping`);
return;
}
try {
// Copy node-pty (pty.node + spawn-helper on Unix, conpty.node + conpty/ on Windows)
// into copilot prebuilds so the SDK finds them via loadNativeModule.
const copilotPrebuildsDir = path.join(copilotBase, 'prebuilds', platformArch);
fs.mkdirSync(copilotPrebuildsDir, { recursive: true });
fs.cpSync(nodePtySource, copilotPrebuildsDir, { recursive: true });
console.log(`[copyCopilotNativeDeps] Copied node-pty from ${nodePtySource} to ${copilotPrebuildsDir}`);
} catch (err) {
console.warn(`[copyCopilotNativeDeps] Failed to copy node-pty for ${platformArch}: ${err}`);
}
}
/**
* Materializes copilot CLI shims directly inside the built-in copilot extension.
* Materializes the copilot CLI ripgrep shim directly inside the built-in copilot extension.
*
* This is used when copilot is shipped as a built-in extension so startup does
* not need to create shims at runtime. The destination layout matches the
* not need to create the shim at runtime. The destination layout matches the
* runtime shim logic in the copilot extension:
* - node-pty: node_modules/@github/copilot/sdk/prebuilds/{platform-arch}
* - ripgrep: node_modules/@github/copilot/sdk/ripgrep/bin/{platform-arch}
* - marker: node_modules/@github/copilot/shims.txt
*
* Note: `node-pty` is no longer shimmed. The copilot CLI SDK resolves
* `node-pty` from the embedder (VS Code) via `hostRequire` and falls back to
* its bundled copy only if that fails.
*
* Failures throw to fail the build because built-in packaging must guarantee
* these artifacts are present.
* this artifact is present.
*/
export function prepareBuiltInCopilotExtensionShims(platform: string, arch: string, builtInCopilotExtensionDir: string, appNodeModulesDir: string): void {
export function prepareBuiltInCopilotRipgrepShim(platform: string, arch: string, builtInCopilotExtensionDir: string, appNodeModulesDir: string): void {
const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch);
const platformArch = `${nodePlatform}-${nodeArch}`;
@@ -130,33 +87,24 @@ export function prepareBuiltInCopilotExtensionShims(platform: string, arch: stri
const copilotBase = path.join(extensionNodeModules, '@github', 'copilot');
const copilotSdkBase = path.join(copilotBase, 'sdk');
if (!fs.existsSync(copilotSdkBase)) {
throw new Error(`[prepareBuiltInCopilotExtensionShims] Copilot SDK directory not found at ${copilotSdkBase}`);
}
const nodePtySource = path.join(appNodeModulesDir, 'node-pty', 'build', 'Release');
if (!fs.existsSync(nodePtySource)) {
throw new Error(`[prepareBuiltInCopilotExtensionShims] node-pty source not found at ${nodePtySource}`);
throw new Error(`[prepareBuiltInCopilotRipgrepShim] Copilot SDK directory not found at ${copilotSdkBase}`);
}
const ripgrepSource = path.join(appNodeModulesDir, '@vscode', 'ripgrep', 'bin');
if (!fs.existsSync(ripgrepSource)) {
throw new Error(`[prepareBuiltInCopilotExtensionShims] ripgrep source not found at ${ripgrepSource}`);
throw new Error(`[prepareBuiltInCopilotRipgrepShim] ripgrep source not found at ${ripgrepSource}`);
}
const nodePtyDest = path.join(copilotSdkBase, 'prebuilds', platformArch);
const ripgrepDest = path.join(copilotSdkBase, 'ripgrep', 'bin', platformArch);
const shimMarkerPath = path.join(copilotBase, 'shims.txt');
try {
fs.mkdirSync(nodePtyDest, { recursive: true });
fs.cpSync(nodePtySource, nodePtyDest, { recursive: true });
fs.mkdirSync(ripgrepDest, { recursive: true });
fs.cpSync(ripgrepSource, ripgrepDest, { recursive: true });
fs.writeFileSync(shimMarkerPath, 'Shims created successfully');
console.log(`[prepareBuiltInCopilotExtensionShims] Materialized shims for ${platformArch} in ${builtInCopilotExtensionDir}`);
console.log(`[prepareBuiltInCopilotRipgrepShim] Materialized ripgrep shim for ${platformArch} in ${builtInCopilotExtensionDir}`);
} catch (err) {
throw new Error(`[prepareBuiltInCopilotExtensionShims] Failed to materialize shims for ${platformArch}: ${err}`);
throw new Error(`[prepareBuiltInCopilotRipgrepShim] Failed to materialize ripgrep shim for ${platformArch}: ${err}`);
}
}
-1
View File
@@ -338,7 +338,6 @@ export default tseslint.config(
ignores: [
'src/util/vs/**/*.ts', // vendored code
'src/**/*.spec.ts', // allow in tests
'./src/extension/agents/copilotcli/node/nodePtyShim.ts',
'./src/extension/byok/common/anthropicMessageConverter.ts',
'./src/extension/byok/common/geminiFunctionDeclarationConverter.ts',
'./src/extension/byok/common/geminiMessageConverter.ts',
@@ -78,7 +78,6 @@ copilotcli/
│ ├── copilotCLISkills.ts # Skills location resolution
│ ├── copilotCLIImageSupport.ts # Image attachment handling
│ ├── mcpHandler.ts # MCP server configuration for SDK sessions
│ ├── nodePtyShim.ts # Copies VS Code's node-pty for SDK use
│ ├── userInputHelpers.ts # User question/input handling interface
│ ├── exitPlanModeHandler.ts # Plan mode exit flow with user choice
│ ├── ripgrepShim.ts # Copies VS Code's ripgrep for SDK use
@@ -313,7 +312,7 @@ Orchestrates the start and end of each chat request turn, coordinating worktree
## Critical Pitfalls
- **Shims before SDK import**: `ensureNodePtyShim()` and `ensureRipgrepShim()` in `node/nodePtyShim.ts` / `node/ripgrepShim.ts` MUST be called before any `import('@github/copilot/sdk')`. They copy VS Code's bundled native binaries to the SDK's expected locations. See `node/copilotCli.ts` for the initialization order.
- **Shims before SDK import**: `ensureRipgrepShim()` in `node/ripgrepShim.ts` MUST be called before any `import('@github/copilot/sdk')`. It copies VS Code's bundled ripgrep binary to the SDK's expected location. `node-pty` is no longer shimmed: the copilot CLI SDK resolves it from VS Code's own `node_modules` via `hostRequire`, falling back to its bundled copy only if that fails. See `node/copilotCli.ts` for the initialization order.
- **Delayed permission UI**: Tool invocation messages are held in `toolCallWaitingForPermissions` until permission resolves. `flushPendingInvocationMessageForToolCallId()` flushes only the specific approved tool, not all pending tools. This is intentional — don't bypass it.
@@ -23,7 +23,6 @@ import { basename } from '../../../../util/vs/base/common/resources';
import { URI } from '../../../../util/vs/base/common/uri';
import { IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation';
import { getCopilotLogger } from './logger';
import { ensureNodePtyShim } from './nodePtyShim';
import { ensureRipgrepShim } from './ripgrepShim';
import { CancellationToken } from '../../../../util/vs/base/common/cancellation';
@@ -460,7 +459,7 @@ export class CopilotCLISDK implements ICopilotCLISDK {
public async getPackage(): Promise<typeof import('@github/copilot/sdk')> {
try {
// Ensure the node-pty shim exists before importing the SDK (required for CLI sessions)
// Ensure the ripgrep shim exists before importing the SDK (required for CLI sessions)
await this._ensureShimsPromise;
return await import('@github/copilot/sdk');
} catch (error) {
@@ -497,10 +496,7 @@ export class CopilotCLISDK implements ICopilotCLISDK {
if (await checkFileExists(successfulPlaceholder)) {
return;
}
await Promise.all([
ensureNodePtyShim(this.extensionContext.extensionPath, this.envService.appRoot, this.logService),
ensureRipgrepShim(this.extensionContext.extensionPath, this.envService.appRoot, this.logService)
]);
await ensureRipgrepShim(this.extensionContext.extensionPath, this.envService.appRoot, this.logService);
await fs.writeFile(successfulPlaceholder, 'Shims created successfully');
}
@@ -1,144 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { promises as fs } from 'fs';
import * as path from 'path';
import { ILogService } from '../../../../platform/log/common/logService';
let shimCreated: Promise<void> | undefined = undefined;
const RETRIABLE_COPY_ERROR_CODES = new Set(['EPERM', 'EBUSY']);
const MAX_COPY_ATTEMPTS = 6;
const RETRY_DELAY_BASE_MS = 50;
const RETRY_DELAY_CAP_MS = 500;
const MATERIALIZATION_TIMEOUT_MS = 4000;
const MATERIALIZATION_POLL_INTERVAL_MS = 100;
/**
* Copies the node-pty files from VS Code's installation into a @github/copilot location
*
* MUST be called before any `import('@github/copilot/sdk')` or `import('@github/copilot')`.
*
* @github/copilot bundles the node-pty code and its no longer possible to shim the package.
*
* @param extensionPath The extension's path (where to create the shim)
* @param vscodeAppRoot VS Code's installation path (where node-pty is located)
*/
export async function ensureNodePtyShim(extensionPath: string, vscodeAppRoot: string, logService: ILogService): Promise<void> {
if (shimCreated) {
return shimCreated;
}
const creation = _ensureNodePtyShim(extensionPath, vscodeAppRoot, logService);
shimCreated = creation.catch(error => {
shimCreated = undefined;
throw error;
});
return shimCreated;
}
async function _ensureNodePtyShim(extensionPath: string, vscodeAppRoot: string, logService: ILogService): Promise<void> {
const vscodeNodePtyPath = path.join(vscodeAppRoot, 'node_modules', 'node-pty', 'build', 'Release');
await copyNodePtyFiles(extensionPath, vscodeNodePtyPath, logService);
}
export async function copyNodePtyFiles(extensionPath: string, sourceNodePtyPath: string, logService: ILogService): Promise<void> {
const nodePtyDir = path.join(extensionPath, 'node_modules', '@github', 'copilot', 'sdk', 'prebuilds', process.platform + '-' + process.arch);
logService.info(`Creating node-pty shim: source=${sourceNodePtyPath}, dest=${nodePtyDir}`);
try {
await fs.mkdir(nodePtyDir, { recursive: true });
const entries = await fs.readdir(sourceNodePtyPath);
const uniqueEntries = [...new Set(entries)];
logService.info(`Found ${uniqueEntries.length} entries to copy${uniqueEntries.length !== entries.length ? ` (${entries.length - uniqueEntries.length} duplicates ignored)` : ''}: ${uniqueEntries.join(', ')}`);
await copyNodePtyWithRetries(sourceNodePtyPath, nodePtyDir, uniqueEntries, logService);
} catch (error) {
logService.error(`Failed to create node-pty shim (source dir: ${sourceNodePtyPath}, extension dir: ${nodePtyDir})`, error);
throw error;
}
}
async function copyNodePtyWithRetries(sourceDir: string, destDir: string, entries: string[], logService: ILogService): Promise<void> {
const primaryBinary = entries.find(entry => entry.endsWith('.node'));
for (let attempt = 1; attempt <= MAX_COPY_ATTEMPTS; attempt++) {
try {
await fs.cp(sourceDir, destDir, {
recursive: true,
dereference: true,
force: true,
filter: async (srcPath) => shouldCopyEntry(srcPath, logService)
});
logService.trace(`Copied node-pty prebuilds to ${destDir} (attempt ${attempt})`);
return;
} catch (error) {
if (await waitForMaterializedShim(destDir, primaryBinary, logService)) {
logService.trace(`Detected node-pty shim materialized at ${destDir} by another extension host`);
return;
}
if (!RETRIABLE_COPY_ERROR_CODES.has(error?.code) || attempt === MAX_COPY_ATTEMPTS) {
throw error;
}
const delayMs = Math.min(RETRY_DELAY_BASE_MS * Math.pow(2, attempt - 1), RETRY_DELAY_CAP_MS);
logService.warn(`Retryable error (${error.code}) copying node-pty shim. Retrying in ${delayMs}ms (attempt ${attempt + 1}/${MAX_COPY_ATTEMPTS})`);
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
}
async function shouldCopyEntry(srcPath: string, logService: ILogService): Promise<boolean> {
try {
const stat = await fs.stat(srcPath);
if (stat.isDirectory()) {
return true;
}
if (stat.size === 0) {
logService.trace(`Skipping ${path.basename(srcPath)}: zero-byte file (likely symlink or special file)`);
return false;
}
return true;
} catch (error) {
logService.warn(`Failed to stat ${srcPath}: ${error?.message ?? error}`);
return false;
}
}
async function waitForMaterializedShim(destDir: string, primaryBinary: string | undefined, logService: ILogService): Promise<boolean> {
const deadline = Date.now() + MATERIALIZATION_TIMEOUT_MS;
while (Date.now() <= deadline) {
if (await isShimMaterialized(destDir, primaryBinary)) {
logService.trace(`Reusing node-pty shim that materialized at ${destDir}`);
return true;
}
await new Promise(resolve => setTimeout(resolve, MATERIALIZATION_POLL_INTERVAL_MS));
}
return false;
}
async function isShimMaterialized(destDir: string, primaryBinary: string | undefined): Promise<boolean> {
if (primaryBinary) {
const binaryStat = await fs.stat(path.join(destDir, primaryBinary)).catch(() => undefined);
if (binaryStat && binaryStat.isFile() && binaryStat.size > 0) {
return true;
}
}
const entries = await fs.readdir(destDir).catch(() => []);
for (const entry of entries) {
const stat = await fs.stat(path.join(destDir, entry)).catch(() => undefined);
if (stat && stat.isFile() && stat.size > 0) {
return true;
}
}
return false;
}
@@ -8,7 +8,6 @@ import { isBinaryFile } from 'isbinaryfile';
import * as path from 'path';
import { beforeAll, describe, it } from 'vitest';
import { TestLogService } from '../../../../platform/testing/common/testLogService';
import { copyNodePtyFiles } from '../../copilotcli/node/nodePtyShim';
import { copyRipgrepShim } from '../../copilotcli/node/ripgrepShim';
describe('CopilotCLI SDK Upgrade', function () {
@@ -59,6 +58,16 @@ describe('CopilotCLI SDK Upgrade', function () {
// win32 native module (formerly win_error_mode)
path.join('prebuilds', 'win32-arm64', 'win32.node'),
path.join('prebuilds', 'win32-x64', 'win32.node'),
// Second copy of computer.node / win32.node re-shipped by the @github/copilot/sdk subpackage
// (previously hidden by a broad sdk/prebuilds/** exclusion that masked the node-pty files we used to shim in at test setup).
path.join('sdk', 'prebuilds', 'darwin-arm64', 'computer.node'),
path.join('sdk', 'prebuilds', 'darwin-x64', 'computer.node'),
path.join('sdk', 'prebuilds', 'linux-arm64', 'computer.node'),
path.join('sdk', 'prebuilds', 'linux-x64', 'computer.node'),
path.join('sdk', 'prebuilds', 'win32-arm64', 'computer.node'),
path.join('sdk', 'prebuilds', 'win32-x64', 'computer.node'),
path.join('sdk', 'prebuilds', 'win32-arm64', 'win32.node'),
path.join('sdk', 'prebuilds', 'win32-x64', 'win32.node'),
path.join('ripgrep', 'bin', 'darwin-arm64', 'rg'),
path.join('ripgrep', 'bin', 'darwin-x64', 'rg'),
path.join('ripgrep', 'bin', 'linux-x64', 'rg'),
@@ -89,15 +98,13 @@ describe('CopilotCLI SDK Upgrade', function () {
'tree-sitter-scala.wasm',
].map(p => path.join(copilotSDKPath, p)));
// Exclude ripgrep files that we copy over in src/extension/agents/copilotcli/node/ripgrepShim.ts (until we get better API/solution from SDK)
// Exclude ripgrep files that we copy over in src/extension/chatSessions/copilotcli/node/ripgrepShim.ts (until we get better API/solution from SDK)
const ripgrepFilesWeCopy = path.join(copilotSDKPath, 'sdk', 'ripgrep', 'bin');
// Exclude nodepty files that we copy over in src/extension/agents/copilotcli/node/nodePtyShim.ts (until we get better API/solution from SDK)
const nodeptyFilesWeCopy = path.join(copilotSDKPath, 'sdk', 'prebuilds');
const errors: string[] = [];
// Look for new binaries
for (const binary of existingBinaries) {
if (binary.startsWith(ripgrepFilesWeCopy) || binary.startsWith(nodeptyFilesWeCopy)) {
if (binary.startsWith(ripgrepFilesWeCopy)) {
continue;
}
const binaryName = path.basename(binary);
@@ -110,7 +117,7 @@ describe('CopilotCLI SDK Upgrade', function () {
}
// Look for removed binaries.
for (const binary of knownBinaries) {
if (binary.startsWith(ripgrepFilesWeCopy) || binary.startsWith(nodeptyFilesWeCopy)) {
if (binary.startsWith(ripgrepFilesWeCopy)) {
continue;
}
if (!existingBinaries.has(binary)) {
@@ -124,19 +131,13 @@ describe('CopilotCLI SDK Upgrade', function () {
});
it('should be able to load the @github/copilot module without errors', async function () {
await copyNodePtyFiles(
extensionPath,
path.join(copilotSDKPath, 'prebuilds', process.platform + '-' + process.arch),
new TestLogService()
);
await import('@github/copilot/sdk');
});
});
async function copyBinaries(extensionPath: string) {
const nodePtyPrebuilds = path.join(extensionPath, 'node_modules', '@github', 'copilot', 'prebuilds', process.platform + '-' + process.arch);
const vscodeRipgrepPath = path.join(extensionPath, 'node_modules', '@github', 'copilot', 'ripgrep', 'bin', process.platform + '-' + process.arch);
await copyNodePtyFiles(extensionPath, nodePtyPrebuilds, new TestLogService());
const copilotSDKPath = path.join(extensionPath, 'node_modules', '@github', 'copilot');
const vscodeRipgrepPath = path.join(copilotSDKPath, 'ripgrep', 'bin', process.platform + '-' + process.arch);
await copyRipgrepShim(extensionPath, vscodeRipgrepPath, new TestLogService());
}
async function findAllBinaries(dir: string): Promise<string[]> {