RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/AGENTS.md/microsoft/vscode

AGENTS.md

extensions/copilot/src/extension/chatSessions/claude/AGENTS.md
AGENTS.md

Quality

66/100

Scores the file, not the repository.

Length

3,943 words

46 headings · 9 code blocks

Repository

188k

— · pushed 0 days ago

Last changed

3 days ago

First indexed 3 days ago.
microsoft/vscode/extensions/copilot/src/extension/chatSessions/claude/AGENTS.mdRawGitHub
1# Claude Code Integration
2 
3This folder contains the Claude Code integration for VS Code Chat. It enables users to open a new Chat window and interact with a Claude Code instance directly within VS Code. **VS Code provides the UI, Claude Code provides the smarts.**
4 
5> 📖 **New to the Claude session target?** See the **[User Guide](./CLAUDE_SESSION_USER_GUIDE.md)** for a comprehensive walkthrough of features, slash commands, permission modes, and best practices.
6 
7## Official Claude Agent SDK Documentation
8 
9> **Important:** For the most up-to-date information on the Claude Agent SDK, always refer to the official documentation:
10>
11> - **[Agent SDK Overview](https://platform.claude.com/docs/en/agent-sdk/overview)** - General SDK concepts, capabilities, and getting started guide
12> - **[Agent SDK Quickstart](https://platform.claude.com/docs/en/agent-sdk/quickstart)** - Step-by-step guide to building your first agent
13> - **[TypeScript SDK Reference](https://platform.claude.com/docs/en/agent-sdk/typescript)** - Complete API reference for the TypeScript SDK including all functions, types, and interfaces
14> - **[TypeScript V2 Preview](https://platform.claude.com/docs/en/agent-sdk/typescript-v2-preview)** - Preview of the simplified V2 interface with session-based send/stream patterns
15>
16> The SDK package is `@anthropic-ai/claude-agent-sdk`. The official documentation covers tools, hooks, subagents, MCP integration, permissions, sessions, and more.
17 
18### Core SDK Features
19 
20**Getting Started:**
21- [Overview](https://platform.claude.com/docs/en/agent-sdk/overview) - Learn about the Agent SDK architecture and core concepts
22- [Quickstart](https://platform.claude.com/docs/en/agent-sdk/quickstart) - Get up and running with your first agent in minutes
23 
24**Core SDK Implementation:**
25- [TypeScript](https://platform.claude.com/docs/en/agent-sdk/typescript) - Main TypeScript SDK reference for building agents
26- [TypeScript v2 Preview](https://platform.claude.com/docs/en/agent-sdk/typescript-v2-preview) - Preview of upcoming v2 API with enhanced features
27- [Streaming vs Single Mode](https://platform.claude.com/docs/en/agent-sdk/streaming-vs-single-mode) - Choose between streaming responses or single-turn completions
28 
29**User Interaction & Control:**
30- [Permissions](https://platform.claude.com/docs/en/agent-sdk/permissions) - Control what actions Claude can take with user approval flows
31- [User Input](https://platform.claude.com/docs/en/agent-sdk/user-input) - Collect clarifications and decisions from users during execution
32- [Hooks](https://platform.claude.com/docs/en/agent-sdk/hooks) - Execute custom logic at key points in the agent lifecycle
33 
34**State & Session Management:**
35- [Sessions](https://platform.claude.com/docs/en/agent-sdk/sessions) - Manage conversation history and context across interactions
36- [File Checkpointing](https://platform.claude.com/docs/en/agent-sdk/file-checkpointing) - Save and restore file states for undo/redo functionality
37 
38**Advanced Features:**
39- [Structured Outputs](https://platform.claude.com/docs/en/agent-sdk/structured-outputs) - Get reliable JSON responses with schema validation
40- [Modifying System Prompts](https://platform.claude.com/docs/en/agent-sdk/modifying-system-prompts) - Customize Claude's behavior and instructions
41- [MCP](https://platform.claude.com/docs/en/agent-sdk/mcp) - Connect to Model Context Protocol servers for extended capabilities
42- [Custom Tools](https://platform.claude.com/docs/en/agent-sdk/custom-tools) - Build your own tools to extend Claude's functionality
43 
44**Agent Composition & UX:**
45- [Subagents](https://platform.claude.com/docs/en/agent-sdk/subagents) - Compose complex workflows by delegating to specialized agents
46- [Slash Commands](https://platform.claude.com/docs/en/agent-sdk/slash-commands) - Add custom `/commands` for quick actions
47- [Skills](https://platform.claude.com/docs/en/agent-sdk/skills) - Package reusable agent capabilities as installable modules
48- [Todo Tracking](https://platform.claude.com/docs/en/agent-sdk/todo-tracking) - Help Claude manage and display task progress
49- [Plugins](https://platform.claude.com/docs/en/agent-sdk/plugins) - Extend the SDK with community-built integrations
50 
51## Overview
52 
53The Claude Code integration allows VS Code's chat interface to communicate with Claude Code, Anthropic's agentic coding assistant. When a user sends a message in a VS Code Chat window using this integration, the message is routed to a Claude Code session that can:
54 
55- Read and analyze code
56- Execute shell commands
57- Edit files
58- Search the workspace
59- Manage tasks and todos
60 
61All interactions are displayed through VS Code's native chat UI, providing a seamless experience.
62 
63## Architecture
64 
65```
66┌─────────────────────────────────────────────────────────────────┐
67│ VS Code Chat UI │
68└─────────────────────────┬───────────────────────────────────────┘
69 │
70 ▼
71┌─────────────────────────────────────────────────────────────────┐
72│ ClaudeAgentManager │
73│ - Manages language model server lifecycle │
74│ - Routes requests to appropriate sessions │
75│ - Resolves prompts with file references │
76└─────────────────────────┬───────────────────────────────────────┘
77 │
78 ▼
79┌─────────────────────────────────────────────────────────────────┐
80│ ClaudeCodeSession │
81│ - Maintains a single Claude Code conversation │
82│ - Processes messages (assistant, user, result) │
83│ - Handles tool invocation and confirmation │
84│ - Queues multiple requests for sequential processing │
85└─────────────────────────┬───────────────────────────────────────┘
86 │
87 ▼
88┌─────────────────────────────────────────────────────────────────┐
89│ Claude Code SDK (@anthropic-ai) │
90│ - Communicates with Claude Code │
91│ - Manages tool hooks (pre/post tool use) │
92│ - Handles message streaming │
93└─────────────────────────────────────────────────────────────────┘
94```
95 
96## Key Components
97 
98### `node/claudeCodeAgent.ts`
99 
100**ClaudeAgentManager**
101- Entry point for handling chat requests from VS Code
102- Starts and manages the language model server (`LanguageModelServer`)
103- Creates and caches `ClaudeCodeSession` instances by session ID
104- Resolves prompts by replacing VS Code references (files, locations) with actual paths
105 
106**ClaudeCodeSession**
107- Represents a single Claude Code conversation session
108- Manages a queue of incoming requests from VS Code Chat
109- Uses an async iterable to feed prompts to Claude Code SDK
110- Processes three message types:
111 - **Assistant messages**: Text responses and tool use requests
112 - **User messages**: Tool results from executed tools
113 - **Result messages**: Session completion or error states
114- Handles tool confirmation dialogs via VS Code's chat API
115- Auto-approves safe operations (file edits in workspace)
116- Tracks external edits to show proper diffs
117 
118### `node/claudeCodeSdkService.ts`
119 
120**IClaudeCodeSdkService / ClaudeCodeSdkService**
121- Thin wrapper around the `@anthropic-ai/claude-agent-sdk`
122- Provides dependency injection for testability
123- Enables mocking in unit tests
124 
125### `node/sessionParser/claudeCodeSessionService.ts`
126 
127**IClaudeCodeSessionService / ClaudeCodeSessionService**
128- Loads and manages persisted Claude Code sessions from disk
129- Reads `.jsonl` session files from `~/.claude/projects/<workspace-slug>/`
130- Builds message chains from leaf nodes to reconstruct full conversations
131- Loads subagent sessions via SDK APIs (`listSubagents` + `getSubagentMessages`) and correlates them with their spawning tool use via `parent_tool_use_id` (stored as `ISubagentSession.parentToolUseId`)
132- Provides session caching with mtime-based invalidation
133- Used to resume previous Claude Code conversations
134- See `node/sessionParser/README.md` for detailed documentation
135 
136### `node/sessionParser/sdkSessionAdapter.ts`
137 
138Adapts raw SDK session data into the internal `IClaudeCodeSession` / `ISubagentSession` schemas:
139- **`buildClaudeCodeSession()`**: Assembles a full `IClaudeCodeSession` from session info, messages, and subagents
140- **`sdkSubagentMessagesToSubagentSession()`**: Converts raw SDK `SessionMessage[]` into an `ISubagentSession`
141- **`extractParentToolUseId()`**: Helper that scans a `SessionMessage[]` array until it finds a string `parent_tool_use_id`, used to correlate a subagent session with the Agent/Task tool_use block that spawned it
142 
143### `node/claudeSkills.ts`
144 
145**IClaudePluginService / ClaudePluginService**
146- Resolves plugin root directories for the Claude SDK's `plugins` option
147- Combines three sources of plugin locations:
148 1. **Config skill locations** — from `chat.agentSkillsLocations` setting, resolved via the shared `resolveSkillConfigLocations()` utility. These point to skills directories (e.g. `.../skills/`), so the service walks **one level up** to reach the plugin root expected by the SDK.
149 2. **Discovered skills** — from `IPromptsService.getSkills()`. Each skill has a `SKILL.md` at `<plugin-root>/skills/<skill-name>/SKILL.md`, so the service walks **three levels up** (`dirname(dirname(dirname(uri)))`) to reach the plugin root.
150 3. **Direct plugins** — from `IPromptsService.getPlugins()`, returned as-is since they already point to plugin root directories.
151- Filters out `.claude` directories (the Claude SDK loads these automatically)
152- Deduplicates results using `ResourceSet`
153- Plugin roots are passed to the SDK as `SdkPluginConfig[]` with `{ type: 'local', path }` in `ClaudeCodeSession._doStartSession()`
154 
155**Shared utility:** `../../common/skillConfigLocations.ts` — `resolveSkillConfigLocations()` handles `~/` expansion, absolute paths, and relative paths joined to workspace folders. Used by both `ClaudePluginService` and `CopilotCLISkills`.
156 
157### `common/claudeTools.ts`
158 
159Defines Claude Code's tool interface:
160- **ClaudeToolNames**: Enum of all supported tool names (Bash, Read, Edit, Write, etc.). `Agent` is the current name (SDK v2.1.63+); `Task` is kept for backward compatibility with older sessions.
161- **Tool input interfaces**: Type definitions for each tool's input parameters
162- **claudeEditTools**: List of tools that modify files (Edit, MultiEdit, Write, NotebookEdit)
163- **getAffectedUrisForEditTool**: Extracts file URIs that will be modified by edit operations
164 
165### `common/toolInvocationFormatter.ts`
166 
167Formats tool invocations for display in VS Code's chat UI:
168- Creates `ChatToolInvocationPart` instances with appropriate messaging
169- Handles tool-specific formatting (Bash commands, file reads, searches, etc.)
170- Suppresses certain tools from display (TodoWrite, Edit, Write) where other UI handles them
171 
172### `../../chatSessions/vscode-node/chatHistoryBuilder.ts`
173 
174Converts a persisted `IClaudeCodeSession` into VS Code `ChatResponsePart[]` for replay in the chat UI:
175- Reconstructs assistant text, thinking blocks, tool invocations, and tool results into chat response parts
176- Matches subagent sessions to their spawning Agent/Task tool_use blocks using `ISubagentSession.parentToolUseId`, injecting the subagent's tool calls inline under the parent tool invocation
177 
178## Message Flow
179 
1801. **User sends message** in VS Code Chat
1812. **ClaudeAgentManager** receives the request and routes to existing or new session
1823. **ClaudeCodeSession** queues the request and feeds the prompt to Claude Code SDK
1834. **Claude Code SDK** returns streaming messages:
184 - Text content → rendered as markdown in chat
185 - Tool use requests → shown as progress, then confirmed via VS Code's confirmation API
186 - Tool results → formatted and displayed in chat
1875. **Result message** signals turn completion, request is resolved
188 
189## Tool Confirmation
190 
191Claude Code tools require user confirmation before execution:
192- **Auto-approved**: File edits (Edit, Write, MultiEdit) are auto-approved if the file is within the workspace
193- **Manual confirmation**: All other tools show a confirmation dialog via `CoreConfirmationTool`
194- **Denied tools**: User denial sends a "user declined" message back to Claude Code
195 
196## Session Persistence
197 
198Claude Code sessions are persisted to `~/.claude/projects/<workspace-slug>/` as `.jsonl` files. The `ClaudeCodeSessionService` can:
199- Load all sessions for the current workspace
200- Resume a previous session by ID
201- Cache sessions with mtime-based invalidation
202 
203## Folder and Working Directory Management
204 
205The integration deterministically resolves the working directory (`cwd`) and additional directories for each Claude session, rather than inheriting from `process.cwd()`. This is managed by the `ClaudeChatSessionContentProvider` and exposed through the `ClaudeFolderInfo` interface.
206 
207### `ClaudeFolderInfo` (`common/claudeFolderInfo.ts`)
208 
209```typescript
210interface ClaudeFolderInfo {
211 readonly cwd: string; // Primary working directory
212 readonly additionalDirectories: string[]; // Extra directories Claude can access
213}
214```
215 
216### Folder Resolution by Workspace Type
217 
218| Workspace Type | cwd | additionalDirectories | Folder Picker |
219|---|---|---|---|
220| **Single-root** (1 folder) | That folder | `[]` | Hidden |
221| **Multi-root** (2+ folders) | Selected folder (default: first) | All other workspace folders | Shown with workspace folders |
222| **Empty** (0 folders) | Selected MRU folder | `[]` | Shown with MRU entries |
223 
224### Data Flow
225 
2261. **`ClaudeChatSessionItemController`** resolves `ClaudeFolderInfo` via `getFolderInfoForSession(sessionId)`
2272. The folder info is passed through `ClaudeAgentManager.handleRequest()` to `ClaudeCodeSession`
2283. `ClaudeCodeSession._startSession()` uses `folderInfo.cwd` and `folderInfo.additionalDirectories` when building SDK `Options`
229 
230### Folder Picker UI
231 
232In multi-root and empty workspaces, a folder picker option appears in the chat session options:
233- **Multi-root**: Lists all workspace folders; selecting one makes it `cwd`, the rest become `additionalDirectories`
234- **Empty workspace**: Lists MRU folders from `IFolderRepositoryManager` (max 10 entries)
235- The folder option is **locked** for existing (non-untitled) sessions to prevent cwd changes mid-conversation
236 
237### Session Discovery Across Folders
238 
239`ClaudeCodeSessionService._getProjectSlugs()` generates workspace slugs for **all** workspace folders, enabling session discovery across all project directories in multi-root workspaces. For empty workspaces, it generates slugs for all folders known to `IFolderRepositoryManager` (MRU entries).
240 
241### Key Files
242 
243- **`common/claudeFolderInfo.ts`**: `ClaudeFolderInfo` interface
244- **`../../chatSessions/common/claudeWorkspaceFolderService.ts`**: `IClaudeWorkspaceFolderService` interface — computes git diff changes for session items
245- **`../../chatSessions/vscode-node/claudeWorkspaceFolderServiceImpl.ts`**: Implementation — diffs the session's branch against its base branch, caches results, and maps changes to `ChatSessionChangedFile[]` for display in the Sessions view
246- **`../../chatSessions/vscode-node/claudeChatSessionContentProvider.ts`**: Folder resolution, picker options, session metadata enrichment, and git command handlers
247- **`../../chatSessions/common/builtinSlashCommands.ts`**: Shared constants for built-in slash commands (`/commit`, `/sync`, `/merge`, etc.) used by both Claude and CopilotCLI sessions
248- **`../../chatSessions/vscode-node/folderRepositoryManagerImpl.ts`**: `FolderRepositoryManager` (abstract base) with `ClaudeFolderRepositoryManager` subclass — the Claude subclass does not depend on `ICopilotCLISessionService` (CopilotCLI has its own subclass `CopilotCLIFolderRepositoryManager`)
249- **`node/claudeCodeAgent.ts`**: Consumes `ClaudeFolderInfo` in `ClaudeCodeSession._startSession()`
250- **`node/sessionParser/claudeCodeSessionService.ts`**: `_getProjectSlugs()` generates slugs for all folders
251 
252## Input State Reactive Pipeline
253 
254The chat session input controls (permission mode picker, folder picker) are driven by a reactive observable pipeline, not by imperative setter calls. Understanding this pipeline is important when modifying input state behavior.
255 
256### Overview
257 
258VS Code calls `getChatSessionInputState` to get a `ChatSessionInputState` object whose `.groups` array drives the UI. Rather than computing groups once and returning them, the pipeline keeps `groups` live: shared observables push changes into each state object whenever relevant configuration changes.
259 
260### Key Types
261 
262```
263InputStateReactivePipeline {
264 permissionMode: ISettableObservable<PermissionMode>
265 folderUri: ISettableObservable<URI | undefined>
266 folderItems: ISettableObservable<readonly vscode.ChatSessionProviderOptionItem[]>
267 isSessionStarted: ISettableObservable<boolean>
268 store: DisposableStore // owns all autoruns for this pipeline
269}
270```
271 
272### Seeding: Extracting Initial Values
273 
274Before attaching any autoruns, `_createInputStateReactivePipeline` calls `_computeSeedValues(state.groups)` to extract the current groups into typed values. This must happen *before* the first autorun runs, because the first autorun pass immediately reads `allGroups` and writes to `state.groups` — if the per-state observables were left at defaults, that write would discard the carefully-constructed initial groups.
275 
276`_computeSeedValues` extracts four values:
277 
278| Value | Source | Fallback |
279|---|---|---|
280| `permissionMode` | Selected item id in the `permissionMode` group | `lastUsedPermissionMode` |
281| `folderUri` | Selected item id in the `folder` group | `undefined` |
282| `folderItems` | Full item list of the `folder` group | `[]` |
283| `isSessionStarted` | `locked: true` on any folder item or the selected item | `false` |
284 
285The `isSessionStarted` recovery from `locked` items is important for the `previousInputState` path: the previous state's groups encode the lock signal via `locked: true` on their items. If `_computeSeedValues` did not recover this, the pipeline would start with `isSessionStarted = false` and the `folderGroup` derived would re-render all items as unlocked.
286 
287### Shared vs. Per-State Observables
288 
289`ClaudeChatSessionItemController` holds two **shared** observables (one instance per controller, not per session):
290 
291| Observable | Source | Purpose |
292|---|---|---|
293| `_bypassPermissionsEnabled` | `IConfigurationService` event | Controls which permission mode items are available |
294| `_workspaceFolders` | `IWorkspaceService` event | Controls folder picker items and visibility |
295 
296Each call to `getChatSessionInputState` creates a **per-state** pipeline with `_createInputStateReactivePipeline(state)`. The per-state observables are seeded via `_computeSeedValues`.
297 
298`folderItems` is a settable per-state observable (not a pure `derived`) because of an async edge case: when the workspace has no folders, the items come from an async MRU fetch (`IFolderRepositoryManager`). An autorun watches `_workspaceFolders` and updates `folderItems` synchronously when folders exist, or kicks off the async MRU fetch when the workspace is empty.
299 
300### Derived Computation and Autorun
301 
302Inside `_createInputStateReactivePipeline`, `derived` observables combine shared and per-state inputs:
303 
304```
305permissionModeGroup = derived(bypassEnabled, permissionMode)
306folderGroup = derived(folderItems, workspaceFolders, folderUri, isSessionStarted)
307allGroups = derived(permissionModeGroup, folderGroup)
308```
309 
310An `autorun` reads `allGroups` and writes to `state.groups`. This is the only place `state.groups` is written — the pipeline is the single source of truth for the UI.
311 
312### Lifetime Management (onDidDispose)
313 
314Each pipeline's `store` is disposed via `state.onDidDispose`:
315 
316```typescript
317pipeline.store.add(state.onDidDispose(() => pipeline.store.dispose()));
318```
319 
320When VS Code discards a `ChatSessionInputState`, the `onDidDispose` event fires and deterministically cleans up all autoruns for that state. The `onDidDispose` subscription is itself registered on the pipeline store, so it is cleaned up as part of disposal.
321 
322### External Permission Mode Updates
323 
324When Claude executes `EnterPlanMode` or `ExitPlanMode` tools, `claudeMessageDispatch.ts` calls `IClaudeSessionStateService.setPermissionModeForSession()`, which fires `onDidChangeSessionState`. The pipeline subscribes to this event via a second autorun:
325 
326```typescript
327const externalPermissionMode = observableFromEvent(
328 this,
329 Event.filter(sessionStateService.onDidChangeSessionState,
330 e => e.sessionId === sessionId && e.permissionMode !== undefined),
331 () => sessionStateService.getPermissionModeForSession(sessionId),
332);
333pipeline.store.add(autorun(reader => {
334 pipeline.permissionMode.set(externalPermissionMode.read(reader), undefined);
335}));
336```
337 
338This autorun is registered on `pipeline.store`, so it is disposed along with all other pipeline autoruns when the state is disposed.
339 
340### Session-Started Signal
341 
342The `isSessionStarted` observable controls whether folder items carry `locked: true`. It is set to `true` when `getChatSessionInputState` is called with a `sessionResource` — i.e., whenever VS Code provides a resource for the session. This covers both existing on-disk sessions and sessions that have been started (where a resource has been assigned).
343 
344For the `previousInputState` path, the lock state is recovered from the items themselves: `_computeSeedValues` checks for `locked: true` on folder items and restores `isSessionStarted` accordingly.
345 
346### Critical Invariant: Subscribe After Both Branches
347 
348`_setupInputState` creates `state` and `pipeline` in one of two branches:
349- **`context.previousInputState` path** — VS Code already has a state for this session and is asking for a fresh one; seed from the old groups.
350- **New-state path** — first call for this session; fetch groups from disk or defaults.
351 
352**The external permission mode subscription must run after both branches.** If it only runs in the new-state path, permission mode changes from `EnterPlanMode`/`ExitPlanMode` are silently dropped for every session after the first `getChatSessionInputState` call. Guard against this regression by ensuring the subscription is placed outside the `if/else` block.
353 
354## Session Metadata and Git Commands
355 
356### Session Metadata Enrichment
357 
358Each Claude session item carries metadata that drives the Sessions view UI (button visibility, status indicators). The `ClaudeChatSessionItemController._buildSessionMetadata()` method enriches session items with git repository state.
359 
360**Workspace Trust:** Session metadata and git change detection are gated on workspace trust via `IWorkspaceService.isResourceTrusted()`. For untrusted working directories, `_buildSessionMetadata()` returns only the `workingDirectoryPath` (no git data), and `getWorkspaceChanges()` is skipped entirely. The trust check is resolved once in `_createClaudeChatSessionItem` and passed into `_buildSessionMetadata` to avoid redundant calls. When trusted, the metadata fetch and workspace changes fetch run concurrently via `Promise.all`.
361 
362| Field | Type | Description |
363|-------|------|-------------|
364| `workingDirectoryPath` | `string` | Session's working directory (always present) |
365| `repositoryPath` | `string?` | Git repository root path |
366| `branchName` | `string?` | Current HEAD branch name |
367| `upstreamBranchName` | `string?` | Upstream tracking ref (e.g., `origin/main`) |
368| `hasGitHubRemote` | `boolean?` | Whether any remote points to GitHub |
369| `incomingChanges` | `number?` | Commits behind upstream |
370| `outgoingChanges` | `number?` | Commits ahead of upstream |
371| `uncommittedChanges` | `number?` | Total uncommitted changes (merge + index + working tree + untracked) |
372 
373These metadata fields map to `when`-clause context keys in `package.json` (e.g., `sessions.hasGitRepository`, `sessions.hasUncommittedChanges`, `sessions.hasUpstream`) that control which action buttons appear in the Changes view.
374 
375### Git Action Commands
376 
377The `ClaudeChatSessionItemController` registers four git-related commands that appear as action buttons in the Sessions/Changes view:
378 
379| Command | When Visible | Action |
380|---------|-------------|--------|
381| `github.copilot.claude.sessions.commit` | Has git repo + uncommitted changes | Sends `/commit` prompt to the session |
382| `github.copilot.claude.sessions.commitAndSync` | Has git repo + uncommitted changes + upstream | Sends `/commit and /sync` prompt |
383| `github.copilot.claude.sessions.sync` | Has git repo + no uncommitted changes + upstream | Sends `/sync` prompt |
384| `github.copilot.claude.sessions.initializeRepository` | No git repo | Calls `IGitService.initRepository()` on the session's workspace folder |
385 
386The commit, commitAndSync, and sync commands use a shared `_registerPromptCommand()` helper that extracts the session resource and dispatches via `workbench.action.chat.openSessionWithPrompt.claude-code`. The slash command strings come from the shared `builtinSlashCommands` module (`../../common/builtinSlashCommands.ts`).
387 
388## Testing
389 
390Unit tests are located in `node/test/`:
391- `claudeCodeAgent.spec.ts`: Tests for agent and session logic
392- `claudeCodeSessionService.spec.ts`: Tests for session loading and persistence
393- `claudePluginService.spec.ts`: Tests for plugin location resolution
394- `mockClaudeCodeSdkService.ts`: Mock SDK service for testing
395- `fixtures/`: Sample `.jsonl` session files for testing
396 
397Additional tests for the session item controller and content provider:
398- `../../chatSessions/vscode-node/test/claudeChatSessionContentProvider.spec.ts`: Tests for session metadata enrichment, git command handlers, session lifecycle, and content provider behavior
399 
400## Extension Registries
401 
402The Claude integration uses several registries to organize and manage extensibility points:
403 
404### Hook Registry
405 
406**Location:** `node/hooks/claudeHookRegistry.ts`
407 
408The hook registry allows registering custom hooks that execute at key points in the agent lifecycle. Hooks are organized by `HookEvent` type from the Claude SDK.
409 
410**Key Features:**
411- Register handlers using `registerClaudeHook(hookEvent, ctor)`
412- Handlers are constructed via dependency injection using `IInstantiationService`
413- Hook instances are built from the registry and passed to the Claude SDK
414- Multiple handlers can be registered for the same event
415 
416**Example Hook Events:**
417- `'PreToolUse'` - Before a tool is executed
418- `'PostToolUse'` - After a tool completes
419- `'SubagentStart'` - When a subagent starts
420- `'SubagentEnd'` - When a subagent completes
421- `'SessionStart'` - When a session begins
422- `'SessionEnd'` - When a session ends
423 
424**Current Hook Handlers:**
425- `loggingHooks.ts` - Logging hooks for debugging and telemetry
426- `sessionHooks.ts` - Session lifecycle management
427- `subagentHooks.ts` - Subagent lifecycle tracking
428- `toolHooks.ts` - Tool execution tracking and processing
429 
430### Slash Command Registry
431 
432**Location:** `vscode-node/slashCommands/claudeSlashCommandRegistry.ts`
433 
434The slash command registry manages custom slash commands available in Claude chat sessions. Commands allow users to trigger specific functionality via `/commandname` syntax.
435 
436**Key Features:**
437- Register handlers using `registerClaudeSlashCommand(handler)`
438- Each handler implements `IClaudeSlashCommandHandler` interface
439- Commands can optionally register with VS Code Command Palette
440- Handlers receive arguments, response stream, and cancellation token
441 
442**Handler Interface:**
443```typescript
444interface IClaudeSlashCommandHandler {
445 readonly commandName: string; // Command name (without /)
446 readonly description: string; // Human-readable description
447 readonly commandId?: string; // Optional VS Code command ID
448 handle(args: string, stream: ChatResponseStream | undefined, token: CancellationToken): Promise<ChatResult | void>;
449}
450```
451 
452**UI Patterns for Slash Commands:**
453 
454Slash commands often need to present choices or gather input from users. When doing so, prefer the simpler one-shot APIs over the more complex builder APIs:
455 
456- **Prefer:** `vscode.window.showQuickPick()` - Simple function call that returns the selected item(s)
457- **Avoid:** `vscode.window.createQuickPick()` - More complex, requires manual lifecycle management
458 
459- **Prefer:** `vscode.window.showInputBox()` - Simple function call that returns the entered text
460- **Avoid:** `vscode.window.createInputBox()` - More complex, requires manual lifecycle management
461 
462The `show*` APIs are sufficient for most slash command use cases and result in cleaner, more maintainable code. Only use `create*` APIs when you need advanced features like dynamic item updates, multi-step wizards, or custom event handling.
463 
464**Current Slash Commands:**
465- `/hooks` - Configure Claude Agent hooks for tool execution and events (from `hooksCommand.ts`)
466- `/memory` - Open memory files (CLAUDE.md) for editing (from `memoryCommand.ts`)
467- `/agents` - Create and manage specialized Claude agents (from `agentsCommand.ts`)
468- `/terminal` - Create a terminal with Claude CLI configured to use Copilot Chat endpoints (from `terminalCommand.ts`) _Temporarily disabled pending legal review_
469 
470### Tool Permission Handlers
471 
472**Location:** `node/toolPermissionHandlers/` and `common/toolPermissionHandlers/`
473 
474Tool permission handlers control what actions Claude can take without user confirmation. They define the approval logic for various tool operations.
475 
476**Key Features:**
477- Auto-approve safe operations (e.g., file edits within workspace)
478- Request user confirmation for potentially dangerous operations
479- Handlers are organized by platform (common, node, vscode-node)
480 
481**Handler Types:**
482- **Common handlers** (`common/toolPermissionHandlers/`):
483 - `bashToolHandler.ts` - Controls bash/shell command execution
484 - `exitPlanModeHandler.ts` - Manages plan mode transitions
485 - `askUserQuestionHandler.ts` - Delegates to the core `vscode_askQuestions` tool for question carousel UI
486 
487- **Node handlers** (`node/toolPermissionHandlers/`):
488 - `editToolHandler.ts` - Handles file edit operations (Edit, Write, MultiEdit)
489 
490**Auto-approval Rules:**
491- File edits are auto-approved if the file is within the workspace
492- All other tools show a confirmation dialog via VS Code's chat API
493- User denials send appropriate messages back to Claude
494 
495### MCP Server Registry
496 
497**Location:** `common/claudeMcpServerRegistry.ts`
498 
499The MCP server registry allows contributing MCP (Model Context Protocol) server configurations to the Claude SDK Options. Contributors provide server configurations that are merged and passed to the SDK at session start.
500 
501**Key Features:**
502- Register contributors using `registerClaudeMcpServerContributor(ctor)`
503- Contributors are constructed via dependency injection using `IInstantiationService`
504- Contributors implement `IClaudeMcpServerContributor` with an async `getMcpServers()` method
505- Server configurations are merged into a single `Record<string, McpServerConfig>` for the SDK
506 
507**Contributor Interface:**
508```typescript
509interface IClaudeMcpServerContributor {
510 getMcpServers(): Promise<Record<string, McpServerConfig>>;
511}
512```
513 
514**Supported Server Types:**
515- `McpStdioServerConfig` - Standard input/output process transport (`{ command, args?, env? }`)
516- `McpSSEServerConfig` - Server-Sent Events (`{ type: 'sse', url, headers? }`)
517- `McpHttpServerConfig` - HTTP transport (`{ type: 'http', url, headers? }`)
518- `McpSdkServerConfigWithInstance` - In-process SDK servers
519 
520**Index Chain:**
521- `common/mcpServers/index.ts` → Platform-agnostic contributors
522- `node/mcpServers/index.ts` → Node-specific contributors (imports common first)
523- `vscode-node/mcpServers/index.ts` → VS Code-specific contributors (imports node first)
524 
525**Extending the Registries:**
526 
527To add new functionality:
528 
5291. **New Hook Handler:**
530 - Create a class implementing `HookCallbackMatcher`
531 - Call `registerClaudeHook(hookEvent, YourHandler)` at module load time
532 - Import your handler module in `node/hooks/index.ts`
533 
5342. **New Slash Command:**
535 - Create a class implementing `IClaudeSlashCommandHandler`
536 - Call `registerClaudeSlashCommand(YourHandler)` at module load time
537 - Import your command module in `vscode-node/slashCommands/index.ts`
538 - If providing a `commandId`, register the command in `package.json`:
539```json
540 {
541 "command": "copilot.claude.yourCommand",
542 "title": "Your Command Title",
543 "category": "Claude Agent"
544 }
545```
546 
5473. **New Tool Permission Handler:**
548 - Create handler in appropriate directory (common/node/vscode-node)
549 - Implement tool approval logic
550 - Import your handler module in `index.ts` to trigger registration
551 
5524. **New MCP Server Contributor:**
553 - Create a class implementing `IClaudeMcpServerContributor`
554 - Call `registerClaudeMcpServerContributor(YourContributor)` at module load time
555 - Import your contributor module in the appropriate `mcpServers/index.ts` (common/node/vscode-node)
556 
557## Configuration
558 
559The integration respects VS Code settings:
560- `github.copilot.advanced.claudeCodeDebugEnabled`: Enables debug logging from Claude Code SDK
561 
562## Upgrading Anthropic SDK Packages
563 
564For the complete upgrade process, use the **anthropic-sdk-upgrader** Claude Code agent. The agent provides step-by-step guidance for upgrading `@anthropic-ai/claude-agent-sdk` and `@anthropic-ai/sdk` packages, including:
565 
566- Checking changelogs and summarizing changes
567- Categorizing changes by impact level
568- Fixing compilation errors in key files
569- Complete testing checklist
570- Troubleshooting common issues
571 
572See `.claude/agents/anthropic-sdk-upgrader.md` for the full process.
573 
574## Dependencies
575 
576- `@anthropic-ai/claude-agent-sdk`: Official Claude Code SDK
577- `@anthropic-ai/sdk`: Anthropic API types
578- Internal services: `ILogService`, `IConfigurationService`, `IWorkspaceService`, `IToolsService`, etc.
579 

Commands it names

  • node/claudeCodeAgent.ts
  • node/claudeCodeSdkService.ts
  • node/sessionParser/claudeCodeSessionService.ts
  • node/sessionParser/README.md
  • node/sessionParser/sdkSessionAdapter.ts
  • node/claudeSkills.ts
  • node/test/
  • node/hooks/claudeHookRegistry.ts
  • node/toolPermissionHandlers/
  • node/mcpServers/index.ts
  • node/hooks/index.ts

Sections

  • Claude Code Integration
  • Official Claude Agent SDK Documentation
  • Core SDK Features
  • Overview
  • Architecture
  • Key Components
  • `node/claudeCodeAgent.ts`
  • `node/claudeCodeSdkService.ts`
  • `node/sessionParser/claudeCodeSessionService.ts`
  • `node/sessionParser/sdkSessionAdapter.ts`
  • `node/claudeSkills.ts`
  • `common/claudeTools.ts`
  • `common/toolInvocationFormatter.ts`
  • `../../chatSessions/vscode-node/chatHistoryBuilder.ts`
  • Message Flow
  • Tool Confirmation
  • Session Persistence
  • Folder and Working Directory Management
  • `ClaudeFolderInfo` (`common/claudeFolderInfo.ts`)
  • Folder Resolution by Workspace Type
  • Data Flow
  • Folder Picker UI
  • Session Discovery Across Folders
  • Key Files
  • Input State Reactive Pipeline
  • Overview
  • Key Types
  • Seeding: Extracting Initial Values
  • Shared vs. Per-State Observables
  • Derived Computation and Autorun
  • Lifetime Management (onDidDispose)
  • External Permission Mode Updates
  • Session-Started Signal
  • Critical Invariant: Subscribe After Both Branches
  • Session Metadata and Git Commands
  • Session Metadata Enrichment
  • Git Action Commands
  • Testing
  • Extension Registries
  • Hook Registry
  • Slash Command Registry
  • Tool Permission Handlers
  • MCP Server Registry
  • Configuration
  • Upgrading Anthropic SDK Packages
  • Dependencies

What it covers

testcode-stylearchitecturetypestesting-strategygit-prdependenciesuideploymentmonorepoagent-behaviourdocs

Stack — with the evidence

typescript

(1.00)

node

(1.00)

javascript

(0.60)

eslint

(0.60)

github-actions

(0.60)

Format

AGENTS.md

A plain-markdown README for coding agents, deliberately unopinionated: no frontmatter, no globs, no vendor keys. That minimalism is why it became the one file a dozen different agents will read, and why it carries the least per-file targeting power of any format here.

What the corpus says about it

Repository

Owner
microsoft
Language
—
License
—
Archived
no

All configs in this repo

Also in microsoft/vscode

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
microsoft/vscode.github/instructions/accessibility.instructions.md · 188kCopilot instructionstypescriptnode+3styledo-not61/1003 days ago
microsoft/vscode.github/instructions/chat.instructions.md · 188kCopilot instructionstypescriptnode+3no sections39/1003 days ago
microsoft/vscodeextensions/copilot/src/platform/authentication/common/AGENTS.md · 188kAGENTS.mdtypescriptnode+3archsecurityagent-behaviour58/1003 days ago
microsoft/vscode.github/copilot-instructions.md · 188kCopilot instructionstypescriptnode+3stylearchtypesui+274/1002 days ago
microsoft/vscode.github/instructions/agentHostTesting.instructions.md · 188kCopilot instructionstypescriptnode+3teststyletesting-strategyagent-behaviour55/1003 days ago
microsoft/vscode.github/instructions/ai-customization.instructions.md · 188kCopilot instructionstypescriptnode+3archtypesui58/1003 days ago
microsoft/vscode.github/instructions/best-practices.instructions.md · 188kCopilot instructionstypescriptnode+3styleui60/1003 days ago
microsoft/vscode.github/instructions/buildNext.instructions.md · 188kCopilot instructionstypescriptnode+3setupbuildtestarch+166/1003 days ago
microsoft/vscode.github/instructions/coding-guidelines.instructions.md · 188kCopilot instructionstypescriptnode+3styletypesuidocs60/1003 days ago
microsoft/vscode.github/instructions/committing.instructions.md · 188kCopilot instructionstypescriptnode+3do-not23/1003 days ago
microsoft/vscode.github/instructions/css-best-practices.instructions.md · 188kCopilot instructionstypescriptnode+3styleui29/1003 days ago
microsoft/vscode.github/instructions/design-philosophy.instructions.md · 188kCopilot instructionstypescriptnode+3style34/1003 days ago
microsoft/vscode.github/instructions/design-tokens.instructions.md · 188kCopilot instructionstypescriptnode+3styledo-not65/1003 days ago
microsoft/vscode.github/instructions/disposable.instructions.md · 188kCopilot instructionstypescriptnode+3no sections16/1003 days ago
microsoft/vscode.github/instructions/interactive.instructions.md · 188kCopilot instructionstypescriptnode+3ui43/1003 days ago
microsoft/vscode.github/instructions/kusto.instructions.md · 188kCopilot instructionstypescriptnode+3agent-behaviour16/1003 days ago
microsoft/vscode.github/instructions/learnings.instructions.md · 188kCopilot instructionstypescriptnode+3style40/1003 days ago
microsoft/vscode.github/instructions/notebook.instructions.md · 188kCopilot instructionstypescriptnode+3no sections48/1003 days ago
microsoft/vscode.github/instructions/observables.instructions.md · 188kCopilot instructionstypescriptnode+3no sections40/1003 days ago
microsoft/vscode.github/instructions/oss-third-party-notices.instructions.md · 188kCopilot instructionstypescriptnode+3buildgitdependenciesdeployment+165/1003 days ago
Diff against .github/instructions/accessibility.instructions.md Diff against .github/instructions/chat.instructions.md Diff against extensions/copilot/src/platform/authentication/common/AGENTS.md Diff against .github/copilot-instructions.md Diff against .github/instructions/agentHostTesting.instructions.md Diff against .github/instructions/ai-customization.instructions.md Diff against .github/instructions/best-practices.instructions.md Diff against .github/instructions/buildNext.instructions.md Diff against .github/instructions/coding-guidelines.instructions.md Diff against .github/instructions/committing.instructions.md Diff against .github/instructions/css-best-practices.instructions.md Diff against .github/instructions/design-philosophy.instructions.md Diff against .github/instructions/design-tokens.instructions.md Diff against .github/instructions/disposable.instructions.md Diff against .github/instructions/interactive.instructions.md Diff against .github/instructions/kusto.instructions.md Diff against .github/instructions/learnings.instructions.md Diff against .github/instructions/notebook.instructions.md Diff against .github/instructions/observables.instructions.md Diff against .github/instructions/oss-third-party-notices.instructions.md

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199kAGENTS.mdtypescriptlangchain+16buildteststylearch+3100/1003 days ago
aaif-goose/gooseAGENTS.md · 52kAGENTS.mdrusttypescript+2setupbuildtestlint-format+6100/1003 days ago
wpscanteam/wpscanAGENTS.md · 9.7kAGENTS.mdrubyvue+3setupbuildteststyle+6100/1002 days ago
mui/material-uiAGENTS.md · 99kAGENTS.mdtypescriptjavascript+13setupbuildtestlint-format+9100/1003 days ago
SkeneTechnologies/skene-cookbookAGENTS.md · 51AGENTS.mdpythoneslint+4setupbuildtestlint-format+7100/1002 days ago
duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70AGENTS.mdtypescriptjavascript+5buildteststylearch+3100/1003 days ago
trick77/agents-md-syncAGENTS.md · 2AGENTS.mdtypescriptnode+4setupbuildteststyle+5100/1003 days ago
TryGhost/Ghoste2e/AGENTS.md · 55kAGENTS.mdtypescriptjavascript+12setupteststylearch+2100/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack