* 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.
* 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
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>
* fix(cli): keep failed plugins visible in config UI ENG-2073
Preserve plugins that fail during load or setup and attach their
diagnostic phase and error message. Surface those errors in config detail
rows so users can identify and fix broken plugin definitions.
* fix(cli): preserve multiple plugin initialization failures
Aggregate all setup/load failures per plugin path instead of overwriting earlier errors. Summarize multiple errors in the config UI so rows remain readable while retaining the full failure details.
Destructure `loadConfigData` from `props` alongside the other props already
destructured at the top of `ConfigPanelContent`, and use the local binding in
the plugin-tools `useEffect` (both inside the body and in the dependency
array). This clears two Biome `lint/correctness/useExhaustiveDependencies`
errors introduced by #10819:
sdk/apps/cli/src/tui/views/config-view.tsx:265:2
× This hook specifies a dependency more specific than its captures:
props.loadConfigData
× This hook does not specify its dependency on props.
The previous shape mixed `props.loadConfigData` in the dep array with `props`
captures inside the effect body, which Biome flags because it cannot prove
that re-reading `props.loadConfigData` between renders is equivalent to
re-reading `props`. Destructuring once at the top resolves both diagnostics
without broadening the dep set to all of `props` (the rule's suggested
"unsafe fix") — the effect still only refires when `loadConfigData` itself
changes, matching the original intent.
No behavior change. The destructure pattern matches how `resolve`, `dismiss`,
`dialogId`, and `config` are already pulled off `props` on the same line.
The failure was first surfaced by the JetBrains-plugin integration workflow
on PR #10819, where `cline/intellij-plugin`'s `:buildClineCoreZip` task runs
`npm run lint` against the merged tree. Verified locally with:
npx @biomejs/biome lint --diagnostic-level=error \
sdk/apps/cli/src/tui/views/config-view.tsx
— clean, exit 0. Full repo `biome lint`: 2537 files, no errors.
* fix(cli): resolve macOS screenshot paths with narrow no-break space
macOS Sonoma+ embeds U+202F (NARROW NO-BREAK SPACE) before AM/PM in
screenshot filenames like "Screenshot 2026-05-12 at 4.42.48\u202FPM.png".
When the path travels through clipboards, terminals, or anything that
normalizes whitespace, U+202F collapses to a regular space (U+0020) --
but the on-disk filename still contains U+202F, so readFileSync fails
with ENOENT and the paste handler silently drops the image.
Add resolveExistingImagePath() with a tiered Unicode-variant lookup
(narrow no-break space before AM/PM, NFD normalization, curly
apostrophe for localized names, and a parent-directory canonical-
whitespace scan as a last-resort fallback). Wire it into the TUI image
paste handler so dragged/pasted screenshots resolve correctly.
Tests added in image-paste.test.ts cover both the targeted AM/PM
variant and the generic NBSP-in-filename fallback path.
* fix(core): resolve macOS U+202F screenshot paths in read_files tool
The first commit on this branch fixed the CLI image-paste handler only.
A live repro from session 1778635423953_jac9b showed the same U+202F bug
on a different surface: the agent`s read_files tool. When the LLM was
asked about a macOS screenshot, it called read_files with the path text
from the user message -- which had a regular space where the on-disk
filename has U+202F -- and fs.stat returned ENOENT.
Extract the tiered Unicode-variant resolver into @cline/shared as
resolveExistingFilePath (the algorithm is generic, not image-specific).
Wire it into:
- packages/core/src/extensions/tools/executors/file-read.ts (the
new fix; read_files now tolerates U+202F / NFD / curly apostrophe
variants before falling back to a parent-dir scan).
- apps/cli/src/utils/image-attachments.ts (refactor to use the
shared helper instead of duplicating the algorithm).
Regression tests in packages/shared/src/path-resolution.test.ts and
packages/core/src/extensions/tools/executors/file-read.test.ts; the
CLI tests from the first commit continue to pass via the shared helper.
Live verification against the real screenshot from the bug repro
(/Users/robin/Desktop/Screenshots/Screenshot 2026-05-12 at 6.18.40 PM.png,
on-disk name uses U+202F): direct invocation of the executor with a
regular-space path now returns an image block (42,296 bytes) instead
of throwing ENOENT.
* fix(shared): tighten unicode path variant probes
* fix(shared): move path resolver to storage exports
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* feat(cli): add --worktree flag to auto-create and run in a new git worktree
Adds a --worktree flag to the CLI root command and 'cline task' that detects the git repo root for the current directory, creates a detached-HEAD worktree at ~/.cline/worktrees/<uuid>/<repoName>/ (matching Kanban's convention), and runs the task with cwd set to the new worktree.
The core implementation lives in src/utils/git-worktree.ts as createTaskWorktree() so any surface (CLI, VS Code, JetBrains, future tools) can use the same helper.
Works with --taskId and --continue so the legitimate workflow of 'resume this task in a fresh clean worktree to try a different approach' is supported. For --continue, the most-recent-task lookup uses the original cwd before the worktree rewrite so history resolves correctly.
Refs: ENG-2028
* address greptile review
- Distinguish 'git not installed' from 'not a git repo' so the error message points at the actual problem instead of misleading the user.
- Reject taskIds containing a null byte; would otherwise sneak past the '..' substring check on some kernels (e.g. 'safe\\0../escape').
- Reject `--worktree` without a prompt / --taskId / --continue before kanban auto-launches, so 'cline --worktree' no longer creates an orphan worktree that's abandoned if the user exits the welcome TUI without submitting a task.
* feat(cli): move worktree flag to sdk cli
* fix(cli): match kanban worktree ids
* fix(cli): handle piped worktree input
* chore: remove legacy worktree diff
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* feat(core): add user.provider_configured event and captureProviderConfigured helper
Adds a new standardized telemetry event for when a user successfully
saves a BYO (bring-your-own) provider API key, separate from the
existing user.auth_* OAuth events.
- Add USER.PROVIDER_CONFIGURED = 'user.provider_configured' to the
core event registry.
- Add captureProviderConfigured(telemetry, provider) helper that
mirrors the { provider } payload shape of captureAuthSucceeded and
routes through capture() (so it respects telemetry opt-out).
- Export captureProviderConfigured from @cline/core.
- Add focused tests for payload shape, provider=undefined fallback,
and telemetry=undefined no-op.
* feat(core): thread optional telemetry through loginLocalProvider
Adds an optional telemetry parameter to loginLocalProvider so callers
can opt into standardized auth event emission without changing
existing behavior when no telemetry is passed.
- loginLocalProvider() accepts optional telemetry service.
- Forwards telemetry to loginClineOAuth, loginOcaOAuth, and
loginOpenAICodex for the start/success/failure auth events.
- For Cline device-code login, passes telemetry into
completeClineDeviceAuth().
- Telemetry remains optional throughout; existing callers continue to
compile and run unchanged.
* feat(sdk-tui): emit auth and provider_configured telemetry in onboarding flows
Wires the SDK TUI onboarding login page into the standardized
telemetry events introduced in earlier commits.
- runOAuthAuthFlow() and runDeviceCodeAuthFlow() accept an optional
telemetry service and forward it into loginLocalProvider so the
start/success/failure auth events fire from the underlying core
auth helpers.
- useOnboardingController() passes getCliTelemetryService() into the
OAuth and device-code login paths so events use existing CLI
metadata and respect telemetry opt-out.
- saveByoConfig() fires captureProviderConfigured for the BYO
(bring-your-own API key) onboarding path right after the
credential save. Invalid credentials still surface later as the
existing task.provider_api_error on the first API call.
- Esc/cancel remains a local abort and does not synthesize extra
failure telemetry unless the underlying auth helper itself emits
an error.
- Adds a focused test confirming the SDK TUI auth path passes
telemetry into the underlying auth helpers.
ENG-2018
* test(core): lock in telemetry opt-out policy for captureProviderConfigured
Adds captureProviderConfigured to the existing telemetry-policy
regression suite (`describe("telemetry policy: helpers respect
telemetry opt-out")`) so a disabled adapter is verified to drop the
event end-to-end through a real TelemetryService instance, matching
the coverage the other capture* helpers already have.
Addresses PR #10686 review feedback.
* test(core): include captureProviderConfigured in disabled-adapter policy test
The policy regression test that asserts a correctly-policed disabled
adapter drops all non-required events was missing a call to
captureProviderConfigured. Add it alongside the other captures and
include the expected dropped event in the assertion.
Display session status labels in CLI history output and refresh the
standalone history TUI so running sessions can update in place.
Merge refreshed status rows with existing hydrated metadata to preserve
titles and cost details while keeping status current.
* feat(sdk): emit telemetry for compaction lifecycle events
Adds two SDK telemetry events to give us observability into the
compaction pipeline, which previously only fired a generic
`agent.status-notice` pass-through that carried no result data.
- `task.compaction_executed` fires after a successful compaction with
strategy, mode, before/after message counts, before/after token
counts, threshold, durationMs, provider, modelId, and agent identity.
- `task.compaction_skipped` fires when the configured strategy returns
`undefined` (reason: "no_result"). Strategy exceptions still propagate.
`createContextCompactionPrepareTurn` is extended to accept `telemetry`
and `sessionId` from `CoreSessionConfig`; the CLI manual `/compact`
path forwards both so manual compactions emit events alongside auto.
Known gap (documented inline): plugin `registerMessageBuilder()` and
runtime hook `beforeModel` compactions bypass this wrapper and emit no
telemetry today.
Field names follow the existing `TASK.*` capture-function convention
(`provider`, `modelId`, `ulid`, `Partial<TelemetryAgentIdentityProperties>`)
so downstream PostHog joins remain consistent.
Fixes CLINE-2174
* test(sdk): cover compaction telemetry opt-out policy
* fix(cli): wire telemetry service into run config so compaction events fire