* perf(file-search): route @-mention picker through host index when available
Adds a new SearchWorkspaceItems RPC on WorkspaceService that lets
hosts serve the @-mention file search from their own native index
(JetBrains FilenameIndex, eventually anything similar). When the
host returns results, core skips ripgrep entirely; when the host
throws, core falls back to ripgrep as today.
Why: on slow filesystems (the CLINE-2092 reporter is on a
2000-mile SSHFS mount) ripgrep's stat fan-out blows up to 15s+
per keystroke as it walks the workspace. JetBrains already has
the answer in memory.
Contract:
- searchWorkspaceItems thrown error -> host can't answer, use ripgrep.
- searchWorkspaceItems returns items -> authoritative, including [].
This split lets a host that says "zero matches" short-circuit the
ripgrep fallback, which is the entire point of the change for slow
filesystems.
Implementation notes:
- VS Code / CLI / ACP host adapters throw "not implemented". Core
swallows the throw silently in the @-mention path because on
these hosts the throw is steady state, not an error worth
logging on every keystroke.
- Telemetry: captureMentionSearchResults now records a search_source
property (host_index | ripgrep) so we can see how often the host
index actually picks up the load per fs_class.
- Multiroot aggregation reports source=host_index only when *every*
contributing root used the host index; any root falling back to
ripgrep marks the aggregate as ripgrep so the metric isn't misleading.
- Telemetry calls in searchFiles.ts are now fire-and-forget; the
webview shouldn't block on a metrics flush.
CLINE-2092
* fix(file-search): scope host-index per workspace root in multiroot
In multi-root projects searchWorkspaceFilesMultiroot calls
searchWorkspaceFiles once per root. Each call hit the host index
without telling it which root, so a JetBrains host returned
project-wide results; the caller then path.join'd those against the
wrong base, lstat silently swallowed the ENOENT, and the user saw
fabricated paths.
Add an optional workspace_path field to SearchWorkspaceItemsRequest
and forward the workspacePath argument into executeHostIndexForFiles.
Hosts that can't honor the field ignore it; this preserves
project-wide behavior for older plugins paired with newer core.
Surfaced in code review on CLINE-2092.
* file-search: distinguish unimplemented host index from real failures
Previously the catch in executeHostIndexForFiles returned null on every
exception with no client-side trace. That's the right behavior on
VS Code/CLI/ACP where the RPC stub throws every keystroke, but it also
hides real degradation on JetBrains (UNAVAILABLE during indexing,
INTERNAL, transport errors) — operators have no way to tell whether a
ripgrep fallback was expected or a slow-path regression.
Split: gRPC code 12 / messages matching /not implemented/i log at debug
(steady state, stays quiet); everything else logs at warn with the code
and message so degraded sessions are visible. Fallback policy unchanged
— still returns null and lets the caller use ripgrep — and core has no
useful action on the error type, so we don't propagate further.
Surfaced in code review on CLINE-2092.
* fix(file-search): dedup host folders against parent-walk inferred dirs
When the host index returns a folder explicitly (e.g. 'src') *and* a file
underneath it (e.g. 'src/main.ts') for the same query, the parent-walk that
seeds the inferred directory set was re-adding 'src' as an inferred parent,
producing two identical entries in the picker.
Pre-pass the host items to record which directory paths were returned as
explicit folders, then skip those during the parent-walk so we don't double
list them. Transitive ancestors above an explicit folder are still added
because the loop keeps walking up.
Adds a regression test that reproduces the duplicate and fails without the
fix.
* Tag mention-search telemetry with workspace filesystem class
Adds best-effort filesystem-type detection for the workspace root and
emits it as `fs_class` (local | network | unknown) and `fs_type` (apfs,
ext4, macfuse, nfs, smb, ...) on `task.mention_search_results` and
`task.mention_failed`. Lets us slice slow / empty / failing mention
searches by mount type so reports of "the @-picker is slow / returns
nothing" can be triaged against actual environment, not anecdote.
Implementation:
- `src/utils/fs-info.ts` — `getFsInfo(path)`, cached per-path for the
process lifetime (filesystems don't change at runtime). Returns the
`unknown` sentinel on every error path; the picker must never break
because of telemetry. Detection is platform-specific:
* macOS: parses `mount(8)` output and picks the longest matching
mount point. BSD `stat` has no portable filesystem-type flag —
`stat -f` is a format-string mode where `%T` means "file type"
(regular/directory/etc.), not "filesystem type", which is a
common pitfall when porting Linux scripts.
* Linux: GNU `stat -f -c %T -- /path` returns the FS type as a
string ("ext2/ext3", "btrfs", "fuseblk", ...).
* Windows: not implemented yet, returns the unknown sentinel.
`GetVolumeInformationW`/`GetDriveType` would be the way in if
signal warrants it.
Symlinks are resolved with `fs.realpath` before matching so e.g.
`/tmp` (a symlink to `/private/tmp` on macOS) classifies correctly.
All FUSE variants — sshfs, FUSE-T, NTFS-3G, gocryptfs, rclone — are
bucketed as "network" because macFUSE doesn't expose the underlying
driver and they share the not-actually-local performance profile
that motivated this work.
- `src/services/telemetry/TelemetryService.ts` — both
`captureMentionSearchResults` and `captureMentionFailed` gain an
optional `fsContext` parameter; properties are emitted sparsely so
the nine existing `captureMentionFailed` callsites in
`mentions/index.ts` are untouched.
- `src/core/controller/file/searchFiles.ts` — declares `fsContextPath`
at function scope so the catch block can also pass it; sets it from
the resolved workspace path (multi-root: primary root only — tagging
per-root would mean per-root events, which we'd rather defer until
we see signal). Hits both success and error paths.
- `src/utils/fs-info.test.ts` — covers undefined / empty / non-existent
paths, tmpdir classification, and cache-hit identity.
PostHog properties are schemaless, so no schema migration: `fs_class`
and `fs_type` start appearing in the events index automatically once
the first event with them lands. Pre-PR events have those properties
NULL, so dashboard queries should scope to `timestamp >= <merge-time>`
for clean network-vs-local comparisons.
* Tag mention-search telemetry with workspace filesystem class - fixes
* Tag mention-search telemetry with workspace filesystem class - fixes
* Don't block searchFiles response on FS-class telemetry
Move getFsInfo() + telemetryService.capture* off the awaited path in
searchFiles. The picker awaits this RPC on every keystroke, so any
delay here translates directly into a frozen UI; we already saw a
report (CLINE-1814) where SSHFS made the realpath/mount lookups slow
enough that users saw an apparent 'no results' state until the call
completed. Capture is now scheduled via a fire-and-forget helper that
swallows and logs errors.
Also add a 3s outer Promise.race timeout in fs-info around realpath +
mount detection. The inner execFile already has its own 2s, but
realpath has no timeout and a stale network mount can hang it. With
the outer cap, getFsInfo always settles within ~3s and falls back to
the unknown sentinel. The picker no longer waits on it anyway, but
this also keeps the per-process cache from being polluted by an
indefinitely pending entry.
* Tag fs-class telemetry against the workspace actually searched
In multi-root mode searchFiles always wrote getRoots()[0] into
fsContextPath, so a search hinted at a slow secondary root
(e.g. an SSHFS-backed sibling of a local-disk primary) was tagged as
the primary's fsClass. That hides exactly the cases we wrote this
telemetry to surface.
Resolve workspaceHint to its root the same way searchWorkspaceFilesMultiroot
does (by name first, then by path), and tag against that. Cross-root
searches with no hint still fall back to the primary root — attributing
a single event correctly there would require per-root events, deferred
until we see signal.
Don't poison the fs-info cache with UNKNOWN
Previously every getFsInfo() result, including the shared UNKNOWN
sentinel returned by failure paths (timeout, exec error, unsupported
platform), was written to the per-process cache. A single transient
slow detection — exactly the case this telemetry was added to surface
— would therefore tag that path as 'unknown' for the rest of the
process and never re-attempt classification.
Skip the cache write when info === UNKNOWN. Reference equality
distinguishes the failure sentinel from a successful detect() that
happens to land in the 'unknown' bucket (which returns a fresh object
with a real fsType — that result is still cached normally).
Adds a _getFsInfoCacheSizeForTests helper and a test that asserts the
cache stays empty across UNKNOWN-returning calls, then grows by one
on a successful classify.
The previous copy ("Cline is moving out of the terminal", "old CLI")
gave the impression that the terminal TUI was being deprecated. Updated
to frame Kanban as the new default while making clear the TUI is still
fully available.
* feat(cli): unify update flow for cline and kanban
* fix(cli): only install kanban when update is available
* fix(cli): include cline and kanban versions in no-update message
The migration announcement didn't explain what Kanban is. Swap the
"run cline --tui" line for a one-liner describing the product so users
know what they're opting into. The --tui escape hatch is still
discoverable via the Exit menu item.
* feat(cli): refresh welcome banner and kanban launcher
* feat(cli): launch kanban by default with migration view
* feat(cli): add kanban process lifecycle management
Detach the kanban child process on Unix so it gets its own process
group, forward signals to the group for graceful shutdown, and fall
back to SIGKILL after a 10s timeout. Resolves exit codes from signals
correctly (130 for SIGINT, 143 for SIGTERM).
* fix(cli): use kanban@latest to always fetch newest version
npx -y kanban may use a cached version. Using @latest ensures
users always get the most recent kanban release.
* chore(cli): bump version to 2.8.2 and update changelog
* Implement minimal change set for latency improvements
Cline's code review improvements
Further code review improvements
* fix: address code review issues for presentation scheduler
- Add reset() method to TaskPresentationScheduler to prevent stale
timer leaks between API request retries within the same task
- Call presentationScheduler.reset() in streaming state reset section
- Fix hadVisibleAssistantContent to track reasoning content, not just
text, preventing every reasoning chunk from getting immediate priority
- Remove unused 'low' priority from PresentationPriority type and
associated cadence configuration (YAGNI)
- Trim TaskLatencyTrigger to only values actually used: text/reasoning/tool
- Add JSDoc to isRemoteWorkspaceEnvironment documenting the heuristic
fallback and its false-positive risk
- Add Logger.warn for invalid cadence env-var overrides
- Add comment at scheduler construction explaining detection promise
dependency on remoteWorkspaceDetectionPromise
- Add comments to CLI host bridge about intentional remoteName omission
- Expand test coverage: reset(), coalescing, priority upgrade tests
* fix: address code review issues in latency/presentation scheduler
- Fix #1/#3: Set didPresentAnyContent=true for text and tool_calls chunks
so coalescing actually activates for text-only and tool streams (was
only set for reasoning chunks, defeating the 40/90ms cadence goal)
- Fix#2: Re-check flushInProgress after awaiting in-flight flush in
runFlushCycle to prevent two concurrent callers from both proceeding
past the guard and starting concurrent flushes
- Fix#4: Document flushNow() disposed no-op contract so callers
understand the finalization guarantee
- Fix#5: Add disposed guard to reset() to prevent post-dispose state
mutation
- Fix#6: Remove platform/version heuristic from isRemoteWorkspaceEnvironment
— only use remoteName. The substring match on 'remote' produced false
positives for version strings like '1.0.0-remote-fix'. Non-VSCode hosts
should populate remoteName explicitly to opt in to the higher cadence.
- Fix#7: Add remoteWorkspaceDetectionSettled flag and warn if getDelayMs
is called before detection resolves, making the timing dependency
explicit and detectable in production logs
- Fix#8: Upgrade disabled-scheduler bypass error from Logger.debug to
Logger.warn so silent flush failures are visible
- Update latency.test.ts: replace heuristic test with false-positive
regression tests and add null/empty-field coverage
* fix: address code review issues in latency/presentation scheduler
- Fix flushNow race condition: wait for all in-flight flushes to drain
before setting pendingPriority so the post-flush continuation cannot
steal it, guaranteeing at least one flush runs after flushNow() returns
- Add regression test for the flushNow race condition
- Fix disabled-path (CLINE_DISABLE_PRESENTATION_SCHEDULER): use
presentationScheduler.flushNow() instead of a fire-and-forget void
call so the presentAssistantMessage lock/pending-updates mechanism
is respected when the scheduler is bypassed
- Rename didPresentAnyContent -> didScheduleAnyContent to accurately
reflect that content has been scheduled, not necessarily flushed
- Update stale comment in streaming loop to match new variable semantics
- Upgrade remote workspace detection failure log level from debug to warn
- Document reset() interaction with in-flight flush on already-reset state
- Document empty-string remoteName edge case in getHostVersion.ts
* refactor: polish presentation scheduler for production readiness
- Extract PresentationPriority type to shared presentation-types.ts,
breaking the latency.ts → TaskPresentationScheduler.ts type coupling
- Remove redundant pendingWhileFlushing flag from TaskPresentationScheduler;
pendingPriority alone is sufficient for the post-flush continuation check
- Cache env var reads in latency.ts at module load (hot path optimization)
- Inline flushAssistantPresentation() one-liner into the scheduler constructor
- Make processNativeToolCalls protected to enable type-safe test access
- Remove as any cast in Task.processNativeToolCalls.test.ts
* Fixes as per Greptile review feedback
* Further fixes as per Greptile feedback
* Further fixes as per Greptile feedback
* feat(wandb): add W&B Inference by CoreWeave provider
Adds support for W&B Inference as an API provider using a W&B API key.
Implements a provider handler with OpenAI-compatible streaming and a static
model catalog, and wires the provider through the API layer, configuration
schema, storage, CLI model picker, and settings UI.
* Updated input/output price of NVIDIA-Nemotron
* Updated helpText
* handle reasoning tokens in streaming respons
* Added clarifying comment on how W&B token usage is reported and why cached tokens
* fix: restore proto field numbers changed by generation script
* Update src/core/api/providers/wandb.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
- calling telemetry service before initializeCli call causes a
"hostprovider not initialized error", which invokes errorservice, which
causes another "hostprovider not initialized error", which was breaking
this cline use case: echo "say hello" | cline
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
- cli was storing fields to persistent state when it shouldn't be. The
value of these flags should only live for the duration of the CLI
session
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
Exposes the existing useAutoCondense setting as a CLI flag, following
the same pattern as --double-check-completion. This allows enabling
auto-condense in eval runs (e.g. SWE-bench via Harbor) to reduce
context exhaustion failures.
Made-with: Cursor
* Add implementation plan doc
* feat(hooks): reintroduce runtime hooks feature toggle
* fix: thread effective hooks toggle through hook execution
* test: cover hooks feature toggle visibility and settings wiring
* Remove implementation plan doc
* Move Hooks toggle to Advanced section in Feature Settings
* Fixes as per PR feedback
* Clarifying hooksEnabled
* Make hooksEnabled true by default
* Further fixes as per Greptile feedback
* Further fixes as per Greptile feedback
* Fix failing tests
* feat(cli): add --hooks-dir flag for runtime hook injection
Adds a --hooks-dir <path> CLI flag that allows passing an additional
hooks directory at spawn time. This enables orchestration tools (like
Kanbanana) to inject per-session lifecycle hooks without mutating
the user's global or workspace hooks directories.
The runtime hooks directory is included alongside existing global
(~/Documents/Cline/Hooks/) and workspace (.clinerules/hooks/)
directories during hook discovery. All hooks from all directories
are merged and run in parallel, so runtime hooks are purely additive.
* fix(cli): initialize runtime hooks before interactive startup