diff --git a/build/darwin/create-universal-app.ts b/build/darwin/create-universal-app.ts index 459bd55b3500a..7b6910a05e0e2 100644 --- a/build/darwin/create-universal-app.ts +++ b/build/darwin/create-universal-app.ts @@ -121,7 +121,7 @@ async function main(buildDir?: string) { outAppPath, force: true, mergeASARs: true, - x64ArchFiles: '{*/kerberos.node,**/extensions/microsoft-authentication/dist/libmsalruntime.dylib,**/extensions/microsoft-authentication/dist/msal-node-runtime.node,**/node_modules/@github/copilot-darwin-*/copilot,**/node_modules/@github/copilot/prebuilds/darwin-*/*,**/node_modules/@github/copilot/tgrep/bin/darwin-*/*,**/node_modules/@github/copilot/sdk/tgrep/bin/darwin-*/*,**/node_modules.asar.unpacked/@github/copilot-darwin-*/copilot,**/node_modules.asar.unpacked/@github/copilot/prebuilds/darwin-*/*,**/node_modules.asar.unpacked/@github/copilot/tgrep/bin/darwin-*/*,**/node_modules.asar.unpacked/@github/copilot/sdk/tgrep/bin/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/sdk/prebuilds/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/sdk/ripgrep/bin/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/sdk/tgrep/bin/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/tgrep/bin/darwin-*/*,**/node_modules/@vscode/ripgrep-universal/bin/darwin-*/*,**/node_modules.asar.unpacked/@vscode/ripgrep-universal/bin/darwin-*/*,**/node_modules/@microsoft/mxc-sdk/bin/**,**/node_modules.asar.unpacked/@microsoft/mxc-sdk/bin/**}', + x64ArchFiles: '{*/kerberos.node,**/extensions/microsoft-authentication/dist/libmsalruntime.dylib,**/extensions/microsoft-authentication/dist/msal-node-runtime.node,**/node_modules/@github/copilot-darwin-*/**,**/node_modules/@github/copilot/prebuilds/darwin-*/*,**/node_modules/@github/copilot/tgrep/bin/darwin-*/*,**/node_modules/@github/copilot/sdk/tgrep/bin/darwin-*/*,**/node_modules.asar.unpacked/@github/copilot-darwin-*/**,**/node_modules.asar.unpacked/@github/copilot/prebuilds/darwin-*/*,**/node_modules.asar.unpacked/@github/copilot/tgrep/bin/darwin-*/*,**/node_modules.asar.unpacked/@github/copilot/sdk/tgrep/bin/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/sdk/prebuilds/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/sdk/ripgrep/bin/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/sdk/tgrep/bin/darwin-*/*,**/extensions/copilot/node_modules/@github/copilot/tgrep/bin/darwin-*/*,**/node_modules/@vscode/ripgrep-universal/bin/darwin-*/*,**/node_modules.asar.unpacked/@vscode/ripgrep-universal/bin/darwin-*/*,**/node_modules/@microsoft/mxc-sdk/bin/**,**/node_modules.asar.unpacked/@microsoft/mxc-sdk/bin/**}', filesToSkipComparison: (file: string) => { for (const expected of filesToSkip) { if (minimatch(file, expected)) { diff --git a/build/gulpfile.reh.ts b/build/gulpfile.reh.ts index b00894781aee6..caf85b4d72c3b 100644 --- a/build/gulpfile.reh.ts +++ b/build/gulpfile.reh.ts @@ -31,7 +31,7 @@ import log from 'fancy-log'; import buildfile from './buildfile.ts'; import { fetchUrls } from './lib/fetch.ts'; import { downloadFeedPackage } from './lib/azureFeed.ts'; -import { getCopilotExcludeFilter, getCopilotRuntimePrebuildFiles, getCopilotTgrepExcludeFilter, getRipgrepExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts'; +import { ensureCopilotPlatformPackage, getCopilotExcludeFilter, getCopilotRuntimePrebuildFiles, getCopilotTgrepExcludeFilter, getRipgrepExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts'; import { readAgentSdkResults } from './agent-sdk/common.ts'; @@ -442,6 +442,7 @@ function packageTask(type: string, platform: string, arch: string, sourceFolderN .pipe(filter(['**', '!**/package-lock.json', '!**/*.{js,css}.map'])) .pipe(util.cleanNodeModules(path.join(import.meta.dirname, '.moduleignore'))) .pipe(util.cleanNodeModules(path.join(import.meta.dirname, `.moduleignore.${process.platform}`))); + ensureCopilotPlatformPackage(platform, arch, 'remote/node_modules'); const copilotRuntimePrebuilds = gulp.src(getCopilotRuntimePrebuildFiles(platform, arch, 'remote/node_modules'), { base: 'remote', dot: true, allowEmpty: true }); const deps = es.merge(cleanedDeps, copilotRuntimePrebuilds) .pipe(filter(getCopilotExcludeFilter(platform, arch))) diff --git a/build/gulpfile.vscode.ts b/build/gulpfile.vscode.ts index 53987f88edb1a..02750e9a85610 100644 --- a/build/gulpfile.vscode.ts +++ b/build/gulpfile.vscode.ts @@ -28,7 +28,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, getCopilotRuntimePrebuildFiles, getCopilotTgrepExcludeFilter, getRipgrepExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts'; +import { ensureCopilotPlatformPackage, getCopilotExcludeFilter, getCopilotRuntimePrebuildFiles, getCopilotTgrepExcludeFilter, getRipgrepExcludeFilter, prepareBuiltInCopilotRipgrepShim } from './lib/copilot.ts'; import { readAgentSdkResults } from './agent-sdk/common.ts'; import { useEsbuildTranspile } from './buildConfig.ts'; import { promisify } from 'util'; @@ -340,6 +340,7 @@ function packageTask(platform: string, arch: string, sourceFolderName: string, d .pipe(filter(depFilterPattern)) .pipe(util.cleanNodeModules(path.join(import.meta.dirname, '.moduleignore'))) .pipe(util.cleanNodeModules(path.join(import.meta.dirname, `.moduleignore.${process.platform}`))); + ensureCopilotPlatformPackage(platform, arch); const copilotRuntimePrebuilds = gulp.src(getCopilotRuntimePrebuildFiles(platform, arch), { base: '.', dot: true, allowEmpty: true }); const deps = es.merge(cleanedDeps, copilotRuntimePrebuilds) .pipe(filter(getCopilotExcludeFilter(platform, arch))) diff --git a/build/lib/copilot.ts b/build/lib/copilot.ts index 74babc798f4e4..8344512dd307a 100644 --- a/build/lib/copilot.ts +++ b/build/lib/copilot.ts @@ -4,7 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; +import { createHash } from 'crypto'; +import { execFileSync } from 'child_process'; +import * as os from 'os'; import * as path from 'path'; +import { extract } from 'tar'; /** * The platforms that @github/copilot ships platform-specific packages for. @@ -13,6 +17,7 @@ import * as path from 'path'; export const copilotPlatforms = [ 'darwin-arm64', 'darwin-x64', 'linux-arm64', 'linux-x64', + 'linuxmusl-arm64', 'linuxmusl-x64', 'win32-arm64', 'win32-x64', ]; @@ -73,6 +78,38 @@ function toCopilotTgrepPlatformArch(platform: string, arch: string): string { return `${nodePlatform}-${nodeArch}`; } +function toCopilotPackagePlatformArch(platform: string, arch: string): string { + if (platform === 'alpine') { + return `linuxmusl-${arch}`; + } + if (arch === 'alpine') { + return 'linuxmusl-x64'; + } + + const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch); + return `${nodePlatform}-${nodeArch}`; +} + +const copilotOptionalNativePayloadDirs = [ + 'clipboard', + 'foundry-local-sdk', + 'mxc-bin', + 'pvrecorder', +]; + +function getCopilotOptionalNativePayloadFiles(platform: string): string[] { + const files = [ + 'prebuilds/*/computer.node', + 'prebuilds/*/keytar.node', + ]; + + if (platform !== 'win32') { + files.push('prebuilds/*/cli-native.node'); + } + + return files; +} + /** * Returns a glob filter that strips @vscode/ripgrep-universal bin directories * for architectures other than the build target. @@ -102,14 +139,13 @@ export function getCopilotTgrepExcludeFilter(platform: string, arch: string): st * Returns a glob filter that strips @github/copilot platform packages * 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 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. + * Alpine uses the linuxmusl-* packages. Other platform package names follow + * Node's `${process.platform}-${process.arch}` naming. If Copilot does not + * ship the computed platform package (for example linux-arm for armhf builds), + * this strips every known @github/copilot-* platform package. */ export function getCopilotExcludeFilter(platform: string, arch: string): string[] { - const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch); - const targetPlatformArch = `${nodePlatform}-${nodeArch}`; + const targetPlatformArch = toCopilotPackagePlatformArch(platform, arch); const nonTargetPlatforms = copilotPlatforms.filter(p => p !== targetPlatformArch); // Strip wrong-architecture @github/copilot-{platform} packages. @@ -119,55 +155,121 @@ export function getCopilotExcludeFilter(platform: string, arch: string): string[ } /** - * Returns the public @github/copilot-sdk runtime native addon files that must - * survive app/remote packaging for the target platform. + * Returns the public @github/copilot package files that must survive + * app/remote packaging for the target platform. * - * .moduleignore strips @github/copilot/prebuilds/** globally because the - * internal extension SDK uses a copied sdk/prebuilds layout. Agent Host uses - * the public SDK, whose runtime addon loader expects runtime.node in the root - * prebuilds layout. The SDK's built-in shell tool additionally spawns commands - * through node-pty, whose native binaries live in the same root prebuilds - * layout, so those must be preserved too (otherwise the sandboxed shell fails - * with `Cannot find module './prebuilds//pty.node'` — or conpty.node - * on Windows). + * .moduleignore strips all @github/copilot-* platform packages globally. + * Re-add the selected runtime package so Agent Host can launch its index.js + * entrypoint and load runtime prebuilds. Keep the standalone SEA executable + * and optional native payload trees out of the product build. */ export function getCopilotRuntimePrebuildFiles(platform: string, arch: string, nodeModulesRoot = 'node_modules'): string[] { - const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch); - const targetPlatformArch = `${nodePlatform}-${nodeArch}`; - const prebuildDir = path.posix.join(nodeModulesRoot, '@github', 'copilot', 'prebuilds', targetPlatformArch); + const copilotPackagePlatformArch = toCopilotPackagePlatformArch(platform, arch); + const copilotPlatformPackageDir = path.posix.join(nodeModulesRoot, '@github', `copilot-${copilotPackagePlatformArch}`); - const files = [ - path.posix.join(prebuildDir, 'runtime.node'), + return [ + path.posix.join(copilotPlatformPackageDir, '**'), + `!${path.posix.join(copilotPlatformPackageDir, 'copilot')}`, + `!${path.posix.join(copilotPlatformPackageDir, 'copilot.exe')}`, + ...copilotOptionalNativePayloadDirs.map(dir => `!${path.posix.join(copilotPlatformPackageDir, dir, '**')}`), + ...getCopilotOptionalNativePayloadFiles(platform).map(file => `!${path.posix.join(copilotPlatformPackageDir, file)}`), ]; +} - // node-pty native binaries for the SDK's built-in shell tool. Windows uses - // ConPTY (conpty.node plus the conpty/ helpers); darwin/linux use pty.node, - // and darwin additionally ships the spawn-helper executable. - if (nodePlatform === 'win32') { - files.push( - path.posix.join(prebuildDir, 'conpty.node'), - path.posix.join(prebuildDir, 'conpty_console_list.node'), - path.posix.join(prebuildDir, 'conpty', 'OpenConsole.exe'), - path.posix.join(prebuildDir, 'conpty', 'conpty.dll'), - ); - } else { - files.push(path.posix.join(prebuildDir, 'pty.node')); - if (nodePlatform === 'darwin') { - files.push(path.posix.join(prebuildDir, 'spawn-helper')); - } +interface NpmPackageLock { + packages?: Record; +} + +interface EnsureCopilotPlatformPackageOptions { + packPackage?: (packageName: string, version: string, tempDir: string) => string; +} + +/** + * Ensures the selected @github/copilot-{platform} package is present before + * packaging. npm only installs the host-compatible optional dependency, but + * VS Code packaging can cross-build targets such as darwin-x64 on arm64 hosts. + */ +export function ensureCopilotPlatformPackage(platform: string, arch: string, nodeModulesRoot = 'node_modules', options: EnsureCopilotPlatformPackageOptions = {}): void { + const copilotPackagePlatformArch = toCopilotPackagePlatformArch(platform, arch); + if (!copilotPlatforms.includes(copilotPackagePlatformArch)) { + return; } - return files; + const packageName = `@github/copilot-${copilotPackagePlatformArch}`; + const packageDir = path.join(nodeModulesRoot, '@github', `copilot-${copilotPackagePlatformArch}`); + if (fs.existsSync(packageDir)) { + return; + } + + const lockFilePath = path.join(path.dirname(nodeModulesRoot), 'package-lock.json'); + const lockPackageKey = path.posix.join('node_modules', '@github', `copilot-${copilotPackagePlatformArch}`); + const lockPackage = readNpmPackageLock(lockFilePath).packages?.[lockPackageKey]; + if (!lockPackage?.version) { + throw new Error(`[ensureCopilotPlatformPackage] Missing ${lockPackageKey} in ${lockFilePath}. Run npm install to refresh the lockfile.`); + } + + const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vscode-copilot-platform-')); + try { + const tarballPath = (options.packPackage ?? packCopilotPlatformPackage)(packageName, lockPackage.version, tempDir); + verifyNpmIntegrity(tarballPath, lockPackage.integrity); + + fs.mkdirSync(packageDir, { recursive: true }); + extract({ file: tarballPath, cwd: packageDir, strip: 1, sync: true }); + console.log(`[ensureCopilotPlatformPackage] Materialized ${packageName}@${lockPackage.version} in ${packageDir}`); + } catch (err) { + fs.rmSync(packageDir, { recursive: true, force: true }); + throw new Error(`[ensureCopilotPlatformPackage] Failed to materialize ${packageName}@${lockPackage.version}: ${err instanceof Error ? err.message : String(err)}`); + } finally { + fs.rmSync(tempDir, { recursive: true, force: true }); + } +} + +function packCopilotPlatformPackage(packageName: string, version: string, tempDir: string): string { + execFileSync(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['pack', `${packageName}@${version}`, '--pack-destination', tempDir, '--silent'], { stdio: 'pipe', shell: process.platform === 'win32' }); + + const tarball = fs.readdirSync(tempDir).find(name => name.endsWith('.tgz')); + if (!tarball) { + throw new Error(`npm pack did not produce a tarball in ${tempDir}`); + } + + return path.join(tempDir, tarball); +} + +function readNpmPackageLock(lockFilePath: string): NpmPackageLock { + try { + return JSON.parse(fs.readFileSync(lockFilePath, 'utf8')); + } catch (err) { + throw new Error(`[ensureCopilotPlatformPackage] Failed to read ${lockFilePath}: ${err instanceof Error ? err.message : String(err)}`); + } +} + +function verifyNpmIntegrity(tarballPath: string, integrity: string | undefined): void { + if (!integrity) { + return; + } + + const sha512Integrity = integrity.split(/\s+/).find(entry => entry.startsWith('sha512-')); + if (!sha512Integrity) { + return; + } + + const expected = sha512Integrity.slice('sha512-'.length); + const actual = createHash('sha512').update(fs.readFileSync(tarballPath)).digest('base64'); + if (actual !== expected) { + throw new Error(`integrity mismatch for ${tarballPath}`); + } } /** - * Materializes the copilot CLI ripgrep shim directly inside the built-in copilot extension. + * Materializes target-platform Copilot CLI SDK files 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 the shim at runtime. The destination layout matches the - * runtime shim logic in the copilot extension: - * - ripgrep: node_modules/@github/copilot/sdk/ripgrep/bin/{platform-arch} - * - marker: node_modules/@github/copilot/shims.txt + * not need to create the shim at runtime. The Copilot VSIX is built once on the + * Linux x64 host, so product packaging also restores target-platform SDK + * natives from the selected @github/copilot-{platform} package. * * 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 @@ -179,6 +281,7 @@ export function getCopilotRuntimePrebuildFiles(platform: string, arch: string, n export function prepareBuiltInCopilotRipgrepShim(platform: string, arch: string, builtInCopilotExtensionDir: string, appNodeModulesDir: string): void { const { nodePlatform, nodeArch } = toNodePlatformArch(platform, arch); const platformArch = `${nodePlatform}-${nodeArch}`; + const copilotPackagePlatformArch = toCopilotPackagePlatformArch(platform, arch); const tgrepPlatformArch = toCopilotTgrepPlatformArch(platform, arch); const extensionNodeModules = path.join(builtInCopilotExtensionDir, 'node_modules'); @@ -187,7 +290,8 @@ export function prepareBuiltInCopilotRipgrepShim(platform: string, arch: string, if (!fs.existsSync(copilotSdkBase)) { throw new Error(`[prepareBuiltInCopilotRipgrepShim] Copilot SDK directory not found at ${copilotSdkBase}`); } - pruneNonTargetCopilotSdkPrebuilds(platformArch, path.join(copilotSdkBase, 'prebuilds'), copilotPlatforms); + materializeBuiltInCopilotSdkPlatformFiles(copilotPackagePlatformArch, tgrepPlatformArch, copilotBase, appNodeModulesDir); + pruneNonTargetCopilotSdkPrebuilds(copilotPackagePlatformArch, path.join(copilotSdkBase, 'prebuilds'), copilotPlatforms); pruneNonTargetCopilotSdkPrebuilds(tgrepPlatformArch, path.join(copilotSdkBase, path.join('tgrep', 'bin')), copilotTgrepPlatforms); pruneNonTargetCopilotSdkPrebuilds(tgrepPlatformArch, path.join(copilotBase, path.join('tgrep', 'bin')), copilotTgrepPlatforms); @@ -219,6 +323,49 @@ export function prepareBuiltInCopilotRipgrepShim(platform: string, arch: string, } } +function materializeBuiltInCopilotSdkPlatformFiles(copilotPackagePlatformArch: string, tgrepPlatformArch: string, copilotBase: string, appNodeModulesDir: string): void { + if (!copilotPlatforms.includes(copilotPackagePlatformArch)) { + return; + } + + const platformPackageDir = path.join(appNodeModulesDir, '@github', `copilot-${copilotPackagePlatformArch}`); + if (!fs.existsSync(platformPackageDir)) { + throw new Error(`[prepareBuiltInCopilotRipgrepShim] Copilot platform package not found at ${platformPackageDir}`); + } + + copyRequiredDirectory( + path.join(platformPackageDir, 'prebuilds', copilotPackagePlatformArch), + path.join(copilotBase, 'sdk', 'prebuilds', copilotPackagePlatformArch), + `Copilot SDK native prebuilds for ${copilotPackagePlatformArch}` + ); + + if (!copilotTgrepPlatforms.includes(tgrepPlatformArch)) { + return; + } + + const tgrepSource = path.join(platformPackageDir, 'tgrep', 'bin', tgrepPlatformArch); + copyRequiredDirectory( + tgrepSource, + path.join(copilotBase, 'tgrep', 'bin', tgrepPlatformArch), + `Copilot tgrep for ${tgrepPlatformArch}` + ); + copyRequiredDirectory( + tgrepSource, + path.join(copilotBase, 'sdk', 'tgrep', 'bin', tgrepPlatformArch), + `Copilot SDK tgrep for ${tgrepPlatformArch}` + ); +} + +function copyRequiredDirectory(source: string, target: string, description: string): void { + if (!fs.existsSync(source)) { + throw new Error(`[prepareBuiltInCopilotRipgrepShim] ${description} not found at ${source}`); + } + + fs.rmSync(target, { recursive: true, force: true }); + fs.mkdirSync(path.dirname(target), { recursive: true }); + fs.cpSync(source, target, { recursive: true }); +} + function pruneNonTargetCopilotSdkPrebuilds(targetPlatformArch: string, prebuildsDir: string, platformArchs: string[]): void { if (!fs.existsSync(prebuildsDir)) { return; diff --git a/build/lib/test/copilot.test.ts b/build/lib/test/copilot.test.ts new file mode 100644 index 0000000000000..67c9421b10f22 --- /dev/null +++ b/build/lib/test/copilot.test.ts @@ -0,0 +1,251 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'assert'; +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import { suite, test } from 'node:test'; +import { create } from 'tar'; +import { copilotPlatforms, ensureCopilotPlatformPackage, getCopilotExcludeFilter, getCopilotRuntimePrebuildFiles, prepareBuiltInCopilotRipgrepShim } from '../copilot.ts'; + +suite('copilot', () => { + test('keeps the public copilot platform package include list scoped to the selected package', () => { + const files = getCopilotRuntimePrebuildFiles('linux', 'x64'); + + assert.deepStrictEqual(files, [ + 'node_modules/@github/copilot-linux-x64/**', + '!node_modules/@github/copilot-linux-x64/copilot', + '!node_modules/@github/copilot-linux-x64/copilot.exe', + '!node_modules/@github/copilot-linux-x64/clipboard/**', + '!node_modules/@github/copilot-linux-x64/foundry-local-sdk/**', + '!node_modules/@github/copilot-linux-x64/mxc-bin/**', + '!node_modules/@github/copilot-linux-x64/pvrecorder/**', + '!node_modules/@github/copilot-linux-x64/prebuilds/*/computer.node', + '!node_modules/@github/copilot-linux-x64/prebuilds/*/keytar.node', + '!node_modules/@github/copilot-linux-x64/prebuilds/*/cli-native.node', + ]); + assertCopilotPlatformPackageIncludes(files, 'node_modules/@github/copilot-linux-x64', [ + 'index.js', + 'app.js', + 'prebuilds/linux-x64/runtime.node', + 'prebuilds/linux-x64/pty.node', + ]); + assertCopilotStandaloneExecutableExcluded(files, 'node_modules/@github/copilot-linux-x64'); + assertOptionalCopilotNativeDependenciesExcluded(files, 'node_modules/@github/copilot-linux-x64'); + }); + + test('uses the linuxmusl package runtime for alpine builds', () => { + const files = getCopilotRuntimePrebuildFiles('alpine', 'x64'); + + assert.deepStrictEqual(files, [ + 'node_modules/@github/copilot-linuxmusl-x64/**', + '!node_modules/@github/copilot-linuxmusl-x64/copilot', + '!node_modules/@github/copilot-linuxmusl-x64/copilot.exe', + '!node_modules/@github/copilot-linuxmusl-x64/clipboard/**', + '!node_modules/@github/copilot-linuxmusl-x64/foundry-local-sdk/**', + '!node_modules/@github/copilot-linuxmusl-x64/mxc-bin/**', + '!node_modules/@github/copilot-linuxmusl-x64/pvrecorder/**', + '!node_modules/@github/copilot-linuxmusl-x64/prebuilds/*/computer.node', + '!node_modules/@github/copilot-linuxmusl-x64/prebuilds/*/keytar.node', + '!node_modules/@github/copilot-linuxmusl-x64/prebuilds/*/cli-native.node', + ]); + assertCopilotPlatformPackageIncludes(files, 'node_modules/@github/copilot-linuxmusl-x64', [ + 'index.js', + 'app.js', + 'prebuilds/linuxmusl-x64/runtime.node', + ]); + assertCopilotStandaloneExecutableExcluded(files, 'node_modules/@github/copilot-linuxmusl-x64'); + assertOptionalCopilotNativeDependenciesExcluded(files, 'node_modules/@github/copilot-linuxmusl-x64'); + }); + + test('uses the .exe package runtime for windows builds', () => { + assert.deepStrictEqual(getCopilotRuntimePrebuildFiles('win32', 'x64'), [ + 'node_modules/@github/copilot-win32-x64/**', + '!node_modules/@github/copilot-win32-x64/copilot', + '!node_modules/@github/copilot-win32-x64/copilot.exe', + '!node_modules/@github/copilot-win32-x64/clipboard/**', + '!node_modules/@github/copilot-win32-x64/foundry-local-sdk/**', + '!node_modules/@github/copilot-win32-x64/mxc-bin/**', + '!node_modules/@github/copilot-win32-x64/pvrecorder/**', + '!node_modules/@github/copilot-win32-x64/prebuilds/*/computer.node', + '!node_modules/@github/copilot-win32-x64/prebuilds/*/keytar.node', + ]); + assertCopilotPlatformPackageIncludes(getCopilotRuntimePrebuildFiles('win32', 'x64'), 'node_modules/@github/copilot-win32-x64', [ + 'index.js', + 'app.js', + 'prebuilds/win32-x64/cli-native.node', + 'prebuilds/win32-x64/runtime.node', + 'prebuilds/win32-x64/conpty.node', + 'prebuilds/win32-x64/conpty_console_list.node', + 'prebuilds/win32-x64/conpty/OpenConsole.exe', + 'prebuilds/win32-x64/conpty/conpty.dll', + ]); + assertCopilotStandaloneExecutableExcluded(getCopilotRuntimePrebuildFiles('win32', 'x64'), 'node_modules/@github/copilot-win32-x64'); + + assert.deepStrictEqual(getCopilotRuntimePrebuildFiles('win32', 'arm64'), [ + 'node_modules/@github/copilot-win32-arm64/**', + '!node_modules/@github/copilot-win32-arm64/copilot', + '!node_modules/@github/copilot-win32-arm64/copilot.exe', + '!node_modules/@github/copilot-win32-arm64/clipboard/**', + '!node_modules/@github/copilot-win32-arm64/foundry-local-sdk/**', + '!node_modules/@github/copilot-win32-arm64/mxc-bin/**', + '!node_modules/@github/copilot-win32-arm64/pvrecorder/**', + '!node_modules/@github/copilot-win32-arm64/prebuilds/*/computer.node', + '!node_modules/@github/copilot-win32-arm64/prebuilds/*/keytar.node', + ]); + assertOptionalCopilotNativeDependenciesExcluded(getCopilotRuntimePrebuildFiles('win32', 'x64'), 'node_modules/@github/copilot-win32-x64'); + assertCopilotStandaloneExecutableExcluded(getCopilotRuntimePrebuildFiles('win32', 'arm64'), 'node_modules/@github/copilot-win32-arm64'); + }); + + test('keeps macOS runtime prebuilds in the selected platform package', () => { + const files = getCopilotRuntimePrebuildFiles('darwin', 'arm64'); + + assertCopilotPlatformPackageIncludes(files, 'node_modules/@github/copilot-darwin-arm64', [ + 'index.js', + 'app.js', + 'sea-loader.js', + 'prebuilds/darwin-arm64/runtime.node', + 'prebuilds/darwin-arm64/pty.node', + 'prebuilds/darwin-arm64/spawn-helper', + ]); + assertCopilotStandaloneExecutableExcluded(files, 'node_modules/@github/copilot-darwin-arm64'); + assertOptionalCopilotNativeDependenciesExcluded(files, 'node_modules/@github/copilot-darwin-arm64'); + }); + + test('materializes missing target platform packages from the lockfile', () => { + const repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'vscode-copilot-platform-test-')); + const nodeModulesRoot = path.join(repoRoot, 'node_modules'); + try { + fs.mkdirSync(nodeModulesRoot, { recursive: true }); + fs.writeFileSync(path.join(repoRoot, 'package-lock.json'), JSON.stringify({ + packages: { + 'node_modules/@github/copilot-darwin-x64': { + version: '1.0.64-1', + } + } + })); + + ensureCopilotPlatformPackage('darwin', 'x64', nodeModulesRoot, { + packPackage: (_packageName, _version, tempDir) => { + const packageRoot = path.join(tempDir, 'package'); + fs.mkdirSync(path.join(packageRoot, 'prebuilds', 'darwin-x64'), { recursive: true }); + fs.writeFileSync(path.join(packageRoot, 'index.js'), ''); + fs.writeFileSync(path.join(packageRoot, 'prebuilds', 'darwin-x64', 'runtime.node'), ''); + const tarball = path.join(tempDir, 'copilot-darwin-x64.tgz'); + create({ file: tarball, cwd: tempDir, gzip: true, sync: true }, ['package']); + return tarball; + } + }); + + assert(fs.existsSync(path.join(nodeModulesRoot, '@github', 'copilot-darwin-x64', 'index.js'))); + assert(fs.existsSync(path.join(nodeModulesRoot, '@github', 'copilot-darwin-x64', 'prebuilds', 'darwin-x64', 'runtime.node'))); + } finally { + fs.rmSync(repoRoot, { recursive: true, force: true }); + } + }); + + test('materializes target Copilot SDK prebuilds and tgrep for the built-in extension', () => { + const repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'vscode-copilot-sdk-prebuild-test-')); + try { + const builtInCopilotExtensionDir = path.join(repoRoot, 'extensions', 'copilot'); + const extensionCopilotDir = path.join(builtInCopilotExtensionDir, 'node_modules', '@github', 'copilot'); + const appNodeModulesDir = path.join(repoRoot, 'node_modules'); + const platformPackageDir = path.join(appNodeModulesDir, '@github', 'copilot-win32-x64'); + + fs.mkdirSync(path.join(extensionCopilotDir, 'sdk', 'prebuilds', 'linux-x64'), { recursive: true }); + fs.writeFileSync(path.join(extensionCopilotDir, 'sdk', 'prebuilds', 'linux-x64', 'runtime.node'), ''); + fs.mkdirSync(path.join(platformPackageDir, 'prebuilds', 'win32-x64', 'conpty'), { recursive: true }); + fs.writeFileSync(path.join(platformPackageDir, 'prebuilds', 'win32-x64', 'runtime.node'), ''); + fs.writeFileSync(path.join(platformPackageDir, 'prebuilds', 'win32-x64', 'conpty.node'), ''); + fs.writeFileSync(path.join(platformPackageDir, 'prebuilds', 'win32-x64', 'conpty', 'OpenConsole.exe'), ''); + fs.mkdirSync(path.join(platformPackageDir, 'tgrep', 'bin', 'win32-x64'), { recursive: true }); + fs.writeFileSync(path.join(platformPackageDir, 'tgrep', 'bin', 'win32-x64', 'tgrep.exe'), ''); + fs.mkdirSync(path.join(appNodeModulesDir, '@vscode', 'ripgrep-universal', 'bin', 'win32-x64'), { recursive: true }); + fs.writeFileSync(path.join(appNodeModulesDir, '@vscode', 'ripgrep-universal', 'bin', 'win32-x64', 'rg.exe'), ''); + + prepareBuiltInCopilotRipgrepShim('win32', 'x64', builtInCopilotExtensionDir, appNodeModulesDir); + + assert(fs.existsSync(path.join(extensionCopilotDir, 'sdk', 'prebuilds', 'win32-x64', 'runtime.node'))); + assert(fs.existsSync(path.join(extensionCopilotDir, 'sdk', 'prebuilds', 'win32-x64', 'conpty.node'))); + assert(fs.existsSync(path.join(extensionCopilotDir, 'sdk', 'prebuilds', 'win32-x64', 'conpty', 'OpenConsole.exe'))); + assert(!fs.existsSync(path.join(extensionCopilotDir, 'sdk', 'prebuilds', 'linux-x64'))); + assert(fs.existsSync(path.join(extensionCopilotDir, 'tgrep', 'bin', 'win32-x64', 'tgrep.exe'))); + assert(fs.existsSync(path.join(extensionCopilotDir, 'sdk', 'tgrep', 'bin', 'win32-x64', 'tgrep.exe'))); + assert(fs.existsSync(path.join(extensionCopilotDir, 'sdk', 'ripgrep', 'bin', 'win32-x64', 'rg.exe'))); + } finally { + fs.rmSync(repoRoot, { recursive: true, force: true }); + } + }); + + test('strips all copilot platform packages for unsupported armhf builds', () => { + assert.deepStrictEqual( + getCopilotExcludeFilter('linux', 'armhf'), + [ + '**', + ...copilotPlatforms.map(platform => `!**/node_modules/@github/copilot-${platform}/**`) + ] + ); + }); +}); + +function assertCopilotPlatformPackageIncludes(patterns: string[], packageDir: string, relativeFiles: string[]): void { + assert(patterns.includes(`${packageDir}/**`)); + for (const relativeFile of relativeFiles) { + assert(matchesGlob(`${packageDir}/${relativeFile}`, patterns), relativeFile); + } +} + +function assertCopilotStandaloneExecutableExcluded(patterns: string[], packageDir: string): void { + for (const executable of ['copilot', 'copilot.exe']) { + assert(patterns.includes(`!${packageDir}/${executable}`), executable); + assert(!matchesGlob(`${packageDir}/${executable}`, patterns), executable); + } +} + +function assertOptionalCopilotNativeDependenciesExcluded(patterns: string[], packageDir: string): void { + for (const dir of ['clipboard', 'foundry-local-sdk', 'mxc-bin', 'pvrecorder']) { + assert(patterns.includes(`!${packageDir}/${dir}/**`), dir); + assert(!matchesGlob(`${packageDir}/${dir}/index.js`, patterns), dir); + } + assert(patterns.includes(`!${packageDir}/prebuilds/*/computer.node`), 'computer.node'); + assert(!matchesGlob(`${packageDir}/prebuilds/linux-x64/computer.node`, patterns), 'computer.node'); + assert(patterns.includes(`!${packageDir}/prebuilds/*/keytar.node`), 'keytar.node'); + assert(!matchesGlob(`${packageDir}/prebuilds/linux-x64/keytar.node`, patterns), 'keytar.node'); + + if (!packageDir.includes('win32')) { + assert(patterns.includes(`!${packageDir}/prebuilds/*/cli-native.node`), 'cli-native.node'); + assert(!matchesGlob(`${packageDir}/prebuilds/linux-x64/cli-native.node`, patterns), 'cli-native.node'); + } +} + +function matchesGlob(file: string, patterns: string[]): boolean { + let included = false; + for (const pattern of patterns) { + const isExclude = pattern.startsWith('!'); + const glob = isExclude ? pattern.slice(1) : pattern; + if (matchesPattern(file, glob)) { + included = !isExclude; + } + } + return included; +} + +function matchesPattern(file: string, pattern: string): boolean { + if (pattern.endsWith('/**')) { + return file.startsWith(pattern.slice(0, -2)); + } + + if (pattern.includes('*')) { + const regex = new RegExp(`^${pattern.split('*').map(escapeRegExp).join('[^/]+')}$`); + return regex.test(file); + } + + return file === pattern; +} + +function escapeRegExp(value: string): string { + return value.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); +} diff --git a/extensions/copilot/.vscodeignore b/extensions/copilot/.vscodeignore index 6ba2b99990919..e1fe34c33bcb7 100644 --- a/extensions/copilot/.vscodeignore +++ b/extensions/copilot/.vscodeignore @@ -22,7 +22,10 @@ assets/walkthroughs/** !node_modules/@vscode/copilot-typescript-server-plugin/dist/*.js node_modules/@github/copilot/index.js node_modules/@github/copilot/clipboard/** +node_modules/@github/copilot/foundry-local-sdk/** +node_modules/@github/copilot/mxc-bin/** node_modules/@github/copilot/prebuilds/** +node_modules/@github/copilot/pvrecorder/** node_modules/@github/copilot/sharp/** !node_modules/@github/copilot/package.json !node_modules/@github/copilot/sdk/**/package.json diff --git a/extensions/copilot/package-lock.json b/extensions/copilot/package-lock.json index 765ab4aee4ee7..04682c7d7cc23 100644 --- a/extensions/copilot/package-lock.json +++ b/extensions/copilot/package-lock.json @@ -13,7 +13,7 @@ "@anthropic-ai/claude-agent-sdk": "0.2.112", "@anthropic-ai/sdk": "^0.82.0", "@github/blackbird-external-ingest-utils": "^0.3.0", - "@github/copilot": "^1.0.64-0", + "@github/copilot": "^1.0.64-1", "@google/genai": "^1.22.0", "@humanwhocodes/gitignore-to-minimatch": "1.0.2", "@microsoft/tiktokenizer": "^1.0.10", @@ -2948,32 +2948,31 @@ "license": "MIT" }, "node_modules/@github/copilot": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-0.tgz", - "integrity": "sha512-PlH7ByBHjmPLqLXS4CE2q8hN6CFEfkCMV6ScBEzW/u73+KYQB4fGNouo8Lr8okL6D5CW5rzPJbsXyISyJqVOZg==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-1.tgz", + "integrity": "sha512-lojV4Cb7oT4VJnYPEKBRH8KI3W43Q4Lh0Pc+V6sej+xjPJkoqwm68sNKn73/p3wXPBSTVTzPeCm9WhIisgf1Jw==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { - "detect-libc": "^2.1.2", - "os-theme": "^0.0.8" + "detect-libc": "^2.1.2" }, "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.64-0", - "@github/copilot-darwin-x64": "1.0.64-0", - "@github/copilot-linux-arm64": "1.0.64-0", - "@github/copilot-linux-x64": "1.0.64-0", - "@github/copilot-linuxmusl-arm64": "1.0.64-0", - "@github/copilot-linuxmusl-x64": "1.0.64-0", - "@github/copilot-win32-arm64": "1.0.64-0", - "@github/copilot-win32-x64": "1.0.64-0" + "@github/copilot-darwin-arm64": "1.0.64-1", + "@github/copilot-darwin-x64": "1.0.64-1", + "@github/copilot-linux-arm64": "1.0.64-1", + "@github/copilot-linux-x64": "1.0.64-1", + "@github/copilot-linuxmusl-arm64": "1.0.64-1", + "@github/copilot-linuxmusl-x64": "1.0.64-1", + "@github/copilot-win32-arm64": "1.0.64-1", + "@github/copilot-win32-x64": "1.0.64-1" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-0.tgz", - "integrity": "sha512-97DUGiuYrkCYOlSSLWMmr+K0uGzAxz1JOL/GyO/7mNl6V/1xgs6Van1Jj+Dpj4ly96iHE8lUIW8cQNCG66644g==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-1.tgz", + "integrity": "sha512-MQHZT9LhmCiq+ogO1E8cPCWrurZ6x+r9lPJfYUSnOyMO+EHbREpiJwOOChxtLHgL2/tKJSZdId2pg3tDgUlcsw==", "cpu": [ "arm64" ], @@ -2987,9 +2986,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-0.tgz", - "integrity": "sha512-2PXY4mSFtIjFdRaAt8PakegRgGtf6Sz9z6U/dIgVygNfctVNzaL5FH65PNPm8Y80jaDvEcz1/XY5MiQtxnlzZQ==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-1.tgz", + "integrity": "sha512-kOQY7CvI7He0eO3ObQAHePWdkNLWAOegCSzUqUmdcpa1SNVqbZ3GBMsQ7uAZQip2cQxnGZ7pS1v6tKQ0HJdkYw==", "cpu": [ "x64" ], @@ -3003,15 +3002,12 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-0.tgz", - "integrity": "sha512-PLP+vR508fOTlCr9CSZiXi9geicHKXuX9jLGdwNqK2TMZO5TqCLz8wP7dBEmkdkeXcFKovMb8nQVB1Toc6xutw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-1.tgz", + "integrity": "sha512-hIfuO7Q+pWs0SKfIRYqT+CjMaupudnhp4RMS6XoJ5s/e33rvpj2tkTkXYlHJo1PMDI823vvbqgpEdr+KeewMwg==", "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3022,15 +3018,12 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-0.tgz", - "integrity": "sha512-NvVjQ69zr390ijzo2f75+v0DHm6xnvPbi67ugnKDk7ZPbx8P3vSxVdAnrzrrL4T3T8ng3pJANcC4p+eGbx+UDw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-1.tgz", + "integrity": "sha512-VHaE62pha0rDDvuNN3bd97gf0EZ+EJebstM1ejHsMYoPT1IOUkYEXlNfGGHY+GfUGYxAiy/+Uew4xw5mJyy/Sw==", "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3041,15 +3034,12 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-0.tgz", - "integrity": "sha512-qCnVF5vIcTO74CukAENZo8e5nqXm4QUshuKN69aiZb5GOhVvyyIKsf5Jo7ikZt54jJBHycAMUKlTA8L3/nK+KA==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-1.tgz", + "integrity": "sha512-L/YrZPotRujAP0QERq+DlkR1SLr7abbTSz/56JqKKOqEdjKZPdQW1bUlhL/w1CZg1gXlTNUsNVyKz/fUfrEBgw==", "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3060,15 +3050,12 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-0.tgz", - "integrity": "sha512-WDBEmkBk1RulTfdLK5IuttNBadjLOBpvQyonGQ/aLeaetRNNdapoygrSjFU7q1QBSenmCyanXH6D+TS7tP3Qsw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-1.tgz", + "integrity": "sha512-AGMjXqR128oyjiJhoI6Gd7JP5ddWkib+P4YH/JoHm05iNn23ZYl4tSc0XihHzeyMI1ix7Aacn8UINYB7lGOGOA==", "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3079,9 +3066,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-0.tgz", - "integrity": "sha512-PC7yuUKcVbhli4bpzWFVT3juxj+v/iONazetNe3tMpHWza3W7MeFRifzAseSErKQCt2fHJth3m8bQAwFN2jfrA==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-1.tgz", + "integrity": "sha512-vvv+gnemi9WKaxF41zz7Xmq6a493n8Yjps5UFaOY6a3WR222kKXZXfOpeRvIYsDgnIPHGBHIj1TBOmnHQT4V4w==", "cpu": [ "arm64" ], @@ -3095,9 +3082,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-0.tgz", - "integrity": "sha512-d2fnUTIlqNxCqS2PuV+FD99ZOYBaX72OLtAmphbKyz36KyZ6D4ssiu8M4vHVTKWWdyc3TWiLsnIB+ryWdv1gGw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-1.tgz", + "integrity": "sha512-mcHvD0fjGDuqr/YXzy8mKuDmah1F+qjPujxoFuGmabmTJZ33cSIJ3nq7RRvxZNIdp8YJ57NkbcW30WvIcOeJ3w==", "cpu": [ "x64" ], @@ -4869,45 +4856,6 @@ "node": ">=14" } }, - "node_modules/@os-theme/darwin-arm64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/darwin-arm64/-/darwin-arm64-0.0.8.tgz", - "integrity": "sha512-gMsOs+8Ju396a5yyMWigkbA0dMTxD78U3HzG3mlpiAyn6hfd5dbyI4VGP+sfTB82KGgWLzIhWWTFX5UYY6iX0A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@os-theme/linux-x64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/linux-x64/-/linux-x64-0.0.8.tgz", - "integrity": "sha512-zvjmBUiSQPjM1RbhpsfCDYMJxW4eLlGmkFPnpteC/03X2lz6CjiX2hfbN2EWLxXjNnIje3Jqaen8IsqEnWrRBg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@os-theme/win32-x64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/win32-x64/-/win32-x64-0.0.8.tgz", - "integrity": "sha512-N3yxKNbVl2IBa/ncDuq55QhwqwUjnYLJxDKMEmYeJbLIV950qZNojPw3scXA6PbfxPZfIiRa8iz1pzNg9XxP8w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@oxc-project/types": { "version": "0.133.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", @@ -5100,9 +5048,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5120,9 +5065,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5140,9 +5082,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5160,9 +5099,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5180,9 +5116,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5200,9 +5133,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -11942,9 +11872,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11966,9 +11893,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11990,9 +11914,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -12014,9 +11935,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -13595,20 +13513,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/os-theme": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/os-theme/-/os-theme-0.0.8.tgz", - "integrity": "sha512-u1q3bLSv5uMHNIiPItkfDrHXu6ZFs2juwqxWREFM/uVBa+7Kkhy2v49LmJev2JcinGwqiEccElB/XsH9gwasuA==", - "license": "MIT", - "optionalDependencies": { - "@os-theme/darwin-arm64": "0.0.8", - "@os-theme/linux-x64": "0.0.8", - "@os-theme/win32-x64": "0.0.8" - }, - "peerDependencies": { - "typescript": "^5" - } - }, "node_modules/outdent": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz", diff --git a/extensions/copilot/package.json b/extensions/copilot/package.json index 0e917130e913e..087251ecd5b35 100644 --- a/extensions/copilot/package.json +++ b/extensions/copilot/package.json @@ -7086,7 +7086,7 @@ "@anthropic-ai/claude-agent-sdk": "0.2.112", "@anthropic-ai/sdk": "^0.82.0", "@github/blackbird-external-ingest-utils": "^0.3.0", - "@github/copilot": "^1.0.64-0", + "@github/copilot": "^1.0.64-1", "@google/genai": "^1.22.0", "@humanwhocodes/gitignore-to-minimatch": "1.0.2", "@microsoft/tiktokenizer": "^1.0.10", diff --git a/extensions/copilot/script/postinstall.ts b/extensions/copilot/script/postinstall.ts index a3a322b2c5932..a135f4bf529bd 100644 --- a/extensions/copilot/script/postinstall.ts +++ b/extensions/copilot/script/postinstall.ts @@ -60,9 +60,105 @@ const treeSitterGrammars: ITreeSitterGrammar[] = [ ]; const REPO_ROOT = path.join(__dirname, '..'); +const COPILOT_PACKAGE_DIR = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot'); +const COPILOT_CLI_TOP_LEVEL_DIRS = [ + 'worker', + 'definitions', + 'builtin-skills', + 'builtin', + 'tgrep', + 'queries', + 'prebuilds', + 'ripgrep', + 'foundry-local-sdk', + 'pvrecorder', + 'mxc-bin', + 'clipboard', + 'copilot-sdk', + 'schemas', + 'preloads', +]; + +interface ICopilotPackageJson { + exports?: Record; +} + +function isLinuxMuslRuntime(): boolean { + if (process.platform !== 'linux') { + return false; + } + + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + return !report?.header?.glibcVersionRuntime; +} + +function getCopilotPlatformPackageCandidates(): string[] { + const arch = process.arch; + + if (process.platform === 'linux') { + const linuxCandidates = [`linux-${arch}`, `linuxmusl-${arch}`]; + return isLinuxMuslRuntime() ? linuxCandidates.reverse() : linuxCandidates; + } + + return [`${process.platform}-${arch}`]; +} + +async function resolveCopilotCliSourceDir(): Promise { + const tried: string[] = []; + for (const platformPackage of getCopilotPlatformPackageCandidates()) { + const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', `copilot-${platformPackage}`); + tried.push(sourceDir); + if (fs.existsSync(path.join(sourceDir, 'sdk', 'index.js'))) { + return sourceDir; + } + } + + if (fs.existsSync(path.join(COPILOT_PACKAGE_DIR, 'sdk', 'index.js'))) { + return COPILOT_PACKAGE_DIR; + } + + throw new Error(`Could not find @github/copilot SDK files. Tried: ${[COPILOT_PACKAGE_DIR, ...tried].join(', ')}`); +} + +async function ensureCopilotSdkExport() { + const packageJsonPath = path.join(COPILOT_PACKAGE_DIR, 'package.json'); + const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, 'utf8')) as ICopilotPackageJson; + packageJson.exports = { + ...(packageJson.exports ?? {}), + './sdk': { + types: './sdk/index.d.ts', + import: './sdk/index.js' + } + }; + + await fs.promises.writeFile(packageJsonPath, `${JSON.stringify(packageJson, undefined, 2)}\n`); +} + +async function materializeCopilotCliSdkLayout(): Promise { + const sourceDir = await resolveCopilotCliSourceDir(); + + if (sourceDir !== COPILOT_PACKAGE_DIR) { + await copyCopilotCLIFolders(path.join(sourceDir, 'sdk'), path.join(COPILOT_PACKAGE_DIR, 'sdk')); + for (const dir of COPILOT_CLI_TOP_LEVEL_DIRS) { + const sourcePath = path.join(sourceDir, dir); + if (fs.existsSync(sourcePath)) { + await copyCopilotCLIFolders(sourcePath, path.join(COPILOT_PACKAGE_DIR, dir)); + } + } + + for (const entry of await fs.promises.readdir(sourceDir)) { + if (entry.startsWith('tree-sitter') && entry.endsWith('.wasm')) { + await fs.promises.copyFile(path.join(sourceDir, entry), path.join(COPILOT_PACKAGE_DIR, entry)); + } + } + } + + await ensureCopilotSdkExport(); + return sourceDir; +} async function removeCopilotCLIShim() { - const shimsPath = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'shims.txt'); + const shimsPath = path.join(COPILOT_PACKAGE_DIR, 'shims.txt'); await fs.promises.rm(shimsPath, { force: true }).catch(() => { /* ignore */ }); } @@ -70,44 +166,44 @@ async function removeCopilotCLIShim() { * @github/copilot/sdk/index.js depends on @github/copilot/worker/*.js files. * We need to copy these files into the sdk directory to ensure they are available at runtime. */ -async function copyCopilotCliWorkerFiles() { - const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'worker'); - const targetDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'sdk', 'worker'); +async function copyCopilotCliWorkerFiles(copilotCliSourceDir: string) { + const sourceDir = path.join(copilotCliSourceDir, 'worker'); + const targetDir = path.join(COPILOT_PACKAGE_DIR, 'sdk', 'worker'); await copyCopilotCLIFolders(sourceDir, targetDir); } -async function copyCopilotCliTGrepFiles() { - const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'tgrep'); - const targetDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'sdk', 'tgrep'); +async function copyCopilotCliTGrepFiles(copilotCliSourceDir: string) { + const sourceDir = path.join(copilotCliSourceDir, 'tgrep'); + const targetDir = path.join(COPILOT_PACKAGE_DIR, 'sdk', 'tgrep'); await copyCopilotCLIFolders(sourceDir, targetDir); } -async function copyCopilotCliDefinitionFiles() { - const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'definitions'); - const targetDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'sdk', 'definitions'); +async function copyCopilotCliDefinitionFiles(copilotCliSourceDir: string) { + const sourceDir = path.join(copilotCliSourceDir, 'definitions'); + const targetDir = path.join(COPILOT_PACKAGE_DIR, 'sdk', 'definitions'); await copyCopilotCLIFolders(sourceDir, targetDir); } -async function copyCopilotCliSkillsFiles() { - const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'builtin-skills'); - const targetDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'sdk', 'builtin-skills'); +async function copyCopilotCliSkillsFiles(copilotCliSourceDir: string) { + const sourceDir = path.join(copilotCliSourceDir, 'builtin-skills'); + const targetDir = path.join(COPILOT_PACKAGE_DIR, 'sdk', 'builtin-skills'); await copyCopilotCLIFolders(sourceDir, targetDir); } -async function copyCopilotCliQueryFiles() { - const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'queries'); - const targetDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'sdk', 'queries'); +async function copyCopilotCliQueryFiles(copilotCliSourceDir: string) { + const sourceDir = path.join(copilotCliSourceDir, 'queries'); + const targetDir = path.join(COPILOT_PACKAGE_DIR, 'sdk', 'queries'); await copyCopilotCLIFolders(sourceDir, targetDir); } -async function copyCopilotCliPrebuildFiles() { - const sourceDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'prebuilds'); - const targetDir = path.join(REPO_ROOT, 'node_modules', '@github', 'copilot', 'sdk', 'prebuilds'); +async function copyCopilotCliPrebuildFiles(copilotCliSourceDir: string) { + const sourceDir = path.join(copilotCliSourceDir, 'prebuilds'); + const targetDir = path.join(COPILOT_PACKAGE_DIR, 'sdk', 'prebuilds'); await fs.promises.rm(targetDir, { recursive: true, force: true }); await fs.promises.mkdir(targetDir, { recursive: true }); await fs.promises.cp(sourceDir, targetDir, { @@ -115,9 +211,6 @@ async function copyCopilotCliPrebuildFiles() { try { if (fs.statSync(src).isFile()) { const normalizedSrc = src.split(path.sep).join(path.posix.sep); - if (normalizedSrc.includes('/prebuilds/linuxmusl-')) { - return false; - } return src.endsWith('computer.node') || src.endsWith('runtime.node') || src.endsWith('cli-native.node') @@ -191,13 +284,14 @@ async function main() { 'node_modules/@github/blackbird-external-ingest-utils/pkg/nodejs/external_ingest_utils_bg.wasm', ], 'dist'); + const copilotCliSourceDir = await materializeCopilotCliSdkLayout(); await removeCopilotCLIShim(); - await copyCopilotCliWorkerFiles(); - await copyCopilotCliDefinitionFiles(); - await copyCopilotCliSkillsFiles(); - await copyCopilotCliTGrepFiles(); - await copyCopilotCliQueryFiles(); - await copyCopilotCliPrebuildFiles(); + await copyCopilotCliWorkerFiles(copilotCliSourceDir); + await copyCopilotCliDefinitionFiles(copilotCliSourceDir); + await copyCopilotCliSkillsFiles(copilotCliSourceDir); + await copyCopilotCliTGrepFiles(copilotCliSourceDir); + await copyCopilotCliQueryFiles(copilotCliSourceDir); + await copyCopilotCliPrebuildFiles(copilotCliSourceDir); // Check if the base cache file exists (dev-only sanity check, non-fatal in CI) const baseCachePath = path.join('test', 'simulation', 'cache', 'base.sqlite'); diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts index 9acd2aa786d68..603c74457c492 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts @@ -643,9 +643,13 @@ export function buildChatHistoryFromEvents(sessionId: string, modelId: string | range }); } else if (attachment.type === 'blob') { + if (typeof attachment.data !== 'string') { + return; + } + const data = attachment.data; const binaryDataSupplier = async () => { try { - return decodeBase64(attachment.data).buffer; + return decodeBase64(data).buffer; } catch (error) { logger.error(error, `Failed to decode blob attachment ${attachment.displayName || ''}`); throw error; diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts index 6e0634f28de55..54d482b6f9b1c 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts @@ -1435,7 +1435,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes reportUsage(event.data.inputTokens, event.data.outputTokens); } // Accumulate per-turn credits from SDK copilotUsage data - const copilotUsage = (event.data as Record).copilotUsage; + const copilotUsage = (event.data as unknown as Record).copilotUsage; let copilotUsageNanoAiu: number | undefined; if (copilotUsage && typeof copilotUsage === 'object') { const { totalNanoAiu } = copilotUsage as { totalNanoAiu?: number }; diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts index 20a47e2e12773..737693658b8bc 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts @@ -424,7 +424,7 @@ export function getFileBeingEdited(permissionRequest: Extract): string { +function codeBlock(obj: unknown): string { return `\n\n\`\`\`\n${JSON.stringify(obj, null, 2)}\n\`\`\``; } diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/copilotCLISDKUpgrade.spec.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/copilotCLISDKUpgrade.spec.ts index d3e0c4f38103a..d85c85b4a9f62 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/copilotCLISDKUpgrade.spec.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/copilotCLISDKUpgrade.spec.ts @@ -19,7 +19,7 @@ describe('CopilotCLI SDK Upgrade', function () { it('should be able to load the SDK without errors', async function () { await import('@github/copilot/sdk'); - }); + }, 10000); it('should not contain new native binaries nor removed native binaries', async function () { // This is a very basic check to ensure that when the Copilot CLI SDK is upgraded, @@ -224,6 +224,9 @@ describe('CopilotCLI SDK Upgrade', function () { continue; } if (!existingBinaries.has(binary)) { + if (isNonCurrentCopilotPlatformBinary(copilotSDKPath, binary) || isNonCurrentPvRecorderBinary(copilotSDKPath, binary)) { + continue; + } errors.push(`Expected native binary missing from Copilot CLI SDK: ${path.relative(copilotSDKPath, binary)}`); } } @@ -231,13 +234,66 @@ describe('CopilotCLI SDK Upgrade', function () { if (errors.length > 0) { throw new Error(errors.join('\n')); } - }); + }, 30000); it('should be able to load the @github/copilot module without errors', async function () { await import('@github/copilot/sdk'); }); }); +const copilotPlatformArchs = new Set([ + 'darwin-arm64', + 'darwin-x64', + 'linux-arm64', + 'linux-x64', + 'linuxmusl-arm64', + 'linuxmusl-x64', + 'win32-arm64', + 'win32-x64', +]); + +function currentCopilotPlatformArch(): string { + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + if (process.platform === 'linux' && !report?.header?.glibcVersionRuntime) { + return `linuxmusl-${process.arch}`; + } + + return `${process.platform}-${process.arch}`; +} + +function isNonCurrentCopilotPlatformBinary(copilotSDKPath: string, binary: string): boolean { + const relativeSegments = path.relative(copilotSDKPath, binary).split(path.sep); + const platformArch = relativeSegments.find(segment => copilotPlatformArchs.has(segment)); + return platformArch !== undefined && platformArch !== currentCopilotPlatformArch(); +} + +function isNonCurrentPvRecorderBinary(copilotSDKPath: string, binary: string): boolean { + const relative = path.relative(copilotSDKPath, binary).split(path.sep).join(path.posix.sep); + const pvRecorderPrefix = 'pvrecorder/node_modules/@picovoice/pvrecorder-node/lib/'; + if (!relative.startsWith(pvRecorderPrefix)) { + return false; + } + + const currentPlatformArch = currentCopilotPlatformArch(); + if (relative.startsWith(`${pvRecorderPrefix}mac/arm64/`)) { + return currentPlatformArch !== 'darwin-arm64'; + } + if (relative.startsWith(`${pvRecorderPrefix}mac/x86_64/`)) { + return currentPlatformArch !== 'darwin-x64'; + } + if (relative.startsWith(`${pvRecorderPrefix}linux/x86_64/`)) { + return currentPlatformArch !== 'linux-x64' && currentPlatformArch !== 'linuxmusl-x64'; + } + if (relative.startsWith(`${pvRecorderPrefix}windows/amd64/`)) { + return currentPlatformArch !== 'win32-x64'; + } + if (relative.startsWith(`${pvRecorderPrefix}windows/arm64/`)) { + return currentPlatformArch !== 'win32-arm64'; + } + + return false; +} + async function copyBinaries(extensionPath: string) { const copilotSDKPath = path.join(extensionPath, 'node_modules', '@github', 'copilot'); const vscodeRipgrepPath = path.join(copilotSDKPath, 'ripgrep', 'bin', process.platform + '-' + process.arch); diff --git a/package-lock.json b/package-lock.json index ef3fdc7d24a48..3250723231847 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.82.0", - "@github/copilot": "^1.0.64-0", - "@github/copilot-sdk": "^1.0.2", + "@github/copilot": "^1.0.64-1", + "@github/copilot-sdk": "^1.0.3", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@microsoft/dev-tunnels-connections": "^1.3.41", @@ -1085,32 +1085,31 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-0.tgz", - "integrity": "sha512-PlH7ByBHjmPLqLXS4CE2q8hN6CFEfkCMV6ScBEzW/u73+KYQB4fGNouo8Lr8okL6D5CW5rzPJbsXyISyJqVOZg==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-1.tgz", + "integrity": "sha512-lojV4Cb7oT4VJnYPEKBRH8KI3W43Q4Lh0Pc+V6sej+xjPJkoqwm68sNKn73/p3wXPBSTVTzPeCm9WhIisgf1Jw==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { - "detect-libc": "^2.1.2", - "os-theme": "^0.0.8" + "detect-libc": "^2.1.2" }, "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.64-0", - "@github/copilot-darwin-x64": "1.0.64-0", - "@github/copilot-linux-arm64": "1.0.64-0", - "@github/copilot-linux-x64": "1.0.64-0", - "@github/copilot-linuxmusl-arm64": "1.0.64-0", - "@github/copilot-linuxmusl-x64": "1.0.64-0", - "@github/copilot-win32-arm64": "1.0.64-0", - "@github/copilot-win32-x64": "1.0.64-0" + "@github/copilot-darwin-arm64": "1.0.64-1", + "@github/copilot-darwin-x64": "1.0.64-1", + "@github/copilot-linux-arm64": "1.0.64-1", + "@github/copilot-linux-x64": "1.0.64-1", + "@github/copilot-linuxmusl-arm64": "1.0.64-1", + "@github/copilot-linuxmusl-x64": "1.0.64-1", + "@github/copilot-win32-arm64": "1.0.64-1", + "@github/copilot-win32-x64": "1.0.64-1" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-0.tgz", - "integrity": "sha512-97DUGiuYrkCYOlSSLWMmr+K0uGzAxz1JOL/GyO/7mNl6V/1xgs6Van1Jj+Dpj4ly96iHE8lUIW8cQNCG66644g==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-1.tgz", + "integrity": "sha512-MQHZT9LhmCiq+ogO1E8cPCWrurZ6x+r9lPJfYUSnOyMO+EHbREpiJwOOChxtLHgL2/tKJSZdId2pg3tDgUlcsw==", "cpu": [ "arm64" ], @@ -1124,9 +1123,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-0.tgz", - "integrity": "sha512-2PXY4mSFtIjFdRaAt8PakegRgGtf6Sz9z6U/dIgVygNfctVNzaL5FH65PNPm8Y80jaDvEcz1/XY5MiQtxnlzZQ==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-1.tgz", + "integrity": "sha512-kOQY7CvI7He0eO3ObQAHePWdkNLWAOegCSzUqUmdcpa1SNVqbZ3GBMsQ7uAZQip2cQxnGZ7pS1v6tKQ0HJdkYw==", "cpu": [ "x64" ], @@ -1140,9 +1139,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-0.tgz", - "integrity": "sha512-PLP+vR508fOTlCr9CSZiXi9geicHKXuX9jLGdwNqK2TMZO5TqCLz8wP7dBEmkdkeXcFKovMb8nQVB1Toc6xutw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-1.tgz", + "integrity": "sha512-hIfuO7Q+pWs0SKfIRYqT+CjMaupudnhp4RMS6XoJ5s/e33rvpj2tkTkXYlHJo1PMDI823vvbqgpEdr+KeewMwg==", "cpu": [ "arm64" ], @@ -1156,9 +1155,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-0.tgz", - "integrity": "sha512-NvVjQ69zr390ijzo2f75+v0DHm6xnvPbi67ugnKDk7ZPbx8P3vSxVdAnrzrrL4T3T8ng3pJANcC4p+eGbx+UDw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-1.tgz", + "integrity": "sha512-VHaE62pha0rDDvuNN3bd97gf0EZ+EJebstM1ejHsMYoPT1IOUkYEXlNfGGHY+GfUGYxAiy/+Uew4xw5mJyy/Sw==", "cpu": [ "x64" ], @@ -1172,9 +1171,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-0.tgz", - "integrity": "sha512-qCnVF5vIcTO74CukAENZo8e5nqXm4QUshuKN69aiZb5GOhVvyyIKsf5Jo7ikZt54jJBHycAMUKlTA8L3/nK+KA==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-1.tgz", + "integrity": "sha512-L/YrZPotRujAP0QERq+DlkR1SLr7abbTSz/56JqKKOqEdjKZPdQW1bUlhL/w1CZg1gXlTNUsNVyKz/fUfrEBgw==", "cpu": [ "arm64" ], @@ -1188,9 +1187,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-0.tgz", - "integrity": "sha512-WDBEmkBk1RulTfdLK5IuttNBadjLOBpvQyonGQ/aLeaetRNNdapoygrSjFU7q1QBSenmCyanXH6D+TS7tP3Qsw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-1.tgz", + "integrity": "sha512-AGMjXqR128oyjiJhoI6Gd7JP5ddWkib+P4YH/JoHm05iNn23ZYl4tSc0XihHzeyMI1ix7Aacn8UINYB7lGOGOA==", "cpu": [ "x64" ], @@ -1204,12 +1203,12 @@ } }, "node_modules/@github/copilot-sdk": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-1.0.2.tgz", - "integrity": "sha512-JJDsGM/bA1LGy1Ro/8iC8RLpKsLmuiFdQ67oFAVfi0Hfxyx289teHwmM70ehK76DXBkrPqqcxcliJi56k1ggFA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-1.0.3.tgz", + "integrity": "sha512-ujnH2QVw3+xvjgo9cbpY0wik4fNxAmdMDSFnxGScDSvRuK2vUCL2xWW4V2ANc9pWwRHPBpEpMuNJMtmydmLCIQ==", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.64-0", + "@github/copilot": "^1.0.64-1", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -1227,9 +1226,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-0.tgz", - "integrity": "sha512-PC7yuUKcVbhli4bpzWFVT3juxj+v/iONazetNe3tMpHWza3W7MeFRifzAseSErKQCt2fHJth3m8bQAwFN2jfrA==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-1.tgz", + "integrity": "sha512-vvv+gnemi9WKaxF41zz7Xmq6a493n8Yjps5UFaOY6a3WR222kKXZXfOpeRvIYsDgnIPHGBHIj1TBOmnHQT4V4w==", "cpu": [ "arm64" ], @@ -1243,9 +1242,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-0.tgz", - "integrity": "sha512-d2fnUTIlqNxCqS2PuV+FD99ZOYBaX72OLtAmphbKyz36KyZ6D4ssiu8M4vHVTKWWdyc3TWiLsnIB+ryWdv1gGw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-1.tgz", + "integrity": "sha512-mcHvD0fjGDuqr/YXzy8mKuDmah1F+qjPujxoFuGmabmTJZ33cSIJ3nq7RRvxZNIdp8YJ57NkbcW30WvIcOeJ3w==", "cpu": [ "x64" ], @@ -2329,45 +2328,6 @@ "node": ">=8.0.0" } }, - "node_modules/@os-theme/darwin-arm64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/darwin-arm64/-/darwin-arm64-0.0.8.tgz", - "integrity": "sha512-gMsOs+8Ju396a5yyMWigkbA0dMTxD78U3HzG3mlpiAyn6hfd5dbyI4VGP+sfTB82KGgWLzIhWWTFX5UYY6iX0A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@os-theme/linux-x64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/linux-x64/-/linux-x64-0.0.8.tgz", - "integrity": "sha512-zvjmBUiSQPjM1RbhpsfCDYMJxW4eLlGmkFPnpteC/03X2lz6CjiX2hfbN2EWLxXjNnIje3Jqaen8IsqEnWrRBg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@os-theme/win32-x64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/win32-x64/-/win32-x64-0.0.8.tgz", - "integrity": "sha512-N3yxKNbVl2IBa/ncDuq55QhwqwUjnYLJxDKMEmYeJbLIV950qZNojPw3scXA6PbfxPZfIiRa8iz1pzNg9XxP8w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@parcel/watcher": { "version": "2.5.6", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", @@ -14912,20 +14872,6 @@ "node": ">=0.10.0" } }, - "node_modules/os-theme": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/os-theme/-/os-theme-0.0.8.tgz", - "integrity": "sha512-u1q3bLSv5uMHNIiPItkfDrHXu6ZFs2juwqxWREFM/uVBa+7Kkhy2v49LmJev2JcinGwqiEccElB/XsH9gwasuA==", - "license": "MIT", - "optionalDependencies": { - "@os-theme/darwin-arm64": "0.0.8", - "@os-theme/linux-x64": "0.0.8", - "@os-theme/win32-x64": "0.0.8" - }, - "peerDependencies": { - "typescript": "^5" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", diff --git a/package.json b/package.json index 981197c902d12..ea9089da1c086 100644 --- a/package.json +++ b/package.json @@ -95,8 +95,8 @@ }, "dependencies": { "@anthropic-ai/sdk": "^0.82.0", - "@github/copilot": "^1.0.64-0", - "@github/copilot-sdk": "^1.0.2", + "@github/copilot": "^1.0.64-1", + "@github/copilot-sdk": "^1.0.3", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@microsoft/dev-tunnels-connections": "^1.3.41", diff --git a/remote/package-lock.json b/remote/package-lock.json index a829c6d594600..c8bcd6e93056f 100644 --- a/remote/package-lock.json +++ b/remote/package-lock.json @@ -8,8 +8,8 @@ "name": "vscode-reh", "version": "0.0.0", "dependencies": { - "@github/copilot": "^1.0.64-0", - "@github/copilot-sdk": "^1.0.2", + "@github/copilot": "^1.0.64-1", + "@github/copilot-sdk": "^1.0.3", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@microsoft/mxc-sdk": "0.6.0", @@ -60,32 +60,31 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-0.tgz", - "integrity": "sha512-PlH7ByBHjmPLqLXS4CE2q8hN6CFEfkCMV6ScBEzW/u73+KYQB4fGNouo8Lr8okL6D5CW5rzPJbsXyISyJqVOZg==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-1.tgz", + "integrity": "sha512-lojV4Cb7oT4VJnYPEKBRH8KI3W43Q4Lh0Pc+V6sej+xjPJkoqwm68sNKn73/p3wXPBSTVTzPeCm9WhIisgf1Jw==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { - "detect-libc": "^2.1.2", - "os-theme": "^0.0.8" + "detect-libc": "^2.1.2" }, "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.64-0", - "@github/copilot-darwin-x64": "1.0.64-0", - "@github/copilot-linux-arm64": "1.0.64-0", - "@github/copilot-linux-x64": "1.0.64-0", - "@github/copilot-linuxmusl-arm64": "1.0.64-0", - "@github/copilot-linuxmusl-x64": "1.0.64-0", - "@github/copilot-win32-arm64": "1.0.64-0", - "@github/copilot-win32-x64": "1.0.64-0" + "@github/copilot-darwin-arm64": "1.0.64-1", + "@github/copilot-darwin-x64": "1.0.64-1", + "@github/copilot-linux-arm64": "1.0.64-1", + "@github/copilot-linux-x64": "1.0.64-1", + "@github/copilot-linuxmusl-arm64": "1.0.64-1", + "@github/copilot-linuxmusl-x64": "1.0.64-1", + "@github/copilot-win32-arm64": "1.0.64-1", + "@github/copilot-win32-x64": "1.0.64-1" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-0.tgz", - "integrity": "sha512-97DUGiuYrkCYOlSSLWMmr+K0uGzAxz1JOL/GyO/7mNl6V/1xgs6Van1Jj+Dpj4ly96iHE8lUIW8cQNCG66644g==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-1.tgz", + "integrity": "sha512-MQHZT9LhmCiq+ogO1E8cPCWrurZ6x+r9lPJfYUSnOyMO+EHbREpiJwOOChxtLHgL2/tKJSZdId2pg3tDgUlcsw==", "cpu": [ "arm64" ], @@ -99,9 +98,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-0.tgz", - "integrity": "sha512-2PXY4mSFtIjFdRaAt8PakegRgGtf6Sz9z6U/dIgVygNfctVNzaL5FH65PNPm8Y80jaDvEcz1/XY5MiQtxnlzZQ==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-1.tgz", + "integrity": "sha512-kOQY7CvI7He0eO3ObQAHePWdkNLWAOegCSzUqUmdcpa1SNVqbZ3GBMsQ7uAZQip2cQxnGZ7pS1v6tKQ0HJdkYw==", "cpu": [ "x64" ], @@ -115,15 +114,12 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-0.tgz", - "integrity": "sha512-PLP+vR508fOTlCr9CSZiXi9geicHKXuX9jLGdwNqK2TMZO5TqCLz8wP7dBEmkdkeXcFKovMb8nQVB1Toc6xutw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-1.tgz", + "integrity": "sha512-hIfuO7Q+pWs0SKfIRYqT+CjMaupudnhp4RMS6XoJ5s/e33rvpj2tkTkXYlHJo1PMDI823vvbqgpEdr+KeewMwg==", "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -134,15 +130,12 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-0.tgz", - "integrity": "sha512-NvVjQ69zr390ijzo2f75+v0DHm6xnvPbi67ugnKDk7ZPbx8P3vSxVdAnrzrrL4T3T8ng3pJANcC4p+eGbx+UDw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-1.tgz", + "integrity": "sha512-VHaE62pha0rDDvuNN3bd97gf0EZ+EJebstM1ejHsMYoPT1IOUkYEXlNfGGHY+GfUGYxAiy/+Uew4xw5mJyy/Sw==", "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -153,15 +146,12 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-0.tgz", - "integrity": "sha512-qCnVF5vIcTO74CukAENZo8e5nqXm4QUshuKN69aiZb5GOhVvyyIKsf5Jo7ikZt54jJBHycAMUKlTA8L3/nK+KA==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-1.tgz", + "integrity": "sha512-L/YrZPotRujAP0QERq+DlkR1SLr7abbTSz/56JqKKOqEdjKZPdQW1bUlhL/w1CZg1gXlTNUsNVyKz/fUfrEBgw==", "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -172,15 +162,12 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-0.tgz", - "integrity": "sha512-WDBEmkBk1RulTfdLK5IuttNBadjLOBpvQyonGQ/aLeaetRNNdapoygrSjFU7q1QBSenmCyanXH6D+TS7tP3Qsw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-1.tgz", + "integrity": "sha512-AGMjXqR128oyjiJhoI6Gd7JP5ddWkib+P4YH/JoHm05iNn23ZYl4tSc0XihHzeyMI1ix7Aacn8UINYB7lGOGOA==", "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -191,12 +178,12 @@ } }, "node_modules/@github/copilot-sdk": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-1.0.2.tgz", - "integrity": "sha512-JJDsGM/bA1LGy1Ro/8iC8RLpKsLmuiFdQ67oFAVfi0Hfxyx289teHwmM70ehK76DXBkrPqqcxcliJi56k1ggFA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@github/copilot-sdk/-/copilot-sdk-1.0.3.tgz", + "integrity": "sha512-ujnH2QVw3+xvjgo9cbpY0wik4fNxAmdMDSFnxGScDSvRuK2vUCL2xWW4V2ANc9pWwRHPBpEpMuNJMtmydmLCIQ==", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.64-0", + "@github/copilot": "^1.0.64-1", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -214,9 +201,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-0.tgz", - "integrity": "sha512-PC7yuUKcVbhli4bpzWFVT3juxj+v/iONazetNe3tMpHWza3W7MeFRifzAseSErKQCt2fHJth3m8bQAwFN2jfrA==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-1.tgz", + "integrity": "sha512-vvv+gnemi9WKaxF41zz7Xmq6a493n8Yjps5UFaOY6a3WR222kKXZXfOpeRvIYsDgnIPHGBHIj1TBOmnHQT4V4w==", "cpu": [ "arm64" ], @@ -230,9 +217,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.64-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-0.tgz", - "integrity": "sha512-d2fnUTIlqNxCqS2PuV+FD99ZOYBaX72OLtAmphbKyz36KyZ6D4ssiu8M4vHVTKWWdyc3TWiLsnIB+ryWdv1gGw==", + "version": "1.0.64-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-1.tgz", + "integrity": "sha512-mcHvD0fjGDuqr/YXzy8mKuDmah1F+qjPujxoFuGmabmTJZ33cSIJ3nq7RRvxZNIdp8YJ57NkbcW30WvIcOeJ3w==", "cpu": [ "x64" ], @@ -312,45 +299,6 @@ "node": ">=18.0.0" } }, - "node_modules/@os-theme/darwin-arm64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/darwin-arm64/-/darwin-arm64-0.0.8.tgz", - "integrity": "sha512-gMsOs+8Ju396a5yyMWigkbA0dMTxD78U3HzG3mlpiAyn6hfd5dbyI4VGP+sfTB82KGgWLzIhWWTFX5UYY6iX0A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@os-theme/linux-x64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/linux-x64/-/linux-x64-0.0.8.tgz", - "integrity": "sha512-zvjmBUiSQPjM1RbhpsfCDYMJxW4eLlGmkFPnpteC/03X2lz6CjiX2hfbN2EWLxXjNnIje3Jqaen8IsqEnWrRBg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@os-theme/win32-x64": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@os-theme/win32-x64/-/win32-x64-0.0.8.tgz", - "integrity": "sha512-N3yxKNbVl2IBa/ncDuq55QhwqwUjnYLJxDKMEmYeJbLIV950qZNojPw3scXA6PbfxPZfIiRa8iz1pzNg9XxP8w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@parcel/watcher": { "version": "2.5.6", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", @@ -1443,20 +1391,6 @@ "ot": "bin/ot" } }, - "node_modules/os-theme": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/os-theme/-/os-theme-0.0.8.tgz", - "integrity": "sha512-u1q3bLSv5uMHNIiPItkfDrHXu6ZFs2juwqxWREFM/uVBa+7Kkhy2v49LmJev2JcinGwqiEccElB/XsH9gwasuA==", - "license": "MIT", - "optionalDependencies": { - "@os-theme/darwin-arm64": "0.0.8", - "@os-theme/linux-x64": "0.0.8", - "@os-theme/win32-x64": "0.0.8" - }, - "peerDependencies": { - "typescript": "^5" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", diff --git a/remote/package.json b/remote/package.json index 879eb7d6593b8..8b10a67c006cc 100644 --- a/remote/package.json +++ b/remote/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "dependencies": { - "@github/copilot": "^1.0.64-0", - "@github/copilot-sdk": "^1.0.2", + "@github/copilot": "^1.0.64-1", + "@github/copilot-sdk": "^1.0.3", "@microsoft/1ds-core-js": "^3.2.13", "@microsoft/1ds-post-js": "^3.2.13", "@microsoft/mxc-sdk": "0.6.0", diff --git a/src/vs/platform/agentHost/node/copilot/copilotAgent.ts b/src/vs/platform/agentHost/node/copilot/copilotAgent.ts index a186cc08ccf68..986cbf05e5653 100644 --- a/src/vs/platform/agentHost/node/copilot/copilotAgent.ts +++ b/src/vs/platform/agentHost/node/copilot/copilotAgent.ts @@ -77,6 +77,53 @@ function copilotCliLogLevelFor(level: LogLevel): NonNullable { + try { + await fs.access(filePath); + return true; + } catch { + return false; + } +} + +function isLinuxMuslRuntime(): boolean { + if (process.platform !== 'linux') { + return false; + } + + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + return !report?.header?.glibcVersionRuntime; +} + +function getCopilotPlatformPackageCandidates(): string[] { + const platformArch = `${process.platform}-${process.arch}`; + if (process.platform !== 'linux') { + return [platformArch]; + } + + const linuxCandidates = [`linux-${process.arch}`, `linuxmusl-${process.arch}`]; + return isLinuxMuslRuntime() ? linuxCandidates.reverse() : linuxCandidates; +} + +async function resolveCopilotCliPath(nodeModulesUri: URI): Promise { + const tried: string[] = []; + for (const platformPackage of getCopilotPlatformPackageCandidates()) { + const cliPath = URI.joinPath(nodeModulesUri, '@github', `copilot-${platformPackage}`, 'index.js').fsPath; + tried.push(cliPath); + if (await fileExists(cliPath)) { + return cliPath; + } + } + + const oldTopLevelPath = URI.joinPath(nodeModulesUri, '@github', 'copilot', 'index.js').fsPath; + tried.push(oldTopLevelPath); + if (await fileExists(oldTopLevelPath)) { + return oldTopLevelPath; + } + + throw new Error(`Unable to resolve @github/copilot CLI path. Tried: ${tried.join(', ')}`); +} + interface ICreatedWorktree { readonly repositoryRoot: URI; readonly worktree: URI; @@ -687,7 +734,7 @@ export class CopilotAgent extends Disposable implements IAgent { // because @github/copilot's exports map blocks direct subpath access. // FileAccess.asFileUri('') points to the `out/` directory; node_modules is one level up. const nodeModulesUri = URI.joinPath(FileAccess.asFileUri(''), '..', 'node_modules'); - const cliPath = URI.joinPath(nodeModulesUri, '@github', 'copilot', 'index.js').fsPath; + const cliPath = await resolveCopilotCliPath(nodeModulesUri); // The SDK's sandbox auto-detection looks for `//wxc-exec.exe` // (and the Linux/macOS equivalents). VS Code core ships the MXC sandbox binaries diff --git a/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts b/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts index 4307a136aca99..00e71613597d7 100644 --- a/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts +++ b/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts @@ -1385,10 +1385,11 @@ export class CopilotAgentSession extends Disposable { const mcpRequestId = generateUuid(); this._pendingMcpSamplings.add(requestId); try { + type McpExecuteSamplingParams = Parameters[0]; const result = await this._wrapper.session.rpc.mcp.executeSampling({ requestId, serverName, - mcpRequestId, + mcpRequestId: mcpRequestId as unknown as McpExecuteSamplingParams['mcpRequestId'], request: params, }); if (result.action === 'success') { diff --git a/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts b/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts index 393db223833f6..59043de575399 100644 --- a/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts +++ b/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts @@ -521,6 +521,9 @@ function sdkAttachmentToProtocol( }; } case 'blob': { + if (typeof attachment.data !== 'string') { + return undefined; + } if (attachment.mimeType.startsWith('text/plain')) { return { type: MessageAttachmentKind.Simple,