RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/cline-cline-clinerules-general ↔ cline-cline-clinerules-cline-overview

Comparison

A · Cline rules · cline/clineB · Cline rules · cline/cline
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections09370%
Commands0810%
Section tags15213%

What each file covers

Sections

0 shared · 9 only in A · 37 only in B
  • − Miscellaneous
  • − Searching the Codebase — Avoiding Build Output
  • − How to skip build output
  • − When you must search minified files
  • − gRPC/Protobuf Communication
  • − Adding New Global State Keys
  • − StateManager Cache vs Direct globalState Access
  • − ChatRow Cancelled/Interrupted States
  • − Debug Harness: clear inherited VSCode/Electron env vars before launching
  • + Cline Extension Architecture & Development Guide
  • + Project Overview
  • + Architecture Overview
  • + Definitions
  • + Core Extension Architecture
  • + WebviewProvider Implementation
  • + Core Extension State
  • + Webview State
  • + API Provider System
  • + API Provider Architecture
  • + API Configuration Management
  • + Plan/Act Mode API Configuration
  • + Task Execution System
  • + Task Execution Loop
  • + Message Streaming System
  • + Tool Execution Flow
  • + Error Handling & Recovery
  • + API Request & Token Management
  • + Context Management System
  • + Task State & Resumption
  • + Plan/Act Mode System
  • + Mode Architecture
  • + Mode Switching Process
  • + Plan Mode
  • + Act Mode
  • + Data Flow & State Management
  • + Core Extension Role
  • + Terminal Management
  • + Browser Session Management
  • + MCP (Model Context Protocol) Integration
  • + MCP Architecture
  • + MCP Server Types
  • + MCP Server Management
  • + MCP Tool Integration
  • + MCP Marketplace
  • + Conclusion
  • + Contributing

Commands

0 shared · 8 only in A · 1 only in B
  • − bun src/dev/debug-harness/server.ts --auto-launch --skip-build
  • − bun run X
  • − bun install
  • − bunx <bin>
  • − bun file.ts
  • − bun run compile
  • − bun run build
  • − bun run protos
  • + task: taskMessage.text,

Section tags

1 shared · 5 only in A · 2 only in B
  • − setup
  • − build
  • − code-style
  • − security
  • − deployment
  • + types
  • + api
  •   architecture

Line diff

+712 added−153 removed53 unchanged6.9% identical
cline/cline · .clinerules/general.md
@@ −1 @@
1This file is the secret sauce for working effectively in this codebase. It captures tribal knowledge—the nuanced, non-obvious patterns that make the difference between a quick fix and hours of back-and-forth & human intervention.
2 
3**When to add to this file:**
4- User had to intervene, correct, or hand-hold
5- Multiple back-and-forth attempts were needed to get something working
6- You discovered something that required reading many files to understand
7- A change touched files you wouldn't have guessed
8- Something worked differently than you expected
9- User explicitly asks to "add this to CLAUDE.md"
10 
11**Proactively suggest additions** when any of the above happen—don't wait to be asked.
12 
13**What NOT to add:** Stuff you can figure out from reading a few files, obvious patterns, or standard practices. This file should be high-signal, not comprehensive.
14 
15## Miscellaneous
16- The whole repo (including `apps/vscode`) uses **bun** for package management and task running. Emit `bun run X` / `bun install` / `bunx <bin>` / `bun file.ts`, never npm/npx. Node remains the *runtime* (VS Code's extension host and the standalone cline-core are Node), so Node-runtime tokens are legitimate and must not be "fixed" to bun — see @.clinerules/bun-and-node.md for the keep-list vs rewrite-list.
17- Avoid provider-specific string matching / hardcoded provider branches when fixing provider/config plumbing. Prefer provider metadata, shared catalog/defaults, explicit protocol/client capabilities, or centralized normalization utilities that apply by data shape rather than `providerId === "..."`. If a provider exception seems necessary, stop and explain why instead of adding ad-hoc string matching.
18- This is a VS Code extension—check `package.json` for available scripts before trying to verify builds (e.g., `bun run compile`, not `bun run build`).
19- When reading a configuration files that users may edit, use `readFileStrippingUtf8Bom`, `readFileSyncStrippingUtf8Bom`, or `stripUtf8Bom` from `@cline/shared/node`. DON'T strip byte order marks of user files handled by tools/passed to models.
20- When creating PRs, contributors should not create changelog-entry files. Maintainers handle release versioning and changelog curation during the release process.
21- When adding new feature flags, see this PR as a reference https://github.com/cline/cline/pull/7566
22- Additional instructions about making requests: @.clinerules/network.md
 
 
 
 
23 
24## Searching the Codebase — Avoiding Build Output
 
 
 
 
25 
26Several directories contain build output or generated code that produces
27noisy or unusable results with `search_files` / `grep`:
 
 
28 
29| Directory | What it is | Why it's a problem |
30|-----------|-----------|-------------------|
31| `out/` | esbuild bundle output | Mirrors `src/` structure as minified JS — every search gets duplicate hits on single-line files |
32| `dist/` | Packaged extension | Entire extension bundled into one minified `extension.js` (~1 long line) |
33| `dist-standalone/` | Standalone build output | Same minification issue |
34| `src/generated/` | Generated protobuf code | Auto-generated from `proto/`; not the source of truth |
35| `src/shared/proto/` | Generated proto type defs | Auto-generated from `proto/`; not the source of truth |
36| `node_modules/` | Dependencies | Huge, not project source |
37 
38### How to skip build output
 
 
 
39 
40**`search_files`** — Point at `src/` (not the project root) and use `file_pattern`:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41```
42search_files(path="src/core", regex="myFunction", file_pattern="*.ts")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43```
44The `file_pattern` parameter is the most effective filter — e.g. `"*.ts"`,
45`"*.tsx"`, `"*.proto"`.
46 
47**`grep` directly** — Exclude build dirs and restrict to source extensions:
48```bash
49grep -rn "myFunction" src/ --include="*.ts" --exclude-dir={out,dist,node_modules,generated}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50```
51 
52### When you must search minified files
53 
54Sometimes you need to verify what got bundled (e.g., checking if a change
55made it into the build). Minified files are typically one long line, so
56normal `grep` shows the entire file as context. Use these approaches:
57 
58- **`grep -oP`** to extract just the match with limited surrounding context:
59 ```bash
60 grep -oP '.{0,40}myFunction.{0,40}' dist/extension.js
61 ```
62- **`read_file`** on files in `out/src/` — these have source maps and are
63 more readable than `dist/extension.js` (which is the fully bundled output).
64- **Source maps** — `out/src/*.js.map` and `dist/extension.js.map` can be
65 used to trace minified output back to original source locations.
 
 
 
 
 
 
 
66 
67## gRPC/Protobuf Communication
68The extension and webview communicate via gRPC-like protocol over VS Code message passing.
69 
70**Proto files live in `proto/`** (e.g., `proto/cline/task.proto`, `proto/cline/ui.proto`)
71- Each feature domain has its own `.proto` file
72- For simple data, use shared types in `proto/cline/common.proto` (`StringRequest`, `Empty`, `Int64Request`)
73- For complex data, define custom messages in the feature's `.proto` file
74- Naming: Services `PascalCaseService`, RPCs `camelCase`, Messages `PascalCase`
75- For streaming responses, use `stream` keyword (see `subscribeToAuthCallback` in `account.proto`)
76 
77**Run `bun run protos`** after any proto changes—generates types in:
78- `src/shared/proto/` - Shared type definitions
79- `src/generated/grpc-js/` - Service implementations
80- `src/generated/nice-grpc/` - Promise-based clients
81- `src/generated/hosts/` - Generated handlers
82 
83**Adding new enum values** (like a new `ClineSay` type) requires updating conversion mappings in `src/shared/proto-conversions/cline-message.ts`
84 
85**Adding new RPC methods** requires:
86- Handler in `src/core/controller/<domain>/`
87- Call from webview via generated client: `UiServiceClient.scrollToSettings(StringRequest.create({ value: "browser" }))`
88 
89**Example—the `explain-changes` feature touched:**
90- `proto/cline/task.proto` - Added `ExplainChangesRequest` message and `explainChanges` RPC
91- `proto/cline/ui.proto` - Added `GENERATE_EXPLANATION = 29` to `ClineSay` enum
92- `src/shared/ExtensionMessage.ts` - Added `ClineSayGenerateExplanation` type
93- `src/shared/proto-conversions/cline-message.ts` - Added mapping for new say type
94- `src/core/controller/task/explainChanges.ts` - Handler implementation
95- `webview-ui/src/components/chat/ChatRow.tsx` - UI rendering
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96 
97## Adding New Global State Keys
98Adding a new key to global state requires updates in multiple places. Missing any step causes silent failures.
99 
100Required steps:
1011. Type definition in `src/shared/storage/state-keys.ts` - Add to `GlobalState` or `Settings` interface
1022. Add any default value or transform in `src/shared/storage/state-keys.ts` if the key needs one
1033. Read and write the value through `StateManager` (`setGlobalState()` / `getGlobalStateKey()`) after initialization
104 
105Persistent state is file-backed through `StateManager`; do not add new runtime reads or writes against VS Code `ExtensionContext` storage. That storage is only a legacy migration source.
 
 
 
 
106 
107Settings plumbing gotcha: if a key is user-toggleable from settings, wire both controller update paths:
108- `src/core/controller/state/updateSettings.ts` for webview `updateSetting(...)`
109- `src/core/controller/state/updateSettingsCli.ts` for CLI/ACP settings updates
110Missing one path causes a toggle to appear to change in one surface while the backend state stays unchanged.
 
 
 
 
 
 
 
 
 
 
 
111 
112Webview toggle gotcha: settings changes must also round-trip back in state payloads.
113- Add the field to `UpdateSettingsRequest` in `proto/cline/state.proto` (for webview update requests), then run `bun run protos`
114- Include the key in `Controller.getStateToPostToWebview()` (`src/core/controller/index.ts`)
115- Ensure `ExtensionState` and webview defaults include the key (`src/shared/ExtensionMessage.ts`, `webview-ui/src/context/ExtensionStateContext.tsx`)
116If this round-trip wiring is missing, the backend value can update but the toggle in webview appears stuck or reverts.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117 
118## StateManager Cache vs Direct globalState Access
119StateManager uses an in-memory cache populated during `StateManager.initialize()` from file-backed storage. For most state, use `controller.stateManager.setGlobalState()`/`getGlobalStateKey()`.
120 
121Exception: host migration code may read legacy VS Code storage before file-backed storage is initialized.
 
 
 
 
122 
123Example pattern:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124```typescript
125// Writing (normal pattern)
126controller.stateManager.setGlobalState("myKey", value)
 
 
 
127 
128// Reading after initialization
129const value = controller.stateManager.getGlobalStateKey("myKey")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130```
131 
132Use `context.globalState` only in VS Code migration code that copies legacy ExtensionContext values into the shared file-backed stores.
133 
134## ChatRow Cancelled/Interrupted States
135When a ChatRow displays a loading/in-progress state (spinner), you must handle what happens when the task is cancelled. This is non-obvious because cancellation doesn't update the message content—you have to infer it from context.
 
 
 
136 
137**The pattern:**
1381. A message has a `status` field (e.g., `"generating"`, `"complete"`, `"error"`) stored in `message.text` as JSON
1392. When cancelled mid-operation, the status stays `"generating"` forever—no one updates it
1403. To detect cancellation, check TWO conditions:
141 - `!isLast` — if this message is no longer the last message, something else happened after it (interrupted)
142 - `lastModifiedMessage?.ask === "resume_task" || "resume_completed_task"` — task was just cancelled and is waiting to resume
143 
144**Example from `generate_explanation`:**
145```tsx
146const wasCancelled =
147 explanationInfo.status === "generating" &&
148 (!isLast ||
149 lastModifiedMessage?.ask === "resume_task" ||
150 lastModifiedMessage?.ask === "resume_completed_task")
151const isGenerating = explanationInfo.status === "generating" && !wasCancelled
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152```
153 
154**Why both checks?**
155- `!isLast` catches: cancelled → resumed → did other stuff → this old message is stale
156- `lastModifiedMessage?.ask === "resume_task"` catches: just cancelled, hasn't resumed yet, this message is still technically "last"
 
 
 
157 
158**See also:** `BrowserSessionRow.tsx` uses similar pattern with `isLastApiReqInterrupted` and `isLastMessageResume`.
 
 
 
 
159 
160**Backend side:** When streaming is cancelled, clean up properly (close tabs, clear comments, etc.) by checking `taskState.abort` after the streaming function returns.
161 
162## Debug Harness: clear inherited VSCode/Electron env vars before launching
163 
164The debug harness (`apps/vscode/src/dev/debug-harness/server.ts`) launches a child
165VSCode via Playwright's `_electron.launch({ env: { ...process.env, ... } })`. If you
166run the harness from a process that was itself spawned by VSCode (e.g. the Cline
167extension host, an integrated terminal, or an agent running inside VSCode), the
168parent's VSCode/Electron env vars leak into the child and break the launch.
 
 
 
169 
170The fatal one is **`ELECTRON_RUN_AS_NODE=1`**: it makes the child VSCode binary run
171as plain Node, so it rejects every VSCode CLI flag. Symptom:
 
172 
 
 
 
 
 
 
 
 
 
 
173```
174.../Visual Studio Code.app/Contents/MacOS/Code: bad option: --extensionDevelopmentPath=...
175Error: Process failed to launch! (Playwright _electron.launch)
176```
177 
178This is NOT the macOS Playwright flakiness mentioned in the harness README — it's
179env inheritance. Fix: strip the inherited vars before starting the harness:
 
 
 
 
180 
181```bash
182env -u ELECTRON_RUN_AS_NODE -u ELECTRON_NO_ATTACH_CONSOLE \
183 -u VSCODE_CLI -u VSCODE_CODE_CACHE_PATH -u VSCODE_CRASH_REPORTER_PROCESS_TYPE \
184 -u VSCODE_CWD -u VSCODE_ESM_ENTRYPOINT -u VSCODE_HANDLES_UNCAUGHT_ERRORS \
185 -u VSCODE_IPC_HOOK -u VSCODE_NLS_CONFIG -u VSCODE_PID -u VSCODE_L10N_BUNDLE_LOCATION \
186 bun src/dev/debug-harness/server.ts --auto-launch --skip-build
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187```
188 
189Check your own env with `env | grep -iE 'electron|vscode_'` first; `ELECTRON_RUN_AS_NODE=1`
190present means you must scrub before launching.
191 
192Other harness notes confirmed in practice:
193- The extension host is **ESM** (`VSCODE_ESM_ENTRYPOINT`), so `ext.evaluate` has no
194 `require` and module-internal functions aren't reachable as globals. To inspect
195 internal builders (e.g. `buildBedrockProviderConfig`), set a breakpoint with
196 `ext.set_breakpoint` and read locals via `ext.evaluate` with the paused `callFrameId`
197 — don't try to `require()` the bundle.
198- `web.evaluate` wraps the expression as a single returned expression; multi-statement
199 snippets must be an IIFE `(() => { ...; return x; })()`, otherwise you get
200 `SyntaxError: Unexpected token ';'`.
201- Webview settings inputs are `vscode-text-field` web components with debounced React
202 onChange. Setting `.value` + dispatching events via `web.evaluate` is unreliable for
203 some fields; focus the inner shadow `input` then use real keystrokes (`ui.type` +
204 `ui.press Tab`, or click the dropdown option) to make the value persist.
205 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206 
cline/cline · .clinerules/cline-overview.md
@@ +1 @@
1# Cline Extension Architecture & Development Guide
2 
3## Project Overview
 
 
 
 
 
 
4 
5Cline is a VSCode extension that provides AI assistance through a combination of a core extension backend and a React-based webview frontend. The extension is built with TypeScript and follows a modular architecture pattern.
6 
7## Architecture Overview
8 
9```mermaid
10graph TB
11 subgraph VSCodeExtensionHost[VSCode Extension Host]
12 subgraph CoreExtension[Core Extension]
13 ExtensionEntry[Extension Entry<br/>src/extension.ts]
14 WebviewProvider[WebviewProvider<br/>src/core/webview/index.ts]
15 Controller[Controller<br/>src/core/controller/index.ts]
16 Task[Task<br/>src/core/task/index.ts]
17 GlobalState[VSCode Global State]
18 SecretsStorage[VSCode Secrets Storage]
19 McpHub[McpHub<br/>src/services/mcp/McpHub.ts]
20 end
21 
22 subgraph WebviewUI[Webview UI]
23 WebviewApp[React App<br/>webview-ui/src/App.tsx]
24 ExtStateContext[ExtensionStateContext<br/>webview-ui/src/context/ExtensionStateContext.tsx]
25 ReactComponents[React Components]
26 end
27 
28 subgraph Storage
29 TaskStorage[Task Storage<br/>Per-Task Files & History]
30 CheckpointSystem[Git-based Checkpoints]
31 end
32 
33 subgraph apiProviders[API Providers]
34 AnthropicAPI[Anthropic]
35 OpenRouterAPI[OpenRouter]
36 BedrockAPI[AWS Bedrock]
37 OtherAPIs[Other Providers]
38 end
 
 
39 
40 subgraph MCPServers[MCP Servers]
41 ExternalMcpServers[External MCP Servers]
42 end
43 end
44 
45 %% Core Extension Data Flow
46 ExtensionEntry --> WebviewProvider
47 WebviewProvider --> Controller
48 Controller --> Task
49 Controller --> McpHub
50 Task --> GlobalState
51 Task --> SecretsStorage
52 Task --> TaskStorage
53 Task --> CheckpointSystem
54 Task --> |API Requests| apiProviders
55 McpHub --> |Connects to| ExternalMcpServers
56 Task --> |Uses| McpHub
57 
58 %% Webview Data Flow
59 WebviewApp --> ExtStateContext
60 ExtStateContext --> ReactComponents
61 
62 %% Bidirectional Communication
63 WebviewProvider <-->|postMessage| ExtStateContext
64 
65 style GlobalState fill:#f9f,stroke:#333,stroke-width:2px
66 style SecretsStorage fill:#f9f,stroke:#333,stroke-width:2px
67 style ExtStateContext fill:#bbf,stroke:#333,stroke-width:2px
68 style WebviewProvider fill:#bfb,stroke:#333,stroke-width:2px
69 style McpHub fill:#bfb,stroke:#333,stroke-width:2px
70 style apiProviders fill:#fdb,stroke:#333,stroke-width:2px
71```
72 
73## Definitions
74 
75- **Core Extension**: Anything inside the src folder, organized into modular components
76- **Core Extension State**: Managed by the Controller class in src/core/controller/index.ts, which serves as the single source of truth for the extension's state. It manages multiple types of persistent storage (global state, workspace state, and secrets), handles state distribution to both the core extension and webview components, and coordinates state across multiple extension instances. This includes managing API configurations, task history, settings, and MCP configurations.
77- **Webview**: Anything inside the webview-ui. All the react or view's seen by the user and user interaction components
78- **Webview State**: Managed by ExtensionStateContext in webview-ui/src/context/ExtensionStateContext.tsx, which provides React components with access to the extension's state through a context provider pattern. It maintains local state for UI components, handles real-time updates through message events, manages partial message updates, and provides methods for state modifications. The context includes extension version, messages, task history, theme, API configurations, MCP servers, marketplace catalog, and workspace file paths. It synchronizes with the core extension through VSCode's message passing system and provides type-safe access to state through a custom hook (useExtensionState).
79 
80### Core Extension Architecture
81 
82The core extension follows a clear hierarchical structure:
83 
841. **WebviewProvider** (src/core/webview/index.ts): Manages the webview lifecycle and communication
852. **Controller** (src/core/controller/index.ts): Handles webview messages and task management
863. **Task** (src/core/task/index.ts): Executes API requests and tool operations
87 
88This architecture provides clear separation of concerns:
89- WebviewProvider focuses on VSCode webview integration
90- Controller manages state and coordinates tasks
91- Task handles the execution of AI requests and tool operations
92 
93### WebviewProvider Implementation
94 
95The WebviewProvider class in `src/core/webview/index.ts` is responsible for:
96 
97- Managing multiple active instances through a static set (`activeInstances`)
98- Handling webview lifecycle events (creation, visibility changes, disposal)
99- Implementing HTML content generation with proper CSP headers
100- Supporting Hot Module Replacement (HMR) for development
101- Setting up message listeners between the webview and extension
102 
103The WebviewProvider maintains a reference to the Controller and delegates message handling to it. It also handles the creation of both sidebar and tab panel webviews, allowing Cline to be used in different contexts within VSCode.
104 
105### Core Extension State
106 
107The `Controller` class manages multiple types of persistent storage:
108 
109- **Global State:** Stored across all VSCode instances. Used for settings and data that should persist globally.
110- **Workspace State:** Specific to the current workspace. Used for task-specific data and settings.
111- **Secrets:** Secure storage for sensitive information like API keys.
112 
113The `Controller` handles the distribution of state to both the core extension and webview components. It also coordinates state across multiple extension instances, ensuring consistency.
114 
115State synchronization between instances is handled through:
116- File-based storage for task history and conversation data
117- VSCode's global state API for settings and configuration
118- Secrets storage for sensitive information
119- Event listeners for file changes and configuration updates
120 
121The Controller implements methods for:
122- Saving and loading task state
123- Managing API configurations
124- Handling user authentication
125- Coordinating MCP server connections
126- Managing task history and checkpoints
127 
128### Webview State
129 
130The `ExtensionStateContext` in `webview-ui/src/context/ExtensionStateContext.tsx` provides React components with access to the extension's state. It uses a context provider pattern and maintains local state for UI components. The context includes:
131 
132- Extension version
133- Messages
134- Task history
135- Theme
136- API configurations
137- MCP servers
138- Marketplace catalog
139- Workspace file paths
140 
141It synchronizes with the core extension through VSCode's message passing system and provides type-safe access to the state via a custom hook (`useExtensionState`).
142 
143The ExtensionStateContext handles:
144- Real-time updates through message events
145- Partial message updates for streaming content
146- State modifications through setter methods
147- Type-safe access to state through a custom hook
148 
149## API Provider System
150 
151Cline supports multiple AI providers through a modular API provider system. Each provider is implemented as a separate module in the `src/api/providers/` directory and follows a common interface.
152 
153### API Provider Architecture
154 
155The API system consists of:
156 
1571. **API Handlers**: Provider-specific implementations in `src/api/providers/`
1582. **API Transformers**: Stream transformation utilities in `src/api/transform/`
1593. **API Configuration**: User settings for API keys and endpoints
1604. **API Factory**: Builder function to create the appropriate handler
161 
162Key providers include:
163- **Anthropic**: Direct integration with Claude models
164- **OpenRouter**: Meta-provider supporting multiple model providers
165- **AWS Bedrock**: Integration with Amazon's AI services
166- **Gemini**: Google's AI models
167- **Cerebras**: High-performance inference with Llama, Qwen, and DeepSeek models
168- **Ollama**: Local model hosting
169- **LM Studio**: Local model hosting
170- **VSCode LM**: VSCode's built-in language models
171 
172### API Configuration Management
173 
174API configurations are stored securely:
175- API keys are stored in VSCode's secrets storage
176- Model selections and non-sensitive settings are stored in global state
177- The Controller manages switching between providers and updating configurations
178 
179The system supports:
180- Secure storage of API keys
181- Model selection and configuration
182- Automatic retry and error handling
183- Token usage tracking and cost calculation
184- Context window management
185 
186### Plan/Act Mode API Configuration
187 
188Cline supports separate model configurations for Plan and Act modes:
189- Different models can be used for planning vs. execution
190- The system preserves model selections when switching modes
191- The Controller handles the transition between modes and updates the API configuration accordingly
192 
193## Task Execution System
194 
195The Task class is responsible for executing AI requests and tool operations. Each task runs in its own instance of the Task class, ensuring isolation and proper state management.
196 
197### Task Execution Loop
198 
199The core task execution loop follows this pattern:
200 
201```typescript
202class Task {
203 async initiateTaskLoop(userContent: UserContent, isNewTask: boolean) {
204 while (!this.abort) {
205 // 1. Make API request and stream response
206 const stream = this.attemptApiRequest()
207
208 // 2. Parse and present content blocks
209 for await (const chunk of stream) {
210 switch (chunk.type) {
211 case "text":
212 // Parse into content blocks
213 this.assistantMessageContent = parseAssistantMessageV2(chunk.text)
214 // Present blocks to user
215 await this.presentAssistantMessage()
216 break
217 }
218 }
219
220 // 3. Wait for tool execution to complete
221 await pWaitFor(() => this.userMessageContentReady)
222
223 // 4. Continue loop with tool result
224 const recDidEndLoop = await this.recursivelyMakeClineRequests(
225 this.userMessageContent
226 )
227 }
228 }
229}
230```
 
 
231 
232### Message Streaming System
233 
234The streaming system handles real-time updates and partial content:
235 
236```typescript
237class Task {
238 async presentAssistantMessage() {
239 // Handle streaming locks to prevent race conditions
240 if (this.presentAssistantMessageLocked) {
241 this.presentAssistantMessageHasPendingUpdates = true
242 return
243 }
244 this.presentAssistantMessageLocked = true
245 
246 // Present current content block
247 const block = this.assistantMessageContent[this.currentStreamingContentIndex]
248
249 // Handle different types of content
250 switch (block.type) {
251 case "text":
252 await this.say("text", content, undefined, block.partial)
253 break
254 case "tool_use":
255 // Handle tool execution
256 break
257 }
258 
259 // Move to next block if complete
260 if (!block.partial) {
261 this.currentStreamingContentIndex++
262 }
263 }
264}
265```
266 
267### Tool Execution Flow
268 
269Tools follow a strict execution pattern:
 
 
270 
271```typescript
272class Task {
273 async executeToolWithApproval(block: ToolBlock) {
274 // 1. Check auto-approval settings
275 if (this.shouldAutoApproveTool(block.name)) {
276 await this.say("tool", message)
277 this.consecutiveAutoApprovedRequestsCount++
278 } else {
279 // 2. Request user approval
280 const didApprove = await askApproval("tool", message)
281 if (!didApprove) {
282 this.didRejectTool = true
283 return
284 }
285 }
286 
287 // 3. Execute tool
288 const result = await this.executeTool(block)
289 
290 // 4. Save checkpoint
291 await this.saveCheckpoint()
 
 
 
 
292 
293 // 5. Return result to API
294 return result
295 }
296}
297```
298 
299### Error Handling & Recovery
300 
301The system includes robust error handling:
 
 
302 
303```typescript
304class Task {
305 async handleError(action: string, error: Error) {
306 // 1. Check if task was abandoned
307 if (this.abandoned) return
308
309 // 2. Format error message
310 const errorString = `Error ${action}: ${error.message}`
311
312 // 3. Present error to user
313 await this.say("error", errorString)
314
315 // 4. Add error to tool results
316 pushToolResult(formatResponse.toolError(errorString))
317
318 // 5. Cleanup resources
319 await this.diffViewProvider.revertChanges()
320 await this.browserSession.closeBrowser()
321 }
322}
323```
324 
325### API Request & Token Management
 
326 
327The Task class handles API requests with built-in retry, streaming, and token management:
 
 
 
328 
329```typescript
330class Task {
331 async *attemptApiRequest(previousApiReqIndex: number): ApiStream {
332 // 1. Wait for MCP servers to connect
333 await pWaitFor(() => this.controllerRef.deref()?.mcpHub?.isConnecting !== true)
334 
335 // 2. Manage context window
336 const previousRequest = this.clineMessages[previousApiReqIndex]
337 if (previousRequest?.text) {
338 const { tokensIn, tokensOut } = JSON.parse(previousRequest.text || "{}")
339 const totalTokens = (tokensIn || 0) + (tokensOut || 0)
340
341 // Truncate conversation if approaching context limit
342 if (totalTokens >= maxAllowedSize) {
343 this.conversationHistoryDeletedRange = this.contextManager.getNextTruncationRange(
344 this.apiConversationHistory,
345 this.conversationHistoryDeletedRange,
346 totalTokens / 2 > maxAllowedSize ? "quarter" : "half"
347 )
348 }
349 }
350 
351 // 3. Handle streaming with automatic retry
352 try {
353 this.isWaitingForFirstChunk = true
354 const firstChunk = await iterator.next()
355 yield firstChunk.value
356 this.isWaitingForFirstChunk = false
357
358 // Stream remaining chunks
359 yield* iterator
360 } catch (error) {
361 // 4. Error handling with retry
362 if (isOpenRouter && !this.didAutomaticallyRetryFailedApiRequest) {
363 await setTimeoutPromise(1000)
364 this.didAutomaticallyRetryFailedApiRequest = true
365 yield* this.attemptApiRequest(previousApiReqIndex)
366 return
367 }
368
369 // 5. Ask user to retry if automatic retry failed
370 const { response } = await this.ask(
371 "api_req_failed",
372 this.formatErrorWithStatusCode(error)
373 )
374 if (response === "yesButtonClicked") {
375 await this.say("api_req_retried")
376 yield* this.attemptApiRequest(previousApiReqIndex)
377 return
378 }
379 }
380 }
381}
382```
383 
384Key features:
 
385 
3861. **Context Window Management**
387 - Tracks token usage across requests
388 - Automatically truncates conversation when needed
389 - Preserves important context while freeing space
390 - Handles different model context sizes
391 
3922. **Streaming Architecture**
393 - Real-time chunk processing
394 - Partial content handling
395 - Race condition prevention
396 - Error recovery during streaming
397 
3983. **Error Handling**
399 - Automatic retry for transient failures
400 - User-prompted retry for persistent issues
401 - Detailed error reporting
402 - State cleanup on failure
403 
4044. **Token Tracking**
405 - Per-request token counting
406 - Cumulative usage tracking
407 - Cost calculation
408 - Cache hit monitoring
409 
410### Context Management System
411 
412The Context Management System handles conversation history truncation to prevent context window overflow errors. Implemented in the `ContextManager` class, it ensures long-running conversations remain within model context limits while preserving critical context.
413 
414Key features:
415 
4161. **Model-Aware Sizing**: Dynamically adjusts based on different model context windows (64K for DeepSeek, 128K for most models, 200K for Claude).
417 
4182. **Proactive Truncation**: Monitors token usage and preemptively truncates conversations when approaching limits, maintaining buffers of 27K-40K tokens depending on the model.
419 
4203. **Intelligent Preservation**: Always preserves the original task message and maintains the user-assistant conversation structure when truncating.
421 
4224. **Adaptive Strategies**: Uses different truncation strategies based on context pressure - removing half of the conversation for moderate pressure or three-quarters for severe pressure.
423 
4245. **Error Recovery**: Includes specialized detection for context window errors from different providers with automatic retry and more aggressive truncation when needed.
425 
426### Task State & Resumption
427 
428The Task class provides robust task state management and resumption capabilities:
429 
430```typescript
431class Task {
432 async resumeTaskFromHistory() {
433 // 1. Load saved state
434 this.clineMessages = await getSavedClineMessages(this.getContext(), this.taskId)
435 this.apiConversationHistory = await getSavedApiConversationHistory(this.getContext(), this.taskId)
436 
437 // 2. Handle interrupted tool executions
438 const lastMessage = this.apiConversationHistory[this.apiConversationHistory.length - 1]
439 if (lastMessage.role === "assistant") {
440 const toolUseBlocks = content.filter(block => block.type === "tool_use")
441 if (toolUseBlocks.length > 0) {
442 // Add interrupted tool responses
443 const toolResponses = toolUseBlocks.map(block => ({
444 type: "tool_result",
445 tool_use_id: block.id,
446 content: "Task was interrupted before this tool call could be completed."
447 }))
448 modifiedOldUserContent = [...toolResponses]
449 }
450 }
451 
452 // 3. Notify about interruption
453 const agoText = this.getTimeAgoText(lastMessage?.ts)
454 newUserContent.push({
455 type: "text",
456 text: `[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context.`
457 })
458 
459 // 4. Resume task execution
460 await this.initiateTaskLoop(newUserContent, false)
461 }
462 
463 private async saveTaskState() {
464 // Save conversation history
465 await saveApiConversationHistory(this.getContext(), this.taskId, this.apiConversationHistory)
466 await saveClineMessages(this.getContext(), this.taskId, this.clineMessages)
467
468 // Create checkpoint
469 const commitHash = await this.checkpointTracker?.commit()
470
471 // Update task history
472 await this.controllerRef.deref()?.updateTaskHistory({
473 id: this.taskId,
474 ts: lastMessage.ts,
475 task: taskMessage.text,
476 // ... other metadata
477 })
478 }
479}
480```
481 
482Key aspects of task state management:
483 
4841. **Task Persistence**
485 - Each task has a unique ID and dedicated storage directory
486 - Conversation history is saved after each message
487 - File changes are tracked through Git-based checkpoints
488 - Terminal output and browser state are preserved
489 
4902. **State Recovery**
491 - Tasks can be resumed from any point
492 - Interrupted tool executions are handled gracefully
493 - File changes can be restored from checkpoints
494 - Context is preserved across VSCode sessions
 
495 
4963. **Workspace Synchronization**
497 - File changes are tracked through Git
498 - Checkpoints are created after tool executions
499 - State can be restored to any checkpoint
500 - Changes can be compared between checkpoints
501 
5024. **Error Recovery**
503 - Failed API requests can be retried
504 - Interrupted tool executions are marked
505 - Resources are cleaned up properly
506 - User is notified of state changes
507 
508## Plan/Act Mode System
509 
510Cline implements a dual-mode system that separates planning from execution:
511 
512### Mode Architecture
513 
514The Plan/Act mode system consists of:
515 
5161. **Mode State**: Stored in `chatSettings.mode` in the Controller's state
5172. **Mode Switching**: Handled by `togglePlanActModeWithChatSettings` in the Controller
5183. **Mode-specific Models**: Optional configuration to use different models for each mode
5194. **Mode-specific Prompting**: Different system prompts for planning vs. execution
520 
521### Mode Switching Process
522 
523When switching between modes:
524 
5251. The current model configuration is saved to mode-specific state
5262. The previous mode's model configuration is restored
5273. The Task instance is updated with the new mode
5284. The webview is notified of the mode change
5295. Telemetry events are captured for analytics
530 
531### Plan Mode
532 
533Plan mode is designed for:
534- Information gathering and context building
535- Asking clarifying questions
536- Creating detailed execution plans
537- Discussing approaches with the user
538 
539In Plan mode, the AI uses the `plan_mode_respond` tool to engage in conversational planning without executing actions.
540 
541### Act Mode
542 
543Act mode is designed for:
544- Executing the planned actions
545- Using tools to modify files, run commands, etc.
546- Implementing the solution
547- Providing results and completion feedback
548 
549In Act mode, the AI has access to all tools except `plan_mode_respond` and focuses on implementation rather than discussion.
550 
551## Data Flow & State Management
552 
553### Core Extension Role
554 
555The Controller acts as the single source of truth for all persistent state. It:
556- Manages VSCode global state and secrets storage
557- Coordinates state updates between components
558- Ensures state consistency across webview reloads
559- Handles task-specific state persistence
560- Manages checkpoint creation and restoration
561 
562### Terminal Management
563 
564The Task class manages terminal instances and command execution:
565 
566```typescript
567class Task {
568 async executeCommandTool(command: string): Promise<[boolean, ToolResponse]> {
569 // 1. Get or create terminal
570 const terminalInfo = await this.terminalManager.getOrCreateTerminal(cwd)
571 terminalInfo.terminal.show()
572 
573 // 2. Execute command with output streaming
574 const process = this.terminalManager.runCommand(terminalInfo, command)
575
576 // 3. Handle real-time output
577 let result = ""
578 process.on("line", (line) => {
579 result += line + "\n"
580 if (!didContinue) {
581 sendCommandOutput(line)
582 } else {
583 this.say("command_output", line)
584 }
585 })
586 
587 // 4. Wait for completion or user feedback
588 let completed = false
589 process.once("completed", () => {
590 completed = true
591 })
592 
593 await process
594 
595 // 5. Return result
596 if (completed) {
597 return [false, `Command executed.\n${result}`]
598 } else {
599 return [
600 false,
601 `Command is still running in the user's terminal.\n${result}\n\nYou will be updated on the terminal status and new output in the future.`
602 ]
603 }
604 }
605}
606```
607 
608Key features:
6091. **Terminal Instance Management**
610 - Multiple terminal support
611 - Terminal state tracking (busy/inactive)
612 - Process cooldown monitoring
613 - Output history per terminal
614 
6152. **Command Execution**
616 - Real-time output streaming
617 - User feedback handling
618 - Process state monitoring
619 - Error recovery
620 
621### Browser Session Management
622 
623The Task class handles browser automation through Puppeteer:
624 
625```typescript
626class Task {
627 async executeBrowserAction(action: BrowserAction): Promise<BrowserActionResult> {
628 switch (action) {
629 case "launch":
630 // 1. Launch browser with fixed resolution
631 await this.browserSession.launchBrowser()
632 return await this.browserSession.navigateToUrl(url)
633 
634 case "click":
635 // 2. Handle click actions with coordinates
636 return await this.browserSession.click(coordinate)
637 
638 case "type":
639 // 3. Handle keyboard input
640 return await this.browserSession.type(text)
641 
642 case "close":
643 // 4. Clean up resources
644 return await this.browserSession.closeBrowser()
645 }
646 }
647}
648```
 
 
 
649 
650Key aspects:
6511. **Browser Control**
652 - Fixed 900x600 resolution window
653 - Single instance per task lifecycle
654 - Automatic cleanup on task completion
655 - Console log capture
656 
6572. **Interaction Handling**
658 - Coordinate-based clicking
659 - Keyboard input simulation
660 - Screenshot capture
661 - Error recovery
662 
663## MCP (Model Context Protocol) Integration
664 
665### MCP Architecture
666 
667The MCP system consists of:
668 
6691. **McpHub Class**: Central manager in `src/services/mcp/McpHub.ts`
6702. **MCP Connections**: Manages connections to external MCP servers
6713. **MCP Settings**: Configuration stored in a JSON file
6724. **MCP Marketplace**: Online catalog of available MCP servers
6735. **MCP Tools & Resources**: Capabilities exposed by connected servers
674 
675The McpHub class:
676- Manages the lifecycle of MCP server connections
677- Handles server configuration through a settings file
678- Provides methods for calling tools and accessing resources
679- Implements auto-approval settings for MCP tools
680- Monitors server health and handles reconnection
681 
682### MCP Server Types
683 
684Cline supports two types of MCP server connections:
685- **Stdio**: Command-line based servers that communicate via standard I/O
686- **SSE**: HTTP-based servers that communicate via Server-Sent Events
687 
688### MCP Server Management
689 
690The McpHub class provides methods for:
691- Discovering and connecting to MCP servers
692- Monitoring server health and status
693- Restarting servers when needed
694- Managing server configurations
695- Setting timeouts and auto-approval rules
696 
697### MCP Tool Integration
698 
699MCP tools are integrated into the Task execution system:
700- Tools are discovered and registered at connection time
701- The Task class can call MCP tools through the McpHub
702- Tool results are streamed back to the AI
703- Auto-approval settings can be configured per tool
704 
705### MCP Marketplace
706 
707The MCP Marketplace provides:
708- A catalog of available MCP servers
709- One-click installation
710- README previews
711- Server status monitoring
712 
713The Controller class manages MCP servers through the McpHub service:
714 
715```typescript
716class Controller {
717 mcpHub?: McpHub
718 
719 constructor(context: vscode.ExtensionContext, webviewProvider: WebviewProvider) {
720 this.mcpHub = new McpHub(this)
721 }
722 
723 async downloadMcp(mcpId: string) {
724 // Fetch server details from marketplace
725 const response = await axios.post<McpDownloadResponse>(
726 "https://api.cline.bot/v1/mcp/download",
727 { mcpId },
728 {
729 headers: { "Content-Type": "application/json" },
730 timeout: 10000,
731 }
732 )
733 
734 // Create task with context from README
735 const task = `Set up the MCP server from ${mcpDetails.githubUrl}...`
736 
737 // Initialize task and show chat view
738 await this.initClineWithTask(task)
739 }
740}
741```
742 
743## Conclusion
 
744 
745This guide provides a comprehensive overview of the Cline extension architecture, with special focus on state management, data persistence, and code organization. Following these patterns ensures robust feature implementation with proper state handling across the extension's components.
 
 
 
 
 
 
 
 
 
 
 
 
746 
747Remember:
748- Always persist important state in the extension
749- The core extension follows a WebviewProvider -> Controller -> Task flow
750- Use proper typing for all state and messages
751- Handle errors and edge cases
752- Test state persistence across webview reloads
753- Follow the established patterns for consistency
754- Place new code in appropriate directories
755- Maintain clear separation of concerns
756- Install dependencies in correct package.json
757 
758## Contributing
759 
760Contributions to the Cline extension are welcome! Please follow these guidelines:
761 
762When adding new tools or API providers, follow the existing patterns in the `src/integrations/` and `src/api/providers/` directories, respectively. Ensure that your code is well-documented and includes appropriate error handling.
763 
764The `.clineignore` file allows users to specify files and directories that Cline should not access. When implementing new features, respect the `.clineignore` rules and ensure that your code does not attempt to read or modify ignored files.
765 
@@ −1 +1 @@
1−This file is the secret sauce for working effectively in this codebase. It captures tribal knowledge—the nuanced, non-obvious patterns that make the difference between a quick fix and hours of back-and-forth & human intervention.
1+# Cline Extension Architecture & Development Guide
22  
3−**When to add to this file:**
4−- User had to intervene, correct, or hand-hold
5−- Multiple back-and-forth attempts were needed to get something working
6−- You discovered something that required reading many files to understand
7−- A change touched files you wouldn't have guessed
8−- Something worked differently than you expected
9−- User explicitly asks to "add this to CLAUDE.md"
3+## Project Overview
104  
11−**Proactively suggest additions** when any of the above happen—don't wait to be asked.
5+Cline is a VSCode extension that provides AI assistance through a combination of a core extension backend and a React-based webview frontend. The extension is built with TypeScript and follows a modular architecture pattern.
126  
13−**What NOT to add:** Stuff you can figure out from reading a few files, obvious patterns, or standard practices. This file should be high-signal, not comprehensive.
7+## Architecture Overview
148  
15−## Miscellaneous
16−- The whole repo (including `apps/vscode`) uses **bun** for package management and task running. Emit `bun run X` / `bun install` / `bunx <bin>` / `bun file.ts`, never npm/npx. Node remains the *runtime* (VS Code's extension host and the standalone cline-core are Node), so Node-runtime tokens are legitimate and must not be "fixed" to bun — see @.clinerules/bun-and-node.md for the keep-list vs rewrite-list.
17−- Avoid provider-specific string matching / hardcoded provider branches when fixing provider/config plumbing. Prefer provider metadata, shared catalog/defaults, explicit protocol/client capabilities, or centralized normalization utilities that apply by data shape rather than `providerId === "..."`. If a provider exception seems necessary, stop and explain why instead of adding ad-hoc string matching.
18−- This is a VS Code extension—check `package.json` for available scripts before trying to verify builds (e.g., `bun run compile`, not `bun run build`).
19−- When reading a configuration files that users may edit, use `readFileStrippingUtf8Bom`, `readFileSyncStrippingUtf8Bom`, or `stripUtf8Bom` from `@cline/shared/node`. DON'T strip byte order marks of user files handled by tools/passed to models.
20−- When creating PRs, contributors should not create changelog-entry files. Maintainers handle release versioning and changelog curation during the release process.
21−- When adding new feature flags, see this PR as a reference https://github.com/cline/cline/pull/7566
22−- Additional instructions about making requests: @.clinerules/network.md
9+```mermaid
10+graph TB
11+ subgraph VSCodeExtensionHost[VSCode Extension Host]
12+ subgraph CoreExtension[Core Extension]
13+ ExtensionEntry[Extension Entry<br/>src/extension.ts]
14+ WebviewProvider[WebviewProvider<br/>src/core/webview/index.ts]
15+ Controller[Controller<br/>src/core/controller/index.ts]
16+ Task[Task<br/>src/core/task/index.ts]
17+ GlobalState[VSCode Global State]
18+ SecretsStorage[VSCode Secrets Storage]
19+ McpHub[McpHub<br/>src/services/mcp/McpHub.ts]
20+ end
2321  
24−## Searching the Codebase — Avoiding Build Output
22+ subgraph WebviewUI[Webview UI]
23+ WebviewApp[React App<br/>webview-ui/src/App.tsx]
24+ ExtStateContext[ExtensionStateContext<br/>webview-ui/src/context/ExtensionStateContext.tsx]
25+ ReactComponents[React Components]
26+ end
2527  
26−Several directories contain build output or generated code that produces
27−noisy or unusable results with `search_files` / `grep`:
28+ subgraph Storage
29+ TaskStorage[Task Storage<br/>Per-Task Files & History]
30+ CheckpointSystem[Git-based Checkpoints]
31+ end
2832  
29−| Directory | What it is | Why it's a problem |
30−|-----------|-----------|-------------------|
31−| `out/` | esbuild bundle output | Mirrors `src/` structure as minified JS — every search gets duplicate hits on single-line files |
32−| `dist/` | Packaged extension | Entire extension bundled into one minified `extension.js` (~1 long line) |
33−| `dist-standalone/` | Standalone build output | Same minification issue |
34−| `src/generated/` | Generated protobuf code | Auto-generated from `proto/`; not the source of truth |
35−| `src/shared/proto/` | Generated proto type defs | Auto-generated from `proto/`; not the source of truth |
36−| `node_modules/` | Dependencies | Huge, not project source |
33+ subgraph apiProviders[API Providers]
34+ AnthropicAPI[Anthropic]
35+ OpenRouterAPI[OpenRouter]
36+ BedrockAPI[AWS Bedrock]
37+ OtherAPIs[Other Providers]
38+ end
3739  
38−### How to skip build output
40+ subgraph MCPServers[MCP Servers]
41+ ExternalMcpServers[External MCP Servers]
42+ end
43+ end
3944  
40−**`search_files`** — Point at `src/` (not the project root) and use `file_pattern`:
45+ %% Core Extension Data Flow
46+ ExtensionEntry --> WebviewProvider
47+ WebviewProvider --> Controller
48+ Controller --> Task
49+ Controller --> McpHub
50+ Task --> GlobalState
51+ Task --> SecretsStorage
52+ Task --> TaskStorage
53+ Task --> CheckpointSystem
54+ Task --> |API Requests| apiProviders
55+ McpHub --> |Connects to| ExternalMcpServers
56+ Task --> |Uses| McpHub
57+ 
58+ %% Webview Data Flow
59+ WebviewApp --> ExtStateContext
60+ ExtStateContext --> ReactComponents
61+ 
62+ %% Bidirectional Communication
63+ WebviewProvider <-->|postMessage| ExtStateContext
64+ 
65+ style GlobalState fill:#f9f,stroke:#333,stroke-width:2px
66+ style SecretsStorage fill:#f9f,stroke:#333,stroke-width:2px
67+ style ExtStateContext fill:#bbf,stroke:#333,stroke-width:2px
68+ style WebviewProvider fill:#bfb,stroke:#333,stroke-width:2px
69+ style McpHub fill:#bfb,stroke:#333,stroke-width:2px
70+ style apiProviders fill:#fdb,stroke:#333,stroke-width:2px
4171 ```
42−search_files(path="src/core", regex="myFunction", file_pattern="*.ts")
72+ 
73+## Definitions
74+ 
75+- **Core Extension**: Anything inside the src folder, organized into modular components
76+- **Core Extension State**: Managed by the Controller class in src/core/controller/index.ts, which serves as the single source of truth for the extension's state. It manages multiple types of persistent storage (global state, workspace state, and secrets), handles state distribution to both the core extension and webview components, and coordinates state across multiple extension instances. This includes managing API configurations, task history, settings, and MCP configurations.
77+- **Webview**: Anything inside the webview-ui. All the react or view's seen by the user and user interaction components
78+- **Webview State**: Managed by ExtensionStateContext in webview-ui/src/context/ExtensionStateContext.tsx, which provides React components with access to the extension's state through a context provider pattern. It maintains local state for UI components, handles real-time updates through message events, manages partial message updates, and provides methods for state modifications. The context includes extension version, messages, task history, theme, API configurations, MCP servers, marketplace catalog, and workspace file paths. It synchronizes with the core extension through VSCode's message passing system and provides type-safe access to state through a custom hook (useExtensionState).
79+ 
80+### Core Extension Architecture
81+ 
82+The core extension follows a clear hierarchical structure:
83+ 
84+1. **WebviewProvider** (src/core/webview/index.ts): Manages the webview lifecycle and communication
85+2. **Controller** (src/core/controller/index.ts): Handles webview messages and task management
86+3. **Task** (src/core/task/index.ts): Executes API requests and tool operations
87+ 
88+This architecture provides clear separation of concerns:
89+- WebviewProvider focuses on VSCode webview integration
90+- Controller manages state and coordinates tasks
91+- Task handles the execution of AI requests and tool operations
92+ 
93+### WebviewProvider Implementation
94+ 
95+The WebviewProvider class in `src/core/webview/index.ts` is responsible for:
96+ 
97+- Managing multiple active instances through a static set (`activeInstances`)
98+- Handling webview lifecycle events (creation, visibility changes, disposal)
99+- Implementing HTML content generation with proper CSP headers
100+- Supporting Hot Module Replacement (HMR) for development
101+- Setting up message listeners between the webview and extension
102+ 
103+The WebviewProvider maintains a reference to the Controller and delegates message handling to it. It also handles the creation of both sidebar and tab panel webviews, allowing Cline to be used in different contexts within VSCode.
104+ 
105+### Core Extension State
106+ 
107+The `Controller` class manages multiple types of persistent storage:
108+ 
109+- **Global State:** Stored across all VSCode instances. Used for settings and data that should persist globally.
110+- **Workspace State:** Specific to the current workspace. Used for task-specific data and settings.
111+- **Secrets:** Secure storage for sensitive information like API keys.
112+ 
113+The `Controller` handles the distribution of state to both the core extension and webview components. It also coordinates state across multiple extension instances, ensuring consistency.
114+ 
115+State synchronization between instances is handled through:
116+- File-based storage for task history and conversation data
117+- VSCode's global state API for settings and configuration
118+- Secrets storage for sensitive information
119+- Event listeners for file changes and configuration updates
120+ 
121+The Controller implements methods for:
122+- Saving and loading task state
123+- Managing API configurations
124+- Handling user authentication
125+- Coordinating MCP server connections
126+- Managing task history and checkpoints
127+ 
128+### Webview State
129+ 
130+The `ExtensionStateContext` in `webview-ui/src/context/ExtensionStateContext.tsx` provides React components with access to the extension's state. It uses a context provider pattern and maintains local state for UI components. The context includes:
131+ 
132+- Extension version
133+- Messages
134+- Task history
135+- Theme
136+- API configurations
137+- MCP servers
138+- Marketplace catalog
139+- Workspace file paths
140+ 
141+It synchronizes with the core extension through VSCode's message passing system and provides type-safe access to the state via a custom hook (`useExtensionState`).
142+ 
143+The ExtensionStateContext handles:
144+- Real-time updates through message events
145+- Partial message updates for streaming content
146+- State modifications through setter methods
147+- Type-safe access to state through a custom hook
148+ 
149+## API Provider System
150+ 
151+Cline supports multiple AI providers through a modular API provider system. Each provider is implemented as a separate module in the `src/api/providers/` directory and follows a common interface.
152+ 
153+### API Provider Architecture
154+ 
155+The API system consists of:
156+ 
157+1. **API Handlers**: Provider-specific implementations in `src/api/providers/`
158+2. **API Transformers**: Stream transformation utilities in `src/api/transform/`
159+3. **API Configuration**: User settings for API keys and endpoints
160+4. **API Factory**: Builder function to create the appropriate handler
161+ 
162+Key providers include:
163+- **Anthropic**: Direct integration with Claude models
164+- **OpenRouter**: Meta-provider supporting multiple model providers
165+- **AWS Bedrock**: Integration with Amazon's AI services
166+- **Gemini**: Google's AI models
167+- **Cerebras**: High-performance inference with Llama, Qwen, and DeepSeek models
168+- **Ollama**: Local model hosting
169+- **LM Studio**: Local model hosting
170+- **VSCode LM**: VSCode's built-in language models
171+ 
172+### API Configuration Management
173+ 
174+API configurations are stored securely:
175+- API keys are stored in VSCode's secrets storage
176+- Model selections and non-sensitive settings are stored in global state
177+- The Controller manages switching between providers and updating configurations
178+ 
179+The system supports:
180+- Secure storage of API keys
181+- Model selection and configuration
182+- Automatic retry and error handling
183+- Token usage tracking and cost calculation
184+- Context window management
185+ 
186+### Plan/Act Mode API Configuration
187+ 
188+Cline supports separate model configurations for Plan and Act modes:
189+- Different models can be used for planning vs. execution
190+- The system preserves model selections when switching modes
191+- The Controller handles the transition between modes and updates the API configuration accordingly
192+ 
193+## Task Execution System
194+ 
195+The Task class is responsible for executing AI requests and tool operations. Each task runs in its own instance of the Task class, ensuring isolation and proper state management.
196+ 
197+### Task Execution Loop
198+ 
199+The core task execution loop follows this pattern:
200+ 
201+```typescript
202+class Task {
203+ async initiateTaskLoop(userContent: UserContent, isNewTask: boolean) {
204+ while (!this.abort) {
205+ // 1. Make API request and stream response
206+ const stream = this.attemptApiRequest()
207+
208+ // 2. Parse and present content blocks
209+ for await (const chunk of stream) {
210+ switch (chunk.type) {
211+ case "text":
212+ // Parse into content blocks
213+ this.assistantMessageContent = parseAssistantMessageV2(chunk.text)
214+ // Present blocks to user
215+ await this.presentAssistantMessage()
216+ break
217+ }
218+ }
219+
220+ // 3. Wait for tool execution to complete
221+ await pWaitFor(() => this.userMessageContentReady)
222+
223+ // 4. Continue loop with tool result
224+ const recDidEndLoop = await this.recursivelyMakeClineRequests(
225+ this.userMessageContent
226+ )
227+ }
228+ }
229+}
43230 ```
44−The `file_pattern` parameter is the most effective filter — e.g. `"*.ts"`,
45−`"*.tsx"`, `"*.proto"`.
46231  
47−**`grep` directly** — Exclude build dirs and restrict to source extensions:
48−```bash
49−grep -rn "myFunction" src/ --include="*.ts" --exclude-dir={out,dist,node_modules,generated}
232+### Message Streaming System
233+ 
234+The streaming system handles real-time updates and partial content:
235+ 
236+```typescript
237+class Task {
238+ async presentAssistantMessage() {
239+ // Handle streaming locks to prevent race conditions
240+ if (this.presentAssistantMessageLocked) {
241+ this.presentAssistantMessageHasPendingUpdates = true
242+ return
243+ }
244+ this.presentAssistantMessageLocked = true
245+ 
246+ // Present current content block
247+ const block = this.assistantMessageContent[this.currentStreamingContentIndex]
248+
249+ // Handle different types of content
250+ switch (block.type) {
251+ case "text":
252+ await this.say("text", content, undefined, block.partial)
253+ break
254+ case "tool_use":
255+ // Handle tool execution
256+ break
257+ }
258+ 
259+ // Move to next block if complete
260+ if (!block.partial) {
261+ this.currentStreamingContentIndex++
262+ }
263+ }
264+}
50265 ```
51266  
52−### When you must search minified files
267+### Tool Execution Flow
53268  
54−Sometimes you need to verify what got bundled (e.g., checking if a change
55−made it into the build). Minified files are typically one long line, so
56−normal `grep` shows the entire file as context. Use these approaches:
269+Tools follow a strict execution pattern:
57270  
58−- **`grep -oP`** to extract just the match with limited surrounding context:
59− ```bash
60− grep -oP '.{0,40}myFunction.{0,40}' dist/extension.js
61− ```
62−- **`read_file`** on files in `out/src/` — these have source maps and are
63− more readable than `dist/extension.js` (which is the fully bundled output).
64−- **Source maps** — `out/src/*.js.map` and `dist/extension.js.map` can be
65− used to trace minified output back to original source locations.
271+```typescript
272+class Task {
273+ async executeToolWithApproval(block: ToolBlock) {
274+ // 1. Check auto-approval settings
275+ if (this.shouldAutoApproveTool(block.name)) {
276+ await this.say("tool", message)
277+ this.consecutiveAutoApprovedRequestsCount++
278+ } else {
279+ // 2. Request user approval
280+ const didApprove = await askApproval("tool", message)
281+ if (!didApprove) {
282+ this.didRejectTool = true
283+ return
284+ }
285+ }
66286  
67−## gRPC/Protobuf Communication
68−The extension and webview communicate via gRPC-like protocol over VS Code message passing.
287+ // 3. Execute tool
288+ const result = await this.executeTool(block)
69289  
70−**Proto files live in `proto/`** (e.g., `proto/cline/task.proto`, `proto/cline/ui.proto`)
71−- Each feature domain has its own `.proto` file
72−- For simple data, use shared types in `proto/cline/common.proto` (`StringRequest`, `Empty`, `Int64Request`)
73−- For complex data, define custom messages in the feature's `.proto` file
74−- Naming: Services `PascalCaseService`, RPCs `camelCase`, Messages `PascalCase`
75−- For streaming responses, use `stream` keyword (see `subscribeToAuthCallback` in `account.proto`)
290+ // 4. Save checkpoint
291+ await this.saveCheckpoint()
76292  
77−**Run `bun run protos`** after any proto changes—generates types in:
78−- `src/shared/proto/` - Shared type definitions
79−- `src/generated/grpc-js/` - Service implementations
80−- `src/generated/nice-grpc/` - Promise-based clients
81−- `src/generated/hosts/` - Generated handlers
293+ // 5. Return result to API
294+ return result
295+ }
296+}
297+```
82298  
83−**Adding new enum values** (like a new `ClineSay` type) requires updating conversion mappings in `src/shared/proto-conversions/cline-message.ts`
299+### Error Handling & Recovery
84300  
85−**Adding new RPC methods** requires:
86−- Handler in `src/core/controller/<domain>/`
87−- Call from webview via generated client: `UiServiceClient.scrollToSettings(StringRequest.create({ value: "browser" }))`
301+The system includes robust error handling:
88302  
89−**Example—the `explain-changes` feature touched:**
90−- `proto/cline/task.proto` - Added `ExplainChangesRequest` message and `explainChanges` RPC
91−- `proto/cline/ui.proto` - Added `GENERATE_EXPLANATION = 29` to `ClineSay` enum
92−- `src/shared/ExtensionMessage.ts` - Added `ClineSayGenerateExplanation` type
93−- `src/shared/proto-conversions/cline-message.ts` - Added mapping for new say type
94−- `src/core/controller/task/explainChanges.ts` - Handler implementation
95−- `webview-ui/src/components/chat/ChatRow.tsx` - UI rendering
303+```typescript
304+class Task {
305+ async handleError(action: string, error: Error) {
306+ // 1. Check if task was abandoned
307+ if (this.abandoned) return
308+
309+ // 2. Format error message
310+ const errorString = `Error ${action}: ${error.message}`
311+
312+ // 3. Present error to user
313+ await this.say("error", errorString)
314+
315+ // 4. Add error to tool results
316+ pushToolResult(formatResponse.toolError(errorString))
317+
318+ // 5. Cleanup resources
319+ await this.diffViewProvider.revertChanges()
320+ await this.browserSession.closeBrowser()
321+ }
322+}
323+```
96324  
97−## Adding New Global State Keys
98−Adding a new key to global state requires updates in multiple places. Missing any step causes silent failures.
325+### API Request & Token Management
99326  
100−Required steps:
101−1. Type definition in `src/shared/storage/state-keys.ts` - Add to `GlobalState` or `Settings` interface
102−2. Add any default value or transform in `src/shared/storage/state-keys.ts` if the key needs one
103−3. Read and write the value through `StateManager` (`setGlobalState()` / `getGlobalStateKey()`) after initialization
327+The Task class handles API requests with built-in retry, streaming, and token management:
104328  
105−Persistent state is file-backed through `StateManager`; do not add new runtime reads or writes against VS Code `ExtensionContext` storage. That storage is only a legacy migration source.
329+```typescript
330+class Task {
331+ async *attemptApiRequest(previousApiReqIndex: number): ApiStream {
332+ // 1. Wait for MCP servers to connect
333+ await pWaitFor(() => this.controllerRef.deref()?.mcpHub?.isConnecting !== true)
106334  
107−Settings plumbing gotcha: if a key is user-toggleable from settings, wire both controller update paths:
108−- `src/core/controller/state/updateSettings.ts` for webview `updateSetting(...)`
109−- `src/core/controller/state/updateSettingsCli.ts` for CLI/ACP settings updates
110−Missing one path causes a toggle to appear to change in one surface while the backend state stays unchanged.
335+ // 2. Manage context window
336+ const previousRequest = this.clineMessages[previousApiReqIndex]
337+ if (previousRequest?.text) {
338+ const { tokensIn, tokensOut } = JSON.parse(previousRequest.text || "{}")
339+ const totalTokens = (tokensIn || 0) + (tokensOut || 0)
340+
341+ // Truncate conversation if approaching context limit
342+ if (totalTokens >= maxAllowedSize) {
343+ this.conversationHistoryDeletedRange = this.contextManager.getNextTruncationRange(
344+ this.apiConversationHistory,
345+ this.conversationHistoryDeletedRange,
346+ totalTokens / 2 > maxAllowedSize ? "quarter" : "half"
347+ )
348+ }
349+ }
111350  
112−Webview toggle gotcha: settings changes must also round-trip back in state payloads.
113−- Add the field to `UpdateSettingsRequest` in `proto/cline/state.proto` (for webview update requests), then run `bun run protos`
114−- Include the key in `Controller.getStateToPostToWebview()` (`src/core/controller/index.ts`)
115−- Ensure `ExtensionState` and webview defaults include the key (`src/shared/ExtensionMessage.ts`, `webview-ui/src/context/ExtensionStateContext.tsx`)
116−If this round-trip wiring is missing, the backend value can update but the toggle in webview appears stuck or reverts.
351+ // 3. Handle streaming with automatic retry
352+ try {
353+ this.isWaitingForFirstChunk = true
354+ const firstChunk = await iterator.next()
355+ yield firstChunk.value
356+ this.isWaitingForFirstChunk = false
357+
358+ // Stream remaining chunks
359+ yield* iterator
360+ } catch (error) {
361+ // 4. Error handling with retry
362+ if (isOpenRouter && !this.didAutomaticallyRetryFailedApiRequest) {
363+ await setTimeoutPromise(1000)
364+ this.didAutomaticallyRetryFailedApiRequest = true
365+ yield* this.attemptApiRequest(previousApiReqIndex)
366+ return
367+ }
368+
369+ // 5. Ask user to retry if automatic retry failed
370+ const { response } = await this.ask(
371+ "api_req_failed",
372+ this.formatErrorWithStatusCode(error)
373+ )
374+ if (response === "yesButtonClicked") {
375+ await this.say("api_req_retried")
376+ yield* this.attemptApiRequest(previousApiReqIndex)
377+ return
378+ }
379+ }
380+ }
381+}
382+```
117383  
118−## StateManager Cache vs Direct globalState Access
119−StateManager uses an in-memory cache populated during `StateManager.initialize()` from file-backed storage. For most state, use `controller.stateManager.setGlobalState()`/`getGlobalStateKey()`.
384+Key features:
120385  
121−Exception: host migration code may read legacy VS Code storage before file-backed storage is initialized.
386+1. **Context Window Management**
387+ - Tracks token usage across requests
388+ - Automatically truncates conversation when needed
389+ - Preserves important context while freeing space
390+ - Handles different model context sizes
122391  
123−Example pattern:
392+2. **Streaming Architecture**
393+ - Real-time chunk processing
394+ - Partial content handling
395+ - Race condition prevention
396+ - Error recovery during streaming
397+ 
398+3. **Error Handling**
399+ - Automatic retry for transient failures
400+ - User-prompted retry for persistent issues
401+ - Detailed error reporting
402+ - State cleanup on failure
403+ 
404+4. **Token Tracking**
405+ - Per-request token counting
406+ - Cumulative usage tracking
407+ - Cost calculation
408+ - Cache hit monitoring
409+ 
410+### Context Management System
411+ 
412+The Context Management System handles conversation history truncation to prevent context window overflow errors. Implemented in the `ContextManager` class, it ensures long-running conversations remain within model context limits while preserving critical context.
413+ 
414+Key features:
415+ 
416+1. **Model-Aware Sizing**: Dynamically adjusts based on different model context windows (64K for DeepSeek, 128K for most models, 200K for Claude).
417+ 
418+2. **Proactive Truncation**: Monitors token usage and preemptively truncates conversations when approaching limits, maintaining buffers of 27K-40K tokens depending on the model.
419+ 
420+3. **Intelligent Preservation**: Always preserves the original task message and maintains the user-assistant conversation structure when truncating.
421+ 
422+4. **Adaptive Strategies**: Uses different truncation strategies based on context pressure - removing half of the conversation for moderate pressure or three-quarters for severe pressure.
423+ 
424+5. **Error Recovery**: Includes specialized detection for context window errors from different providers with automatic retry and more aggressive truncation when needed.
425+ 
426+### Task State & Resumption
427+ 
428+The Task class provides robust task state management and resumption capabilities:
429+ 
124430 ```typescript
125−// Writing (normal pattern)
126−controller.stateManager.setGlobalState("myKey", value)
431+class Task {
432+ async resumeTaskFromHistory() {
433+ // 1. Load saved state
434+ this.clineMessages = await getSavedClineMessages(this.getContext(), this.taskId)
435+ this.apiConversationHistory = await getSavedApiConversationHistory(this.getContext(), this.taskId)
127436  
128−// Reading after initialization
129−const value = controller.stateManager.getGlobalStateKey("myKey")
437+ // 2. Handle interrupted tool executions
438+ const lastMessage = this.apiConversationHistory[this.apiConversationHistory.length - 1]
439+ if (lastMessage.role === "assistant") {
440+ const toolUseBlocks = content.filter(block => block.type === "tool_use")
441+ if (toolUseBlocks.length > 0) {
442+ // Add interrupted tool responses
443+ const toolResponses = toolUseBlocks.map(block => ({
444+ type: "tool_result",
445+ tool_use_id: block.id,
446+ content: "Task was interrupted before this tool call could be completed."
447+ }))
448+ modifiedOldUserContent = [...toolResponses]
449+ }
450+ }
451+ 
452+ // 3. Notify about interruption
453+ const agoText = this.getTimeAgoText(lastMessage?.ts)
454+ newUserContent.push({
455+ type: "text",
456+ text: `[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context.`
457+ })
458+ 
459+ // 4. Resume task execution
460+ await this.initiateTaskLoop(newUserContent, false)
461+ }
462+ 
463+ private async saveTaskState() {
464+ // Save conversation history
465+ await saveApiConversationHistory(this.getContext(), this.taskId, this.apiConversationHistory)
466+ await saveClineMessages(this.getContext(), this.taskId, this.clineMessages)
467+
468+ // Create checkpoint
469+ const commitHash = await this.checkpointTracker?.commit()
470+
471+ // Update task history
472+ await this.controllerRef.deref()?.updateTaskHistory({
473+ id: this.taskId,
474+ ts: lastMessage.ts,
475+ task: taskMessage.text,
476+ // ... other metadata
477+ })
478+ }
479+}
130480 ```
131481  
132−Use `context.globalState` only in VS Code migration code that copies legacy ExtensionContext values into the shared file-backed stores.
482+Key aspects of task state management:
133483  
134−## ChatRow Cancelled/Interrupted States
135−When a ChatRow displays a loading/in-progress state (spinner), you must handle what happens when the task is cancelled. This is non-obvious because cancellation doesn't update the message content—you have to infer it from context.
484+1. **Task Persistence**
485+ - Each task has a unique ID and dedicated storage directory
486+ - Conversation history is saved after each message
487+ - File changes are tracked through Git-based checkpoints
488+ - Terminal output and browser state are preserved
136489  
137−**The pattern:**
138−1. A message has a `status` field (e.g., `"generating"`, `"complete"`, `"error"`) stored in `message.text` as JSON
139−2. When cancelled mid-operation, the status stays `"generating"` forever—no one updates it
140−3. To detect cancellation, check TWO conditions:
141− - `!isLast` — if this message is no longer the last message, something else happened after it (interrupted)
142− - `lastModifiedMessage?.ask === "resume_task" || "resume_completed_task"` — task was just cancelled and is waiting to resume
490+2. **State Recovery**
491+ - Tasks can be resumed from any point
492+ - Interrupted tool executions are handled gracefully
493+ - File changes can be restored from checkpoints
494+ - Context is preserved across VSCode sessions
143495  
144−**Example from `generate_explanation`:**
145−```tsx
146−const wasCancelled =
147− explanationInfo.status === "generating" &&
148− (!isLast ||
149− lastModifiedMessage?.ask === "resume_task" ||
150− lastModifiedMessage?.ask === "resume_completed_task")
151−const isGenerating = explanationInfo.status === "generating" && !wasCancelled
496+3. **Workspace Synchronization**
497+ - File changes are tracked through Git
498+ - Checkpoints are created after tool executions
499+ - State can be restored to any checkpoint
500+ - Changes can be compared between checkpoints
501+ 
502+4. **Error Recovery**
503+ - Failed API requests can be retried
504+ - Interrupted tool executions are marked
505+ - Resources are cleaned up properly
506+ - User is notified of state changes
507+ 
508+## Plan/Act Mode System
509+ 
510+Cline implements a dual-mode system that separates planning from execution:
511+ 
512+### Mode Architecture
513+ 
514+The Plan/Act mode system consists of:
515+ 
516+1. **Mode State**: Stored in `chatSettings.mode` in the Controller's state
517+2. **Mode Switching**: Handled by `togglePlanActModeWithChatSettings` in the Controller
518+3. **Mode-specific Models**: Optional configuration to use different models for each mode
519+4. **Mode-specific Prompting**: Different system prompts for planning vs. execution
520+ 
521+### Mode Switching Process
522+ 
523+When switching between modes:
524+ 
525+1. The current model configuration is saved to mode-specific state
526+2. The previous mode's model configuration is restored
527+3. The Task instance is updated with the new mode
528+4. The webview is notified of the mode change
529+5. Telemetry events are captured for analytics
530+ 
531+### Plan Mode
532+ 
533+Plan mode is designed for:
534+- Information gathering and context building
535+- Asking clarifying questions
536+- Creating detailed execution plans
537+- Discussing approaches with the user
538+ 
539+In Plan mode, the AI uses the `plan_mode_respond` tool to engage in conversational planning without executing actions.
540+ 
541+### Act Mode
542+ 
543+Act mode is designed for:
544+- Executing the planned actions
545+- Using tools to modify files, run commands, etc.
546+- Implementing the solution
547+- Providing results and completion feedback
548+ 
549+In Act mode, the AI has access to all tools except `plan_mode_respond` and focuses on implementation rather than discussion.
550+ 
551+## Data Flow & State Management
552+ 
553+### Core Extension Role
554+ 
555+The Controller acts as the single source of truth for all persistent state. It:
556+- Manages VSCode global state and secrets storage
557+- Coordinates state updates between components
558+- Ensures state consistency across webview reloads
559+- Handles task-specific state persistence
560+- Manages checkpoint creation and restoration
561+ 
562+### Terminal Management
563+ 
564+The Task class manages terminal instances and command execution:
565+ 
566+```typescript
567+class Task {
568+ async executeCommandTool(command: string): Promise<[boolean, ToolResponse]> {
569+ // 1. Get or create terminal
570+ const terminalInfo = await this.terminalManager.getOrCreateTerminal(cwd)
571+ terminalInfo.terminal.show()
572+ 
573+ // 2. Execute command with output streaming
574+ const process = this.terminalManager.runCommand(terminalInfo, command)
575+
576+ // 3. Handle real-time output
577+ let result = ""
578+ process.on("line", (line) => {
579+ result += line + "\n"
580+ if (!didContinue) {
581+ sendCommandOutput(line)
582+ } else {
583+ this.say("command_output", line)
584+ }
585+ })
586+ 
587+ // 4. Wait for completion or user feedback
588+ let completed = false
589+ process.once("completed", () => {
590+ completed = true
591+ })
592+ 
593+ await process
594+ 
595+ // 5. Return result
596+ if (completed) {
597+ return [false, `Command executed.\n${result}`]
598+ } else {
599+ return [
600+ false,
601+ `Command is still running in the user's terminal.\n${result}\n\nYou will be updated on the terminal status and new output in the future.`
602+ ]
603+ }
604+ }
605+}
152606 ```
153607  
154−**Why both checks?**
155−- `!isLast` catches: cancelled → resumed → did other stuff → this old message is stale
156−- `lastModifiedMessage?.ask === "resume_task"` catches: just cancelled, hasn't resumed yet, this message is still technically "last"
608+Key features:
609+1. **Terminal Instance Management**
610+ - Multiple terminal support
611+ - Terminal state tracking (busy/inactive)
612+ - Process cooldown monitoring
613+ - Output history per terminal
157614  
158−**See also:** `BrowserSessionRow.tsx` uses similar pattern with `isLastApiReqInterrupted` and `isLastMessageResume`.
615+2. **Command Execution**
616+ - Real-time output streaming
617+ - User feedback handling
618+ - Process state monitoring
619+ - Error recovery
159620  
160−**Backend side:** When streaming is cancelled, clean up properly (close tabs, clear comments, etc.) by checking `taskState.abort` after the streaming function returns.
621+### Browser Session Management
161622  
162−## Debug Harness: clear inherited VSCode/Electron env vars before launching
623+The Task class handles browser automation through Puppeteer:
163624  
164−The debug harness (`apps/vscode/src/dev/debug-harness/server.ts`) launches a child
165−VSCode via Playwright's `_electron.launch({ env: { ...process.env, ... } })`. If you
166−run the harness from a process that was itself spawned by VSCode (e.g. the Cline
167−extension host, an integrated terminal, or an agent running inside VSCode), the
168−parent's VSCode/Electron env vars leak into the child and break the launch.
625+```typescript
626+class Task {
627+ async executeBrowserAction(action: BrowserAction): Promise<BrowserActionResult> {
628+ switch (action) {
629+ case "launch":
630+ // 1. Launch browser with fixed resolution
631+ await this.browserSession.launchBrowser()
632+ return await this.browserSession.navigateToUrl(url)
169633  
170−The fatal one is **`ELECTRON_RUN_AS_NODE=1`**: it makes the child VSCode binary run
171−as plain Node, so it rejects every VSCode CLI flag. Symptom:
634+ case "click":
635+ // 2. Handle click actions with coordinates
636+ return await this.browserSession.click(coordinate)
172637  
638+ case "type":
639+ // 3. Handle keyboard input
640+ return await this.browserSession.type(text)
641+ 
642+ case "close":
643+ // 4. Clean up resources
644+ return await this.browserSession.closeBrowser()
645+ }
646+ }
647+}
173648 ```
174−.../Visual Studio Code.app/Contents/MacOS/Code: bad option: --extensionDevelopmentPath=...
175−Error: Process failed to launch! (Playwright _electron.launch)
176−```
177649  
178−This is NOT the macOS Playwright flakiness mentioned in the harness README — it's
179−env inheritance. Fix: strip the inherited vars before starting the harness:
650+Key aspects:
651+1. **Browser Control**
652+ - Fixed 900x600 resolution window
653+ - Single instance per task lifecycle
654+ - Automatic cleanup on task completion
655+ - Console log capture
180656  
181−```bash
182−env -u ELECTRON_RUN_AS_NODE -u ELECTRON_NO_ATTACH_CONSOLE \
183− -u VSCODE_CLI -u VSCODE_CODE_CACHE_PATH -u VSCODE_CRASH_REPORTER_PROCESS_TYPE \
184− -u VSCODE_CWD -u VSCODE_ESM_ENTRYPOINT -u VSCODE_HANDLES_UNCAUGHT_ERRORS \
185− -u VSCODE_IPC_HOOK -u VSCODE_NLS_CONFIG -u VSCODE_PID -u VSCODE_L10N_BUNDLE_LOCATION \
186− bun src/dev/debug-harness/server.ts --auto-launch --skip-build
657+2. **Interaction Handling**
658+ - Coordinate-based clicking
659+ - Keyboard input simulation
660+ - Screenshot capture
661+ - Error recovery
662+ 
663+## MCP (Model Context Protocol) Integration
664+ 
665+### MCP Architecture
666+ 
667+The MCP system consists of:
668+ 
669+1. **McpHub Class**: Central manager in `src/services/mcp/McpHub.ts`
670+2. **MCP Connections**: Manages connections to external MCP servers
671+3. **MCP Settings**: Configuration stored in a JSON file
672+4. **MCP Marketplace**: Online catalog of available MCP servers
673+5. **MCP Tools & Resources**: Capabilities exposed by connected servers
674+ 
675+The McpHub class:
676+- Manages the lifecycle of MCP server connections
677+- Handles server configuration through a settings file
678+- Provides methods for calling tools and accessing resources
679+- Implements auto-approval settings for MCP tools
680+- Monitors server health and handles reconnection
681+ 
682+### MCP Server Types
683+ 
684+Cline supports two types of MCP server connections:
685+- **Stdio**: Command-line based servers that communicate via standard I/O
686+- **SSE**: HTTP-based servers that communicate via Server-Sent Events
687+ 
688+### MCP Server Management
689+ 
690+The McpHub class provides methods for:
691+- Discovering and connecting to MCP servers
692+- Monitoring server health and status
693+- Restarting servers when needed
694+- Managing server configurations
695+- Setting timeouts and auto-approval rules
696+ 
697+### MCP Tool Integration
698+ 
699+MCP tools are integrated into the Task execution system:
700+- Tools are discovered and registered at connection time
701+- The Task class can call MCP tools through the McpHub
702+- Tool results are streamed back to the AI
703+- Auto-approval settings can be configured per tool
704+ 
705+### MCP Marketplace
706+ 
707+The MCP Marketplace provides:
708+- A catalog of available MCP servers
709+- One-click installation
710+- README previews
711+- Server status monitoring
712+ 
713+The Controller class manages MCP servers through the McpHub service:
714+ 
715+```typescript
716+class Controller {
717+ mcpHub?: McpHub
718+ 
719+ constructor(context: vscode.ExtensionContext, webviewProvider: WebviewProvider) {
720+ this.mcpHub = new McpHub(this)
721+ }
722+ 
723+ async downloadMcp(mcpId: string) {
724+ // Fetch server details from marketplace
725+ const response = await axios.post<McpDownloadResponse>(
726+ "https://api.cline.bot/v1/mcp/download",
727+ { mcpId },
728+ {
729+ headers: { "Content-Type": "application/json" },
730+ timeout: 10000,
731+ }
732+ )
733+ 
734+ // Create task with context from README
735+ const task = `Set up the MCP server from ${mcpDetails.githubUrl}...`
736+ 
737+ // Initialize task and show chat view
738+ await this.initClineWithTask(task)
739+ }
740+}
187741 ```
188742  
189−Check your own env with `env | grep -iE 'electron|vscode_'` first; `ELECTRON_RUN_AS_NODE=1`
190−present means you must scrub before launching.
743+## Conclusion
191744  
192−Other harness notes confirmed in practice:
193−- The extension host is **ESM** (`VSCODE_ESM_ENTRYPOINT`), so `ext.evaluate` has no
194− `require` and module-internal functions aren't reachable as globals. To inspect
195− internal builders (e.g. `buildBedrockProviderConfig`), set a breakpoint with
196− `ext.set_breakpoint` and read locals via `ext.evaluate` with the paused `callFrameId`
197− — don't try to `require()` the bundle.
198−- `web.evaluate` wraps the expression as a single returned expression; multi-statement
199− snippets must be an IIFE `(() => { ...; return x; })()`, otherwise you get
200− `SyntaxError: Unexpected token ';'`.
201−- Webview settings inputs are `vscode-text-field` web components with debounced React
202− onChange. Setting `.value` + dispatching events via `web.evaluate` is unreliable for
203− some fields; focus the inner shadow `input` then use real keystrokes (`ui.type` +
204− `ui.press Tab`, or click the dropdown option) to make the value persist.
745+This guide provides a comprehensive overview of the Cline extension architecture, with special focus on state management, data persistence, and code organization. Following these patterns ensures robust feature implementation with proper state handling across the extension's components.
205746  
747+Remember:
748+- Always persist important state in the extension
749+- The core extension follows a WebviewProvider -> Controller -> Task flow
750+- Use proper typing for all state and messages
751+- Handle errors and edge cases
752+- Test state persistence across webview reloads
753+- Follow the established patterns for consistency
754+- Place new code in appropriate directories
755+- Maintain clear separation of concerns
756+- Install dependencies in correct package.json
757+ 
758+## Contributing
759+ 
760+Contributions to the Cline extension are welcome! Please follow these guidelines:
761+ 
762+When adding new tools or API providers, follow the existing patterns in the `src/integrations/` and `src/api/providers/` directories, respectively. Ensure that your code is well-documented and includes appropriate error handling.
763+ 
764+The `.clineignore` file allows users to specify files and directories that Cline should not access. When implementing new features, respect the `.clineignore` rules and ensure that your code does not attempt to read or modify ignored files.
206765  
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