diff --git a/extensions/copilot/package-lock.json b/extensions/copilot/package-lock.json index a684008c2cf4aa..ff3cb2a51e4fe3 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.49", + "@github/copilot": "^1.0.57", "@google/genai": "^1.22.0", "@humanwhocodes/gitignore-to-minimatch": "1.0.2", "@microsoft/tiktokenizer": "^1.0.10", @@ -2932,28 +2932,31 @@ "license": "MIT" }, "node_modules/@github/copilot": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.49.tgz", - "integrity": "sha512-40Udj9uCNXaVT2XYbB93CaA7P/rWdy7DP1r088t11s0chWfm5smm9RDMNRj2KqMywwYw3xgf3ZcTFoTLy7kleA==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.57.tgz", + "integrity": "sha512-7dpOu9/qiodmFohZVpTxYmTcjbcXfstWeHof0Ka5RkhguKMkbS3c+sW23a7TTjtlViTV73z+IZFfFW1ru621kw==", "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "detect-libc": "^2.1.2" + }, "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.49", - "@github/copilot-darwin-x64": "1.0.49", - "@github/copilot-linux-arm64": "1.0.49", - "@github/copilot-linux-x64": "1.0.49", - "@github/copilot-linuxmusl-arm64": "1.0.49", - "@github/copilot-linuxmusl-x64": "1.0.49", - "@github/copilot-win32-arm64": "1.0.49", - "@github/copilot-win32-x64": "1.0.49" + "@github/copilot-darwin-arm64": "1.0.57", + "@github/copilot-darwin-x64": "1.0.57", + "@github/copilot-linux-arm64": "1.0.57", + "@github/copilot-linux-x64": "1.0.57", + "@github/copilot-linuxmusl-arm64": "1.0.57", + "@github/copilot-linuxmusl-x64": "1.0.57", + "@github/copilot-win32-arm64": "1.0.57", + "@github/copilot-win32-x64": "1.0.57" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.49.tgz", - "integrity": "sha512-b/qtH1ttG7dnoEC3gLDdrI9n7f5+3LEXD2rOvpdeoxoe8lDlSpUeF4AUpfh7kUivhCKlCIRV+H3+NcRX2rexuQ==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.57.tgz", + "integrity": "sha512-ZmsojZbitPSRfgw3W9wBrHGLRDsBvMCjGsGnJ7xXOU6qxeF/IyWHADxEv1WKfDw8BdCM+LE5yITPXB8bcvCdqQ==", "cpu": [ "arm64" ], @@ -2967,9 +2970,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.49.tgz", - "integrity": "sha512-hHqoeCKqHttqtX3ZHj2TkAIX6jUg159tHDm7qVLccGotgz5bp6ywFxHyGYs7uwD0D90if/m+s87lXu2xAIkN9A==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.57.tgz", + "integrity": "sha512-F4TFDOdORy4oSHJS4DE+3sTk09uk1lohOloe0jfvoEVxJSU6jdQcJLNGoo+BQljcG7a1HEBrmB04iAWG1UXVfA==", "cpu": [ "x64" ], @@ -2983,12 +2986,15 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.49.tgz", - "integrity": "sha512-faNys7OcjoG6g2vlmOVLgzd4pZPmi0LpZJ0pnOLW6lJ2d9Lk5KsY3aX2g/Uqdoz9oqAPg64t8NH2WPSdHPmBTg==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.57.tgz", + "integrity": "sha512-6apNY/v7CMxKk45CctUZLzQnddBpIG9keSendFKYN+kBIEBSdy//s/Cz/4YQX1iERnklpgZRP7FvcwaKs0/7YA==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -2999,12 +3005,15 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.49.tgz", - "integrity": "sha512-bMqMoJ2r304yCmzZ+iv9Nf4xS4KdiqNZo+Ld7Iq9y5Rc5T+DVsrgISb9j2rBqtlOe0rdtKhwOuzSc4XP7BDcvw==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.57.tgz", + "integrity": "sha512-EOOnU4Y+vZHfxVl8eBAP7JtSTmu5d4ZDUC9wCGpAA5k703lEnpu8UOv04mTHRn8KTzb8gj+ijNhxDWe3Xljbaw==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3015,12 +3024,15 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.49.tgz", - "integrity": "sha512-j2Ow72hiamC3yU1GQBl4WEAB9okuUxdGCs+bcYxtDSUY144F9i9U9WE8Oil3KP3Je+WLUZSf81OYsHTCM5OjbA==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.57.tgz", + "integrity": "sha512-FCAaaJLX5T2ZpMeS1TCNnhQuGqyH9WVZndFdN1VOEnN/iWeSSaVF3lM4TPyRHHnWDVxzZtB+VLqOSjINZntD6g==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3031,12 +3043,15 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.49.tgz", - "integrity": "sha512-/a0iNVqXeEvvm0UyPMjW3UPl0meQSSd8SeaMYkkI2OQkYhlUrd9oaUEJzfYnBgPl37AK5+i73DFy09gSH+Efvw==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.57.tgz", + "integrity": "sha512-AMIBN830yOvNcrj2Q0tGMImqat/V24wZS/4m5BaUssELM7r7KrT9ZBnBs+nWDZYeQaRoblFWL3f4AfxE3t94lQ==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -3047,9 +3062,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.49.tgz", - "integrity": "sha512-2oaOoB47i2EcM1tSO+ay2X7xF29Yc/9LFOqkGZZrdS4gTQvTD3oITQBGwdj5CR3GN9pOFxWrhUvyDf9N77AHFg==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.57.tgz", + "integrity": "sha512-3TL2bd1/p/sYbNgDIqbnjES//zlXP5b0sPEXKQRrpVF9ZLN3vjQ1tmBWx8Qx7zn2J3oywH2dG7qKjuxWTJRXKA==", "cpu": [ "arm64" ], @@ -3063,9 +3078,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.49.tgz", - "integrity": "sha512-XwoiiCV3Q9PBV1eFNAag1KnIqN/cNDoNi2B6BJUkGPJUEW3AgrOABV6cmyZ3yEKUEXMZ78JIfS9kUEmTtCAY0g==", + "version": "1.0.57", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.57.tgz", + "integrity": "sha512-zuKqRn0pIF+ZvuiMXbZkYK1AMlrV21kFTpyf5l7gdI1dzJuwHNI0Qfe0gzaZYaU1B4htbzMk9MhEbjR1PQcoJg==", "cpu": [ "x64" ], @@ -9662,7 +9677,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" diff --git a/extensions/copilot/package.json b/extensions/copilot/package.json index 9f9ff9956adf52..ec67fa36d73948 100644 --- a/extensions/copilot/package.json +++ b/extensions/copilot/package.json @@ -6971,7 +6971,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.49", + "@github/copilot": "^1.0.57", "@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 ddcae4a3a33038..4d0de1c87cb2b3 100644 --- a/extensions/copilot/script/postinstall.ts +++ b/extensions/copilot/script/postinstall.ts @@ -120,6 +120,7 @@ async function copyCopilotCliPrebuildFiles() { } return src.endsWith('computer.node') || src.endsWith('runtime.node') + || src.endsWith('cli-native.node') // node-pty natives: pty.node (+ spawn-helper) on Unix, // conpty.node and its companions on Windows. `endsWith('pty.node')` // also matches `conpty.node`. The conpty native additionally needs diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts index aaf1ee465875b2..3b331a40e71534 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/common/copilotCLITools.ts @@ -609,7 +609,7 @@ export function buildChatHistoryFromEvents(sessionId: string, modelId: string | } }); ((event.data.attachments || [])) - .filter(attachment => attachment.type === 'selection' || attachment.type === 'github_reference' || attachment.type === 'blob' ? true : !isInstructionAttachmentPath(attachment.path)) + .filter(attachment => attachment.type === 'selection' || attachment.type === 'github_reference' || attachment.type === 'blob' || attachment.type === 'extension_context' ? true : !isInstructionAttachmentPath(attachment.path)) .forEach(attachment => { if (attachment.type === 'github_reference') { return; diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/common/utils.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/common/utils.ts index b70995b49aa839..2d520c416b6ae6 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/common/utils.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/common/utils.ts @@ -5,6 +5,10 @@ import type { Uri } from 'vscode'; import { URI } from '../../../../util/vs/base/common/uri'; +import type { internal } from '@github/copilot/sdk'; + +export type LocalSession = NonNullable>>; +export type Session = LocalSession; export namespace SessionIdForCLI { export function getResource(sessionId: string): Uri { diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotCli.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotCli.ts index 7f4df498a64010..43c1fdbf0d87b9 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotCli.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotCli.ts @@ -605,12 +605,17 @@ export class CopilotCLISDK implements ICopilotCLISDK { }; } + const { resolveAuthInfoFromToken } = await this.getPackage(); const copilotToken = await this.authentService.getGitHubSession('any', { silent: true }); - return { - type: 'token', - token: copilotToken?.accessToken ?? '', - host: 'https://github.com' - }; + const userInfo = copilotToken ? await resolveAuthInfoFromToken(copilotToken?.accessToken) : undefined; + if (!userInfo) { + return { + type: 'token', + token: copilotToken?.accessToken ?? '', + host: 'https://github.com' + }; + } + return userInfo; } } diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts index a9353fb2677451..c59b176ed83b34 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSession.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Attachment, LocalSession, SendOptions, Session, SessionOptions, ToolExecutionCompleteEvent } from '@github/copilot/sdk'; +import type { Attachment, SendOptions, SessionOptions, ToolExecutionCompleteEvent } from '@github/copilot/sdk'; import * as l10n from '@vscode/l10n'; import * as cp from 'child_process'; import * as crypto from 'crypto'; @@ -11,35 +11,36 @@ import type * as vscode from 'vscode'; import type { ChatParticipantToolToken } from 'vscode'; import { IAuthenticationService } from '../../../../platform/authentication/common/authentication'; import { IChatQuotaService } from '../../../../platform/chat/common/chatQuotaService'; +import { getQuotaMessageForPlan } from '../../../../platform/chat/common/commonTypes'; import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; +import { IGitService } from '../../../../platform/git/common/gitService'; import { PermissiveAuthRequiredError } from '../../../../platform/github/common/githubService'; import { ILogService } from '../../../../platform/log/common/logService'; import { GenAiMetrics } from '../../../../platform/otel/common/genAiMetrics'; -import { CopilotChatAttr, GenAiAttr, GenAiOperationName, GenAiProviderName, IOTelService, ISpanHandle, SpanKind, SpanStatusCode, truncateForOTel, resolveWorkspaceOTelMetadata, workspaceMetadataToOTelAttributes } from '../../../../platform/otel/common/index'; +import { CopilotChatAttr, GenAiAttr, GenAiOperationName, GenAiProviderName, IOTelService, ISpanHandle, resolveWorkspaceOTelMetadata, SpanKind, SpanStatusCode, truncateForOTel, workspaceMetadataToOTelAttributes } from '../../../../platform/otel/common/index'; import { CapturingToken } from '../../../../platform/requestLogger/common/capturingToken'; import { IRequestLogger, LoggedRequestKind } from '../../../../platform/requestLogger/common/requestLogger'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry'; import { PromptTokenCategory, PromptTokenLabel } from '../../../../platform/tokenizer/node/promptTokenDetails'; -import { IGitService } from '../../../../platform/git/common/gitService'; import { IWorkspaceService } from '../../../../platform/workspace/common/workspaceService'; import { raceCancellation } from '../../../../util/vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from '../../../../util/vs/base/common/cancellation'; import { Codicon } from '../../../../util/vs/base/common/codicons'; import { Emitter } from '../../../../util/vs/base/common/event'; +import { createSingleCallFunction } from '../../../../util/vs/base/common/functional'; import { DisposableStore, IDisposable, toDisposable } from '../../../../util/vs/base/common/lifecycle'; import { truncate } from '../../../../util/vs/base/common/strings'; import { ThemeIcon } from '../../../../util/vs/base/common/themables'; import { IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation'; import { ChatResponseMarkdownPart, ChatResponseThinkingProgressPart, ChatSessionStatus, ChatToolInvocationPart, EventEmitter, MarkdownString, Uri } from '../../../../vscodeTypes'; -import { getQuotaMessageForPlan } from '../../../../platform/chat/common/commonTypes'; import { IToolsService } from '../../../tools/common/toolsService'; import { IChatSessionMetadataStore } from '../../common/chatSessionMetadataStore'; import { ExternalEditTracker } from '../../common/externalEditTracker'; import { getWorkingDirectory, isIsolationEnabled, IWorkspaceInfo } from '../../common/workspaceInfo'; import { clearTodoList, enrichToolInvocationWithSubagentMetadata, isCopilotCliEditToolCall, isCopilotCLIToolThatCouldRequirePermissions, isTodoRelatedSqlQuery, processToolExecutionComplete, processToolExecutionStart, stripReminders, ToolCall, updateTodoListFromSqlItems } from '../common/copilotCLITools'; import { clearPendingCopilotCLIRequestContext, setPendingCopilotCLIRequestContext } from '../common/pendingRequestContext'; +import { LocalSession, Session, SessionIdForCLI } from '../common/utils'; import { getCopilotCLISessionDir } from './cliHelpers'; -import { SessionIdForCLI } from '../common/utils'; import type { CopilotCliBridgeSpanProcessor } from './copilotCliBridgeSpanProcessor'; import { ICopilotCLIImageSupport } from './copilotCLIImageSupport'; import { handleExitPlanMode } from './exitPlanModeHandler'; @@ -47,7 +48,6 @@ import { type McCommand, type McEvent, type McSessionCreateResult, MissionContro import { handleMcpPermission, handleReadPermission, handleShellPermission, handleWritePermission, type PermissionRequest, type PermissionRequestResult, showInteractivePermissionPrompt } from './permissionHelpers'; import { TodoSqlQuery } from './todoSqlQuery'; import { IQuestion, IQuestionAnswer, IUserQuestionHandler } from './userInputHelpers'; -import { createSingleCallFunction } from '../../../../util/vs/base/common/functional'; /** * Known commands that can be sent to a CopilotCLI session instead of a free-form prompt. @@ -1686,7 +1686,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes return; } if (authInfo) { - this._sdkSession.setAuthInfo(authInfo); + this._sdkSession.updateOptions({ authInfo }); } if (modelId) { if (modelId !== currentModel) { @@ -2571,6 +2571,8 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes lines.push(`- ${attachment.title}: (${attachment.number}, ${attachment.type}, ${attachment.referenceType})`); } else if (attachment.type === 'blob') { lines.push(`- ${attachment.displayName ?? 'blob'} (${attachment.type}, ${attachment.mimeType})`); + } else if (attachment.type === 'extension_context') { + lines.push(`- ${attachment.title ?? 'extension_context'} (${attachment.type}, ${attachment.extensionId})`); } else { lines.push(`- ${attachment.displayName} (${attachment.type}, ${attachment.type === 'selection' ? attachment.filePath : attachment.path})`); } diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts index 6bc0bd34d0ed73..d65c76e48a19d1 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts @@ -3,14 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { AutoModeSessionManager as SDKAutoModeSessionManager, AutoModeSessionResult, internal, LocalSession, LocalSessionMetadata, Session, SessionContext, SessionEvent, SessionOptions, SweCustomAgent } from '@github/copilot/sdk'; +import type { AutoModeSessionResult, internal, LocalSessionMetadata, AutoModeSessionManager as SDKAutoModeSessionManager, SessionContext, SessionEvent, SessionOptions, SweCustomAgent } from '@github/copilot/sdk'; import * as l10n from '@vscode/l10n'; import { createReadStream } from 'node:fs'; import { devNull } from 'node:os'; import { createInterface } from 'node:readline'; import type { ChatCustomAgent, ChatRequest, ChatSessionItem } from 'vscode'; import { IChatDebugFileLoggerService } from '../../../../platform/chat/common/chatDebugFileLoggerService'; +import { ModelDetailsInfo } from '../../../../platform/chat/common/chatModelDetails'; import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; +import { INTEGRATION_ID } from '../../../../platform/endpoint/common/licenseAgreement'; import { INativeEnvService } from '../../../../platform/env/common/envService'; import { IVSCodeExtensionContext } from '../../../../platform/extContext/common/extensionContext'; import { IFileSystemService } from '../../../../platform/filesystem/common/fileSystemService'; @@ -41,17 +43,15 @@ import { IChatSessionWorktreeService } from '../../common/chatSessionWorktreeSer import { isUntitledSessionId } from '../../common/utils'; import { emptyWorkspaceInfo, getWorkingDirectory, IWorkspaceInfo } from '../../common/workspaceInfo'; import { buildChatHistoryFromEvents, RequestIdDetails, stripReminders } from '../common/copilotCLITools'; -import { ModelDetailsInfo } from '../../../../platform/chat/common/chatModelDetails'; import { ICustomSessionTitleService } from '../common/customSessionTitleService'; import { IChatDelegationSummaryService } from '../common/delegationSummaryService'; -import { SessionIdForCLI } from '../common/utils'; +import { LocalSession, Session, SessionIdForCLI } from '../common/utils'; import { getCopilotCLISessionDir } from './cliHelpers'; import { getAgentFileNameFromFilePath, ICopilotCLIAgents, ICopilotCLIModels, ICopilotCLISDK, isEnabledForCopilotCLI } from './copilotCli'; import { CopilotCliBridgeSpanProcessor } from './copilotCliBridgeSpanProcessor'; import { CopilotCLISession, ICopilotCLISession } from './copilotcliSession'; import { ICopilotCLISkills } from './copilotCLISkills'; import { ICopilotCLIMCPHandler, McpServerMappings, remapCustomAgentTools } from './mcpHandler'; -import { INTEGRATION_ID } from '../../../../platform/endpoint/common/licenseAgreement'; const COPILOT_CLI_WORKSPACE_JSON_FILE_KEY = 'github.copilot.cli.workspaceSessionFile'; @@ -778,17 +778,19 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS } })); } - promises.push(sessionManager.loadDeferredRepoHooks(sdkSession)); + promises.push(sessionManager.loadDeferredRepoHooks(sdkSession.sessionId)); await Promise.all(promises); if (sessionOptions.copilotUrl) { - sdkSession.setAuthInfo({ - type: 'hmac', - hmac: 'empty', - host: 'https://github.com', - copilotUser: { - endpoints: { - api: sessionOptions.copilotUrl + sdkSession.updateOptions({ + authInfo: { + type: 'hmac', + hmac: 'empty', + host: 'https://github.com', + copilotUser: { + endpoints: { + api: sessionOptions.copilotUrl + } } } }); @@ -1014,7 +1016,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS this.logService.error(`[CopilotCLISession] CopilotCLI failed to get session ${options.sessionId}.`); return undefined; } - await sessionManager.loadDeferredRepoHooks(sdkSession); + await sessionManager.loadDeferredRepoHooks(sdkSession.sessionId); const session = this.createCopilotSession(sdkSession, options.workspace, options.agent?.name, sessionManager); session.object.add(mcpGateway); return session; @@ -1296,7 +1298,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS } private createCopilotSession(sdkSession: Session, workspaceInfo: IWorkspaceInfo, agentName: string | undefined, sessionManager: internal.LocalSessionManager): RefCountedSession { - sdkSession.setPermissionsRequired(true); + sdkSession.permissions.setRequired({ required: true }); const session = this.instantiationService.createInstance(CopilotCLISession, workspaceInfo, agentName, sdkSession, []); this._debugFileLogger.startSession(session.sessionId).catch(err => { this.logService.error('[CopilotCLISession] Failed to start debug log session', err); diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/exitPlanModeHandler.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/exitPlanModeHandler.ts index e971147b78204a..c5b41e28f14c77 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/exitPlanModeHandler.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/exitPlanModeHandler.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Session, SessionOptions } from '@github/copilot/sdk'; +import type { SessionOptions } from '@github/copilot/sdk'; import * as l10n from '@vscode/l10n'; import type { CancellationToken, ChatParticipantToolToken, TextDocument } from 'vscode'; import { ILogService } from '../../../../platform/log/common/logService'; @@ -13,6 +13,7 @@ import { DisposableStore } from '../../../../util/vs/base/common/lifecycle'; import { isEqual } from '../../../../util/vs/base/common/resources'; import { LanguageModelTextPart, Uri } from '../../../../vscodeTypes'; import { IToolsService } from '../../../tools/common/toolsService'; +import { Session } from '../common/utils'; type ExitPlanModeActionType = Parameters>[0]['actions'][number]; diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/mcpHandler.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/mcpHandler.ts index b13b0dbb286e97..c0c81716a931f8 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/mcpHandler.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/mcpHandler.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Session, SessionOptions, SweCustomAgent } from '@github/copilot/sdk'; +import type { SessionOptions, SweCustomAgent } from '@github/copilot/sdk'; import type { CancellationToken } from 'vscode'; import { IAuthenticationService } from '../../../../platform/authentication/common/authentication'; import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; @@ -15,6 +15,7 @@ import { hasKey } from '../../../../util/vs/base/common/types'; import { URI } from '../../../../util/vs/base/common/uri'; import type { LanguageModelToolInformation } from '../../../../vscodeTypes'; import { GitHubMcpDefinitionProvider } from '../../../githubMcp/common/githubMcpDefinitionProvider'; +import { Session } from '../common/utils'; const toolInvalidCharRe = /[^a-z0-9_-]/gi; diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts index 7eb7dba2096a64..20a47e2e127734 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/permissionHelpers.ts @@ -18,6 +18,7 @@ import { createEditConfirmation, formatDiffAsUnified } from '../../../tools/node import { ExternalEditTracker } from '../../common/externalEditTracker'; import { getWorkingDirectory, isIsolationEnabled, IWorkspaceInfo } from '../../common/workspaceInfo'; import { getAffectedUrisForEditTool, getCdPresentationOverrides, ToolCall } from '../common/copilotCLITools'; +import type { Session } from '../common/utils'; import { getCopilotCLISessionStateDir } from './cliHelpers'; import { ICopilotCLIImageSupport } from './copilotCLIImageSupport'; @@ -43,7 +44,7 @@ type CoreConfirmationToolParams = { * The result of requesting permissions — the full union accepted by `Session.respondToPermission`. * Extracted from the SDK's second parameter type to stay in sync automatically. */ -export type PermissionRequestResult = Parameters[1]; +export type PermissionRequestResult = Parameters[1]; /** * Handles `read` permission requests. diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotCliAuth.spec.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotCliAuth.spec.ts index 84f9139620e2c1..04c960efc779e8 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotCliAuth.spec.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotCliAuth.spec.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import type { SessionOptions } from '@github/copilot/sdk'; +import * as path from 'path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { IAuthenticationService } from '../../../../../platform/authentication/common/authentication'; import { ConfigKey, IConfigurationService } from '../../../../../platform/configuration/common/configurationService'; @@ -17,6 +18,7 @@ import { CopilotCLISDK } from '../copilotCli'; type TokenAuthInfo = Extract, { type: 'token' }>; type HmacAuthInfo = Extract, { type: 'hmac' }>; +type CopilotSDKPackage = typeof import('@github/copilot/sdk'); describe('CopilotCLISDK Authentication', () => { const disposables = new DisposableStore(); @@ -24,6 +26,19 @@ describe('CopilotCLISDK Authentication', () => { let logService: ILogService; class TestCopilotCLISDK extends CopilotCLISDK { + public override async getPackage(): Promise { + return { + logger: { + setLogWriter: () => { }, + }, + resolveAuthInfoFromToken: async (token: string) => ({ + type: 'token', + token, + host: 'https://github.com', + }), + } as unknown as CopilotSDKPackage; + } + protected override async ensureShims(): Promise { return; } @@ -32,6 +47,7 @@ describe('CopilotCLISDK Authentication', () => { // Helper to create a mock extension context function createMockExtensionContext(): IVSCodeExtensionContext { return { + extensionPath: path.join(__dirname, '..', '..', '..', '..', '..', '..'), workspaceState: { get: () => ({}), update: async () => { }, diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotcliSession.spec.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotcliSession.spec.ts index 558e71f8361b64..270db27003b48a 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotcliSession.spec.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/copilotcliSession.spec.ts @@ -3,14 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Session, SessionOptions } from '@github/copilot/sdk'; +import type { SessionOptions } from '@github/copilot/sdk'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import type { ChatParticipantToolToken, ChatResponseStream } from 'vscode'; import { ConfigKey, IConfigurationService } from '../../../../../platform/configuration/common/configurationService'; +import { MockGitService } from '../../../../../platform/ignore/node/test/mockGitService'; import { ILogService } from '../../../../../platform/log/common/logService'; import { NoopOTelService, resolveOTelConfig } from '../../../../../platform/otel/common/index'; import { IRequestLogger } from '../../../../../platform/requestLogger/common/requestLogger'; import { NullRequestLogger } from '../../../../../platform/requestLogger/node/nullRequestLogger'; +import { NullTelemetryService } from '../../../../../platform/telemetry/common/nullTelemetryService'; +import type { ITelemetryService, TelemetryEventMeasurements, TelemetryEventProperties } from '../../../../../platform/telemetry/common/telemetry'; import { TestWorkspaceService } from '../../../../../platform/test/node/testWorkspaceService'; import { IWorkspaceService } from '../../../../../platform/workspace/common/workspaceService'; import { CancellationToken, CancellationTokenSource } from '../../../../../util/vs/base/common/cancellation'; @@ -25,13 +28,11 @@ import { ExternalEditTracker } from '../../../common/externalEditTracker'; import { MockChatSessionMetadataStore } from '../../../common/test/mockChatSessionMetadataStore'; import { IWorkspaceInfo } from '../../../common/workspaceInfo'; import { FakeToolsService, ToolCall } from '../../common/copilotCLITools'; +import { Session } from '../../common/utils'; import { CopilotCLISession } from '../copilotcliSession'; import { PermissionRequest } from '../permissionHelpers'; import { IQuestion, IQuestionAnswer, IUserQuestionHandler, UserInputResponse } from '../userInputHelpers'; import { NullICopilotCLIImageSupport } from './testHelpers'; -import { MockGitService } from '../../../../../platform/ignore/node/test/mockGitService'; -import { NullTelemetryService } from '../../../../../platform/telemetry/common/nullTelemetryService'; -import type { ITelemetryService, TelemetryEventMeasurements, TelemetryEventProperties } from '../../../../../platform/telemetry/common/telemetry'; vi.mock('../cliHelpers', async (importOriginal) => ({ ...(await importOriginal()), @@ -149,8 +150,14 @@ class MockSdkSession { set toolMetadata(value: unknown[] | undefined) { this._toolMetadata = value; } setAuthInfo(info: any) { this.authInfo = info; } + updateOptions(options: { authInfo?: unknown }) { + if (options.authInfo !== undefined) { + this.authInfo = options.authInfo; + } + } async getSelectedModel() { return this._selectedModel; } async setSelectedModel(model: string, _reasoningEffort?: string) { this._selectedModel = model; } + getReasoningEffort(): string | undefined { return undefined; } async getEvents() { return []; } getPlanPath(): string | null { return null; } diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/exitPlanModeHandler.spec.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/exitPlanModeHandler.spec.ts index cbd9f5fe6e8b42..cdd6ba2d2f03f4 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/exitPlanModeHandler.spec.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/exitPlanModeHandler.spec.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Session } from '@github/copilot/sdk'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import type * as vscode from 'vscode'; import type { CancellationToken, ChatParticipantToolToken, TextDocumentChangeEvent } from 'vscode'; @@ -17,6 +16,7 @@ import { LanguageModelTextPart } from '../../../../../vscodeTypes'; import { ToolName } from '../../../../tools/common/toolNames'; import { ICopilotTool } from '../../../../tools/common/toolsRegistry'; import { IOnWillInvokeToolEvent, IToolsService, IToolValidationResult } from '../../../../tools/common/toolsService'; +import { Session } from '../../common/utils'; import { handleExitPlanMode, type ExitPlanModeEventData, type ExitPlanModeResponse } from '../exitPlanModeHandler'; // ---------- helpers / mocks ---------- diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/testHelpers.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/testHelpers.ts index 0cbad1ecd8c615..dd5b9524073800 100644 --- a/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/testHelpers.ts +++ b/extensions/copilot/src/extension/chatSessions/copilotcli/node/test/testHelpers.ts @@ -48,9 +48,19 @@ export class MockCliSdkSession { clearCustomAgent() { return; } - setPermissionsRequired(_required: boolean): void { - // no-op in tests - } + get permissions() { + return { + setRequired: (_required: boolean) => { + // no-op in tests + } + }; + } + updateOptions(options: { authInfo?: unknown }) { + // if (options.authInfo !== undefined) { + // this.authInfo = options.authInfo; + // } + } + getReasoningEffort(): string | undefined { return undefined; } } export class MockSkillLocations implements ICopilotCLISkills { 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 379f000ed4cf8e..95817a3a5d62cf 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 @@ -56,26 +56,25 @@ describe('CopilotCLI SDK Upgrade', function () { path.join('prebuilds', 'linux-x64', 'computer.node'), path.join('prebuilds', 'win32-arm64', 'computer.node'), path.join('prebuilds', 'win32-x64', 'computer.node'), + // cli-native to be included + path.join('prebuilds', 'darwin-arm64', 'cli-native.node'), + path.join('prebuilds', 'darwin-x64', 'cli-native.node'), + path.join('prebuilds', 'linux-arm64', 'cli-native.node'), + path.join('prebuilds', 'linux-x64', 'cli-native.node'), + path.join('prebuilds', 'linuxmusl-arm64', 'cli-native.node'), + path.join('prebuilds', 'linuxmusl-x64', 'cli-native.node'), + path.join('prebuilds', 'win32-arm64', 'cli-native.node'), + path.join('prebuilds', 'win32-x64', 'cli-native.node'), // Native modules present in the raw @github/copilot package. Root // prebuilds are stripped from the shipped extension by .vscodeignore. - path.join('prebuilds', 'darwin-arm64', 'icu-native.node'), path.join('prebuilds', 'darwin-arm64', 'runtime.node'), - path.join('prebuilds', 'darwin-x64', 'icu-native.node'), path.join('prebuilds', 'darwin-x64', 'runtime.node'), - path.join('prebuilds', 'linux-arm64', 'icu-native.node'), path.join('prebuilds', 'linux-arm64', 'runtime.node'), - path.join('prebuilds', 'linux-x64', 'icu-native.node'), path.join('prebuilds', 'linux-x64', 'runtime.node'), - path.join('prebuilds', 'linuxmusl-arm64', 'icu-native.node'), path.join('prebuilds', 'linuxmusl-arm64', 'runtime.node'), - path.join('prebuilds', 'linuxmusl-x64', 'icu-native.node'), path.join('prebuilds', 'linuxmusl-x64', 'runtime.node'), - path.join('prebuilds', 'win32-arm64', 'icu-native.node'), path.join('prebuilds', 'win32-arm64', 'runtime.node'), - path.join('prebuilds', 'win32-arm64', 'win32-native.node'), - path.join('prebuilds', 'win32-x64', 'icu-native.node'), path.join('prebuilds', 'win32-x64', 'runtime.node'), - path.join('prebuilds', 'win32-x64', 'win32-native.node'), // Second copy of native prebuilds 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'), @@ -112,6 +111,13 @@ describe('CopilotCLI SDK Upgrade', function () { path.join('ripgrep', 'bin', 'linux-arm64', 'rg'), path.join('ripgrep', 'bin', 'linuxmusl-arm64', 'rg'), path.join('ripgrep', 'bin', 'linuxmusl-x64', 'rg'), + // cli-native to be included + path.join('sdk', 'prebuilds', 'darwin-arm64', 'cli-native.node'), + path.join('sdk', 'prebuilds', 'darwin-x64', 'cli-native.node'), + path.join('sdk', 'prebuilds', 'linux-arm64', 'cli-native.node'), + path.join('sdk', 'prebuilds', 'linux-x64', 'cli-native.node'), + path.join('sdk', 'prebuilds', 'win32-arm64', 'cli-native.node'), + path.join('sdk', 'prebuilds', 'win32-x64', 'cli-native.node'), // sharp related files path.join('sharp', 'node_modules', '@img', 'sharp-wasm32', 'lib', 'sharp-wasm32.node.wasm'), // sharp related files, files copied by us. @@ -134,21 +140,27 @@ describe('CopilotCLI SDK Upgrade', function () { path.join('mxc-bin', 'arm64', 'wslcsdk.dll'), path.join('mxc-bin', 'arm64', 'wxc-exec.exe'), path.join('mxc-bin', 'arm64', 'wxc-test-proxy.exe'), + path.join('mxc-bin', 'arm64', 'wxc-host-prep.exe'), path.join('mxc-bin', 'arm64', 'wxc-windows-sandbox-daemon.exe'), path.join('mxc-bin', 'arm64', 'wxc-windows-sandbox-guest.exe'), + path.join('mxc-bin', 'arm64', 'mxc-diagnostic-console.exe'), path.join('mxc-bin', 'arm64', '_manifest', 'spdx_2.2', 'bsi.cose'), path.join('mxc-bin', 'arm64', '_manifest', 'spdx_2.2', 'manifest.cat'), path.join('mxc-bin', 'arm64', '_manifest', 'spdx_2.2', 'manifest.spdx.cose'), + path.join('mxc-bin', 'arm64', 'linux-test-proxy'), path.join('mxc-bin', 'x64', 'lxc-exec'), path.join('mxc-bin', 'x64', 'winhttp-proxy-shim.exe'), path.join('mxc-bin', 'x64', 'wslcsdk.dll'), path.join('mxc-bin', 'x64', 'wxc-exec.exe'), path.join('mxc-bin', 'x64', 'wxc-test-proxy.exe'), + path.join('mxc-bin', 'x64', 'wxc-host-prep.exe'), path.join('mxc-bin', 'x64', 'wxc-windows-sandbox-daemon.exe'), path.join('mxc-bin', 'x64', 'wxc-windows-sandbox-guest.exe'), + path.join('mxc-bin', 'x64', 'mxc-diagnostic-console.exe'), path.join('mxc-bin', 'x64', '_manifest', 'spdx_2.2', 'bsi.cose'), path.join('mxc-bin', 'x64', '_manifest', 'spdx_2.2', 'manifest.cat'), path.join('mxc-bin', 'x64', '_manifest', 'spdx_2.2', 'manifest.spdx.cose'), + path.join('mxc-bin', 'x64', 'linux-test-proxy'), // parsing commands for shell. 'tree-sitter-bash.wasm', 'tree-sitter.wasm', @@ -170,6 +182,10 @@ describe('CopilotCLI SDK Upgrade', function () { 'tree-sitter-scala.wasm', ].map(p => path.join(copilotSDKPath, p))); + const optionalKnownBinaries = new Set([ + path.join(copilotSDKPath, 'mxc-bin', 'x64', 'mxc-exec-mac'), + ]); + // 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'); @@ -183,7 +199,7 @@ describe('CopilotCLI SDK Upgrade', function () { if (binaryName.startsWith('keytar') || binaryName.startsWith('clipboard')) { continue; } - if (!knownBinaries.has(binary)) { + if (!knownBinaries.has(binary) && !optionalKnownBinaries.has(binary)) { errors.push(`Unexpected native binary found in Copilot CLI SDK: ${path.relative(copilotSDKPath, binary)}`); } } diff --git a/extensions/xml/package.json b/extensions/xml/package.json index 4758ebb01cee62..70c8d6db22e14a 100644 --- a/extensions/xml/package.json +++ b/extensions/xml/package.json @@ -64,6 +64,7 @@ ".vbproj.user", ".vcxproj", ".vcxproj.filters", + ".wixproj", ".wsdl", ".wxi", ".wxl", diff --git a/src/main.ts b/src/main.ts index 219cfa9b9c6bdf..e92fe6afa715d6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -101,6 +101,10 @@ protocol.registerSchemesAsPrivileged([ { scheme: 'vscode-file', privileges: { secure: true, standard: true, supportFetchAPI: true, corsEnabled: true, codeCache: true } + }, + { + scheme: 'vscode-remote-resource', + privileges: { secure: true, supportFetchAPI: true, corsEnabled: true } } ]); diff --git a/src/vs/sessions/services/sessions/browser/sessionsManagementService.ts b/src/vs/sessions/services/sessions/browser/sessionsManagementService.ts index 3abeb1d14c51b8..c0600b9ce82875 100644 --- a/src/vs/sessions/services/sessions/browser/sessionsManagementService.ts +++ b/src/vs/sessions/services/sessions/browser/sessionsManagementService.ts @@ -321,7 +321,7 @@ export class SessionsManagementService extends Disposable implements ISessionsMa if (e.removed.length && e.removed.some(r => r.sessionId === currentActive.sessionId)) { const fallback = this._visibility.activeSession.get(); - if (fallback) { + if (fallback && this.getSession(fallback.resource)) { this.openSession(fallback.resource); } else { this.openNewSessionView(); diff --git a/test/sanity/scripts/run-docker.sh b/test/sanity/scripts/run-docker.sh index ac30c4c0b6b70c..4055a0eb74be22 100755 --- a/test/sanity/scripts/run-docker.sh +++ b/test/sanity/scripts/run-docker.sh @@ -46,6 +46,7 @@ echo "Running sanity tests in container" docker run \ --rm \ --platform "linux/$ARCH" \ + --shm-size=2g \ --volume "$ROOT_DIR:/root" \ ${GITHUB_ACCOUNT:+--env GITHUB_ACCOUNT} \ ${GITHUB_PASSWORD:+--env GITHUB_PASSWORD} \