Wire SDK/core telemetry into the SDK-backed VS Code session path so
`@cline/core` can emit telemetry events through the SDK
`ITelemetryService` interface, while preserving VS Code and Cline user
opt-out behavior.
- Use the SDK's own telemetry service, not the legacy extension
`TelemetryService`, for SDK/core events.
- Configure the SDK telemetry service using SDK-style OpenTelemetry
environment variables:
- `OTEL_TELEMETRY_ENABLED`
- `OTEL_METRICS_EXPORTER`
- `OTEL_LOGS_EXPORTER`
- `OTEL_TRACES_EXPORTER`
- `OTEL_EXPORTER_OTLP_PROTOCOL`
- `OTEL_EXPORTER_OTLP_ENDPOINT`
- `OTEL_EXPORTER_OTLP_HEADERS`
- `OTEL_METRIC_EXPORT_INTERVAL`
- Do not bridge the legacy extension `CLINE_OTEL_*` config into this SDK
telemetry path.
- Do not make the legacy extension `TelemetryService` implement SDK
`ITelemetryService`.
- Do not inject telemetry from `src/sdk/cline-session-factory.ts`; keep
that factory focused on session config construction from
state/provider/model settings.
- Own the shared SDK telemetry handle in `SdkController`, because it
owns the SDK session lifecycle for the VS Code extension.
- Pass the shared telemetry service down through:
- `SdkController`
- `SdkSessionLifecycle`
- `VscodeSessionHost`
- `ClineCore.create({ telemetry })`
- `CoreSessionConfig.telemetry` via
`VscodeSessionHost.prepare.applyToStartSessionInput(...)`
- Preserve existing per-session telemetry if remote config or another
prepare step already set `config.telemetry`:
```ts
telemetry: inputWithRemoteConfig.config.telemetry ?? options.telemetry
```
The SDK telemetry service must be wrapped by a VS Code/Cline policy
gate.
Ordinary telemetry includes:
- `capture(...)`
- `recordCounter(...)`
- `recordHistogram(...)`
- `recordGauge(...)`
These calls are allowed only when both are true:
1. VS Code/host telemetry is enabled.
2. Cline's `telemetrySetting` is not `"disabled"`.
`"unset"` counts as allowed, matching the existing extension behavior.
`captureRequired(...)` bypasses Cline's `telemetrySetting ===
"disabled"`, but still respects VS Code/host telemetry disabled.
This keeps VS Code's global telemetry setting as the hard privacy gate.
The wrapper starts with host telemetry disabled until
`HostProvider.env.getTelemetrySettings({})` resolves.
This is privacy-conservative: early events are dropped rather than
emitted before VS Code's host telemetry setting is known.
The wrapper also subscribes to
`HostProvider.env.subscribeToTelemetrySettings(...)` so runtime VS Code
telemetry changes are reflected.
- `SdkController` creates the shared SDK telemetry handle once.
- `SdkController.dispose()` disposes the shared SDK telemetry handle.
- `VscodeSessionHost` does not own or dispose the telemetry handle.
- `ClineCore.dispose()` does not dispose the telemetry object it
receives, so passing the shared telemetry service into per-session
`ClineCore` instances is safe.
- [x] Add `src/sdk/sdk-telemetry.ts`.
- [x] In `sdk-telemetry.ts`, create a VS Code SDK telemetry handle using
`createConfiguredTelemetryHandle(createClineTelemetryServiceConfig(...))`.
- [x] In `sdk-telemetry.ts`, add a policy wrapper implementing SDK
`ITelemetryService`.
- [x] Gate ordinary telemetry on both VS Code host telemetry and Cline
`telemetrySetting !== "disabled"`.
- [x] Gate `captureRequired(...)` on VS Code host telemetry only.
- [x] Initialize host telemetry state asynchronously from
`HostProvider.env.getTelemetrySettings({})`, defaulting to disabled
until resolved.
- [x] Subscribe to host telemetry changes via
`HostProvider.env.subscribeToTelemetrySettings(...)`.
- [x] Ensure metadata/common-property mutator methods always delegate to
the underlying SDK telemetry service.
- [x] Ensure `flush()` and `dispose()` delegate to the SDK telemetry
handle and clean up any local subscription state.
- [x] Add a shared SDK telemetry field to `SdkController`.
- [x] Create the shared telemetry handle in `SdkController`
construction.
- [x] Dispose the shared telemetry handle in `SdkController.dispose()`.
- [x] Add `telemetry?: ITelemetryService` to
`SdkSessionLifecycleOptions`.
- [x] Pass telemetry from `SdkController` into `SdkSessionLifecycle`.
- [x] Pass telemetry from `SdkSessionLifecycle` into
`VscodeSessionHost.create(...)`.
- [x] Add `telemetry?: ITelemetryService` to `VscodeSessionHostOptions`.
- [x] Pass `options.telemetry` to `ClineCore.create({ telemetry:
options.telemetry, ... })`.
- [x] In `VscodeSessionHost.prepare.applyToStartSessionInput(...)`, set
`config.telemetry` to existing `config.telemetry` or
`options.telemetry`.
- [x] Remove any telemetry injection from
`src/sdk/cline-session-factory.ts`.
- [x] Add unit coverage for the policy wrapper behavior.
- [x] Add/adjust tests for telemetry propagation through
`SdkSessionLifecycle` and `VscodeSessionHost`.
- [x] Run targeted tests for changed SDK files.
- [x] Run TypeScript validation for the touched paths.
Evidence to collect during implementation:
- SDK `session.started` is emitted through the shared SDK telemetry
service when allowed.
- SDK local runtime events that read `config.telemetry` receive the same
service.
- Ordinary events are dropped when Cline `telemetrySetting` is
`"disabled"`.
- Ordinary and required events are dropped when VS Code host telemetry
is disabled.
- Required events still emit when Cline telemetry is disabled but VS
Code host telemetry is enabled.
- Remote-config-provided `config.telemetry` is preserved and not
overwritten by the VS Code default telemetry service.
The Cline CLI (cline mcp add) writes servers in a nested transport format:
{ transport: { type, url }, disabled, oauth }
The VSCode extension only accepted the flat format it writes:
{ type, url, disabled, autoApprove }
This caused all MCP servers to silently disappear with a generic
'Invalid MCP settings schema.' error that told users nothing useful.
Changes:
- schemas.ts: Add nestedTransportConfigSchema as the first union arm in
ServerConfigSchema, placed first so the 'transport:' key acts as an
unambiguous discriminator. The transform flattens nested -> flat format
with zero downstream impact (connection logic unchanged).
- schemas.ts: Add oauth and metadata passthrough fields to BaseConfigSchema
so CLI-written OAuth state and metadata survive round-trips when the
extension modifies the file (e.g. toggling disabled).
- McpHub.ts: Dramatically improve error messages — include file path,
per-server breakdown of which fields failed (from Zod error paths), and
an 'Open Settings File' button for one-click navigation.
- schemas.test.ts: 14 new tests covering nested format, flat format,
mixed files, oauth/metadata preservation, and error rejection.
* fix: use correct base URL for Vertex AI global endpoint with Claude models
The AnthropicVertex SDK constructs the API hostname as
`${region}-aiplatform.googleapis.com`, which produces
`global-aiplatform.googleapis.com` when region is "global".
This hostname does not exist and returns 404.
Per Google Cloud docs, the correct global endpoint hostname is
`aiplatform.googleapis.com` (no region prefix). This fix overrides
the baseURL when region is "global" to use the correct hostname.
Fixes#10287
* chore: add changeset for vertex global endpoint fix
* fix: rebase on main and re-apply global endpoint baseURL override
* fix(llms): Use Google auth for Vertex Gemini
- Pass `providerConfig.gcp.projectId` through to Vertex Gemini as `googleAuthOptions.projectId`
- Disable Vertex API-key express mode when GCP project config is present so `google-auth-library` handles auth
- Add coverage for `AgentConfig.providerConfig.gcp` forwarding and Vertex Gemini provider creation
- Fix vertex model list only contains Claude models issue
* feat(core): includes tool names in tool results across messages
Updated `tool_result` content blocks to consistently include the `name` of the tool being executed. This change propagates through provider helpers and applies the new schema across all associated unit and live tests, ensuring proper tracking and logging of tool interactions within messages.
- Pass `providerConfig.gcp.projectId` through to Vertex Gemini as `googleAuthOptions.projectId`
- Disable Vertex API-key express mode when GCP project config is present so `google-auth-library` handles auth
- Add coverage for `AgentConfig.providerConfig.gcp` forwarding and Vertex Gemini provider creation
- Fix vertex model list only contains Claude models issue
* feat(runtime): track idle and pending session states
Propagate idle and pending as non-terminal session statuses across the CLI, hub records, and active-session checks. Update runtime handling so interactive sessions remain active while idle or awaiting approval instead of being treated as ended.
Removed `status` from showing up in `cline history` for now.
* hydrate: false no longer reads message files for every session.
* feat(uri): add LG task deeplink webhook integration
* feat(uri): include prompt-file path in LG task prompt
* refactor(uri): move LG webhook setup into integration service
* fix(cron): publish failed schedule execution events
Add cron runner execution event publishing for completed and failed runs.
Update connector adapters to react to failed schedule executions so clients are notified when scheduled work does not complete successfully.
* add unit tests
The new Bedrock path is not failing because credential_process is unsupported. Both old and new code use AWS SDK v3’s fromNodeProviderChain, which can load credential_process.
The practical difference is that the migrated config does not include the AWS profile name:
```
"aws": {
"region": "us-east-1",
"authentication": "profile"
}
```
There is no `"profile": "bedrock"` So the new llms provider never targets [profile bedrock]. It calls fromNodeProviderChain({ ignoreCache: true, clientConfig: { region } }), which means AWS SDK will use AWS_PROFILE if present, otherwise default.
## Cause
The migration code only migrates awsProfile when legacy awsUseProfile is true. But the old extension treats profile auth as active when awsAuthentication === "profile" too:
```
profile:
legacyGlobalState.awsAuthentication === "profile" || legacyGlobalState.awsUseProfile
? trimNonEmpty(legacyGlobalState.awsProfile)
: undefined
```
## Fixes
The migration now preserves awsProfile when awsAuthentication === "profile", even if the old awsUseProfile flag is missing. It also treats profile-based Bedrock settings as enough to migrate Bedrock without static AWS keys.
* refactor: cache global settings reads by file metadata
Avoid repeated global settings file reads by caching parsed settings and
validating the cache with path, mtime, and size. Invalidate the cache after
writes so updates remain visible, and clarify the legacy skills config name.
* refactor for performance
mtime-keyed cache of the parsed GlobalSettings — repeated reads do statSync + 4 comparisons instead of readFile + JSON.parse + zod (~30-100× speedup on hot path).
statSync(filePath, { throwIfNoEntry: false }) — avoids exception construction on missing-file path.
Cache invalidated on write — doesn't rely on filesystem mtime resolution.
loadSettingsFromDisk helper — pulls the read/parse/validate flow into one place, eliminates the previous three duplicated settingsCache = {...} assignments.
toggleDisabledTool cleaned up — single set construction + single write call, no branched copy of writeGlobalSettings.
* add unit tests for caching logic
* object freeze
All files automatically changed and formatted by `cd sdk && bun run build:models`
Generated model catalog version updated to 1779251127504
This includes the new X AI build
* fix: Speed up CLI plugin loading and config toggles
Load sandboxed plugins concurrently during initialization while preserving
existing duplicate override ordering. Update plugin tool discovery to use a
single sandbox per listing and cache descriptor results by plugin path stats,
provider, and model.
Make CLI plugin/tool config toggles persistence-only from the data loader and
update the TUI optimistically, avoiding full config reloads and repeated plugin
imports when users disable tools or plugins.
* patches
* fix: refresh plugin tools when config update lacks data
Reload config data with plugin tools included when a plugin action does not return updated data. This keeps the config view in sync and clears stale plugin tool errors after refresh.
* fix(cli): preserve config item state on missing toggle data
Only update the dialog item when toggle responses include a matching item. This avoids applying fallback enabled-state changes that can desync the UI when returned config data is missing or incomplete.
---------
Co-authored-by: Tomás Barreiro <52393857+BarreiroT@users.noreply.github.com>