| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 9 | 11 | 0% |
| Commands | 0 | 8 | 11 | 0% |
| Section tags | 5 | 1 | 4 | 50% |
What each file covers
Sections
0 shared · 9 only in A · 11 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 SDK — Development Reference
- + Repository Scope
- + Package Boundaries
- + Published SDK Packages
- + Dependency Direction
- + Change Routing
- + Verifying Changes
- + Practical Guidance
- + Keep Boundaries Clean
- + Refactor Standard
- + Documentation Responsibilities
Commands
0 shared · 8 only in A · 11 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
- + bun install --frozen-lockfile
- + bun run build:sdk
- + bun run types
- + bun run test
- + bun run check
- + bun -F @cline/shared test
- + bun -F @cline/llms test
- + bun -F @cline/agents test
- + bun -F @cline/core test:unit
- + bun -F @cline/cli test:unit
- + bun test sdk/...
Section tags
5 shared · 1 only in A · 4 only in B- − security
- + test
- + dependencies
- + monorepo
- + docs
- setup
- build
- code-style
- architecture
- deployment
Line diff
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 · sdk/AGENTS.md
@@ +1 @@
1---
2description: Development reference for the Cline SDK workspace.
3globs: "*.ts,*.tsx,*.js,*.jsx,*.json,*.md"
4alwaysApply: true
5---
6
7# Cline SDK — Development Reference
8
9Quick-reference for active development. For onboarding, workspace setup, publishing, and detailed workflow see [CONTRIBUTING.md](./CONTRIBUTING.md). For architecture and runtime flows see [ARCHITECTURE.md](./ARCHITECTURE.md). For API details see [DOC.md](./DOC.md).
10
11## Repository Scope
12
13This file applies to the SDK workspace rooted at this directory (`sdk/`). In this repo, "root" means the SDK workspace root unless explicitly stated otherwise. Ignore the legacy repository root for SDK development except for Git operations or repo-wide searches that are explicitly needed.
14
15Run SDK commands from `sdk/`, not from the legacy repository root. Do not run direct root-level commands such as `bun test sdk/...`; they bypass the SDK workspace setup and can fail to resolve `workspace:*` packages correctly.
16
17## Package Boundaries
18
19### Published SDK Packages
20
21- `@cline/shared`: shared contracts, schemas, path helpers, hook engine, extension registry, low-level utilities
22- `@cline/llms`: provider settings/config, model catalogs, provider manifests, gateway contracts, handler creation
23- `@cline/agents`: stateless agent loop, tool orchestration, hook/extension runtime, event streaming
24- `@cline/core`: stateful orchestration, session lifecycle, storage, config watching, plugin loading, default tools, telemetry. Exposes `@cline/core/hub` for discovery, the detached daemon entry, WebSocket clients, and session/UI client adapters, plus `@cline/core/hub/daemon-entry` for launching the shared daemon
25
26### Dependency Direction
27
28```mermaid
29flowchart TD
30 shared["@cline/shared"] --> llms["@cline/llms"] & agents["@cline/agents"] & core["@cline/core"]
31 llms --> agents & core
32 agents --> core
33 core --> apps["CLI / VS Code / Code App"]
34```
35
36Rules:
37- `shared` stays low-level and reusable
38- `agents` stays stateless — no session/storage/config concerns
39- `core` owns stateful orchestration, including the shared-hub daemon, server, and client adapters under `src/hub/`
40
41## Change Routing
42
43Route changes to the package that owns the concern:
44
45- model/provider schemas or handler behavior: `@cline/llms`
46- stateless loop, tool orchestration, streaming, hook/extension runtime: `@cline/agents`
47- session lifecycle, storage, config watching, default tools, plugin loading, telemetry, hub runtime services, hub discovery, hub daemon spawn, and session-oriented client helpers (`HubSessionClient`, `HubUIClient`, `connectToHub`): `@cline/core` (hub pieces live under `src/hub/`)
48- remote-config schemas, managed instruction materialization, blob upload metadata, and OpenTelemetry config normalization: `@cline/shared/src/remote-config`
49- host-specific UX or shell behavior: app package
50
51## Verifying Changes
52
53Before testing in a fresh worktree, install SDK dependencies from the SDK workspace root:
54
55```sh
56cd sdk
57bun install --frozen-lockfile
58```
59
60SDK package exports resolve sibling packages through compiled `dist/` files. If `dist/` is missing, build the SDK packages before running package tests:
61
62```sh
63bun run build:sdk
64```
65
66SDK-root commands for cross-package confidence:
67
68```sh
69bun run types # typecheck all packages
70bun run test # run all tests
71bun run check # lint + build + typecheck + check-publish
72```
73
74For focused verification, prefer workspace package scripts from the SDK root:
75
76```sh
77bun -F @cline/shared test
78bun -F @cline/llms test
79bun -F @cline/agents test
80bun -F @cline/core test:unit
81bun -F @cline/cli test:unit
82```
83
84If a focused test command fails with a missing `@cline/*` export or missing `dist/` file, build the relevant dependency package or run `bun run build:sdk`, then rerun the same test command. Treat that as a workspace setup issue, not as evidence of a source-code bug.
85
86If you touch hub/bootstrap/session flows, please update `ARCHITECTURE.md`.
87
88## Practical Guidance
89
90### Keep Boundaries Clean
91
92- Don't move stateful logic down into `agents`
93- For `@cline/llms` provider/model routing rules, follow [packages/llms/AGENTS.md](./packages/llms/AGENTS.md).
94- Don't put app-specific behavior into `core` unless it is truly shared host behavior
95- Keep remote-config primitives generic in `shared`; host-facing session integration belongs in `core`
96
97### Refactor Standard
98
99- Prefer direct architectural cleanup over compatibility shims
100- Move code to the layer that owns the concern and update all call sites
101- If a helper just projects watcher state, keep it with the config layer instead of creating thin runtime wrappers
102
103## Documentation Responsibilities
104
105- `README.md`: visitor-facing overview. Update when the repo story or package inventory changes.
106- `CONTRIBUTING.md`: onboarding, workflow, publishing. Update when contributor setup or release process changes.
107- `AGENTS.md` (this file): development reference. Update when package boundaries, dependency rules, or change routing changes.
108- `ARCHITECTURE.md`: design, boundaries, runtime flows. Update when system design or architectural constraints change.
109- `DOC.md`: API and behavior reference. Update when exported surfaces, lifecycle semantics, or runtime behavior changes.
110
@@ −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+---
2+description: Development reference for the Cline SDK workspace.
3+globs: "*.ts,*.tsx,*.js,*.jsx,*.json,*.md"
4+alwaysApply: true
5+---
26
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"
7+# Cline SDK — Development Reference
108
11−**Proactively suggest additions** when any of the above happen—don't wait to be asked.
9+Quick-reference for active development. For onboarding, workspace setup, publishing, and detailed workflow see [CONTRIBUTING.md](./CONTRIBUTING.md). For architecture and runtime flows see [ARCHITECTURE.md](./ARCHITECTURE.md). For API details see [DOC.md](./DOC.md).
1210
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.
11+## Repository Scope
1412
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
13+This file applies to the SDK workspace rooted at this directory (`sdk/`). In this repo, "root" means the SDK workspace root unless explicitly stated otherwise. Ignore the legacy repository root for SDK development except for Git operations or repo-wide searches that are explicitly needed.
2314
24−## Searching the Codebase — Avoiding Build Output
15+Run SDK commands from `sdk/`, not from the legacy repository root. Do not run direct root-level commands such as `bun test sdk/...`; they bypass the SDK workspace setup and can fail to resolve `workspace:*` packages correctly.
2516
26−Several directories contain build output or generated code that produces
27−noisy or unusable results with `search_files` / `grep`:
17+## Package Boundaries
2818
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 |
19+### Published SDK Packages
3720
38−### How to skip build output
21+- `@cline/shared`: shared contracts, schemas, path helpers, hook engine, extension registry, low-level utilities
22+- `@cline/llms`: provider settings/config, model catalogs, provider manifests, gateway contracts, handler creation
23+- `@cline/agents`: stateless agent loop, tool orchestration, hook/extension runtime, event streaming
24+- `@cline/core`: stateful orchestration, session lifecycle, storage, config watching, plugin loading, default tools, telemetry. Exposes `@cline/core/hub` for discovery, the detached daemon entry, WebSocket clients, and session/UI client adapters, plus `@cline/core/hub/daemon-entry` for launching the shared daemon
3925
40−**`search_files`** — Point at `src/` (not the project root) and use `file_pattern`:
41−```
42−search_files(path="src/core", regex="myFunction", file_pattern="*.ts")
43−```
44−The `file_pattern` parameter is the most effective filter — e.g. `"*.ts"`,
45−`"*.tsx"`, `"*.proto"`.
26+### Dependency Direction
4627
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}
28+```mermaid
29+flowchart TD
30+ shared["@cline/shared"] --> llms["@cline/llms"] & agents["@cline/agents"] & core["@cline/core"]
31+ llms --> agents & core
32+ agents --> core
33+ core --> apps["CLI / VS Code / Code App"]
5034 ```
5135
52−### When you must search minified files
36+Rules:
37+- `shared` stays low-level and reusable
38+- `agents` stays stateless — no session/storage/config concerns
39+- `core` owns stateful orchestration, including the shared-hub daemon, server, and client adapters under `src/hub/`
5340
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:
41+## Change Routing
5742
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.
43+Route changes to the package that owns the concern:
6644
67−## gRPC/Protobuf Communication
68−The extension and webview communicate via gRPC-like protocol over VS Code message passing.
45+- model/provider schemas or handler behavior: `@cline/llms`
46+- stateless loop, tool orchestration, streaming, hook/extension runtime: `@cline/agents`
47+- session lifecycle, storage, config watching, default tools, plugin loading, telemetry, hub runtime services, hub discovery, hub daemon spawn, and session-oriented client helpers (`HubSessionClient`, `HubUIClient`, `connectToHub`): `@cline/core` (hub pieces live under `src/hub/`)
48+- remote-config schemas, managed instruction materialization, blob upload metadata, and OpenTelemetry config normalization: `@cline/shared/src/remote-config`
49+- host-specific UX or shell behavior: app package
6950
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`)
51+## Verifying Changes
7652
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
53+Before testing in a fresh worktree, install SDK dependencies from the SDK workspace root:
8254
83−**Adding new enum values** (like a new `ClineSay` type) requires updating conversion mappings in `src/shared/proto-conversions/cline-message.ts`
55+```sh
56+cd sdk
57+bun install --frozen-lockfile
58+```
8459
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" }))`
60+SDK package exports resolve sibling packages through compiled `dist/` files. If `dist/` is missing, build the SDK packages before running package tests:
8861
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
62+```sh
63+bun run build:sdk
64+```
9665
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.
66+SDK-root commands for cross-package confidence:
9967
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
104−
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.
106−
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.
111−
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.
117−
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()`.
120−
121−Exception: host migration code may read legacy VS Code storage before file-backed storage is initialized.
122−
123−Example pattern:
124−```typescript
125−// Writing (normal pattern)
126−controller.stateManager.setGlobalState("myKey", value)
127−
128−// Reading after initialization
129−const value = controller.stateManager.getGlobalStateKey("myKey")
68+```sh
69+bun run types # typecheck all packages
70+bun run test # run all tests
71+bun run check # lint + build + typecheck + check-publish
13072 ```
13173
132−Use `context.globalState` only in VS Code migration code that copies legacy ExtensionContext values into the shared file-backed stores.
74+For focused verification, prefer workspace package scripts from the SDK root:
13375
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.
136−
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
143−
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
76+```sh
77+bun -F @cline/shared test
78+bun -F @cline/llms test
79+bun -F @cline/agents test
80+bun -F @cline/core test:unit
81+bun -F @cline/cli test:unit
15282 ```
15383
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"
84+If a focused test command fails with a missing `@cline/*` export or missing `dist/` file, build the relevant dependency package or run `bun run build:sdk`, then rerun the same test command. Treat that as a workspace setup issue, not as evidence of a source-code bug.
15785
158−**See also:** `BrowserSessionRow.tsx` uses similar pattern with `isLastApiReqInterrupted` and `isLastMessageResume`.
86+If you touch hub/bootstrap/session flows, please update `ARCHITECTURE.md`.
15987
160−**Backend side:** When streaming is cancelled, clean up properly (close tabs, clear comments, etc.) by checking `taskState.abort` after the streaming function returns.
88+## Practical Guidance
16189
162−## Debug Harness: clear inherited VSCode/Electron env vars before launching
90+### Keep Boundaries Clean
16391
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.
92+- Don't move stateful logic down into `agents`
93+- For `@cline/llms` provider/model routing rules, follow [packages/llms/AGENTS.md](./packages/llms/AGENTS.md).
94+- Don't put app-specific behavior into `core` unless it is truly shared host behavior
95+- Keep remote-config primitives generic in `shared`; host-facing session integration belongs in `core`
16996
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:
97+### Refactor Standard
17298
173−```
174−.../Visual Studio Code.app/Contents/MacOS/Code: bad option: --extensionDevelopmentPath=...
175−Error: Process failed to launch! (Playwright _electron.launch)
176−```
99+- Prefer direct architectural cleanup over compatibility shims
100+- Move code to the layer that owns the concern and update all call sites
101+- If a helper just projects watcher state, keep it with the config layer instead of creating thin runtime wrappers
177102
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:
103+## Documentation Responsibilities
180104
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
187−```
188−
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.
191−
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.
205−
105+- `README.md`: visitor-facing overview. Update when the repo story or package inventory changes.
106+- `CONTRIBUTING.md`: onboarding, workflow, publishing. Update when contributor setup or release process changes.
107+- `AGENTS.md` (this file): development reference. Update when package boundaries, dependency rules, or change routing changes.
108+- `ARCHITECTURE.md`: design, boundaries, runtime flows. Update when system design or architectural constraints change.
109+- `DOC.md`: API and behavior reference. Update when exported surfaces, lifecycle semantics, or runtime behavior changes.
206110
