Path: blob/main/extensions/copilot/src/extension/chatSessions/copilotcli/AGENTS.md
13399 views
Copilot CLI Integration
This folder contains the Copilot CLI integration for VS Code Chat. It enables users to open a new Chat window and interact with a Copilot CLI agent instance directly within VS Code. VS Code provides the UI, Copilot CLI SDK provides the smarts.
Important: The Copilot CLI agent functionality is powered by the
@github/copilot/sdkpackage. See the SDK package for full type definitions.
Architecture
Folder Structure
The integration follows VS Code's platform layering pattern with three layers:
Layering Rules
Strict import dependency rules — violations will cause build failures:
| Layer | Can import from | Cannot import from |
|---|---|---|
common/ | src/util/common/, src/platform/, sibling ../common/ | node/, vscode-node/, vscode module |
node/ | common/, src/util/, src/platform/, Node.js builtins | vscode-node/, vscode module |
vscode-node/ | common/, node/, src/util/, src/platform/, vscode module | (top layer — no restrictions) |
Key Components
node/copilotCli.ts
ICopilotCLISDK / CopilotCLISDK
Service interface wrapping the dynamic
import('@github/copilot/sdk')for dependency injection and testability
ICopilotCLIModels / CopilotCLIModels
Fetches and caches available AI models from the SDK via
getAvailableModels()Registers a
LanguageModelChatProviderwithtargetChatSessionType: 'copilotcli'so VS Code's model picker shows CLI modelsExposes model capabilities: vision support, reasoning effort levels, token limits, billing multiplier
Rebuilds model list on authentication changes
Builds configuration schema for reasoning effort per model (low/medium/high/xhigh)
ICopilotCLIAgents / CopilotCLIAgents
Discovers custom agents
node/copilotcliSession.ts
CopilotCLISession
Wraps a single
Sessionobject from the@github/copilot/sdkEntry point for every chat request via
handleRequest()Listens to SDK events and translates them to VS Code chat UI parts
Manages permission flow
Tracks external edits via
ExternalEditTrackerfor proper diff displaySupports CLI commands:
compact,plan,fleetBuilt-in slash commands:
/commit,/sync,/merge,/create-pr,/create-draft-pr,/update-prCaptures pull request URLs from
create_pull_requesttool results
node/copilotcliSessionService.ts
ICopilotCLISessionService / CopilotCLISessionService
Central service managing the lifecycle of all Copilot CLI sessions
common/copilotCLITools.ts
Defines all tool type interfaces used by the Copilot CLI agent:
File Operations
Shell Operations
Search Operations
Agent & Task Operations
User Interaction
Code Review & Git
Data, Memory & MCP
Security
common/copilotCLIPrompt.ts
Parses raw user prompts and extracts structured chat prompt references (files, locations, diagnostics)
node/copilotcliPromptResolver.ts
CopilotCLIPromptResolver
Resolves chat request prompts by processing variable references and building attachments
Extracts prompt variables from
ChatVariablesCollection(files, locations, diagnostics, custom instructions)Converts image attachments
Generates the final user prompt
Handles workspace folder path translation for multi-folder isolation
node/permissionHelpers.ts
Handles permission requests from the SDK. Each permission kind has a dedicated handler:
handleReadPermission
handleWritePermission
handleShellPermission
handleMcpPermission
showInteractivePermissionPrompt
node/mcpHandler.ts
ICopilotCLIMCPHandler / CopilotCLIMCPHandler
Loads MCP server configuration for SDK sessions
Proxies all VS Code-configured MCP servers through a gateway URL with
type: 'http'config per server
node/copilotCLIImageSupport.ts
ICopilotCLIImageSupport / CopilotCLIImageSupport
Stores image data as files in extension global storage (
copilot-cli-images/)Tracks trusted image URIs to auto-approve read permissions
Supports PNG, JPEG, GIF, WebP, and BMP formats via
isImageMimeType()
node/exitPlanModeHandler.ts
handleExitPlanMode()
Presents exit options when the SDK finishes plan generation: Autopilot, Interactive, Exit Only, Autopilot Fleet
Syncs saved plan changes back to the SDK session
node/cliHelpers.ts
Path helpers for Copilot CLI directories.
Message Flow
User sends message in VS Code Chat
CopilotCLISessionService creates or retrieves an existing session wrapper
CopilotCLISession.handleRequest() is called:
If session is idle → normal request via
send()If session is busy → steering request via
send({ mode: 'immediate' })
SDK Session processes the request and emits events:
assistant.message_delta→ streamed markdown to chat UItool.execution_start/tool.execution_complete→ tool invocation UI partspermission.requested→ routed to permission handler (auto-approve or interactive)user_input.requested→ question carousel shown to userexit_plan_mode.requested→ plan mode exit choicessession.title_changed→ session title updatedsubagent.started/completed/failed→ subagent metadata enriches tool invocationshook.start/end→ forwarded to OTel bridge for debug panel
Session completes — status set to
Completed, usage reported
Permission System
The SDK emits permission.requested events with a kind field.
When autopilot / autoApprove permission level is set, all permissions are auto-approved without user interaction.
Tool invocation messages are intentionally held in a queue (toolCallWaitingForPermissions) until the permission resolves, preventing a flash of "Running..." immediately followed by "Permission requested...".
Session Persistence
Copilot CLI sessions are persisted to ~/.copilot/session-state/<sessionId>/ directories containing:
events.jsonl— Ordered event stream (messages, tool calls, results)workspace.yaml— Workspace configuration
IWorkspaceInfo (../common/workspaceInfo.ts)
Central type representing all workspace/repository/worktree state for a session:
IChatSessionMetadataStore (../common/chatSessionMetadataStore.ts)
Persists VS Code-specific metadata that sits alongside the SDK's own session data. This metadata is not part of the SDK's events.jsonl — it tracks VS Code concepts like worktree properties, request-to-tool mappings, mode instructions, and checkpoint refs.
Key Types:
ChatSessionMetadataFile — The full metadata shape per session:
RequestDetails — Per-request metadata:
RepositoryProperties — Git repository metadata:
IChatSessionWorktreeService (../common/chatSessionWorktreeService.ts)
Manages Git worktree lifecycle for session isolation. When isolation is enabled, each session gets its own Git worktree so the agent can make changes without affecting the user's working copy.
IChatSessionWorktreeCheckpointService (../common/chatSessionWorktreeCheckpointService.ts)
Creates Git checkpoints (lightweight commits or refs) at the start and end of each request turn. These checkpoints enable the undo/revert feature — users can roll back to any previous turn's state.
IChatSessionWorkspaceFolderService (../common/chatSessionWorkspaceFolderService.ts)
Handles workspace folder tracking for sessions without Git worktree isolation — i.e., when the agent works directly in the user's workspace. Used in multi-root workspaces where some folders may not have Git repositories.
IFolderRepositoryManager (../common/folderRepositoryManager.ts)
Orchestrates the full folder/repository initialization flow for a session. This is the high-level coordinator that brings together worktree creation, trust verification, uncommitted change handling, and folder tracking.
ISessionRequestLifecycle (../vscode-node/sessionRequestLifecycle.ts)
Orchestrates the start and end of each chat request turn, coordinating worktree commits, checkpoint creation, PR detection, and metadata updates. Handles the complexity of steering — where multiple requests can be in-flight for the same session simultaneously.
Architecture Diagram: Shared Services
How to Add New Features
Adding a new permission handler
Add
handle<Kind>Permission()innode/permissionHelpers.tsfollowing the existing patternAdd a
case '<kind>':in the permission switch innode/copilotcliSession.ts(~line 468)Handler should return a
PermissionRequestResultwithkind: 'approved' | 'denied-interactively-by-user' | ...
Handling a new SDK event
Add a listener in
node/copilotcliSession.tsusingthis._sdkSession.on(eventName, handler)Wrap with
toDisposable()and add to theDisposableStorefor proper cleanupUse
this._stream?.markdown()/this._stream?.push()to output to the chat UI
Critical Pitfalls
Shims before SDK import:
ensureRipgrepShim()innode/ripgrepShim.tsMUST be called before anyimport('@github/copilot/sdk'). It copies VS Code's bundled ripgrep binary to the SDK's expected location.node-ptyis no longer shimmed: the copilot CLI SDK resolves it from VS Code's ownnode_modulesviahostRequire, falling back to its bundled copy only if that fails. Seenode/copilotCli.tsfor the initialization order.Delayed permission UI: Tool invocation messages are held in
toolCallWaitingForPermissionsuntil permission resolves.flushPendingInvocationMessageForToolCallId()flushes only the specific approved tool, not all pending tools. This is intentional — don't bypass it.Steering mode: When a session is already busy (
InProgressorNeedsInput), usesend({ mode: 'immediate' })to inject messages into the running conversation instead of starting a new request.
Commands & Slash Commands
Copilot CLI commands (user-facing, sent programmatically):
compact— compress conversation history to reduce tokensplan— enter plan mode (SDK generates plan before executing)fleet— start fleet mode for multi-agent parallel execution
Built-in custom slash commands (user-facing): /commit, /sync, /merge, /create-pr, /create-draft-pr, /update-pr
VS Code Session commands (registered via registerCLIChatCommands in vscode-node/copilotCLIChatSessions.ts):
Configuration
The integration respects these VS Code settings (all under github.copilot.chat.cli.*):
| Setting | Default | Description |
|---|---|---|
mcp.enabled | true | Enable MCP server proxying for CLI sessions |
branchSupport.enabled | false | Enable Git branch support features |
showExternalSessions | false | Show sessions created outside VS Code (e.g., terminal CLI) |
planExitMode.enabled | true | Show plan exit mode choices (Autopilot/Interactive/Exit) |
planCommand.enabled | true | Enable the /plan command |
aiGenerateBranchNames.enabled | true | AI-generated branch names for worktrees |
forkSessions.enabled | true | Allow forking sessions into new conversations |
isolationOption.enabled | true | Show worktree isolation option in session UI |
autoCommit.enabled | true | Auto-commit worktree changes at end of each turn |
sessionController.enabled | false | Use session controller API (V2) |
thinkingEffort.enabled | true | Show thinking effort control per model |
sessionControllerForSessionsApp.enabled | false | Use session controller for Sessions window |
terminalLinks.enabled | true | Enable terminal link detection |
Dependencies
@github/copilot/sdk: Official Copilot CLI SDK (session management, tools, permissions, events)
Deprecated Code
V1 registration in ../vscode-node/copilotCLIChatSessionsContribution.ts and registerCopilotCLIServicesV1 are deprecated. All new development should use CopilotCLISessionService and the controller-based V2 API.