* chore: bump @clinebot/* packages to 0 0.0.38
Upgrade @ai-sdk providers (amazon-bedrock, anthropic, gateway, google) and
@clinebot packages from v0.0.37 to v0.0.38. Adjust the return type of
_createSwitchToActModeTool() to AgentTool and update test imports to use
SdkSessionHost to match the updated core library.
* fix empty workspace
* remove resolveSdkWorkspaceRoot
Instead of aggressively closing idle terminals and warning about busy
ones when the terminal profile changes, we now simply update the setting.
Existing terminals stay open and remain eligible for reuse if the user
switches back. New terminals use the new profile, and getOrCreateTerminal()
skips terminals with a different effective shell during reuse matching.
- Simplified setDefaultTerminalProfile() to void return
- Removed handleTerminalProfileChange() (dead code)
- Removed terminal close/warn notifications from updateSettings.ts
and updateSettingsCli.ts
- Cleaned up unused imports
Previously, terminal matching compared raw shellPath values directly:
- 'default' profile terminals had shellPath=undefined
- 'zsh' profile terminals had shellPath='/bin/zsh'
These never matched, even though on macOS they resolve to the same shell.
Now effectiveShellPath() resolves undefined (default) to the actual
default shell via getShell(), so switching between 'zsh' and 'default'
on macOS won't needlessly close compatible terminals, and terminal reuse
correctly matches terminals running the same effective shell.
When a non-default shell profile is selected (e.g. bash), the terminal
was spawning the correct shell binary via shellPath but inheriting
$SHELL from the parent process (VSCode extension host), which still
pointed to the user's login shell (e.g. /bin/zsh). This caused child
processes that read $SHELL (make, npm scripts, etc.) to see the wrong
shell.
Now VscodeTerminalRegistry.createTerminal() sets SHELL in the terminal's
env to match the shellPath when a specific profile is selected.
When the user changes terminal settings (shell profile, timeout, reuse,
output limit) while terminals are open, the changes now propagate
immediately to the live VscodeTerminalManager instance via
controller.terminalManager (a public getter on SdkController).
Previously, updateSettings.ts and updateSettingsCli.ts tried to access
controller.task.terminalManager which doesn't exist in the SDK controller.
Now they use controller.terminalManager which is the shared instance
created lazily in SdkController.
When the lazy VscodeTerminalManager is first created, applyTerminalSettings()
reads from StateManager and configures:
- defaultTerminalProfile (shell choice: default/zsh/bash/etc.)
- shellIntegrationTimeout
- terminalReuseEnabled
- terminalOutputLineLimit
Also exposes a public terminalManager getter so updateSettings handlers
can apply runtime changes to the existing instance.
Introduces a VSCode-specific run_commands tool that replaces the SDK's
built-in version. This is an IDE-level feature built on top of the SDK,
not integrated into the SDK itself.
The tool supports two execution modes, switchable dynamically:
- Foreground (vscodeTerminal): Uses VscodeTerminalManager for visible
VS Code terminals with shell integration, real-time output streaming,
and 'Proceed While Running' support.
- Background (backgroundExec): Delegates to the SDK's createBashExecutor
for headless child_process.spawn execution with configurable timeout.
Wiring:
- SdkController creates a lazy VscodeTerminalManager
- SdkSessionFactory passes getTerminalManager to VscodeSessionHost
- VscodeSessionHost suppresses SDK's built-in run_commands (bash: undefined)
- createVscodeExtraTools includes the custom run_commands tool
Design doc: sdk-migration/FOREGROUND-TERMINAL-DESIGN.md
Root cause: initial-message-sanitizer only checked the immediately next
user message (i+1) for matching tool results. The SDK persists each
parallel tool result as a separate user message, so for N parallel tool
calls only 1/N was found and (N-1) placeholders were created. The
remaining (N-1) real results were left as separate messages. On merge,
this produced duplicate tool_result blocks causing Anthropic API errors.
Fix:
- Scan ALL consecutive user messages after the assistant to collect tool
results, then consolidate into a single message via splice()
- Add defensive dedup in convertToOpenAiMessages as a safety net
Tests: 12 pass (5 sanitizer + 7 openai-format conversion)
The ask:"completion_result" message was emitted at content_end (when the
attempt_completion tool finished), but a usage event with
say:"api_req_started" always arrived between content_end and done,
becoming the last raw message. The webview uses the last raw message to
determine UI state, so it showed "Thinking..." instead of the completion
UI with the "Start New Task" button.
Fix: defer the ask:"completion_result" emission from content_end to the
done handler, which always runs after the usage event. The done handler
now unconditionally emits ask:"completion_result" (previously it was
conditional on !wasAttemptCompletionSeen). This ensures the ask is
always the final message regardless of whether attempt_completion was
used.
The SDK spawn_agent tool was rendering as a generic tool row in the
webview. This translates its events into the ClineMessage types that
SubagentStatusRow already handles:
- content_start → say:"use_subagents" (prompts list with stable ts)
- content_update → say:"subagent" (running progress, partial=true)
- content_end → say:"subagent" (completed/failed) + say:"subagent_usage"
Also filters sub-agent agent_events by parentAgentId so only the root
agent produces ClineMessages. Without this, every sub-agent tool call,
text output, iteration, and usage event flooded the main chat.
No webview/CLI changes needed — existing SubagentStatusRow and
messageUtils filtering handle all the emitted message types.
Remove the strictPlanModeEnabled feature toggle from the entire codebase.
The setting is not used by the SDK controller path and plan mode behavior
is now handled via system prompt instructions and the switch_to_act_mode
tool in the SDK layer.
Changes:
- Remove state key, ExtensionMessage field, and proto fields (reserved)
- Remove ToolExecutor plan-mode restriction logic (PLAN_MODE_RESTRICTED_TOOLS,
isPlanModeToolRestricted, and the enforcement block)
- Remove from TaskConfig interface, validation, and TASK_CONFIG_KEYS
- Remove settings toggle from webview FeatureSettingsSection and CLI
- Remove from getStateToPostToWebview and updateSettings handlers
- Remove from ExtensionStateContext defaults and test mocks
- Regenerate proto types
Remove the Focus Chain feature toggle from the settings view and
all associated state wiring:
- Settings UI: Remove Focus Chain toggle, reminder interval slider,
and nested-key handling that was only used by focus chain
- ChatView: Remove focus chain checklist state, progress message
memo, and placeholder memo
- TaskSection/TaskHeader: Remove focus chain props and FocusChain
component rendering
- ExtensionStateContext: Remove focus chain settings default and
currentFocusChainChecklist from state provider
- ExtensionMessage: Remove focusChainSettings and
currentFocusChainChecklist from shared ExtensionState type
- getStateToPostToWebview: Stop sending focus chain state to webview
- updateSettings/updateSettingsCli: Remove focus chain settings
update handlers and telemetry toggle tracking
buildSessionConfig() only read subagentsEnabled from taskSettings (per-task
overrides), which is undefined for normal chat flow. This caused
enableSpawnAgent to always be false, making the SDK hide the spawn_agent
tool and causing the model to fall back to the skills tool.
Now reads the global subagentsEnabled setting from StateManager as the
default, with taskSettings still able to override it.
The remote config system (fetch.ts, utils.ts) and other core modules
import AuthService from src/services/auth/AuthService.ts. In the SDK
migration, this was still the classic AuthService class with its own
separate singleton — completely disconnected from the SDK AuthService
that SdkController initializes with actual credentials.
This caused fetchRemoteConfig() to silently fail because:
- AuthService.getInstance().getAuthToken() returned null (no credentials)
- AuthService.getInstance().getActiveOrganizationId() returned null
- ClineAccountService.fetchUserRemoteConfig() failed silently
Fix: Replace src/services/auth/AuthService.ts with a re-export barrel
that points to src/sdk/auth-service.ts, matching the pattern used for
Controller (src/core/controller/index.ts → src/sdk/SdkController.ts).
This ensures all modules that import AuthService get the SDK singleton
which has the actual auth state.
Also stub out AuthServiceMock.ts which extended the classic AuthService
using protected members that no longer exist in the SDK version. The
mock was only used via dynamic require in E2E test mode and is not
referenced by any production code.
The SdkController was missing all remote config support that the classic
Controller provides for enterprise customers (org-level policy enforcement,
MCP server management, provider lockdown, OpenTelemetry, etc.).
Changes:
- Add startRemoteConfigTimer() that fetches immediately then every 1 hour
- Chain timer start after auth restore in constructor
- Call fetchRemoteConfig() on login (handleAuthCallback)
- Fire-and-forget fetchRemoteConfig() at task start (initTask)
- Call clearRemoteConfig() on sign-out (handleSignOut)
- Clear interval timer in dispose() to prevent memory leaks
- Verify refreshRemoteConfig gRPC handler is already wired correctly
The SDK run_commands tool can pass input as a bare string[] (e.g.
["biome check --write src/"]) instead of wrapped { commands: [...] }.
parseToolInput() returns undefined for arrays, so commandText ended up
as "", rendering an empty shell fence in the command approval UI.
Extend both content_start and content_end handlers to detect bare
arrays and bare strings before falling through to parseToolInput(),
mirroring the fix already applied for search_codebase (S6-47).
Adds 6 unit tests covering bare array, multi-element array, bare
string, content_end round-trip, and wrapped-object regression.
- Replace exportTaskWithId stub in SdkController with real implementation
that opens the task directory in the file manager (matching classic behavior)
- Fix openDiskConversationHistory to await openFileIntegration and move
path construction inside the null check
Closes ENG-1828
After consecutive tool failures hitting maxConsecutiveMistakes (default 3),
the UI buttons stayed as Approve/Reject instead of updating to
"Proceed Anyways"/"Start New Task".
Root cause: In the SDK path, trackToolErrors() emitted the
mistake_limit_reached message but the SDK agent continued running,
immediately appending more messages. The mistake_limit_reached message
was never the last message, so the webview never showed correct buttons.
Fix: When the mistake limit is reached, set result.turnComplete = true
and abort the SDK session so the agent stops producing events. The
existing askResponse -> tryResumeSessionFromTask flow handles resumption
when the user clicks "Proceed Anyways".
Closes ENG-1874
The SDK execution path was missing consecutive tool error tracking that
the classic Task class provides via consecutiveMistakeCount. When tools
failed repeatedly, the UI buttons stayed showing "Approve"/"Reject"
instead of updating to "Proceed Anyways"/"Start New Task".
This change:
1. Adds toolError/toolSuccess flags to TranslationResult so the message
translator signals when tool calls succeed or fail (content_end events
with/without event.error)
2. Adds consecutiveToolErrorCount tracking to SdkSessionEventCoordinator
3. When the count reaches maxConsecutiveMistakes (default: 3), emits an
ask="mistake_limit_reached" ClineMessage, which the webview already
handles correctly to show the right buttons
4. Resets the counter on tool success or after emitting the limit message
Fixes ENG-1874
Bridge SDK provider settings with the legacy Codex OAuth manager so ChatGPT Subscription sign-in updates settings state and inference can read the stored token. Clear both stores on sign-out and refresh incomplete SDK-stored credentials.
The webview's onModeToggle handler in ChatTextArea.tsx treats the
returned boolean as 'did I consume your pending input' and calls
setInputValue('') when true. The SDK flow rebuilds the session
without consuming chatContent, so returning true incorrectly wiped
any text the user had typed before toggling.
Match the classic extension's semantic: only return true when the
chatContent was actually consumed as a plan-response message. The
SDK flow never does this, so both success branches now return false
(same-mode no-op already returned false).
ClineMessages and mode indicator continue to update correctly because:
- rebuildSessionForMode keeps this.task and its messageStateHandler
alive across the session rebuild, so clineMessages are preserved
- getStateToPostToWebview() reads mode from stateManager which is
updated before postStateToWebview() is called
- oldUnsubscribe() is called before old session stop/dispose, so no
stale 'ended' events reach the gRPC bridge after rebuild
Adds 7 unit tests in src/sdk/toggle-plan-act-mode.test.ts covering
PLAN/ACT enum decode, chatContent pass-through, boolean round-trip,
invalid enum handling, and error propagation.
rebuildSessionForMode() now logs the resolved provider/model/apiKey from
buildSessionConfig({ cwd, mode: newMode }) so it is visible that the
mode-specific provider and model were picked up (planModeApiProvider /
actModeApiProvider, planModeApiModelId / actModeApiModelId, etc.).
Also adds an auth pre-check mirroring the one in initTask(): if the new
mode resolves to the cline provider without an auth token, emit the
standard auth error message sequence (say:task, say:api_req_started,
ask:api_req_failed) so the webview renders the "Sign in to Cline" button
via ErrorRow instead of crashing on the first SDK API call.
The pre-check runs BEFORE tearing down the old session, so the user
keeps their chat history and can retry after signing in or toggle back
to the original mode.
Replaces the old togglePlanActMode() behavior (which just cancelled the task and left the user to start over) with a full session rebuild that preserves conversation history while swapping in the new mode's system prompt and tools. Mirrors the CLI's onModeChange callback in apps/cli/src/runtime/run-interactive.ts.
Changes in src/sdk/SdkController.ts:
- Add rebuildSessionForMode(newMode): persists mode to global state, reads conversation history from the active session via loadInitialMessages(), tears down the old VscodeSessionHost (unsubscribe + stop + dispose), builds a fresh CoreSessionConfig for the new mode (new system prompt via buildSessionConfig, switch_to_act_mode re-injected for plan), preserves the task/session ID, and starts a new session with initialMessages. Task proxy stays alive so currentTaskItem and clineMessages remain stable across the rebuild.
- Implement applyPendingModeChange(): was a TODO stub; now reads pendingModeChange, clears it, and delegates to rebuildSessionForMode. This is the path the switch_to_act_mode tool uses when the model programmatically transitions plan -> act.
- Rewrite togglePlanActMode(): if activeSession exists, call rebuildSessionForMode; otherwise persist mode and refresh state. No more cancelTask() followed by the user manually restarting.
- Wire applyPendingModeChange into handleSessionEvent: when turnComplete/sessionEnded flips isRunning=false, check pendingModeChange and apply it fire-and-forget. Complements the existing check in fireAndForgetSend so we catch the mode change via either the event stream or the send promise resolution.
Cancel-style teardown on mid-turn toggle (matches classic Cline UX of "switch modes cancels the current task"):
- Reject any pendingToolApprovalResolve with { approved: false, reason: "Mode changed" } so the SDK tool executor unwinds cleanly
- Clear pendingAskResolve (no meaningful answer to give the dying session)
- Cancel the debounced save timer so it does not race with the finalization we write below
- await oldManager.abort(oldSessionId) (same call cancelTask uses) so the AbortSignal propagates through the tool executor: running shell commands get SIGTERM, in-flight LLM streams terminate
- Finalize in-memory messages via finalizeMessagesForSave() to strip partial: true flags and stamp the open api_req_started with cancelReason: "user_cancelled", re-add via messageStateHandler.addMessages() which updates by ts in-place, and persist synchronously via saveClineMessages so on-disk history reflects a cleanly cancelled turn
- Set activeSession.isRunning=false before teardown so late events from the dying session cannot flip state on the new session
Tests: npx tsc --noEmit and npx biome lint both pass clean.
Mirrors the CLI's plan -> act flow (apps/cli/src/runtime/run-interactive.ts)
by adding a programmatic mode-switch tool to SDK sessions started in plan
mode. When the model calls switch_to_act_mode after the user agrees to
the plan, the tool sets a pendingModeChange flag and returns a success
message so the current turn completes normally. After sessionManager.send()
returns, applyPendingModeChange() is invoked as the plumbing entry point
for the full session-rebuild flow (to be implemented in Task 4).
Changes to src/sdk/SdkController.ts:
- Import createTool and Tool type from @clinebot/shared
- Add pendingModeChange: Mode | null field
- Add createSwitchToActModeTool() private method matching the CLI's
tool definition (name, description, success message, timeouts)
- Add injectModeExtraTools() helper and wire it into all four
session-creation code paths: initTask, reinitExistingTaskFromId,
resumeSessionFromTask, and restartSessionForMcpTools
- Add applyPendingModeChange() stub that reads and clears the flag
(Task 4 will fill in the full session rebuild)
- Invoke applyPendingModeChange() from fireAndForgetSend's .then()
after the turn completes (skipped for queue/steer deliveries)
CoreSessionConfig.mode is already set correctly in buildSessionConfig(),
so the SDK's plan preset (which disables editor tools) continues to be
selected -- our injected tool is merged with that preset.
Verification: tsc --noEmit passes with 0 errors; SDK vitest suite
shows 143 passing tests (same as baseline).
Mirrors the CLI plan-mode guardrails (apps/cli/src/runtime/prompt.ts)
so plan mode in VSCode tells the model to explore/analyze/plan and NOT
implement. Previously buildClineSystemPrompt did not emit these
instructions, so plan mode in VSCode had weaker guardrails than the CLI.
Implement the remaining two feasible Cline hooks as SDK AgentExtension
plugins, since AgentHooks lacks the right hook points for these:
- UserPromptSubmit → onInput: fires before the prompt enters the agent
loop, supports cancel and contextModification
- TaskCancel → onSessionShutdown: fires only on user-initiated
cancellation (reason === session_stop), fire-and-forget
Changes:
- hooks-adapter.ts: add buildHookExtensions() returning AgentExtension[]
with one inline extension (cline-lifecycle-hooks) implementing onInput
and onSessionShutdown callbacks
- SdkController.ts: add buildExtensionsWithEmitter() method and wire
config.extensions at all 4 session creation sites (initTask,
reinitExistingTaskFromId, resumeSessionFromTask,
restartSessionForMcpTools)
The existing buildAgentHooks() for the 4 AgentHooks-based hooks
(TaskStart, PreToolUse, PostToolUse, TaskComplete) is untouched.
When using the 'cline' provider without authentication, the SDK throws a
generic 'Missing API key' error that surfaces as a raw red error message
with an infinite 'Thinking...' spinner. The classic extension shows a
friendly login prompt with a 'Sign in to Cline' button instead.
Fix by adding a pre-check in initTask() that detects the cline provider
with no auth token and emits the same message sequence the classic
extension uses (say:task -> say:api_req_started -> ask:api_req_failed
with a serialized ClineError). The webview's ErrorRow already handles
this pattern and renders the sign-in UI.
Also updates catch blocks in fireAndForgetSend(), askResponse(), and
reinitExistingTaskFromId() to detect cline auth errors and emit the
proper auth UI instead of raw say:error messages.
The SDK invokes AgentHooks callbacks inline (not through onEvent), so the
message-translator case "hook" handler never fires for adapter hooks. This
means hooks run silently with no UI feedback.
Fix by emitting hook_status ClineMessages directly from the hooks-adapter
callbacks via a HookMessageEmitter callback provided by SdkController.
Changes to hooks-adapter.ts:
- Add HookMessageEmitter type and buildHookStatusMessage() helper
- Add optional emitHookMessage param to buildAgentHooks()
- In all 4 callbacks, check factory.hasHook() before emitting
- Emit running/completed/cancelled/failed status messages
Changes to SdkController.ts:
- Add buildHooksWithEmitter() that wires emitter to messageStateHandler,
pushMessageToWebview, and debouncedSaveClineMessages
- Override config.hooks at all 4 buildSessionConfig() call sites
Create src/sdk/hooks-adapter.ts that maps 4 Cline hooks to SDK
lifecycle callbacks:
- TaskStart → onSessionStart
- PreToolUse → onToolCallStart
- PostToolUse → onToolCallEnd
- TaskComplete → onRunEnd (gated on finishReason === completed)
Each callback dynamically checks hooksEnabled via StateManager so
toggling mid-session takes effect immediately. All callbacks are
fail-open (errors logged, never block the SDK).
Wire buildAgentHooks() into buildSessionConfig() in
cline-session-factory.ts so every new session gets hook callbacks.
The attempt_completion extra tool defined a command parameter in its schema
but the execute function silently discarded it, wasting tokens.
Re-use the SDK built-in bash executor (via createDefaultExecutors) to run
the command when provided, and append its output to the completion result
returned to the model.
Changes:
- vscode-runtime-builder.ts: createAttemptCompletionTool now accepts cwd,
lazily creates a bash executor, and executes the command parameter
- vscode-session-host.ts: passes input.config.cwd to createVscodeExtraTools
Closes S6-47
When the user sends a follow-up message while the agent is mid-turn,
askResponse() now detects isRunning and passes delivery: "queue" to
the SDK send() call. The SDK enqueues the message and drains it after
the current turn completes, preventing "already in progress" errors.
Changes:
- fireAndForgetSend(): accept optional delivery param, skip isRunning
reset when message was queued (turn didnt complete)
- askResponse(): capture wasAlreadyRunning before setting isRunning,
compute delivery accordingly, skip translator reset for queued msgs
- handleSessionEvent(): log pending_prompts/pending_prompt_submitted
events for visibility
MCP tools were bypassing the approval flow because buildToolPolicies()
only covered built-in SDK tools. MCP tools registered as extra tools
with serverName__toolName names had no policy entries, so the SDK
defaulted them to autoApprove:true.
- Add MCP tool iteration in buildToolPolicies() using McpHub.getServers()
- Gate MCP tool auto-approve on both the global useMcp toggle and each
tool's individual autoApprove flag
- Use serverName__toolName format matching the SDK's default name transform
- Remove unnecessary regex sanitization helper (sdkMcpToolName)
The SDK defaults all tools to autoApprove:true when no toolPolicies
are provided. The user's auto-approval settings (readFiles, editFiles,
executeSafeCommands, etc.) were not being translated into SDK
toolPolicies, so requestToolApproval was never called.
- Add buildToolPolicies() that maps AutoApprovalSettings actions to
SDK tool names with { autoApprove: boolean } policies
- Add toolPolicies option to VscodeSessionHostOptions, pass through
to ClineCore.create()
- Read autoApprovalSettings from StateManager in startNewSession()
and pass the derived toolPolicies to VscodeSessionHost.create()
Implement the requestToolApproval callback so the SDK can request user
approval for non-auto-approved tools (S6-26 Part A).
- Export sdkToolToClineSayTool from message-translator.ts for reuse
- Add handleRequestToolApproval() private method to SdkController that
converts SDK ToolApprovalRequest to ClineSayTool JSON, emits a
ClineMessage with type:ask/ask:tool, and returns a Promise resolved
when the user clicks Approve/Reject in the webview
- Add handleAskQuestion() private method (extracted from inline callback)
- Wire both callbacks into startNewSession() via VscodeSessionHost.create()
- Add pendingToolApprovalResolve field to SdkController, resolved in
askResponse() by reading taskState.askResponse (yesButtonClicked=approve,
noButtonClicked=deny)
- Clean up pendingToolApprovalResolve in cancelTask() and clearTask()
to prevent Promise leaks
- Update PROBLEMS.md to mark Part A as fixed
The SDK built-in ask_question tool was excluded from the agent tool list
because no askQuestion executor was provided. The agent could not ask
clarifying questions when encountering ambiguity.
Changes:
- vscode-session-host.ts: Add askQuestion option, pass defaultToolExecutors
to ClineCore.create() so the SDK includes ask_question in the tool list
- SdkController.ts: Implement askQuestion executor that emits ClineMessage
with ask:"followup" (reusing existing webview UI), stores a pending
Promise resolver, and resolves it when askResponse() is called.
cancelTask()/clearTask() clear pendingAskResolve to prevent leaks.
- message-translator.ts: Update comment to reflect new handling
- PROBLEMS.md: Mark S6-26 Part B as fixed with evidence
The SDK editor tool provides old_text and new_text, but the message
translator stored raw new_text in content. DiffEditRow did not recognize
it as a diff format and fell through to a fallback treating every line
as an addition (all green, no red).
Three fixes:
1. message-translator.ts editor case: when both old_text and new_text
are present, build a SEARCH/REPLACE diff in the format DiffEditRow
expects.
2. message-translator.ts apply_patch case: also check the input field
(SDK format) and populate both content and diff.
3. ChatRow.tsx: prefer tool.diff over tool.content when passing to
DiffEditRow, and check for either in the guard condition.
7 new tests, 1 updated test. All 72 message-translator tests pass.
The SDK search_codebase tool input can be a bare array or string
(per SearchCodebaseUnionInputSchema), but parseToolInput() only
handled objects. This caused empty regex in the UI. Additionally,
the SDK has no path param for search, so the webview showed "/".
Changes:
- message-translator.ts: Handle bare array and string input formats
for search_codebase in sdkToolToClineSayTool()
- ToolGroupRenderer.tsx: Show "codebase" instead of "/" when search
path is empty; fix getActivityText to not require path for search
- RequestStartRow.tsx: Same empty-path fixes for consistency
- 8 new unit tests covering all SDK input formats and content_end
preservation
The SDK migration removed the classic parseMentions() call that resolved
context mentions (@/file, @problems, @git-changes, @https://url, @hash)
into inline content. The SDK's own mention enricher only handles simple
@path mentions and fails with the webview's @/path format.
Add resolveContextMentions() to SdkController that calls parseMentions()
before sending text to the SDK in all three send paths: initTask(),
askResponse(), and resumeSessionFromTask().
Fixes: Context command not returning any response in chat
Three issues fixed in SdkController:
1. Race condition: Late-arriving SDK 'done' events after cancelTask()
produced completion_result messages that replaced the 'Resume Task'
button with 'Start New Task'. Added a filter in handleSessionEvent()
that suppresses these messages when isRunning === false.
2. Dead session: After cancellation, activeSession still existed but the
SDK session was dead (aborted). Clicking 'Resume Task' tried to send()
to the dead session causing 'session not found' error. Changed
askResponse() to also check isRunning, routing cancelled sessions to
resumeSessionFromTask() which creates a fresh SDK session.
3. Idle resume: resumeSessionFromTask() only generated a [TASK RESUMPTION]
prompt when there were no initialMessages. After cancellation there ARE
initialMessages (conversation history), so the prompt was empty and the
session sat idle. Changed to always send a resumption prompt when the
user didn't type anything, matching classic extension behavior.
Main's PR #10196 (Remove foreground terminal, commit 1862f1595) removed
the vscodeTerminalExecutionMode field from ExtensionState. The webview
now unconditionally renders commands as background-exec (ChatRow.tsx
hardcodes isBackgroundExec={true}), so the SDK-adapter override in
getStateToPostToWebview() is both a type error and dead code.
Removes the override and documents why it's no longer needed for any
future archaeology.
S6-39: SDK fetch_web_content uses { requests: [{ url, prompt }] } but
sdkToolToClineSayTool() only checked for a top-level url field. Added
fallback to extract URL from requests[0].url.
S6-40: SDK skills tool uses { skill: "name" } but sdkToolToClineSayTool()
only checked skill_name and name fields. Added skill to the fallback chain.
7 new unit tests covering both SDK and classic input formats.
When the user cancels a running task, AbortController.abort() in the SDK
throws an AbortError that propagated unhandled to the VSCode developer
console. Three fixes:
1. VscodeSessionHost.abort(): wrap inner.abort() in try/catch that
suppresses AbortError (expected) and re-throws others.
2. SdkController.cancelTask(): narrow try/catch to only the abort()
call, suppress AbortError at debug level, and always proceed with
cleanup. Emit ask: "resume_task" instead of say: "info" so the
webview shows the Resume task button (fixes S6-34).
3. SdkController.fireAndForgetSend(): detect AbortError in .catch()
and return early without emitting error events to the UI.
Two bugs combined to cause unbounded stdout accumulation in the SDK
file indexer when starting a new task:
1. SdkController used process.cwd() instead of getCwd() for workspace
resolution. In VSCode extension host, process.cwd() returns the
VSCode installation dir, not the workspace folder, causing rg to
recurse enormous directory trees.
2. SDK file-indexer.ts rg command only excluded .git but not
node_modules/dist/build/etc (which walkDir fallback did exclude).
This is fixed in the linked SDK repo separately.
Fixes:
- Replace all process.cwd() calls in SdkController.ts and
cline-session-factory.ts with getCwd() which resolves the actual
workspace folder via HostProvider.workspace.getWorkspacePaths()
- Document fix in PROBLEMS.md as S6-44
The SDK run_commands tool returns ToolOperationResult[] with structured
output ({query, result, success, error?}). The message translator was
falling through to JSON.stringify() for non-string output, causing raw
JSON like [{"query":"ls","result":"...","success":true}] to appear in
the chat instead of formatted shell output.
Changes:
- Add extractToolOutputText() helper that extracts raw text from
ToolOperationResult[] format, using result.result for success and
result.error for failures
- Update command content_end handler to use extractToolOutputText()
- Override vscodeTerminalExecutionMode to backgroundExec in
SdkController.getStateToPostToWebview() since SDK always uses
background execution
- Add 15 unit tests covering all output extraction cases
Fixes S6-41
The SdkController used process.cwd() in 4 places as the working directory
for SDK sessions. In VSCode, process.cwd() returns the extension host
directory, not the user workspace. This meant Cline could not find project
files without explicit paths.
Added SdkController.getWorkspaceRoot() which resolves the workspace root
via HostProvider.workspace.getWorkspacePaths() (delegates to
vscode.workspace.workspaceFolders[0].uri.fsPath), falling back to
process.cwd() only when no workspace folder is open.
Replaced all 4 process.cwd() calls in initTask(), reinitExistingTaskFromId(),
resumeSessionFromTask(), and restartSessionForMcpTools().
Also added a defensive warning log in buildSessionConfig() for the
process.cwd() fallback path.
Updated PROBLEMS.md: S4-3 marked fixed, S6-38 added.
Renamed isActive to \$isActive in StyledTabButton in ClineRulesToggleModal.tsx.
The dollar-sign prefix tells styled-components to consume the prop for
styling without forwarding it to the underlying DOM element, eliminating
the React warning "React does not recognize the isActive prop on a DOM element."
Updated PROBLEMS.md with S6-45 entry marked as verified fixed.
Keep the active task/session id stable during MCP tool-list restarts so currentTaskItem stays mapped and chat state is not lost after toggling MCP servers.
SessionManager interface changes:
- Add update() and handleHookEvent() to VscodeSessionHost
- Remove readHooks() (no longer in SessionManager interface)
- Import HookEventPayload from @clinebot/core
Auth service fixes:
- Replace InstanceType<typeof UserInfo> with UserInfo type directly
- Fix null assignment to protobuf field (use empty create instead)
In the SDK migration branch, every agent response was showing a green
'Task Completed' rectangle because the done event unconditionally emitted
completion_result messages. In the classic extension, the green rectangle
only appeared when the agent explicitly called the attempt_completion tool.
Changes:
- Register attempt_completion as a custom tool in VscodeRuntimeBuilder
so the SDK agent can call it (the SDK has no built-in equivalent)
- Handle attempt_completion in MessageTranslator: content_start emits
say:'completion_result' (green rectangle), content_end emits
ask:'completion_result' with empty text (enables follow-up input
without a second green rectangle)
- Track attempt_completion calls via MessageTranslatorState so the done
event can skip emitting completion_result when already handled
- When attempt_completion is NOT called, done emits ask:'completion_result'
with empty text (renders as InvisibleSpacer, no green rectangle)
- Update tests: 2 existing tests updated, 1 new test added for the
suppression behavior (35/35 pass)
After restartSessionForMcpTools() completes, the webview was left in
a 'Thinking...' state because no ask:'completion_result' message was
emitted. The webview's handleSendMessage() requires clineAsk to be
set to enable follow-up input.
Fix: Emit ask:'completion_result' after the success info message so
the webview knows the agent is idle and enables the follow-up input.
Tested with debug harness:
1. Sent 'Say hello briefly' → completed
2. Toggled kamibiki MCP server off via UI
3. 'MCP tools changed' + 'reloaded successfully' messages appeared
4. Typed 'Say goodbye' → follow-up inference ran successfully
Three fixes for the SDK migration:
1. Follow-up messages: Changed the 'done' event translation from
say:'completion_result' to ask:'completion_result'. The webview's
handleSendMessage() requires clineAsk to be set to send follow-up
messages. Without the ask message, typing a follow-up and pressing
Enter was silently dropped.
2. Session cleanup: Clear activeSession reference before stop/dispose
to prevent re-entrant calls. Added 3s timeouts to stop()/dispose()
to prevent UI blocking when sessions are in unexpected states.
3. MCP tool change debouncing: When an MCP server connects,
notifyWebviewOfServerChanges() fires multiple times in quick
succession. Added 300ms debounce with fingerprint quick-check
to coalesce these into a single tool list change callback.
Tested with debug harness:
- MCP tools (kb_status, kb_search) work correctly
- Follow-up messages work via both gRPC and DOM (typing + Enter)
- MCP tools work in follow-up turns
- McpHub: Added computeToolFingerprint(), setToolListChangeCallback(),
clearToolListChangeCallback(), and checkToolListChanged() to detect
when the set of available MCP tools changes (servers added/removed/
reconnected). Only fires on actual tool list changes, not mere status
updates.
- SdkController: Added handleMcpToolListChanged() which restarts the
session immediately when idle, or defers via mcpToolRestartPending
flag until the current turn completes. restartSessionForMcpTools()
creates a new VscodeSessionHost with fresh tools, preserves
conversation messages, and emits info messages to the chat.
- SdkController: Fixed MCP settings file path — was reading from
VSCode extension storage (HostProvider.globalStorageFsPath/settings/)
instead of ~/.cline/data/settings/ where the actual MCP settings live.
- task-proxy: Made taskId settable so session restart can update the
proxy's session ID without recreating it.
- Tests: 16 unit tests for tool list change detection covering
fingerprinting, callback firing, and edge cases.
Known issues: S6-28 (reload messages appear twice), S6-29 (new task
button broken after reload). See PROBLEMS.md.
The gRPC handler for showTaskWithId was calling controller.initTask()
which starts a NEW SDK session instead of loading the existing task's
messages from disk. Changed to call controller.showTaskWithId(id)
which correctly: (1) looks up the history item, (2) tears down any
active session, (3) creates a task proxy with loaded messages,
(4) pushes messages through both state updates and partial message
stream, (5) posts state to the webview.
Verified with debug harness: send message → new task → click history
item → conversation restored with all messages.
- S6-24: Preserve tool input from content_start for use at content_end
(MessageTranslatorState stores streamingToolInput/streamingToolName)
- S6-6: Replace readUiMessages (legacy path) with getSavedClineMessages
(uses HostProvider.globalStorageFsPath, matching saveClineMessages)
- Restore postStateToWebview() in handleSessionEvent (needed for streaming)
- Fix TS2352 cast in message-translator.ts (as unknown as Record)
- Add 4 new tests for tool input preservation through streaming lifecycle
- S6-26: Research SDK pending prompts/tool approval/ask_question system
- S6-27: Create focused task for history messages still not rendering
- Update PROBLEMS.md priority section
The partial message handler in ExtensionStateContext only updated
existing messages by matching timestamps — it never appended new ones.
In the classic extension, messages were first added via state updates,
then updated in-place by partial messages. In the SDK migration,
messages arrive via the partial message stream first, so they need
to be appended when no existing message matches.
Also adds debounced ClineMessage persistence in SdkController so
task history can load messages via readUiMessages().
- S6-5: Regressed — inference works but view doesn't switch to chat
- S6-6: Failed verification, merged S6-15 into it
- S6-8: Marked as verified fixed (brown logo)
- S6-19: New — history deletion dialog confirms but doesn't delete
- S6-20: New — MCP tools panel is empty
- Added Priority & Next Steps section recommending S6-5 as top priority
The SDK's DefaultSessionManager passes the systemPrompt from
CoreSessionConfig directly to the Agent — there is no fallback for
empty system prompts. Both the CLI and SDK's VSCode extension call
buildClineSystemPrompt() before passing config to the session manager.
Our buildSessionConfig() was setting systemPrompt: '' (empty string),
which caused the gateway to return empty responses with 0 tokens.
Changes:
- cline-session-factory.ts: Import buildWorkspaceMetadata from
@clinebot/core and buildClineSystemPrompt from @clinebot/shared.
Build the full Cline system prompt in buildSessionConfig() using
workspace metadata, IDE name, mode, provider, and platform.
Falls back to a minimal prompt on error.
- vscode-session-host.ts: Add logging around send() for debugging
inference issues (input/output tokens, response text).
- SdkController.ts: Add logging for session events and agent turn
completion to aid debugging.
Verified: Agent responds correctly with 2776 input tokens (system
prompt) and generates proper output ('Hello, world! 👋').
- Rewrite restoreRefreshTokenAndRetrieveAuthInfo() to read from providers.json
instead of injecting through StateManager secrets
- Add fetchUserInfoFromApi() to get user profile from Cline API at startup
- Delete VscodeOAuthTokenManager (~180 lines) - SDK default handles persistence
- Simplify resolveApiKey() for cline provider to read from providers.json
- Cache getProviderSettings() as singleton to avoid re-reading file
- Net reduction of 94 lines
Documents which directories contain minified/generated code that
produces noisy search results (out/, dist/, src/generated/, etc.),
how to skip them with search_files and grep, and how to search
minified files when necessary (grep -oP, source maps).
Four fixes for making inference work in the VSCode UI:
1. Webview state connection (S6-13): Wire WebviewGrpcBridge to the
controller's getStateToPostToWebview() so state updates include
messages, currentTaskItem, and task history. Added setGetStateFn()
method to the bridge and called it from SdkController constructor.
2. Chat history loading (S6-6): Fix history lookup in showTaskWithId()
and reinitExistingTaskFromId() to check StateManager's taskHistory
first (where updateTaskHistory writes), then fall back to the legacy
file reader. Also clear active session before viewing history.
3. Message translation (S6-12): Add sdkToolToClineSayTool() mapping
function that converts SDK tool names (read_files, editor, etc.) to
classic ClineSayTool format that ChatRow.tsx expects. Add usage event
handling for api_req_started messages. Update tests to match actual
output format.
4. VscodeRuntimeBuilder (S6-14): New custom RuntimeBuilder that bridges
the classic McpHub to the SDK's tool system. Delegates builtin tools
to DefaultRuntimeBuilder but replaces MCP tools with ones loaded from
the classic McpHub, supporting all transport types (stdio, SSE,
streamableHttp). Not yet wired into session creation — needs
VscodeSessionHost wrapper (see S6-9).
All 99 SDK unit tests pass.
- Fix credential resolution: replace broken ProviderSettingsManager and
buildApiHandlerSettings() paths with resolveApiKey()/resolveModelId()
that read directly from StateManager.getApiConfiguration() (includes
secrets). Handles all 30+ providers including cline OAuth token
extraction (idToken from cline:clineAccountId JSON, workos: prefix).
- Fix non-blocking session start: initTask() now calls
core.start({interactive:true}) WITHOUT a prompt (returns immediately),
then fire-and-forgets core.send() for inference. Events stream
in real-time via subscribe(). Same pattern for askResponse().
- Add MCP settings filtering: SDK's StdioMcpClient only supports stdio
transport. ensureFilteredMcpSettings() writes a filtered copy of
cline_mcp_settings.json (stdio-only) and sets CLINE_MCP_SETTINGS_PATH
env var. Future: replace with custom RuntimeBuilder that provides a
clientFactory delegating to classic McpHub for streamableHttp support.
- Fix debug harness gRPC message format for web.post_message.
- Update PROBLEMS.md: S6-5 and S6-11 marked 🟢 Verified Fixed.
Verified: Debug harness sends newTask → session starts, agent runs,
events stream to webview (iteration_start, usage, iteration_end, done).
Protobuf defaults empty strings to ''. The check 'request.clineEnv !== undefined'
was true for empty strings, causing ClineEnv.setEnvironment('') which defaults
to 'production' but also triggers accountLogoutClicked(). This caused the user
to be logged out and the environment to appear to flip when changing models.
Fix: Also check 'request.clineEnv !== ""' before processing.
1. initTask() now saves history item to StateManager immediately
after session starts. Without this, currentTaskItem was undefined
in getStateToPostToWebview(), so the webview never switched to
chat view after sending a message.
2. updateTaskHistory() and deleteTaskFromState() are now real
implementations using StateManager instead of stubs.
3. Exposed window.__clineVsCodeApi in webview for debug harness
access (platform.config.ts).
4. Added detailed logging to initTask() for debugging:
- Session config (provider, model, apiKey presence)
- ClineCore creation
- Session start
- Error details
These fixes address the user-reported issues:
- Send button clears input but doesn't switch to chat view
- Chat history appears empty
TaskProxy improvements for settings handler compatibility:
- api property is now settable (updateSettings replaces it on model switch)
- terminalManager returns a proper stub that safely no-ops
(setDefaultTerminalProfile, setShellIntegrationTimeout, etc.)
- Added TaskProxyTerminalManager interface
SdkController improvements:
- togglePlanActMode() now properly implemented:
- Saves mode to StateManager
- Cancels active task if switching modes mid-task
- Posts state update to webview
- toggleActModeForYoloMode() switches to act mode
These changes ensure the updateSettings gRPC handler works
without modification — it calls controller.task.api and
controller.task.terminalManager which are now properly stubbed.
Following the 'Thunk, Don't Replace' principle, wire the classic
McpHub into SdkController instead of building a custom SDK MCP
manager. The classic McpHub already supports all three transports
(stdio, SSE, streamableHTTP), file watching, and all gRPC handlers.
Changes:
- SdkController.mcpHub: type changed from 'any' to 'McpHub'
- Constructor initializes McpHub with same args as classic Controller
- Existing gRPC handlers (subscribeToMcpServers, restartMcpServer,
deleteMcpServer, toggleMcpServer, etc.) work without modification
- SDK's InMemoryMcpManager will replace it in Step 10 (Cleanup)
Also includes:
- Fix S6-5: buildSessionConfig() falls back to classic StateManager
when SDK ProviderSettingsManager has no provider configured
- Fix S6-6: showTaskWithId() loads messages from disk via
readUiMessages() and adds them to TaskProxy's messageStateHandler
- Updated PROBLEMS.md and README.md with Step 7 progress
S6-5: buildSessionConfig() now falls back to classic StateManager
- Try SDK ProviderSettingsManager first (providers.json)
- If no provider/apiKey found, fall back to StateManager.buildApiHandlerSettings()
- This correctly resolves provider/model/apiKey for the current mode (plan/act)
- Critical because providers.json may not exist yet for existing users
S6-6: showTaskWithId() now loads messages from disk
- Call readUiMessages(taskId) to load ui_messages.json
- Add messages to TaskProxy's messageStateHandler via addMessages()
- This populates the message state so getStateToPostToWebview() returns them
Also: remove unused Settings import from cline-session-factory.ts,
add StateManager import for the fallback path.
- src/sdk/task-proxy.ts: TaskProxy provides classic Task-compatible
interface that delegates to SDK session methods. MessageStateHandler
extends EventEmitter for CLI compatibility (on/off pattern).
TaskProxyState mirrors classic TaskState subset.
- src/sdk/webview-grpc-bridge.ts: Bridges SDK session events to
webview gRPC streams. Translates ClineMessages to proto format
and pushes through sendPartialMessageEvent/sendStateUpdate.
- src/sdk/SdkController.ts: Wired TaskProxy + WebviewGrpcBridge
into session lifecycle. Events flow: SDK → message translator →
gRPC bridge → webview streams. Reuses getStateToPostToWebview()
for state building.
- No 'as' casts in production code — type narrowing used instead.
Stubs throw errors instead of returning undefined as unknown as T.
- 114 unit tests pass across 6 test files.
- 0 new TypeScript errors (3 pre-existing in unrelated files).
- Extension loads, sidebar renders, newTask routes correctly.
- initTask fails at runtime because ClineCore.create() needs SDK
config (Step 6+).
- Add @clinebot/core, @clinebot/llms, @clinebot/shared, @clinebot/agents
as dependencies via file: protocol (linked to ../sdk-wip)
- Create src/sdk/ directory with SdkController stub and barrel export
- Replace src/core/controller/index.ts with re-export from SDK adapter
(classic Controller accessible via origin/main)
- Extract getStateToPostToWebview() to standalone function for reuse
- Add vitest.config.sdk.ts for SDK adapter tests
- Fix implicit any types in handler modules
- Extension compiles and builds successfully (tsc + esbuild pass)
- Single entry point: no CLINE_SDK flag, SDK adapter is the only codepath
Replaces classic src/core/controller/index.ts (see origin/main)
Key changes from feedback:
- Replace 'don't delete what you haven't replaced' with 'delete and document'
- Delete classic code immediately when replaced by SDK equivalent
- Add 'Replaces classic src/core/... (see origin/main)' comments
- Use kb_search/git to reference origin/main for classic implementation
- Single entry point: no CLINE_SDK env variable, no dual codepaths
- Step 1 now modifies src/extension.ts directly
- Rationale: dual entry points caused constant confusion in attempt 2
- Updated ARCHITECTURE.md with key architectural decisions
- Updated .clinerules/sdk-migration.md with new rules
* At-mention picker: show "Searching..." instead of misleading "No results found"
When the @-mention picker fires its initial empty-query searchFiles, slow
workspaces (e.g. network mounts) leave the call in flight for several
seconds. Three small UX bugs combined to make this look broken:
1. The 500ms delayed-loading effect was gated on `searchQuery` being
non-empty, so the spinner never appeared during the initial open —
the user just saw "No results found" forever.
2. While loading, the spinner row stacked above the "No results found"
row, claiming both states at once.
3. The spinner also stacked above the static root-menu items
("Paste URL", "Problems", "Git Commits", "Add File", "Add Folder")
when the picker first opens with empty input, even though those
items are already actionable.
Fixes:
- Drop the `&& searchQuery` guard so the loading effect arms on empty
queries too.
- In `filteredOptions`, strip the lone `NoResults` entry while
`showDelayedLoading` is true — searching is not the same as nothing
matched.
- Render the spinner only when `filteredOptions.length === 0`, so it
never stacks above existing options.
The 500ms delay before the spinner appears is preserved, so fast
searches stay visually quiet.
* fixes
* Drop stale @-mention searchFiles responses to fix "No results" flash
* Track in-flight searches with a monotonic latestSearchTokenRef in
ChatTextArea; resolve/error handlers bail when their captured token
is no longer the latest.
* Send the token as mentionsRequestId; proto already supports it.
* Drop the never-read currentSearchQueryRef scaffold.
* Fixes the cancel-then-re-pick race (Add File → cancel → Add Folder)
reported in CLINE-1814.
Add a checkbox for users to indicate they're on a beta version, and
auto-apply the 'beta' label via the existing auto-label workflow when
the checkbox is checked.
* CLINE-1814 typed RipgrepSpawnError + error_reason proto
* file-search.ts: define RipgrepSpawnError carrying stderr+exitCode; reject
on non-zero ripgrep exit (with empty results) instead of resolving to []
* file-search.ts: re-throw from searchWorkspaceFiles and
searchWorkspaceFilesMultiroot so the controller sees the error and can
attach a structured error_reason to the proto response
* file-search.test.ts: assert spawn-time and exit-time errors both surface
as RipgrepSpawnError
* file.proto/FileSearchResults: add optional error_reason and error_message
fields with the closed enumeration of values documented inline
Phase 1 of the visibility patch. No behaviour change for healthy installs;
broken installs now surface a real error instead of an empty list.
Refs: CLINE-1814
* CLINE-1814 surface error_reason in picker UI
Controller (searchFiles.ts):
* classify thrown errors into a closed enumeration of error_reason values
(workspace_unavailable, ripgrep_spawn_failed, unknown). RipgrepSpawnError
unwraps the first line of stderr into error_message so the picker can
surface ENOENT / EACCES / 'Operation not permitted' verbatim.
* the no-workspace-path branch now returns workspace_unavailable instead
of an empty result list.
* keep using telemetry.captureMentionFailed for aggregate signal but map
ripgrep_spawn_failed -> 'unknown' to stay within the existing closed enum.
Webview (ChatTextArea + ContextMenu):
* ChatTextArea threads errorReason / errorMessage from each searchFiles
RPC response (and from RPC-level rejections) into ContextMenu.
* ContextMenu renders a grey, italic, smaller subtitle beneath the
'No results found' row when an error_reason is present.
* renderErrorSubtitle() carries a short doc-comment for each value so
reviewers can see at a glance how each error_reason maps to UI copy.
Refs: CLINE-1814
* CLINE-1814 trim verbose CLINE-1814 ticket-reference comments
Pure code-quality pass over the Phase 1 changes: condense the long
narrative comments that referenced the ticket into terser explanatory
comments where they still add value, and remove ones that just
repeated what the (now-stable) code already says. No behaviour change.
* CLINE-1814 fix RipgrepSpawnError override of Error.cause
TS error 'This member must have an override modifier because it
overrides a member in the base class Error' - Error gained an optional
'cause' field in ES2022. Drop the explicit field declaration and pass
the cause via the standard ES2022 ErrorOptions in super(). Behaviour
unchanged: instances still expose .cause via the base-class field.
* CLINE-1814 fix Windows race in executeRipgrepForFiles finalisation
CI hit this on Windows:
AssertionError: expected [Promise] to be rejected with a message
matching /ripgrep exited with code 2/, but got 'ripgrep exited with
code null: rg: /bogus: No such file or directory (os error 2)'
The readline 'close' event and the child-process 'exit' event fire in
non-deterministic order on Windows. The previous code keyed off 'close'
alone, which meant the rejection branch could run with exitCode still
null even when the process eventually exited with a real code.
Fix: gate finalisation on both events with a small barrier (rlClosed +
processExited + finalised flags). Idempotent and safe under any
ordering. Test passes on darwin (where the ordering used to be benign)
and the same path now produces the expected exitCode=2 message on
Windows.
No production-behaviour change on the happy path: results still resolve
exactly when the readline finishes parsing stdout.
* CLINE-1814 address Phase 1 code-review feedback
Three small follow-ups from review on the Phase 1 PR:
1) ContextMenu.tsx: drop a stray trailing semicolon on the
selectedType prop declaration so the interface style stays
consistent with the rest of the file (no semicolons on field
declarations). Cosmetic only, no behaviour change.
2) file-search.ts: in executeRipgrepForFiles' rgProcess.on('error')
handler, set finalised = true before reject() so that a subsequent
('close', 'exit') pair can't pass the finalise() guards. The
double-reject was already a no-op (Promises swallow further
reject() calls once settled), but unconditionally maintaining the
barrier invariant makes the lifecycle of this Promise much easier
to reason about and matches the symmetry of the other two
finalise() callers.
3) file-search.test.ts: collapse the awaited-twice rejected-promise
pattern in 'should reject with RipgrepSpawnError when ripgrep
exits non-zero with no results'. The previous form
(await should(p).be.rejectedWith(...); await p.catch(...)) worked
because settled promises replay their value, but it's subtly
misleading. The new form awaits once via .catch() and asserts on
the resulting error directly.
All six File Search unit tests continue to pass.
* CLINE-1814 revert picker error subtitle (UI for impl-detail leak)
Per code-review feedback: surfacing structured error_reason / error_message
from FileSearchResults as a grey-italic subtitle on the 'No results found'
row exposes implementation detail to end-users. The user can't act on
'(ripgrep failed: rg: ENOENT)' or '(internal error: spawn EACCES)' — those
are diagnostic data that belong in logs and aggregate telemetry.
Reverted in this commit:
- ContextMenu.tsx: errorReason / errorMessage props removed,
renderErrorSubtitle helper deleted, NoResults row reverts to a plain
<span>No results found</span>.
- ChatTextArea.tsx: searchErrorReason / searchErrorMessage state and
all setSearchErrorReason / setSearchErrorMessage call-sites removed;
ContextMenu invocation no longer passes the two props.
Kept on purpose:
- The proto field FileSearchResults.error_reason — it's harmless on
the wire and the next commit wires it up to telemetry + structured
logging, which is where this signal actually belongs.
- The classifyError helper and ERROR_REASON_* constants in the
searchFiles controller — same reason, they feed telemetry next.
Six file-search unit tests still pass.
* CLINE-1814 telemetry: surface ripgrep_spawn_failed / workspace_unavailable
Until now the searchFiles controller's catch block collapsed every classified
error_reason — workspace_unavailable, ripgrep_spawn_failed, unknown — onto a
two-value telemetry enum (permission_denied | unknown), throwing away the
diagnostic signal we'd worked hard to extract. The Linear ticket explicitly
asks for the structured signal to feed telemetry; this commit delivers on that.
Changes:
- TelemetryService.captureMentionFailed: extend the errorType enum with
two new categorical values, ripgrep_spawn_failed and workspace_unavailable.
Doc-comment updated to call out that those two are picker-search failures
(vs the existing values which are mention-content retrieval failures).
- searchFiles.ts:
* empty-workspace branch now emits errorType=workspace_unavailable
(previously: not_found).
* catch-block computes errorType from the classified errorReason —
RipgrepSpawnError -> ripgrep_spawn_failed, EACCES -> permission_denied,
otherwise unknown — instead of always permission_denied | unknown.
Net result: ops can now distinguish 'ripgrep is broken on this user's
machine' from 'user is in a one-window-no-folder IntelliJ session' from
genuine code bugs in the search pipeline.
* CLINE-1814 log: include classified errorReason on searchFiles error line
Trivial follow-up to the previous commit. Triagers grepping
~/.cline/cline-core-service.log for searchFiles failures got the raw error
object dumped, but no hint as to which of the structured error_reason
buckets the failure falls into. Now the log line is
[ERROR] Error in searchFiles (errorReason=ripgrep_spawn_failed): <Error...>
so a single grep for 'errorReason=ripgrep_spawn_failed' surfaces every
ripgrep-side failure across the user's session without having to read the
stack trace. Same field value as the gRPC response and the telemetry event,
so the three sources can be cross-referenced in incident triage.
Also moved the classifyError() call above the Logger.error() call (was
below) so the reason is computed once, used twice.
* CLINE-1814 address Phase 1 review feedback (rename, simplify, trim comments)
Five review comments rolled into one commit:
file-search.ts
* Rename RipgrepSpawnError -> RipgrepError. The class covers spawn failures
AND non-zero-exit / stderr-on-empty-stdout paths; the old name only
described half its job.
* Drop the unread 'cause' constructor option. We were never reading
err.cause anywhere downstream, and the only producer was the
spawn-error path which already encodes the underlying message in the
string.
* Replace the rlClosed/processExited/finalised state machine with two
Promise resolvers awaited via Promise.all. Same ordering guarantees on
Windows (both 'close' and 'exit' must fire before we settle), zero
mutable bookkeeping, and the spawn-error path no longer needs to
pre-flip a 'finalised' flag to be safe against a late close+exit pair.
Used new Promise() rather than Promise.withResolvers() because TS lib
is es2022 and withResolvers is es2024; behavior is identical.
searchFiles.ts
* .trim() the stderr before split() so a leading newline doesn't yield
an empty first line on the telemetry / log path.
* Drop the 'this commit' comment (ephemera once 'this commit' is no
longer the most recent one) and the 'Determine mention type based on
the search request' comment, both of which restated the obvious code.
file-search.test.ts
* Update test name and assertion to match the renamed class.
All 6 file-search unit tests pass.
* CLINE-1814 drop unread RipgrepError.exitCode field
Follow-up to the previous review-feedback commit. The 'we're not reading
this anywhere' note was about exitCode, not cause - my mistake. The exit
code is already encoded into the error message string ('ripgrep exited
with code N: <stderr>'), so the dedicated field was carrying no
additional information for any consumer.
Dropped:
* RipgrepError.exitCode field and constructor option
* 'exitCode' from the two new RipgrepError(...) call sites
* 'should(err).have.property(exitCode, 2)' from the unit test
The internal exitCode local in executeRipgrepForFiles stays - it gates
the reject vs resolve decision after both 'close' and 'exit' have fired.
It's just no longer plumbed onto the error.
All 6 file-search unit tests still pass.
* feat(memory-observability): add periodic memory logging to cline-core
Introduces a lightweight memory monitor that logs process.memoryUsage()
snapshots to the existing cline-core log every 5 minutes, plus an
immediate baseline at startup and a final snapshot at graceful shutdown.
Each entry is written as a single `[MEMORY] key=valueMB ...` line so it
is trivially greppable and parseable:
grep '\[MEMORY\]' ~/.cline/cline-core-service.log
The timer is unref()'d so it does not keep the event loop alive on its
own, ensuring the Node process can still exit cleanly.
Also adds an informational log line after process.chdir(__dirname) that
records where V8 will write heap snapshots if --heapsnapshot-near-heap-limit
triggers them, and a best-effort process.on("exit") handler that scans
cwd for .heapsnapshot files on abnormal exit and logs their paths/sizes
so post-mortem investigation starts with the diagnostic data in hand.
This is Part 1 (periodic memory logging) and the Node-side portions of
Part 2 (snapshot directory + exit handler) of the memory observability
implementation plan. The V8 flag itself and the
~/.cline/heapsnapshots/ move-and-cap cleanup live in the Kotlin
CoreProcessManager and are applied separately in the plugin repo.
No business-logic changes; purely additive diagnostics.
* chore(memory-observability): enable --heapsnapshot-near-heap-limit=3 in runclinecore.sh
When cline-core approaches the V8 heap ceiling, V8 will now write up to
3 .heapsnapshot files to the current working directory before giving up
and crashing. These snapshots can be loaded into Chrome DevTools → Memory
tab to identify the objects retaining the most memory.
N=3 is chosen because the last snapshot (written just before the fatal
OOM) shows only live, truly-unreclaimable objects — the earlier ones still
contain garbage the GC hadn't collected yet. Having all three lets us
compare.
This flag is a V8 runtime flag and must be passed on the node command
line; it cannot be enabled from JavaScript at runtime.
Matches the equivalent change on the cline-core launcher in the IntelliJ
plugin repo (CoreProcessManager.kt).
* chore(memory-observability): reduce --heapsnapshot-near-heap-limit from 3 to 1
Reviewer concern: with --max-old-space-size=8192, each heap snapshot
serializes at roughly 4-5x heapUsed on disk, so three snapshots can
burst 24-40 GB to disk in the seconds before an OOM crash — right
when the system is already under memory/CPU pressure. On a laptop
with <40 GB free this can leave partial/corrupted snapshots or
trigger OS pressure on unrelated processes.
The plan doc originally argued 'snapshot 3 of 3 is most valuable
because it contains only live objects'. In practice, by the time V8
triggers the flag it has already run aggressive mark-compact cycles,
so snapshot 1 is nearly-all-live too. Our own Scenario B verification
run confirmed that even the first snapshot contained the retainer
chain — snapshots 2 and 3 added no diagnostic signal.
Trade-off:
- per-OOM disk burst: 24-40 GB -> 8-14 GB (3x reduction)
- time-to-crash (frozen): 30-60 s -> 10-20 s (3x reduction)
- diagnostic signal: essentially unchanged
The persistent-directory cap in CoreProcessManager.kt stays at 3, so
we still retain snapshots from the 3 most recent OOM events for
cross-event comparison.
* chore(memory-observability): shorten runclinecore.sh flag comments
The one-line pointer to CoreProcessManager.kt was more noise than
signal given the flags are visible on the same line as the command.
Rationale for the --heapsnapshot-near-heap-limit value lives in the
Kotlin constant's KDoc and in the commit log.
* Make the nightly publishing script use the stable channel of cline-nightly.
* Address PR review feedback from Greptile and Copilot
- Reject unknown CLI flags with an error message, preventing typos like
--prerelease from silently publishing to the wrong channel (Greptile)
- Rename 'stable' to 'release' throughout docs, help text, and log
messages to match VS Code Marketplace terminology (Copilot)
- Rename workflow step from 'Publish Extension as Pre-release' to
'Publish Nightly Extension' since it now publishes to the release
channel by default (Greptile)
* fix: set --max-old-space-size=8192 for cline-core node process
The cline-core Node.js process was launched without a V8 heap limit,
defaulting to ~2GB. Long conversations with large file reads cause
GC-thrashing and eventual OOM crashes. Set the limit to 8GB to provide
sufficient headroom for extended sessions.
* fix: set --max-old-space-size=8192 for cline-core node process
* docs: add prompt storage schema and OpenTelemetry events reference
- Add comprehensive prompt storage documentation (DEVREL-142)
- Complete enterpriseTelemetry.promptUploading schema
- Setup guides for AWS S3 and Cloudflare R2
- Storage architecture and sync worker behavior
- IAM policies and troubleshooting
- Add OpenTelemetry events catalog (DEVREL-143)
- Document 80+ events across 8 categories
- Example payloads and analytics query patterns
- Integration examples for Datadog, Grafana, New Relic
- Event schema reference and best practices
- Update monitoring documentation
- Add cross-references between related pages
- Update navigation in docs.json
- Integrate new pages into Enterprise > Monitoring section
* fix: update broken link in telemetry.mdx to point to OTel events page
* docs: address PR review comments
- Fix file contents exclusion claim in prompt-storage.mdx
- Remove misleading claim about file contents not being stored
- Add warning that tool inputs (like write_to_file content) are included
- Standardize attribute naming in opentelemetry-events.mdx
- Change model_id to model in event tables for consistency
- Match actual emitted event schema shown in example payloads
- Add SQL syntax note in opentelemetry-events.mdx
- Clarify that attribute access syntax is platform-specific
- Provide examples for BigQuery and ClickHouse
* adjustments
- Update root package.json axios from 1.13.6 to 1.15.0
- Update evals/package.json axios from 1.13.6 to 1.15.0
- Update docs/package.json axios override from 1.13.5 to 1.15.0
- Regenerate all package-lock.json files
* feat: wire up globalSkills consumption from remote config
The remote config schema already includes globalSkills (merged in #10236).
The dashboard can save skills to remote config. This PR wires up the
extension to read and use them.
## Changes
### State storage (Layer 1)
- Add remoteGlobalSkills to REMOTE_CONFIG_EXTRA_FIELDS
- Add remoteSkillsToggles to GLOBAL_STATE_FIELDS
### Remote config transform/apply/clear (Layer 2)
- Map globalSkills → remoteGlobalSkills in transformRemoteConfigToStateShape
- Sync remoteSkillsToggles in applyRemoteConfig using frontmatter.name
as the identity key (not entry.name)
- Clear remoteSkillsToggles in clearRemoteConfig
### Skill discovery (Layer 3)
- discoverSkills accepts optional remoteSkillEntries parameter (pure
utility, no StateManager coupling)
- getSkillContent accepts optional remoteSkillEntries parameter for
remote content loading without disk I/O
- Precedence: remote (enterprise) > disk-global (user) > project
### refreshSkills (Layer 3b)
- Reads remote entries from controller.stateManager, parses frontmatter,
builds SkillInfo entries with alwaysEnabled field
### UseSkillToolHandler (Layer 4)
- Toggle filter checks remoteSkillsToggles for remote: prefixed skills
- Directory note omitted for remote skills
- Passes remoteSkillEntries to both discoverSkills and getSkillContent
### toggleSkill
- Routes remote: prefixed paths to remoteSkillsToggles keyed by name
### Proto + webview
- Added always_enabled field to SkillInfo proto message
- Modal passes isRemote + alwaysEnabled to RuleRow for remote skills
- Uses skill.name as display label for remote skills
## Design decisions
- frontmatter.name is the sole identity for remote skills (entry.name
is ignored). This matches how local skills work.
- remote: path prefix distinguishes remote from disk skills in toggle
stores and content loading.
- skills.ts remains a pure utility module with zero StateManager coupling.
Callers inject remote entries as parameters.
- 42 unit tests covering discovery, precedence, content loading, toggle
sync, and frontmatter parsing.
* fix: enforce alwaysEnabled in toggle sync to prevent stale false overrides
When applyRemoteConfig syncs skill toggles, synchronizeRemoteRuleToggles
preserves existing toggle values — including false. If an admin later
sets alwaysEnabled: true on a skill that a user had previously disabled,
the stale false toggle would survive the sync. The UI would show the
skill as locked-on (via the alwaysEnabled check in refreshSkills), but
UseSkillToolHandler's filter would see false in the toggle store and
exclude it, causing a 'Skill not found' error for a skill the user can
see is active.
Fix: after synchronizeRemoteRuleToggles, force any alwaysEnabled entry
with a false toggle back to true. This makes the toggle store the single
source of truth — both UI and handler now agree.
Adds 4 tests covering the alwaysEnabled enforcement edge cases.
* fix: deduplicate remote skill parsing, add drift validation, and fix architectural gaps
1. Extract shared parseRemoteSkillEntries utility (skills.ts)
- Single validation point for remote skill entries, replacing duplicated
frontmatter parsing in skills.ts, refreshSkills.ts, and remote-config/utils.ts
- Enforces entry.name === frontmatter.name to catch drift between the
dashboard and SKILL.md content (rejects with warning on mismatch)
2. Eliminate redundant frontmatter re-parsing in getSkillContent
- Was re-parsing every entry's frontmatter to find a match by name
- Now uses entry.name for lookup since drift validation guarantees equality
3. Enforce alwaysEnabled in UseSkillToolHandler
- The toggle filter was missing the alwaysEnabled check, so a stale false
toggle could hide an admin-locked skill from the model
- Now matches the logic in refreshSkills.ts
4. Add remote_skills_toggles to SkillsToggles proto
- toggleSkill now returns remoteSkillsToggles in the response, matching
how remote rules/workflows already work
5. Separate Enterprise Skills section in UI
- Remote skills now render under their own "Enterprise Skills" header,
consistent with how rules and workflows display remote entries
6. Update tests for new validation behavior
- Tests now use entry.name matching frontmatter.name (was deliberately
mismatched before); added drift rejection tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: enable viewing remote skills and fix tooltip text in RuleRow
- openRemoteFile now handles remote://skill/{name} URIs (was only
rule and workflow), looking up content from remoteGlobalSkills
- RuleRow's handleEditClick builds the correct URI type for skills
(was falling through to "rule")
- Tooltip text now uses ruleType ("View skill file") instead of
hardcoded "View rule file" for all remote entries
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: soften drift validation to warn-not-reject, fix content lookup fallback
The strict entry.name !== frontmatter.name rejection was silently hiding
org-configured skills when the dashboard's entry.name didn't match the
SKILL.md frontmatter name.
- parseRemoteSkillEntries now warns on drift but uses frontmatter.name as
the canonical identity instead of rejecting the entry
- getSkillContent falls back to frontmatter match when entry.name lookup
misses (handles drift for content loading)
- openRemoteFile falls back to frontmatter match for skill view (same
reason)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: include remote skills in system prompt and fix remote config race
The system prompt generation called discoverSkills() without passing
remoteSkillEntries, so the model never learned about remote skills and
never invoked use_skill for them. This was the actual cause of remote
skills being invisible to the model despite showing in the UI.
Also fixes a race condition in applyRemoteConfig where clearRemoteConfig()
wiped the in-memory cache before repopulating it field-by-field. Any
concurrent reader (e.g., UseSkillToolHandler) during that window would
see an empty cache. Replaced with atomic replaceRemoteConfig() that
builds the new cache and swaps it in a single assignment.
- task/index.ts: pass remoteSkillEntries to discoverSkills, add
remoteSkillsToggles + alwaysEnabled filtering (matching handler)
- StateManager: add replaceRemoteConfig() for atomic cache swap
- remote-config/utils.ts: use replaceRemoteConfig instead of
clearRemoteConfig + setRemoteConfigField loop
- Remove debug logging from parseRemoteSkillEntries and handler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: include remote skills in subagent path
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(models): prepare Claude Opus 4.7 provider support
* remove deprecated params for opus 4.7
- opus 4.7 doesn't accept params like temperature, top_p, top_k anymore.
This commit removes those params only for opus 4.7
* Agent hill climb fixes
* Anthropic adaptive thinking
* Removing 1m context switcher
* Removing 1m models fully
* Restore Anthropic 1M variants and context switchers
* Adding 1m
* remove changeset
* fix Opus 4.5 adaptive thinking detection
---------
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
Co-authored-by: Arafatkatze <arafat.da.khan@gmail.com>
Replace the old client-side per-org scan for remote config with a single
discovery call to GET /api/v1/users/me/remote-config. Reuse the inline
config value when possible, falling back to the org-level endpoint only
when inline parse fails.
Key changes:
- Single discovery call replaces N org-level requests
- Resolve config before switching org to avoid stranding the user
- Transient errors preserve existing config (log-only, no clearing)
- authenticatedRequest() strict null vs undefined validation
- Auth precheck in fetchUserRemoteConfig() with token pass-through
* fix(prompts): add use_subagents to GLM, Hermes, and XS TOOL_USE_SECTION overrides
These variants use hardcoded TOOL_USE_SECTION templates that bypass the
auto-generated tool descriptions. When use_subagents was added as a new tool,
it was registered in each variant's .tools() config but was never added to the
hardcoded override templates — so models using these variants never saw
use_subagents in their system prompt and could not call it.
This adds the use_subagents description block to the TOOL_USE_SECTION override
templates for glm, hermes, and xs variants, and updates the corresponding
test snapshots.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(prompts): gate use_subagents on subagentsEnabled and isSubagentRun context
The previous commit added use_subagents to the GLM, Hermes, and XS
TOOL_USE_SECTION override templates unconditionally. This was incorrect —
the canonical tool spec gates use_subagents with:
context.subagentsEnabled === true && !context.isSubagentRun
Without this guard, models would advertise use_subagents even when
subagents are disabled by the user, and subagent runs could recursively
spawn further subagents.
This commit:
- Wraps the use_subagents block in all three templates with the same
subagentsEnabled && !isSubagentRun conditional
- Converts HERMES_TOOL_USE_TEMPLATE from a plain string constant to a
function so it can access context (matching the pattern used by GLM
and XS templates)
- Updates snapshots accordingly
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(prompts): align use_subagents rendering guard with tool context requirements
---------
Co-authored-by: sunghyun <jjinjukks1227@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(chat): add SpendLimitError UI for SPEND_LIMIT_EXCEEDED (429)
When the Cline backend returns a 429 with code SPEND_LIMIT_EXCEEDED (org
budget cap hit), the chat error flow now shows a dedicated SpendLimitError
component instead of falling through to the generic rate-limit message.
Changes:
- proto/cline/account.proto: add submitLimitIncreaseRequest RPC +
SubmitLimitIncreaseResponse message
- src/services/error/ClineError.ts: add SpendLimit error type; detect
SPEND_LIMIT_EXCEEDED before the generic rate-limit pattern check
- src/services/account/ClineAccountService.ts: add
submitLimitIncreaseRequestRPC() calling POST /api/v1/users/me/budget/request
- src/core/controller/account/submitLimitIncreaseRequest.ts: new gRPC
handler wired automatically by npm run protos
- webview-ui/src/components/chat/SpendLimitError.tsx: new card component
mirroring CreditLimitError; shows spent/limit amounts, resets_at, org
attribution, and a Request Increase button with 5-min localSto
When the Cline backend returns a 429 with code SPEND_LIMIT_EXCEEDED (org
budgetrors to
SpendLbudget cap hit), the chat budget_period,limit_usd,spent_usd,resets_at}
- component instead of falling through to the generic rate-limnd Limit
Reac
Changes:
- proto/cline/account.p
* Update webview-ui/src/components/chat/SpendLimitError.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* chore: shorten spend limit error message verbiage
* fix(storybook): align spend limit story messages with component output
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
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.
* Complete documentation for environment variable-based OpenTelemetry configuration
* Address PR review comments
- Add Values column to OTLP Configuration table for consistency
- Fix New Relic endpoint to include required port 4318
- Add note about Datadog region-specific endpoints
Remove Teams Plan as an option for seat upgrades in the managing-members documentation. This aligns with the product strategy to drive customers toward Enterprise for any multiplayer/team scenarios.
Related: https://github.com/cline/cline-web/pull/256
Surface the actual read_file line window in chat summaries so users can see what context was added, while keeping manual approval and repeated same-file reads rendered accurately.
* 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
- Add linux-aarch64 to TARGET_PLATFORMS in package-standalone.mjs so
better-sqlite3 prebuilt binaries are downloaded for this platform.
- Rename linux-arm64 to linux-aarch64 in download-ripgrep.mjs for
consistency with the JetBrains plugin naming convention (which uses
Java's os.arch value 'aarch64').
* fix(read_file): add stable line labels in act/plan
* prompt: clarify read_file line labels for replace_in_file
* Update prompt snapshots
* feat(read_file): add chunked reading with start_line/end_line parameters
Add optional start_line and end_line parameters to read_file so models
can read files in chunks instead of loading entire files into context.
Default limit is 1000 lines per read, with a continuation hint guiding
the model to paginate when needed.
Made-with: Cursor
* feat: align read_file line format with SDK while keeping superior chunking
- Change line format from 'L1:' to '1 |' to match SDK format
- Add proper NaN validation for start_line/end_line parameters
- Keep 1000-line chunking with continuation hints (superior to SDK)
- Update tool description and tests to reflect new format
- Add directory usage guardrail back to tool description
- Update replace_in_file prompt to reference new line format
This aligns the PR with the newer SDK design patterns while
preserving the superior chunking behavior that prevents context
overflow issues.
* fix: resolve duplicate step numbering in replace_in_file instructions
Fixes the duplicate step 5 issue when NOTEBOOK_INSTRUCTIONS is
concatenated with BASE_DIFF_INSTRUCTIONS for .ipynb files.
Changes notebook instructions to step 6 to avoid ambiguity.
* test: update unit test snapshots
* test: fix gemini3 tools snapshot
* test: regenerate gemini3 tools snapshot
* fix: preserve line ranges on cached file reads
* test: refresh gemini3 tools snapshot
* test: strengthen chunked read assertions
* fix: normalize inverted read file ranges
VSCode's webview doesn't reliably play VP9/WebM, while JetBrains'
JCEF lacks H.264 decoding. Restore the original H.264/MP4 video and
use HTML5 <source> elements with explicit MIME types so each platform
picks the format it supports:
<source src=... type="video/mp4" /> <!-- VSCode -->
<source src=... type="video/webm" /> <!-- JetBrains -->
Also:
- Restore .mp4 Git LFS tracking in .gitattributes
- Update CI LFS verification to check both files
- Add webm to JetBrains MIME type map (BrowserRequestHandler)
JetBrains IDEs use JCEF (Chromium Embedded Framework) for webviews,
which often does not include H.264 decoding due to licensing
restrictions. This causes the kanban demo video to fail to play.
Transcode the video from H.264/MP4 to VP9/WebM, which is a royalty-free
codec universally supported in Chromium derivatives. This also reduces
the file size from 3.6MB to ~900KB.
Updated all references:
- Source component import (ClineKanbanLaunchModal.tsx)
- Git LFS tracking (.gitattributes)
- CI workflow LFS checks (publish.yml, publish-nightly.yml)
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.
* refactor: replace hand-rolled YAML parser in refreshSkills with shared helper
The refreshSkills controller had its own line-by-line YAML parser that
only handled simple key: value pairs. Replace it with the shared
parseYamlFrontmatter helper already used by the skills discovery path.
Same output for name and description fields. The shared parser handles
edge cases (arrays, nested values, quoted colons) more robustly.
* refactor: inline parseYamlFrontmatter, remove redundant wrapper
Remove the parseFrontmatter wrapper since only `data` is used by
the caller. Inline the call directly at the use site.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: John Choi <johnchoi@MacBook-Pro.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: upgrade MiniMax default model to M2.7
- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to model list
- Set MiniMax-M2.7 as default model
- Keep all previous models as alternatives
- Update provider documentation
* fix: correct M2.7 cache pricing and update prompt caching docs
- Updated cacheReadsPrice from 0.015 to 0.03 for both MiniMax-M2.7 and
MiniMax-M2.7-highspeed to match M2.5 pricing (same cache read rate
across M2.x models)
- Updated prompt caching tip to explicitly mention highspeed variants
* fix: correct MiniMax model pricing to match official rates
- M2.7-highspeed/M2.5-highspeed/M2.1-lightning: $0.60/$2.40 (not $0.30/$1.20)
- M2.7 cache: reads $0.06/M (not $0.03), writes $0.375/M (not $0.0375)
- All models: cache writes $0.375/M (not $0.0375)
Ref: https://platform.minimax.io/docs/llms.txt
---------
Co-authored-by: PR Bot <pr-bot@minimaxi.com>
The Kanban launch-by-default feature (beb54a4) redirects bare `cline`
invocations to Kanban, which blocks all TUI tests that launch without
`--tui`. Adding the flag ensures tests reach the legacy TUI as expected.
* 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).
* feat: add repeated tool call loop detection
Detect when the LLM calls the same tool with identical arguments
repeatedly, which wastes tokens without making progress. This is
the #1 active complaint in the Cline issue tracker (13+ open issues
including #9923, #9916, #9846, #9816).
Two-stage escalation:
- Stage 1 (3 identical calls): inject a warning nudging the LLM
to try a different approach
- Stage 2 (5 identical calls): trigger the existing
consecutiveMistakeCount escalation (asks user or fails in YOLO)
Detection uses JSON.stringify with a sorted key replacer for
deterministic comparison. Metadata params like task_progress
(which change every call even when actual tool arguments are
identical) are stripped from the comparison.
Complementary to fileReadCache, which deduplicates file content but
still allows the tool call to succeed and consume a turn. Loop
detection catches the repeated call pattern itself.
Changes:
- loop-detection.ts: shared helper (toolCallSignature, checkRepeatedToolCall)
- TaskState.ts: add lastToolParams, consecutiveIdenticalToolCount
- ToolExecutor.ts: call checkRepeatedToolCall in handleCompleteBlock
- responses.ts: add formatResponse.repeatedToolCall
- loop-detection.test.ts: 5 tests
Manually verified: CLI test confirms soft warning at call 3,
YOLO mode failure at call 5.
Refs: #9923, #9916, #9846, #9816
* fix: address review feedback on loop detection
- Change hardEscalation threshold from >= to === so it fires exactly
once at count 5, matching softWarning behavior
- Widen toolCallSignature param type to Partial<Record<string, string>>
to match actual block.params type from ToolExecutor
- Add negative boundary assertions to verify no false positives at
calls 0, 1, 3, 4
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: reset loop detection state when user continues after mistake_limit_reached
When hard escalation fired at count === 5 and the user clicked
"continue", consecutiveIdenticalToolCount was never reset. The count
would exceed 5 but === 5 never matched again, silently disabling
loop detection for the rest of the task.
Reset consecutiveIdenticalToolCount, lastToolName, and lastToolParams
alongside the existing consecutiveMistakeCount reset so the detector
fully re-arms after the user continues.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: John Choi <johnchoi@MacBook-Pro.local>
* fix: prevent OOM crash from globby's eager .gitignore scanning in listFiles
Replace globby's gitignore:true (which reads ALL .gitignore files in the
entire tree upfront, including inside gitignored directories) with
incremental .gitignore reading during BFS traversal.
In projects with large gitignored vendored dependencies containing many
nested repos, globby collects thousands of patterns, builds a massive
regex, and V8 runs out of memory during regex compilation (~488MB).
The fix reads .gitignore files only from directories the BFS actually
enters. Gitignored directories are never entered, so their .gitignore
files are never parsed and the pattern count stays small.
- Set gitignore:false, handle .gitignore ourselves
- Read root .gitignore in buildIgnorePatterns() to seed initial patterns
- Read subdirectory .gitignore lazily during globbyLevelByLevel BFS
- Accumulate patterns in currentIgnore so deeper levels respect them
- Add 4 tests: root patterns, file patterns, subdirectory .gitignore,
and OOM-prevention (no reading inside gitignored dirs)
* Code review followup
* Potential fix for code scanning alert no. 147: Incomplete string escaping or encoding
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Replace generic "missing parameter" errors with targeted guidance for
the two tools observed failing most in SWE-bench (6% of failures).
The new messages include the expected format (SEARCH/REPLACE blocks,
XML example) without the 30-line boilerplate reminder.
Made-with: Cursor
* fix: read cache_write_tokens from OpenRouter API instead of hardcoding 0
- Read prompt_tokens_details.cache_write_tokens from OpenRouter stream usage
chunks instead of hardcoding cacheWriteTokens to 0
- Read native_tokens_cache_write from generation endpoint fallback
- Replace fragile hardcoded model ID switch statement for cache_control blocks
with prefix-based matching (anthropic/, minimax/) so new models automatically
get prompt caching enabled
- Add unit test verifying cache_write_tokens are correctly extracted
Co-authored-by: Ara <arafat.da.khan@gmail.com>
* fix: read cache_write_tokens from OpenRouter API instead of hardcoding 0
- Read prompt_tokens_details.cache_write_tokens from OpenRouter stream usage
chunks instead of hardcoding cacheWriteTokens to 0
- Read native_tokens_cache_write from generation endpoint fallback
- Replace fragile hardcoded model ID switch statement for cache_control blocks
with prefix-based matching (anthropic/, minimax/) so new models automatically
get prompt caching enabled
- Add unit test verifying cache_write_tokens are correctly extracted
Co-authored-by: Ara <arafat.da.khan@gmail.com>
* Release v3.74.0 Notes
* Release v3.74.0 Notes
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: alex-lum <alex@cline.bot>
The presentation scheduler introduced in ff05ec3bb awaits in-flight
flushes during dispose(), but ask() blocks indefinitely on pWaitFor
waiting for user input. When abortTask() sets abort=true and then
awaits scheduler.dispose(), the in-flight flush (blocked on
ask("completion_result")) never resolves, deadlocking the UI.
Add abort flag check to ask()'s pWaitFor condition so blocked asks
unblock immediately when the task is aborted.
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: fix SDK documentation accuracy and completeness
- Fix setPermissionHandler API Reference to use correct async/return signature
(was showing old callback pattern with (request, resolve) => void)
- Remove non-existent PermissionResolver type from Exported Types table
- Fix PermissionHandler type description to match actual signature
- Add missing hooksDir option to ClineAgentOptions documentation
- Fix newSession() example to use real model IDs
- Replace developer personal path in Full Example with generic path
- Use placeholder for version in initialize() example to avoid staleness
- Expand Stop Reasons table and add note about current implementation
- Add missing key exported types: AcpSessionStatus, AcpSessionState,
RequestPermissionRequest/Response, PermissionOption, SessionUpdatePayload,
SessionModelState, ModelInfo, TextContent/ImageContent/AudioContent,
SetSessionMode/Model request/response types, TranslatedMessage
* docs: improve SDK visibility and disambiguate from API code examples
- Move SDK page higher in Cline CLI nav (after Installation, before Interactive Mode)
- Add sidebarTitle 'SDK (Programmatic Use)' for clearer nav label
- Rename api/sdk-examples to 'Code Examples' to avoid naming confusion with the Cline SDK
- Update API overview card title to match
* Apply suggestions from code review
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* docs: add ClientCapabilities, Error Handling, and BYO API key docs to SDK
- Document clientCapabilities object and its effect on agent behavior
- Add Error Handling section with all throwable errors per method
- Expand BYO API key setup with concrete CLI auth examples
* docs: fix duplicated Stop Reasons table rows from code review
* docs: fix 3 accuracy issues found in source code audit
- Fix protocolVersion: was '0.9.0' (fabricated), actually 1 (number) from @agentclientprotocol/sdk
- Fix clientCapabilities: was claiming they change SDK behavior, but ClineAgent always uses standalone providers (capabilities only matter via AcpAgent stdio wrapper)
- Fix permission options: remove reject_always (never sent by agent, only allow_once/allow_always/reject_once are used)
* docs: clarify custom clineDir usage with CLI --config flag
Address PR review feedback: the BYO auth section mentioned custom
clineDir without showing how to target it from the CLI. Remove the
vague reference and add explicit --config flag documentation with
side-by-side SDK and CLI examples.
* docs: remove misleading 'by default' qualifier from SDK BYO auth section
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* 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
Replace hardcoded free models list with runtime resolution from
recommended models. The handler now dynamically fetches free model
IDs using refreshClineRecommendedModels with fallback to static
defaults, and normalizes model IDs for consistent comparison.
* feat: add file read deduplication cache to prevent repeated reads
- Add fileReadCache to TaskState for tracking read files per task
- ReadFileToolHandler checks cache before reading, returns cached content on repeat reads
- Warns model after 3+ reads of same file to stop re-reading
- WriteToFileToolHandler and ApplyPatchHandler invalidate cache on file changes
- Reduces wasted API tokens from models reading same files repeatedly
* fix: address file read cache gaps - image blocks, execute_command, redundant invalidation
* Update src/core/task/tools/handlers/ExecuteCommandToolHandler.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* PR changes
- __`TaskState.ts`__ — Simplified cache type from `{ content: string; readCount: number; imageBlock? }` to `{ readCount: number; mtime: number; imageBlock? }`. Dropped `content` to save memory; added `mtime` for external change detection.
- __`ReadFileToolHandler.ts`__ — Four improvements:
- __Removed redundant `.set()` call__ — reviewer was correct that objects are modified by reference in Map
- __Added mtime-based cache validation__ — on cache hit, `stat()` the file and compare mtime. If the file was modified externally (user edited in their editor), the cache entry is evicted and a fresh read occurs
- __Dropped content from cache__ — cache now only stores metadata (readCount, mtime, imageBlock). On cache hits, the file is re-read from disk, addressing memory concerns
- __Softened readCount >= 3 warning__ — removed the aggressive "Do NOT read this file again" language; now says "Please use the information you already have and proceed with your task"
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* feat: add feature tips tooltip during thinking state
Show rotating feature tips below the Thinking indicator to keep users engaged and educate them on features like Double-Check Completion, .clinerules, Plan Mode, MCP Servers, checkpoints, and more.
- New FeatureTip component with 12 curated tips
- 2s delayed appearance, 8s cycling with fade transitions
- Visible throughout entire thinking/reasoning phase
- Proper timer cleanup on unmount
* Update webview-ui/src/components/chat/FeatureTip.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Update webview-ui/src/components/chat/FeatureTip.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Update webview-ui/src/components/chat/ChatRow.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: remove unused useMemo import from FeatureTip
* fix: increase test delays in QuitCommand.test.tsx for Windows CI reliability
* Update webview-ui/src/components/chat/FeatureTip.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: add smooth fade-in for first tooltip appearance
The first tooltip was appearing abruptly because the element went from
not-in-DOM (return null) to opacity-100 instantly. Added hasFadedIn state
with requestAnimationFrame to ensure the CSS transition applies on initial
render, giving the first tip a smooth 300ms fade-in.
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
llama.cpp's STB image library doesn't support WebP format. Users running
GLM 4.6V, GLM 4.5, and Devstral models via llama.cpp server (openai-compatible
endpoint) were hitting a 400 error when using the browser tool because Cline
sends screenshots as WebP by default.
modelDoesntSupportWebp() only checked for Grok models. Extend it to also
cover GLM and Devstral model families using the existing family detection
functions. Also update isGLMModelFamily() to handle space-separated model IDs
like 'GLM 4.6V' (the format llama.cpp server reports for this model).
Fixes#8203
* fix: Claude Code provider failing with 4.6 models and newer CLI versions
- Update --disallowedTools list to match current Claude Code CLI tools
(12 new tools were unblocked, causing models to use native tool_use
instead of Cline's XML tools)
- Fix rate_limit_event handling for new CLI format (top-level type
instead of system subtype)
- Handle unknown content block types and new message types gracefully
- Fix assistantHasContent check to account for tool calls accumulated
via toolUseHandler even when useNativeToolCalls is false
* resolved .include mismatch to .containEql
* Update src/integrations/claude-code/types.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Removed `LegacyRateLimitEvent` type and its union reference from `types.ts`
* Fixed loop with async tool calls in new claude code.
* PR review feedback fixes
__Fix #2 (claude-code.ts):__ Cleaned up the error field check — replaced verbose `"error" in message` guard + ternary chain with a simpler `message.error` check using optional chaining and nullish coalescing (`message.content?.[0]` + `?? fallback`).
__Fix #3 (claude-code.ts):__ Replaced `message.content.length > 0 ? message.content[0] : undefined` with `message.content?.[0]` using optional chaining for the `stop_reason` block.
__Fix #4 (claude-code.ts):__ Replaced repeated `(content as any)` casts in the `default` switch case with a single typed cast: `const unknownBlock = content as { type: string; text?: string }`, making the code cleaner and safer.
__Fix #5 (ApplyPatchHandler.ts):__ Replaced both `await import("node:path")` and `require("node:path")` dynamic imports with a static `import { resolve as resolvePath } from "node:path"` at the top of the file.
* Remove file read deduplication feature (moved to separate PR)
* Remove ReadFileToolHandler file-not-found test (moved to separate PR)
* Add LegacyRateLimitEvent type for older CLI format
* Restore ReadFileToolHandler.ts and test from upstream/main (fix stale local main revert)
* Revert ReadFileToolHandler.ts to match fork main (no try/catch, no test file)
* manually reverting back
* Update src/core/api/providers/claude-code.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Restore ReadFileToolHandler.ts and test to match cline/cline upstream main
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* Fix issue with Windows notification
Fix Windows proto tooling
Fix Windows unit test path normalization
Revert "Fix Windows unit test path normalization"
This reverts commit 73400a3ca6f0300d009f7c8238a016d769186f3a.
Remove package-lock.json changes
* Remove unnecessary changes
* Use command approval string for notifications
* Address PR feedback on Windows notifications
* Fix Windows protoc path for CI
* Polish notification safety and test coverage
* Fix unfound tests in CI
* Harden Windows notifications and protoc execution
* Fix Windows path normalization in glob test
* Fix 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>
* fix: catch errors in path-based tool handlers instead of crashing
ListCodeDefinitionNamesToolHandler, ListFilesToolHandler, and
SearchFilesToolHandler let exceptions from their core operations
propagate through ToolExecutor's re-throw path, crashing the CLI
process. This is the same class of bug fixed for ReadFileToolHandler
in #9730.
Changes per handler:
- Wrap the core operation in try/catch, returning formatResponse.toolError()
on failure so the model can see the error and recover gracefully.
- Move consecutiveMistakeCount reset to after a successful operation so
repeated failures accumulate toward the yolo-mode mistake limit.
- Increment consecutiveMistakeCount on caught errors.
Add end-to-end tests exercising each handler with a mock TaskConfig,
covering: non-existent paths, missing parameters, failure accumulation,
and success-based counter reset.
* address review: expand try/catch scope, add stub-based tests
- Include resolveWorkspacePath inside try/catch in
ListCodeDefinitionNamesToolHandler and ListFilesToolHandler (matching
SearchFilesToolHandler's pattern) so path resolution failures are
also caught gracefully.
- Fix trivially-true assertion in file-not-a-directory test.
- Add 6 new stub-based tests that force core operations to throw:
parseSourceCodeForDefinitionsTopLevel, listFiles, and
determineSearchPaths — verifying the catch paths return
formatResponse.toolError() and increment consecutiveMistakeCount.
- Total: 19 passing tests (up from 13).
* address review: move clineignore check before IO in ListFilesToolHandler
Move the .clineignore access validation before resolveWorkspacePath and
listFiles so blocked paths are rejected without incurring IO cost.
Also ensures consecutiveMistakeCount is only reset after all
validations and the core operation succeed.
* address review: increment counter on clineignore denial
Clineignore denial in ListFilesToolHandler now increments
consecutiveMistakeCount so repeated attempts at blocked paths
accumulate toward the yolo-mode mistake limit. Added 2 tests
verifying single and repeated clineignore denials.
Total: 21 passing tests.
* fix: increment consecutiveMistakeCount when SearchFilesToolHandler searches fail
Previously, SearchFilesToolHandler's executeSearch() caught regexSearchFiles
errors and returned {success: false}, but the handler unconditionally reset
consecutiveMistakeCount to 0 even when ALL searches failed. This contradicted
the PR's goal of accumulating failures toward the yolo-mode mistake limit.
Now we check if any search succeeded before resetting the counter:
- If at least one search succeeded: reset to 0 (existing behavior for successes)
- If all searches failed: increment the counter (new fix)
Also added comprehensive test coverage for this scenario, including tests for:
- regexSearchFiles throwing errors
- Repeated search failures accumulating
- Successful search resetting the counter after failures
* fix: detect error strings in ListCodeDefinitionNamesToolHandler
parseSourceCodeForDefinitionsTopLevel returns error strings instead of
throwing exceptions for file paths and non-existent directories. The
handler now detects these error conditions and increments
consecutiveMistakeCount so repeated failures accumulate correctly.
This addresses Greptile's feedback that the counter was unconditionally
resetting to 0 for all real-world failure modes of this handler.
* fix: catch extractFileContent errors in ReadFileToolHandler
When extractFileContent throws (e.g. file not found), the exception
propagated through ToolExecutor which re-threw it, crashing the CLI
process with exit code 1.
Now file read errors are caught and returned as formatResponse.toolError()
so the model can see the error and recover gracefully (e.g. try a
different file path) instead of terminating the entire task.
Also increments consecutiveMistakeCount so the yolo-mode mistake limit
still functions correctly.
* add tui UI tests
using microsoft/tui-test library, can run many headless versions of
cline and execute ui tests (requires Node <= 20)
improve brittle sleep calls
* add cli-tui-tests github action
---------
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
The Oracle Code Assist URL moved from /artificial-intelligence/code-assist/
to /application-development/code-assist/. The old URL returns a 404.
Fixes#9776
Co-authored-by: gatof81 <gatof81@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>
* Add an UsafeImage handler that asks for consent before loading specific images
* Fix div as child of p
* Render self-contained images without consent
* Render alt conditionally and store approved src
* use a block span
* feat(telemetry): restore cache token and cost metrics in captureTokenUsage
Add optional `options` parameter to `captureTokenUsage()` to record
cache write/read token counters and cost histograms that were
previously missing from telemetry.
- Extend `captureTokenUsage` with `cacheWriteTokens`, `cacheReadTokens`,
and `totalCost` fields via an options object
- Record `cline.tokens.cache_write`, `cline.tokens.cache_read` counters/
histograms and `cline.tokens.cost` histogram when provided
- Forward cache/cost data from both streaming `onUsageChunk` and
`getApiStreamUsage` fallback call sites in the task loop
- Add 3 test cases covering options forwarding, undefined skipping,
and event property inclusion
* refactor(telemetry): extract shared TokenUsage type and add value assertions
Address PR review feedback:
- Extract shared TokenUsage interface used by both captureTokenUsage and
captureConversationTurnEvent, preventing future drift
- Add numeric value assertions for cache/cost counters and histograms
so regressions recording wrong values are caught
- 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
The Gemini converter was the only provider that didn't include
parameter-level descriptions in native tool call schemas. Anthropic
and OpenAI converters both resolve param.instruction into each
parameter's description field. This was missing for Google/Gemini,
meaning the model only saw parameter names and types with no
explanation of what each parameter expects.
Made-with: Cursor
listFiles() passed unvalidated paths as globby's `cwd`, crashing with
"The cwd option must be a path to a directory" when the model provided a
file path instead of a directory. This affected ~22% of SWE-bench tasks.
- Add isDirectory guard in listFiles() before calling globby
- Fix listFiles() to use resolved absolutePath for cwd instead of raw dirPath
- Return actionable error in parseSourceCodeForDefinitionsTopLevel when
path is a file, guiding the model to use read_file instead
- Clarify list_code_definition_names parameter description to
distinguish directory input from file input
Made-with: Cursor
- S1: Don't modify test assertions to match buggy code
- S2: Run project's existing test suite to verify fixes
- CLI_RULES: Remove Node.js-specific examples (npm/tsc)
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
Fixes#9269 - Thinking blocks missing in Bedrock Opus 4.6
Changes:
- Add explicit handling for 'thinking' and 'redacted_thinking' content types
in formatMessagesForConverseAPI() so they are silently skipped instead of
triggering 'Unsupported content type: thinking' warnings
- Capture signature from additionalModelResponseFields thinking responses
- Add signature_delta handling in contentBlockDelta for streaming
- Add redacted_thinking block handling in contentBlockStart for streaming
- Extend ContentBlockStart/Delta interfaces with signature and data fields
- Add 'redacted_thinking' and 'document' to SupportedContentType union
- Add tests for thinking/redacted_thinking block filtering in message conversion
* 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
Add --no-verify to the initial checkpoint commit in
CheckpointGitOperations.ts. This was already used for subsequent
commits in CheckpointTracker.ts but was missing from the initial
empty commit, causing Cline to fail to initialize when users have
global pre-commit hooks (e.g., conventional commits enforcement).
Fixes#9672
* feat: add telemetry for AI output accepted/rejected across tool handlers
Add line-level diff stats and file operation tracking to telemetry
events when users accept or reject tool outputs. Introduces a shared
`computeLineDiffStats` utility and `captureAiOutputAccepted`/
`captureAiOutputRejected` methods on the telemetry service, wired
into ApplyPatch, WriteToFile, ExecuteCommand, InsertContent, and
SearchAndReplace handlers.
* feat(telemetry): add source tracking for agent vs human edits
Add telemetry differentiation between agent-generated changes and
human modifications to capture more granular edit metrics:
- Add 'source' field to captureAiOutputAccepted telemetry events
- Track human edits by computing diff stats between agent's proposed
content and final saved content
- Apply source tracking to ApplyPatchHandler and WriteToFileToolHandler
- Enable separate analytics for agent vs human contributions
This allows measuring how often and to what extent users modify
AI-generated code, providing insights into AI output quality and
user trust patterns.
* refactor(telemetry): centralize ai output attribution across file edit handlers
- add shared `AiOutputTelemetry` utility for accepted/rejected events
- refactor `WriteToFileToolHandler` and `ApplyPatchHandler` to use shared helpers
- preserve existing telemetry behavior (`source: "agent" | "human"`) while reducing duplication
- keep line diff/file-op attribution semantics unchanged
* fix(telemetry): use pre-save content for human edit line diff stats
The source:"human" telemetry was diffing agent content against
finalContent (post-save), which includes auto-formatting changes
from the editor. This inflated linesChanged/linesDeleted counts
when the formatter modified lines alongside the user's actual edits.
Use diff.applyPatch() to reconstruct the user's pre-save content
from the existing userEdits patch, excluding formatter noise from
the line diff stats.
* fixing syntax error
* refactor(telemetry): make next-hunk bounds check explicit
* remove comment
Co-authored-by: Tomás Barreiro <52393857+BarreiroT@users.noreply.github.com>
---------
Co-authored-by: Tomás Barreiro <52393857+BarreiroT@users.noreply.github.com>
Add author_association check so only MEMBER, OWNER, and COLLABORATOR
users can trigger the JetBrains test workflow via issue comments.
Previously any GitHub user could trigger it, allowing unauthorized
use of the GitHub App token and Actions minutes.
Fixes GHSA-5fq9-fh5x-w83r (SEC-29)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add provider/model context to all hook payloads
* Fixes as per Greptile feedback
* Further fixes as per Greptile feedback
* Further fixes as per Greptile feedback
* further fixes as per Greptile feedback
* Fix flapping hooks tests on Windows
* fix: stop infinite getLatestMcpServers RPC loop when opening MCP servers panel
The ServersToggleModal useEffect had setMcpServers in its dependency array,
but the context provided an unstable inline wrapper around the useState setter,
creating a new function reference on every render. This caused the effect to
re-fire on every context re-render while the modal was visible, producing 14+
RPC calls in ~15ms.
- Remove setMcpServers from useEffect deps in ServersToggleModal (the effect
should only fire when visibility changes)
- Replace inline arrow wrappers in ExtensionStateContext with direct references
to the stable useState setters (setMcpServers, setRequestyModels,
setHuggingFaceModels, setMcpMarketplaceCatalog)
* address review feedback: add setMcpServers back to deps, use property shorthand
- Add setMcpServers back to useEffect deps in ServersToggleModal now that the
context passes the stable useState setter directly (per Copilot review)
- Remove eslint-disable comment since it's no longer needed
- Use property shorthand for setGroqModels and setBasetenModels in context value
* initial doc changes
* rm general api endpoint
* Add API documentation section with endpoint reference pages
- Add new API docs: overview, getting-started, authentication, models,
chat-completions, errors, and SDK examples
- Update api/reference.mdx with expanded endpoint documentation
- Update enterprise-solutions/api-reference.mdx with improvements
- Update docs.json with new API section navigation entries
---------
Co-authored-by: Juan Pablo <juan@cline.bot>
Co-authored-by: Tony Loehr <turingxo@gmail.com>
* fix: prevent Chinese filename escaping in diff view
Use Uri.parse() instead of Uri.from() for the diff view URI to prevent
non-ASCII characters (e.g. Chinese) in filenames from being
percent-encoded. This is consistent with how other diff URIs are created
in openMultiFileDiff.ts and VscodeCommentReviewController.ts.
Uri.from() encodes the path component, turning Chinese characters into
percent-encoded sequences like %E7%A0%94..., which causes the diff view
to display escaped filenames and fail to open properly.
* fix: encode URI-reserved delimiters in filename before Uri.parse
Encode %, #, and ? in the filename before passing to Uri.parse() to
prevent them from being interpreted as URI delimiters. This handles
edge cases where filenames contain these characters (valid on macOS/Linux)
while preserving non-ASCII characters like Chinese.
* feat(hooks): add Windows hook execution via PowerShell
* chore(changeset): add release note for Windows hooks
* Get hooks working on Windows
Remove changeset file (we no longer use changeset files)
feat(hooks): support Windows PowerShell hook resolution and management
feat(hooks): complete windows powershell hook support and tests
Detect linux-style hooks only on macOS and linux and detect PowerShell-style hooks only on Windows
Fixes for failing unit tests on Windows in CI
Fix failing unit tests on Windows in CI
Fix unit tests for hooks on Windows
Be clear about .ps1 file extension for hooks in PowerShell vs. bash/binary for linux-style hooks
Remove separate test suite step
Reapply hooks-specific test suite
Fix failing hooks tests
* Harden Windows hook PowerShell runtime and test coverage
* test: centralize hook test env and platform overrides
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
When OCA token refresh fails with 400 invalid_grant or 401, legacy secrets
ocaAccessToken and ocaTokenSet (from older Cline versions) were left in VS
Code's secret storage. clearAuth() only cleared ocaApiKey and ocaRefreshToken,
causing every subsequent re-auth attempt to fail in a loop requiring manual
SQLite deletion to recover.
Fix:
- Add ocaAccessToken and ocaTokenSet to SecretKeys in state-keys.ts
- Update OcaAuthProvider.clearAuth() to clear all 4 OCA secrets
Fixes#9567
* fix: resolve 'Could not find the file context' error in Explain Changes
Both handleCommentReply() in explainChangesShared.ts and the onCommentStart
callback in explainChanges.ts were using a strict absolutePath-only match
when looking up files in changedFiles. If the VS Code comment controller
returns a path in a different format (relative vs absolute, different
separators on Windows), the lookup would silently fail and show
'Error: Could not find the file context'.
Add relativePath as a fallback in both lookup sites, making them
consistent with the already-correct logic in streamAIExplanationComments.
Fixes#9382
* Refactor to use parseInt instead of Number.parseInt
* Adding 1m
* fix: wire cline model proto fields for api config
* fix: wire cline picker to shared recommended model logic
* fix: address Cline model picker parity and startup model-info sync
* remove OpenRouter preset model ID support
* rename Cline endpoint feature flag
* Fixing stuff
* Fixing stuff
* Fixing stuff
* refactor: gate cline models endpoint behind feature flag
- Update refreshClineModels to use the EXTENSION_CLINE_MODELS_ENDPOINT feature flag instead of a hardcoded boolean, allowing controlled rollouts of the endpoint source.
- Remove recommended/free models fallback logic, featured model cards, and the initialTab property from OpenRouterModelPicker to simplify the UI component.
* fix: use JSON_SCHEMA for yaml.load to prevent unsafe deserialization
Add { schema: yaml.JSON_SCHEMA } to both yaml.load() calls to reject
custom YAML tags (e.g. !!js/function) that could enable code execution
from untrusted .clinerules or skills files.
Add security tests verifying custom tags are rejected.
* add changeset
The CLI's applyProviderConfig() was reading model info from a disk
cache (controller.readOpenRouterModels) instead of fetching from
the provider API. In headless/Docker environments (e.g., terminal-bench)
the cache doesn't exist, so model info was never set. Both handlers
then fell back to openRouterDefaultModelInfo with maxTokens: 8192,
causing write_to_file truncation on large outputs.
Changes:
- Replace controller.readOpenRouterModels() (disk cache) with
refreshOpenRouterModels() (fetches from API, with cache fallback)
- Add vercel-ai-gateway to the model info fetch path using
refreshVercelAiGatewayModels()
Relates to #7998
Co-authored-by: Cursor <cursoragent@cursor.com>
The "Generate Commit Message" feature was using all changes instead of
only staged changes. Now prioritizes staged changes via getGitDiffStagedFirst(),
falling back to all changes only when nothing is staged.
Closes#5749
Co-authored-by: Raushan Singh <raushrak@Raushans-MacBook-Air.local>
* fix: update stale maxTokens values for Claude 3.7+ models
Every Claude model from 3.7 Sonnet onward had maxTokens set to 8192
in the static model definitions. These values were correct for Claude
3.5 and earlier, but Anthropic has significantly increased output
limits for newer models:
- Claude Opus 4.6: 128K (was 8192, 15.6x too low)
- Claude 3.7 Sonnet: 128K (was 8192, 15.6x too low)
- Claude Sonnet 4.6/4.5/4, Haiku 4.5, Opus 4.5: 64K (was 8192)
- Claude Opus 4, Opus 4.1: 32K (was 8192)
These static definitions are the source of truth for Anthropic direct,
Bedrock, Vertex, and SAP AI Core providers. With the old values, any
write_to_file call exceeding 8192 output tokens would be silently
truncated, producing a missing 'content' parameter error.
Values verified against Anthropic docs, AWS Bedrock docs, Google
Vertex AI docs, and the Vercel AI Gateway API.
Relates to #7998
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: update openRouterDefaultModelInfo.maxTokens to 64K
This fallback ModelInfo (representing claude-sonnet-4.5) is used
when dynamic model info isn't available — notably by the Cline and
Vercel providers in the CLI when the model cache is empty (e.g.,
fresh Docker containers in terminal-bench).
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
The OpenRouter stream transform had a 30-line switch statement that
hardcoded max_tokens=8192 for every Claude model. This was written when
8192 was the actual max output for Claude, but modern Claude models
support much higher limits (e.g. 128K for Sonnet 4.6, 64K for others).
OpenRouter's API already reports the correct max_completion_tokens per
model, and model.info.maxTokens reflects this (128000 for Sonnet 4.6).
The hardcoded switch was silently overriding the dynamic value.
This caused write_to_file failures on OpenRouter (and the Cline
provider, which shares this code path) whenever the tool call content
exceeded 8192 output tokens. The response was truncated
(finish_reason: "length"), producing incomplete JSON that lost the
content parameter.
Runtime evidence:
- Before: max_tokens=8192 sent, completion_tokens=8192 (ceiling),
finish_reason="length", write_to_file content missing
- After: max_tokens=128000 sent, completion_tokens=9824 (needed more
than 8192), finish_reason="tool_calls", write_to_file succeeded
Fixes#7998
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add MiniMax M2.5 model to MiniMax provider
- Add MiniMax-M2.5 to minimaxModels with 192K context, 128K max tokens,
prompt caching, and reasoning/thinking support
- Update minimaxDefaultModelId to MiniMax-M2.5
- Add minimax/minimax-m2.5 to OpenRouter prompt caching switch
Closes#9391
* fix: add temperature: 1 to MiniMax M2.5 for reasoning support
* docs: update MiniMax provider docs with M2.5 model
* feat: wire up thinking/reasoning support for MiniMax M2.5
- Pass thinkingBudgetTokens from factory to MinimaxHandler
- Use thinking param in API call when reasoning is enabled
- Disable temperature and forced tool_choice when thinking is on
- Add ThinkingBudgetSlider to MiniMaxProvider UI for M2.5
* Add MiniMax-M2.5-highspeed
* Add thinking for highspeed
* Refactor thinking logic
---------
Co-authored-by: BarreiroT <tomasmbarreiroi@gmail.com>
Co-authored-by: Tomás Barreiro <52393857+BarreiroT@users.noreply.github.com>
- Update model ID and name from gpt-5.2-codex to gpt-5.3-codex
- Change tag from "HOT" to "NEW" for the updated model
- Add What's New banner entry promoting Codex 5.3 availability
This commit ensures that internal placeholder tools, specifically `focus_chain`, are filtered out from the final list of native tools exposed to the LLM.
- Added a test case in `PromptRegistry.test.ts` to verify `focus_chain` is excluded from native tools output.
- Updated snapshot files for various models (OpenAI GPT-5, Vertex Gemini 3, etc.) to reflect the removal of the `focus_chain` tool definition.
Fixes false positives in getReadablePath() when directories share a prefix
(e.g., /home/user/project matching /home/user/project-backup). The existing
isLocatedInPath() function correctly handles path boundaries using path.relative().
Closes#8761
Co-authored-by: Raushan Singh <raushrak@Raushans-MacBook-Air.local>
* sdk lib
* improve cline sdk api surface
- better api design and messages
* fix some types, fix session id retrieval, improve wording
* hide controller from sdk surface completely
---------
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
* chore: replace baseUrl with explicit relative paths in tsconfig files
Remove `baseUrl: "."` from tsconfig configurations and update all path aliases to use explicit relative paths (e.g., `./src/*` instead of `src/*`). This makes path resolution more explicit and avoids potential ambiguity in module resolution across the main project and webview-ui configurations.
* update package-lock.json
* Release V3.67.0
Bump version from 3.66.0 to 3.67.0 in package.json and
package-lock.json. Add changelog entry for v3.67.0 covering new
features (subagent skills, AgentConfigLoader, Responses API, websocket
preconnect, CLI /q command), bug fixes (reasoning delta crash, OpenAI
tool ID, auth checks, Gemini 3.1 Pro), and other changes. Update
WhatsNewItems fallback banners to reflect current promotions.
* Fixing stuff
* refactor: consolidate subagent request usage tracking into state object
Replace scattered per-request token tracking variables with a structured
`SubagentUsageState` interface containing `currentRequest` and
`lastRequest` states. This improves code organization by grouping related
token metrics (input, output, cache write/read, total tokens, cost) into
a cohesive `SubagentRequestUsageState` object, reducing variable sprawl
and making the usage lifecycle (current → last) more explicit.
* feat(subagent): add support for skills and optional modelId in agent config
- Update `AgentBaseConfigSchema` and `AgentConfigFrontmatterSchema` to include an optional `skills` field and make `modelId` optional.
- Implement `parseSkills` and `normalizeSkillName` in `AgentConfigLoader` to handle skill parsing from YAML frontmatter.
- Update `SubagentBuilder` to provide access to configured skills.
- Modify `SubagentRunner` to filter available skills based on the agent's configuration, falling back to all available skills if none are specified.
- Update host retrieval to use `HostRegistryInfo` instead of `HostProvider`.
This allows subagents to be restricted to specific skills and provides more flexibility in model configuration.
* update unit test
* feat(cli): fetch featured models from backend with local fallback
- Add async getFeaturedModelsForCline() to fetch models via controller
- Load featured models dynamically in AuthView with useEffect
- Update FeaturedModelPicker to accept featuredModels as optional prop
- Refactor helper functions to accept models parameter for flexibility
- Keep local hardcoded models as fallback when backend fetch fails
* Fixing stuff
* Fixing stuff
* Fixing stuff
* refactor: centralize tool handler registration and filter by allowed tools
- Create centralized toolHandlersMap for all tool handler instantiation
- Add registerToolHandlers method to register only allowed tools from config
- Filter subagent tools to only include allowed tools from allowedTools config
- Remove scattered tool handler registration logic in favor of single source of truth
- Improve maintainability by consolidating tool handler creation in one place
This refactoring ensures subagents only have access to explicitly allowed tools
and makes the tool registration process more maintainable and consistent.
It also improves separation of concerns by having the coordinator manage all tool handler registration, while the executor focuses on orchestration. The allowedTools parameter enables runtime filtering of available tools for different contexts.
Also update PromptRegistry to load synchronous and simplify variant lookup
- Convert async load() to synchronous, called in constructor as both loadVariants and loadComponents are not async functions
- Remove health check logic and loaded state tracking
- Extract getVariant() method with proper generic fallback
- Add getComponents() accessor and simplify component loading
- Convert variant/component loaders from async to synchronous
- Remove unnecessary await calls throughout the codebase
- Add PromptRegistry tests for variant resolution and components
* fix test
* feat: add AgentConfigLoader for file-based agent configs
Add AgentConfigLoader singleton to manage agent configurations loaded from
YAML files in the agents directory. Supports hot-reloading via file watcher,
validates config schema with Zod, and integrates with extension lifecycle
(StateManager initialization and tearDown disposal).
* add tests
* add missing export
* update tests
* feat(tools): implement dynamic tool registration for subagents
Updates the tool system to support dynamically registered subagents as individual tools.
- Modifies `ClineToolSet` to generate specific tool definitions for configured subagents via `AgentConfigLoader`.
- Updates `parseAssistantMessageV2` to use `getToolUseNames()` instead of a static list, enabling the parser to recognize dynamic tool tags.
- Replaces the generic `USE_SUBAGENTS` tool with specific subagent instances when available in the system prompt context.
* update config path and refine tool descriptions
- Relocate the subagent configuration directory from `~/.cline/data/agents` to `~/Documents/Cline/Agents` to improve user accessibility.
- Update subagent tool descriptions and parameter instructions in the system prompt to be more descriptive and helpful for the model.
* revert unrelated changes
* revert unrelated changes
* update unit test
* fix: await AgentConfigLoader initialization before StateManager completes
Ensure agent configs are fully loaded during StateManager initialization
by awaiting the `ready()` promise. Previously, `AgentConfigLoader` was
instantiated without waiting for the initial load to complete, causing
potential race conditions where configs might not be available when
needed.
- Add `initialLoadPromise` field to track the async initial load
- Expose a `ready()` method to allow callers to await initialization
- Await `AgentConfigLoader.getInstance().ready()` in StateManager
* set previousRequestTotalTokens
* Made messages api changes
* Made changes
* Added changes
* Made maxTokens point to the right thing
* Removed deprecated max_tokens field
* Reverted the change
* Making an additional change to not cause any issues with chat completions
* reverting changes so we can make them in the backend
* Added changeset
* Fixed changes based on AI comments
Warm up the OpenAI WebSocket connection early in WebSocket mode to avoid handshake latency on the first response.create call. This introduces a responsesWsReadyPromise to track the connection state and prevent duplicate connection attempts while the initial connection is in flight.
* fix: restrict OpenAI tool ID transformation to native provider
Update `convertToOpenAiMessages` and `transformToolCallId` to only apply tool ID transformations when the provider is explicitly set to `openai-native`. This prevents unintended ID modifications for other providers (like OpenRouter or local LLMs) that use the OpenAI format but may have different tool ID requirements or already provide compatible IDs.
* update tests
* transformToolCallIdForNativeApi
* fix: openai native provider token usage mapping
- Add `store` parameter support to OpenAI native provider options to allow persisting completions.
- Fix incorrect mapping of `cached_tokens` and `reasoning_tokens` in usage statistics.
- Include `thoughtsTokenCount` in the final usage report to track reasoning model performance and costs.
* feat: add websocket support for OpenAI Responses API
This commit introduces WebSocket support for the OpenAI Native provider's Responses API, providing an alternative to the standard HTTP streaming.
- Implement `createResponseStreamWebsocket` in `OpenAiNativeHandler` with a fallback to HTTP on failure.
- Refactor `OpenAiNativeHandler` to modularize tool mapping and parameter construction for the Responses API.
- Update `OcaHandler` to explicitly disable `previousResponseId` when using the Responses API and add validation for model information.
- Integrate `undici` WebSocket for better compatibility in the extension environment.
* disablePreviousResponseId
* feat: add timestamp to conversation messages for response chaining
Add `ts` field to `ClineStorageMessage` to track when messages were
created. Use this timestamp to enforce a 23-hour validity window when
chaining OpenAI responses via `previousResponseId`, since the API only
retains responses for 24 hours. Also fix non-null assertion operators
in tests to use optional chaining for safer access.
* add OpenAI Responses Websocket Mode ApiFormat support
- Add `OPENAI_RESPONSES_WEBSOCKET_MODE` to the `ApiFormat` enum in proto definitions.
- Update `OpenAiNativeHandler` to use the new API format for determining when to use websocket mode, replacing previous environment-based logic.
- Refactor tool mapping for OpenAI Responses to support strict mode and correctly handle null parameters.
- Ensure the `store` option is disabled when `previous_response_id` is present in websocket mode.
- Bump version to 2.4.1 and update package dependencies.
* use abortController
* add support for websocket mode to openai-codex
* set behind feature flag
- added a method to StateManager, setSessionOverride, which overrides
state settings while the statemanager lives in memory
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
* fix: inline focus-chain slider within its feature row
Moves the focus-chain reminder interval `SettingsSlider` from a
standalone element rendered after all experimental feature rows to
being rendered directly beneath the focus-chain `FeatureRow`. The
slider now renders conditionally when `feature.id === "focus-chain"`
and the feature is enabled, improving UI cohesion and making the
relationship between the toggle and its configuration more explicit.
Additionally:
- Relocates focus-chain from `experimentalFeatures` to `agentFeatures`
- Removes the `isExperimental` prop and "Experimental:" label badge
from `FeatureRow` and related feature toggle definitions
- Simplifies `SettingsSlider` markup by removing the wrapper card
styling, making it suitable for inline embedding
- Removes unused line from common.ts
* nestedKey
Handle plain Cmd/Ctrl+A directly in `ChatTextArea` keydown to force
textarea-wide selection via `setSelectionRange`, while preventing default
and propagation. This avoids intermittent failures caused by global shortcut
listener races, and keeps Cmd/Ctrl+Shift+A behavior unchanged.fix(chat): make Cmd/Ctrl+A select-all deterministic
Handle plain Cmd/Ctrl+A directly in `ChatTextArea` keydown to force
textarea-wide selection via `setSelectionRange`, while preventing default
and propagation. This avoids intermittent failures caused by global shortcut
listener races, and keeps Cmd/Ctrl+Shift+A behavior unchanged.
* fix: flaky Cancel behavior by preventing duplicate cancel actions
This PR fixes chat cancel behavior where users sometimes had to click Cancel multiple times, and repeated clicks could accidentally transition into Resume/restart behavior.
* move to finally
* refactor: replace non-null assertions with safe null checks in PatchParser
Replace all forbidden non-null assertions (`!`) in PatchParser.ts with
safe alternatives using optional chaining (`?.`) and nullish coalescing
(`?? ""`/`?? 0`). Also refactor the Levenshtein distance matrix from a
2D array to a flat array to eliminate index-based non-null assertions,
improving type safety and code robustness.
No feature behavior changes.
* simplify Levenshtein matrix indexing
Initialize the distance matrix with zeroes and add `at`/`set` helpers for flat-array access in `levenshteinDistance`.
This removes repeated index math and nullish fallbacks, making the algorithm easier to read while keeping bounds-safe access and identical behavior.refactor(patch-parser): simplify Levenshtein matrix indexing
Initialize the distance matrix with zeroes and add `at`/`set` helpers for flat-array access in `levenshteinDistance`.
This removes repeated index math and nullish fallbacks, making the algorithm easier to read while keeping bounds-safe access and identical behavior.
* feat: add welcome banner support from backend
* make DB banner format conform with existing banners
* add support for welcome banner actions
* remove debugging helper that bypass dismissal, dismissal should work again
* undo changes to make welcome banner always appear during debugging
* remove console logs for debugging
* clean up bannerservice
* clean up welcomesection.tsx
* add new tests for ide type filtering
* add welcome banner own feature flag and conditionally display between hard coded welcome banner and DB backed ones
* turn on welcome banner flag locally by default
* close welcome banners when clicking on actions
* apply bot review suggestion, fix memory leak
* address feedback: use p without span
* split welcome banners into a seperate component to keep whatsnewmodal clean
* get action through api schema instead of extractin it from rules_json
* use only bannerWaitTimeoutRef, remove waitingForBannersRef
* resolve new merge conflict
* linter
* cerebra
- Remove `auto_condense_threshold` from `Settings` and `UpdateSettingsRequest` in `state.proto`.
- Remove `autoCondenseThreshold` from `ApiProviderInfo` interface.
- Update `generate-state-proto.mjs` to remove double field handling and improve integer parsing.
- Add error handling to `ContextManager` when parsing previous request JSON to prevent crashes on malformed data.
* fix(models): keep Sonnet 4.5 as default
* chore(changeset): add release note for Sonnet 4.5 default
* fix(models): remove Sonnet 4.6 from curated model lists
* fix(models): restore Sonnet 4.6 in web recommended list
* feat(cerebras): remove deprecated llama-3.3-70b and qwen-3-32b models
These models have been deprecated from the Cerebras inference platform.
- Remove llama-3.3-70b and qwen-3-32b from cerebrasModels in api.ts
- Update supported models documentation in cerebras.mdx
- Add changeset for the deprecation
* fix: remove stale llama-3.3-70b and qwen-3-32b references from rate limits
Remove dead switch cases in getRateLimits() that referenced deprecated models
no longer present in cerebrasModels.
* feat(cli): add /skills slash command for managing skills
- Add /skills to CLI_ONLY_COMMANDS in slashCommands.ts
- Create SkillsPanelContent component with:
- Display global and workspace skills with toggle indicators
- Enter to use skill (inserts @path into input)
- Space to toggle skill enabled/disabled
- Selectable marketplace link to skills.sh
- Keyboard navigation with arrow keys and vim keys
- Wire up panel in ChatView.tsx
- Add comprehensive tests for keyboard interactions
* refactor(cli): use static skill controller imports
* fix(cli): add React import to skills panel test
* fix(cli): suppress required React import lint in skills test
* fix(cli): harden /skills panel interactions
Revert optimistic skill toggle state when persistence fails, and surface a fallback URL when opening the marketplace fails. Also tighten and extend tests to verify exact marketplace URL handling and rollback behavior.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: disable click-to-set auto-condense threshold and hardcode default
Clicking anywhere on the context window progress bar silently set
autoCondenseThreshold to a value based on click position (e.g. 0.05),
persisting in globalState. This caused compaction to fire at ~10K tokens
instead of the intended ~150K, resulting in ~20 context resets per task.
- Comment out click and keyboard handlers on progress bar (keep components
for future release with proper UX)
- Hardcode threshold to 0.75 default, ignoring corrupted stored values
Co-authored-by: Cursor <cursoragent@cursor.com>
* test: add shouldCompactContextWindow unit tests
Cover threshold math including the accidental low-threshold bug case,
undefined/zero fallbacks, cache token inclusion, and maxAllowedSize cap.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: hardcode autoCondenseThreshold in all remaining callsites
Address Greptile review: SubagentRunner.ts, task/index.ts display
logic, and controller/index.ts webview state all still read the
corrupted value from globalState. Hardcode 0.75 everywhere.
Co-authored-by: Cursor <cursoragent@cursor.com>
* style: remove unnecessary union type on hardcoded threshold
Drop `number | undefined` annotation from the hardcoded 0.75 literal
in SubagentRunner.ts per Greptile review feedback.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor: use SETTINGS_DEFAULTS constant, remove commented-out code, clarify test
- Replace hardcoded 0.75 with SETTINGS_DEFAULTS.autoCondenseThreshold
across all 4 callsites for a single source of truth
- Delete commented-out click/keyboard handlers in ContextWindow.tsx,
replace with TODO referencing PR #9348
- Make bug-case test self-documenting by deriving token values from
the threshold calculation
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: smarter retry for write_to_file missing content parameter (#7998)
Replace generic 'missing parameter' error with progressive guidance when
write_to_file fails due to empty content parameter. This breaks the
infinite retry loop where the model repeatedly attempts the same
write_to_file call that exceeds output token limits.
Changes:
- Add writeToFileMissingContentError() to formatResponse with 3 tiers:
1st failure: suggestions (use skeleton + replace_in_file)
2nd failure: strong directive (stop retrying write_to_file)
3rd+ failure: CRITICAL stop, forces alternative strategies
- Add context window awareness: warns model when >50% context used
- Add getContextUsagePercent() helper to WriteToFileToolHandler
- Add 22 unit tests covering progressive escalation and context awareness
Fixes#7998
* add changeset for write_to_file retry fix
* refactor: simplify write_to_file error handling per review
- Simplify writeToFileMissingContentError to single-tier error following
existing diffError pattern (no progressive escalation)
- Use shared getLastApiReqTotalTokens() for context window awareness
- Remove private getContextUsagePercent() method from handler
- Add proactive skeleton + replace_in_file guidance to write_to_file
tool description for all variants
- Simplify tests to match new API (11 tests)
* test: update system prompt snapshots
* chore: revert write_to_file prompt guidance
* feat: restore progressive 3-tier guidance for write_to_file missing content
Restore the progressive escalation that was removed in dd3c12d4e:
- Tier 1 (1st failure): Gentle suggestions (skeleton + replace_in_file)
- Tier 2 (2nd failure): Strong directive, 'Do NOT attempt full write again'
- Tier 3 (3rd+ failure): CRITICAL stop, forces alternative strategies
- Context window warning when >50% full
- Dynamic UI message: 'Retrying...' vs 'multiple times — different approach'
- 21 tests covering all tiers and context awareness
* nit: extract context window warning threshold to named constant
Also replace emoji with plain text in warning message for consistency.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Robin Newhouse <robin@cline.bot>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add Sonnet 5 support and make it default across surfaces
* feat: surface Sonnet 5 as free while keeping Sonnet 4.5 defaults
* fix: rename Sonnet 5 support to Sonnet 4.6 across providers and UI
* fix: allow duplicate onboarding model ids across free and frontier
* chore: update Sonnet 4.6 banner to limited-time free messaging
* fix: align Bedrock Sonnet 4.6 model ids with AWS format
* feat: update whats new promo to Sonnet 4.6 free offer
* chore: update Sonnet 4.6 promo copy and timing
Updating CHANGELOG.md format
update changelog
update banner and bump version
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: add z-ai/glm-5 to free models list
Include Z.AI's GLM 5 in the free model whitelist for zero-cost usage
and update the model picker UI to display the free label.
* Adding thinking
* Adding thinking
* Adding thinking
* changeset version bump
* v3.62.0 Release Notes
- Banners now display immediately when opening the extension instead of requiring user interaction first
- Resolved 17 security vulnerabilities including high-severity DoS issues in dependencies (body-parser, axios, qs, tar, and others)
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
- Fixes for Minimax model family
- Fixes for Response chaining for OpenAI's Responses API
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Add an optional `usePreviousResponseId` flag to
`convertToOpenAIResponsesInput` and gate previous assistant-response
lookup behind it.
This makes response chaining opt-in instead of always-on, so providers
can control whether to continue from the latest stored OpenAI response
ID.feat(openai): make response ID chaining configurable
Add an optional `usePreviousResponseId` flag to
`convertToOpenAIResponsesInput` and gate previous assistant-response
lookup behind it.
This makes response chaining opt-in instead of always-on, so providers
can control whether to continue from the latest stored OpenAI response
ID.
The unit test suite currenlt is running the BannerService tests only when it should run the full suite.
Also update package-lock.json that wentout of sync.
- Add `name` property to minimax, kat-coder-pro, and trinity-large-preview
models that were previously missing it
- Move type annotation from `as FeaturedModel[]` casts to the variable
declaration for proper type checking at assignment time
- Add test to verify all featured models include a display name
* feat: persistant thinking loader at bottom of stream during any cline activity with no visual feedback
* feat: thinking and flicker fix
* refactor: remove multi-layer throttling, use single canonical throttle point
Collapse 4 independent throttle layers (up to ~500ms added latency) into
a single 50ms debounce in subscribeToPartialMessage. Replace index-based
partial message tracking with stable ts-based tracking. Remove webview
queue/timer/flush system in favor of cheap equality dedup.
* fix: Add production-grade improvements to flicker fix
- Fix global mutable state bug in subscribeToPartialMessage.ts
- Add comprehensive test coverage (51 tests passing)
- Rename ThrottledApiHandler → SanitizedApiHandler
- Remove incomplete OpenAI reasoning effort code
* Fix test failures
* PR changes as per Greptile feedback
* Fixes as per feedback during PR review
---------
Co-authored-by: cline-test <132302818+candieduniverse@users.noreply.github.com>
* chore(evals): reorganize eval structure with purpose-based naming
- Move evals/diff-edits/ → evals/benchmarks/tool-precision/replace-in-file/
- Move evals/cli/ → evals/legacy/cli/ (preserve for reference)
- Create evals/benchmarks/real-world/ directory
- Create evals/benchmarks/coding-exercises/cases/ directory
- Create evals/analysis/ directory structure
Note: No repositories/exercism/ directory found to move.
Skipping pre-commit hook as this is a reorganization of legacy code.
* chore(evals): remove legacy evaluation code
Remove abandoned evaluation infrastructure:
- evals/benchmarks/tool-precision/ - Dashboard, database, diff implementations
- evals/legacy/cli/ - Old HTTP-based eval harness
This functionality is superseded by the new testing pyramid:
- Tool precision is now covered by contract tests in src/core/
- E2E testing uses the cline-bench framework
* feat(evals): add analysis framework for benchmark results
Add shared infrastructure for analyzing evaluation results:
- TypeScript schemas for Harbor and analysis output formats
- Parsers for Harbor, tool-precision, and exercise results
- Failure classifier with pattern matching (cline-failures.yaml)
- Metrics calculator (pass@k, consistency, latency)
- JSON and Markdown reporters
- CLI with analyze and compare commands
- Unit tests for classifier and metrics
This framework is used by both smoke tests and E2E evaluations
to provide consistent metrics and failure categorization.
* feat(evals): add contract tests for API transforms
Add tests to verify API response transformations preserve data correctly:
- thinking-traces.test.ts: Tests thinking block extraction and formatting
- tool-parsing.test.ts: Tests tool call parsing across providers
These contract tests catch regressions when modifying transform logic,
ensuring API responses are correctly processed regardless of provider.
Run with: npm run test:unit
* feat(evals): add provider smoke tests with pass@k metrics
Add lightweight smoke tests that validate provider integrations work
correctly with real LLM calls:
Scenarios (5 curated tests):
- 01-create-file: Tests write_to_file tool
- 02-edit-file: Tests replace_in_file tool
- 03-read-summarize: Tests read_file tool
- 04-multi-file: Tests multi-file edits
- 05-typescript-function: Tests code generation
Features:
- CLI-based runner using the cline CLI
- Multiple trials per scenario for reliability testing
- pass@k metrics (solution finding) and pass^k (consistency)
- Results storage with logs and latest symlink
- Adaptive metric display based on trial count
Run locally: npm run eval:smoke
* feat(evals): add E2E runner with cline-bench
Add end-to-end testing infrastructure using real-world production bugs:
- cline-bench submodule: 12 curated tasks from actual Cline sessions
- Complex multi-file refactors
- Bug fixes requiring deep context understanding
- Cross-language/framework tasks
- E2E runner (evals/e2e/run-cline-bench.ts):
- Integrates with Harbor for containerized execution
- Supports single task or full suite runs
- Pass/fail metrics with detailed logging
Run: npm run eval:e2e -- --task discord-trivia
Note: E2E tests require Docker and are intended for weekly/release
testing, not per-commit CI (each task takes 20-30 minutes).
* feat(evals): add CI workflow and documentation
CI Workflow (.github/workflows/cline-evals-regression.yml):
- Triggers on push/PR to main (src/core, src/shared, proto, evals paths)
- Builds CLI from source with Go 1.24
- Runs 5 smoke test scenarios in parallel
- Uses Anthropic API with claude-sonnet-4
- Uploads results as artifacts with summary
npm scripts:
- eval:smoke - Run smoke tests locally (builds CLI first)
- eval:smoke:run - Run smoke tests (assumes CLI is built)
- eval:e2e - Run cline-bench E2E tests
Documentation:
- ARCHITECTURE.md: Testing pyramid overview with ASCII diagrams
- EVALS_OVERVIEW.md: High-level introduction for mixed audience
- Updated README.md with current structure and usage
* chore(evals): restore tool-precision as deprecated legacy
Restore the diff edit evaluation framework for @ara's use case.
Marked as DEPRECATED - target removal Q2 2026 when cline-bench
is fully operational for model comparison.
Note: Skipping linter as this is legacy code being preserved as-is.
* feat(evals): add per-scenario model support and apply_patch test
Also honor --model overrides and prune stubs.
* chore(evals): update smoke tests for CLI 2.0
- Remove Go setup from workflow (CLI 2.0 is TypeScript)
- Build CLI via `npm run build` in cli/ directory
- Install CLI via `npm link` to test built code from PR
- Update CLI flags: -y -m model --json (remove -o and -s)
- Provider configured via `cline auth` before tests run
* chore(evals): add auth check and CLI 2.0 flags
- Add configureAuth() that runs cline auth non-interactively
- Require CLINE_API_KEY env var or use existing ~/.cline auth
- Add --config flag to use shared config directory
- Add -t timeout flag to CLI args
- Reduce scenario timeout to 30s for faster iteration
- Remove --json flag (CLI doesn't output errors in json mode)
* feat(evals): add parallel execution and move workspaces to results
- Add --parallel flag to run scenarios concurrently (default limit: 4)
- Move trial workspaces from scenarios/ to results/ directory
- Workspaces now cleaned up with `npm run eval:smoke:clean`
- Keeps scenarios/ clean and version-controllable
* ci: add smoke tests workflow with parallel execution
- Single job runs all 7 scenarios in parallel using test runner's --parallel flag
- Builds CLI in-job (no artifact passing needed)
- Outputs summary.md to GitHub step summary
- Syncs package-lock.json for tiktoken/commander deps
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(evals): increase 01-create-file timeout to 120s
The 30s timeout was too short for reliable execution.
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: restore changesets deleted during rebase
These changesets belong to the already-merged CLI fix (#9073)
and should not be deleted by this branch.
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore(evals): remove unused dependencies from package.json
Drop execa, node-fetch, ora, sqlite, uuid, yargs and their types.
These were leftovers from the old CLI-based eval runner. The smoke
tests use Node builtins and the tool-precision benchmark only needs
axios, better-sqlite3, chalk, commander, dotenv, tiktoken.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Add TypeScript build info files to .gitignore
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* feat: add .agents/skills directory support for skill discovery
Add compatibility for the standardized .agents/skills directory pattern,
both globally (~/.agents/skills) and locally (.agents/skills in workspace).
* feat: make .agents/skills the default for new skills
New skills are now created in .agents/skills (local) and ~/.agents/skills
(global) by default. These directories also have highest priority in
skill discovery, overriding skills with the same name from other locations.
* docs: update skills documentation for .agents/skills directories
* refactor skills directory helpers
* increases banner cache duration to 24 hours so we make one api calls per day per user; implements a circuit breaker that stops retrying after 3 consecutive failures
* add new tests
* Clear banner cache when auth status changes
* revert 5898bc6e0e
* Fixing circuit breaker
* fix: reset circuitBreakerOpenedAt on failed half-open recovery
Previously, circuitBreakerOpenedAt was only set when consecutiveFailures
reached exactly MAX_CONSECUTIVE_FAILURES. This meant that after a failed
half-open recovery attempt, the timestamp wasn't updated, causing the
circuit breaker to immediately enter half-open state again on the next call.
Now circuitBreakerOpenedAt is updated on every failure once the circuit
breaker is tripped, ensuring proper timeout between recovery attempts.
* refactor: BannerService initialization and cache management
- Move BannerService initialization from common.ts to AuthService (which is initialized in controller)
- Re-initialize BannerService after auth state updates to ensure user context
- Add HostRegistryInfo to centralize host/platform information collection
- Improve rate limiting with exponential backoff (5min → 15min → 30min)
- Refactor error handling to better distinguish between rate limits and server errors
- Remove temporary disabled banner fetching comments
This change ensures banners are only fetched when user authentication is
available and implements more robust rate limiting to prevent API hammering.
The banner service now properly tracks user context and respects server
rate limits with progressive backoff delays.
* refactor(banner): simplify banner service initialization and usage
- Remove `getBanners()` wrapper method from Controller class
- Call `BannerService.get().getActiveBanners()` directly in Controller
- Change `BannerService.initialize()` to synchronous, returns instance immediately
- Make banner fetching non-blocking by moving to background
- Remove unused `BannerCardData` import from Controller
- Update tests to handle asynchronous background fetching with timeouts
- Clean up AuthService banner service initialization comment
This change simplifies the banner service API by removing unnecessary abstraction layers and making initialization non-blocking. The service now fetches banners in the background rather than blocking on initialization, improving application startup performance.
* clean up
* apply feedback
* un-skip unit test
* mock
* mock env
* clean up and add debounce fetch
* log fetch time
* revert
* feature flag: remote-banners
* fix loop in authService on auth update
Co-authored-by: Tomás Barreiro <BarreiroT@users.noreply.github.com>
* Fix tests
* small fixes
* use .? for banner
* moves initializeDistinctId to StateManager
* initializeDistinctId
* use v2 endpoint
---------
Co-authored-by: Zhongying Qiao <cryptoque@users.noreply.github.com>
Co-authored-by: Arafatkatze <arafat.da.khan@gmail.com>
Co-authored-by: Tomás Barreiro <BarreiroT@users.noreply.github.com>
Co-authored-by: Tomás Barreiro <52393857+BarreiroT@users.noreply.github.com>
Co-authored-by: BarreiroT <tomasmbarreiroi@gmail.com>
* fix: openai native provider token usage mapping
- Add `store` parameter support to OpenAI native provider options to allow persisting completions.
- Fix incorrect mapping of `cached_tokens` and `reasoning_tokens` in usage statistics.
- Include `thoughtsTokenCount` in the final usage report to track reasoning model performance and costs.
* Update src/core/api/providers/openai-native.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>
Apply suggestions from code review
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: implement response chaining for Responses API
Implement response chaining by tracking and passing previous_response_id
to continue conversations from the last assistant message. This enables
the Responses API to maintain context across multiple turns.
Key changes:
- Search backwards through messages to find last assistant message with ID
- Only send new messages after the chained response
- Track function call metadata (call_id, name, id) across chunks
- Include call_id in tool_call events for proper correlation
- Clean up debug logging and remove commented code
- Remove redundant "Ran out of tokens" log message
This improves conversation continuity and ensures function calls are
properly tracked with their associated IDs throughout the streaming
response lifecycle.
* clean up
* update oca
* codex
Replaces the inline VS Code launch command with a proper dev script that:
- Builds protos and webview upfront
- Runs esbuild, tsc, and webview watchers in parallel tmux panes
- Waits for dist/extension.js before launching the extension host
- Cleans up all processes and closes the dev window on Ctrl+C
* fix(webview): stabilize focus chain header space and placeholder
* fix(chat): add follow-up bottom scroll to avoid short scroll
* style(chat): refine markdown spacing and tool group summary tone
* fix(chat): retry auto-scroll at 40ms and 70ms
* fix(chat): keep focus chain placeholder visible until checklist exists
* changeset version bump
* Updating CHANGELOG.md format
* changeset version bump
* Updating CHANGELOG.md format
* Eve manually updating the banner and the release version
* Manually update the changelog
* Fix GLM 5 model ID in banner
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: cline-test <132302818+candieduniverse@users.noreply.github.com>
* docs: add subagents feature documentation
Add new documentation page covering the Subagents feature, including
how it works, enabling/configuring, auto-approve behavior, available
tools, and usage guidance. Register the page in docs.json sidebar nav.
* docs: remove hardcoded subagent limit from subagents page
Remove references to 'up to five' subagents, as the limit is no longer
fixed. Updates both the intro paragraph and the How It Works section.
* feat: checkpoint subagent tool workflow and approval UX
* feat: support subagent tool execution without native tool calls
* fix: expose use_subagents when native tool calling is disabled
* fix: stabilize subagent command UX and suppress nested command rows
* chore: tune subagent prompt guidance for context-heavy exploration
* fix: align subagent row spacing with chat row conventions
* fix: keep cancelled subagent state during immediate resume
* feat: implement subagent message rendering for approval prompts and progress updates
* feat: enhance SubagentRunner with tool use ID resolution and fallback handling
* fix: stabilize subagent cline requests with ulid and initial workspace metadata
* refactor: unify subagent chat row rendering
* feat: surface subagent costs in task metrics and status rows
* fix: refine cli subagent tree alignment and wrapping
* fix: refine subagent streaming rows in cli and webview
* fix: ensure unique act mode hint keys in CLI chat
* feat: add subagents settings toggle wiring across webview and cli
* fix(webview): stream subagent stats per prompt while constructing prompts
* fix: remove duplicate subagentsEnabled declaration after rebase
* chore: restore package lockfiles to main
* fix: harden task history usage parsing and clean prompt separators
* chore: refine subagent response formatting guidance
* feat: collapse subagent prompts with show more
* feat: show latest subagent tool call in status rows
* fix: fall back to non-native mode for subagents when native tools are unavailable
* fix: retry empty subagent responses before failing
* fix(subagents): require attempt_completion and dedupe tool result formatting
* feat(subagents): polish prompt guidance and webview status row
* fix(task): prevent duplicate partial text rows after completion
Avoid adding a new partial text message when the latest text row is already completed with the same content. This stops a presenter race from rendering duplicate streamed text lines for MiniMax-style timing.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(task): cover duplicate partial text dedupe behavior
Add a Task.say unit test that reproduces the duplicate-partial-after-complete scenario and verifies we skip creating a second text row with identical content.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(claude-code): add opus 4.6 1m model option
* fix(claude-code): support opus[1m] alias and align opus alias
* fix(claude-code): add sonnet[1m] model support
* add more shortcuts to help output
* Apply suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add Bedrock to the list in isNextGenModelProvider()
* feat(bedrock): Remove testing script used to develop isNextGenModelProvider() change against
* refactor: extract shared isParallelToolCallingEnabled into model-utils
Consolidate duplicated parallel tool calling logic from ToolExecutor.ts
and task/index.ts into a single exported function in model-utils.ts.
Both callers now delegate to the shared function, eliminating the need
to maintain identical checks in two places.
Replaces inline --body with --body-file approach in the PR creation skill documentation. This avoids shell escaping issues, newline problems, and command-line flakiness when creating PRs with complex markdown content.
Related to #8785
* feat: enable sync-ed deletion for remote mcp servers from remote config to extension
* chore: add tests for syncing remote mcp server adding and removal
* address comments
* WIP - Render a Remote Config secttion and add an option to refresh
* Add the different remote config sections and test them
* fixes
* refactor
* Add proper wrapping
* Stack more values
* Properly report errors when prompt uploading fails
* Add a better error message for the otel test button
* clean
* Fix option rendering
* Render less options if they aren't configured
* fix: use vscode.env.asExternalUri for web OAuth callbacks
In VS Code Web (Codespaces, code serve-web), OAuth callbacks using
http://127.0.0.1:PORT break because the extension host runs remotely.
Changes:
- getCallbackUrl now accepts a path parameter
- Desktop: uses vscode://extension-id/path directly
- Web (UIKind.Web): uses vscode.env.asExternalUri() for web-reachable URL
- Updated all callers (/auth, /openrouter, /hicap, /requesty, MCP) to
pass path and use URL+searchParams for proper encoding
- Added regression test asserting web callback URL is not 127.0.0.1
- AuthHandler (localhost HTTP) now only used by CLI/standalone mode
* fix: use URL.searchParams for proper callback URL encoding
Callers were using template literal interpolation to embed callback URLs
into query strings, which breaks when the URL contains special characters
(e.g. from asExternalUri with query params). Use URL+searchParams.set()
which automatically encodes values.
* chore: revert unrelated whitespace change in account.proto
* revert: remove non-essential URL encoding changes in auth callers
Keep only the core fix (getCallbackUrl path parameter + asExternalUri for web).
Revert the URL+searchParams encoding improvement to minimize diff.
* fix: URL-encode callback_url in auth callers, add encoding test
In VS Code Web, callback URLs from asExternalUri can contain their own
query params (?tkn=...&extra=...). String-interpolating them into
callback_url= causes everything after the first & to be parsed as
top-level params, truncating the callback URL.
Use URL + searchParams.set() in openrouter, hicap, and requesty callers.
Replace tautology test with deterministic round-trip encoding assertions.
* feat(tools): add auto-approval support for attempt_completion commands
- Add auto-approval logic for bash commands in AttemptCompletionHandler
- Show commands as 'say' instead of 'ask' when auto-approved
- Display notification prompting user approval when manual approval needed
- Add 30-second timeout notification for long-running auto-approved commands
- Fix Logger import path from @/shared to @shared
* Send to cline provider
* feat(bedrock): Create agent implementation plan for supporting parallel tool calling.
* Add Bedrock tool calling support
* Improve Bedrock tool calling test guidance
* Add Bedrock CLI parallel tool calling test script
* fix: add ALLOW_AWS_DEFAULT_CHAIN support to live integration test script
* chore: add changeset for Bedrock parallel tool calling
* feat(bedrock): enable native parallel tool calling for Bedrock provider
- Add 'bedrock' to isNextGenModelProvider() so native tool calling is enabled
- Add 'bedrock' to getNativeConverter() to use Anthropic-format tool specs (input_schema)
- Fix empty tool description validation error in mapClineToolsToBedrockToolConfig
(Bedrock requires description length >= 1)
- Update CLI test to use Sonnet 4.5 (Haiku too small for native tool calling)
- Add <invoke> XML detection to CLI test to catch XML fallback
Verified: conversation history shows 3 native tool_use blocks in a single
assistant response with 3 matching tool_result blocks — true parallel
tool calling via Bedrock Converse API.
* docs: mark all phases complete in bedrock parallel tool calling implementation plan
* chore: switch test scripts default model to Haiku 4.5 (cheaper for testing)
* feat: enhance CLI verification suite with 3 test cases (single, parallel, round-trip)
* Remove bedrock parallel tool calling implementation plan doc.
* refactor: simplify to single CLI verification script for bedrock parallel tool calling
Remove the handler-level test script (test-bedrock-tool-calling.ts) and consolidate
into a single focused CLI test that proves parallel tool calling works end-to-end:
- Spawns Cline CLI with Bedrock config
- Asks it to read 3 files
- Verifies ≥2 parallel native tool calls (not XML fallback)
- Task completion proves tool result round-trip works
* refactor(bedrock): improve type safety and code quality for parallel tool calling
- Add typed interfaces (ToolUseStart, ToolUseDelta) for Bedrock stream
events instead of relying on `as any` casts
- Extend ContentBlockStart and ContentBlockDelta interfaces with toolUse
fields so stream parsing uses typed property access
- Remove dead `inputBuffer` field from activeToolCalls Map (was tracked
but never read — tool input deltas are yielded immediately)
- Add JSDoc to mapClineToolsToBedrockToolConfig explaining its purpose
and return semantics
- Document why createDeepseekMessage intentionally ignores the tools
parameter (DeepSeek R1 uses InvokeModel, not Converse API)
* refactor(scripts): improve test script readability and resource cleanup
- Add try/finally with cleanupDirs() to remove temp workspace and config
dirs after each run (previously accumulated in $TMPDIR)
- Extract named constants for CLI_TIMEOUT_SECONDS and HEARTBEAT_INTERVAL_MS
- Add CliResult interface for the runCli return type
- Rename cryptic variables: hb → heartbeatInterval, c → chunk, p/d → filePath/data
- Add JSDoc to parseReadFilePaths and hasXmlFallback
- Add explanatory comments to empty catch blocks
- Log stderr on non-zero exit code for easier debugging
- Extract createTestWorkspace() to separate workspace setup from main flow
- Add section separator comments for visual structure
* test(bedrock): add missing edge-case tests and remove dead describe block
- Add tests for mapClineToolsToBedrockToolConfig edge cases:
undefined/empty input returns undefined, tools without input_schema
are silently dropped
- Add test for formatMessagesForConverseAPI with array tool_result
content (multi-block text responses)
- Add test for tool_result is_error → status:'error' mapping
- Remove empty 'reasoning content handling (deprecated)' describe block
35 tests passing (was 31).
* test(bedrock): add integration-level tests covering E2E script gaps
Add 'native tool calling integration' test suite that validates the
concerns previously only covered by the live E2E CLI script:
- Bedrock + Claude 4 is recognized as native tool calling eligible
(catches silent regression if Bedrock is removed from
isNextGenModelProvider or Claude 4 from isNextGenModelFamily)
- Bedrock + Claude 3.x correctly does NOT qualify (pre-4.0 guard)
- Native tool calling disabled when user setting is off
- createAnthropicMessage passes toolConfig to ConverseStreamCommand
(catches the tool spec not reaching the API)
- Full multi-turn tool call round-trip formatting (tool_use in
assistant → tool_result in user → reformatted for next API call)
40 tests passing (was 35).
* Remove functional verification script before code review
The diff editor e2e test flakes consistently on Windows CI because the
40s test timeout is too tight. The test does signin, message send,
history verification, then a second message send before the diff
assertion -- on slow Windows runners this setup alone can eat most of
the budget. Bumping to 60s gives enough headroom.
Add Terminal-Bench-proven rules as items 5 and 6 in the double-check
re-verification checklist, so they're enforced at completion
verification time rather than in the system prompt.
* feat: add double-check completion experimental feature
When enabled, the first attempt_completion call in a task is rejected
with a tool error that instructs the model to re-verify its work
against the original task requirements. The rejection includes the
initial task text for context. The second call proceeds normally.
This is opt-in (default off) and available via:
- Settings > Features > Experimental > Double-Check Completion
- CLI flag: --double-check-completion
- CLI TUI settings panel toggle
Adds completionAttemptCount to TaskState, plumbs the setting through
TaskConfig/ToolExecutor following existing patterns, and includes
9 unit tests.
* chore: add cli:run script for quick CLI testing
* fix: increase task preview to 8000 chars, revert unintended regex change
* fix: preserve existing proto field numbers
The auto-generator renumbered open_ai_headers (175->177) and
openai_codex_oauth_credentials (46->48), and dropped the reserved 146
comment. Restore original field numbers to avoid breaking wire-format
compatibility.
* fix: remove partial completion_result message on double-check rejection
During streaming, handlePartialBlock shows the completion_result in
the chat view. When we reject the first attempt, we need to clean up
that partial message so the user doesn't see a stale completion that
was actually rejected.
* refactor: switch from counter to boolean toggle for double-check
Use a boolean pending flag instead of a counter so that every
attempt_completion gets double-checked, not just the first one in
a task. The flag toggles: reject (set pending), accept (clear pending),
so if the model does more work and tries to complete again later, it
gets double-checked again.
* fix(prompt): add output precision and threshold iteration rules
Two concise rules proven effective via Terminal-Bench testing:
1. Output precision: produce exactly what's specified, no extra columns/fields/debug output
2. Threshold iteration: verify results meet numerical criteria before completing
Tested on 6 targeted Terminal-Bench tasks (job 2026-02-07__16-15-00):
- log-summary-date-ranges: FAIL→PASS (output precision rule eliminated extra columns)
- dna-insert: FAIL→PASS (iterate rule helped agent meet Tm threshold)
A third rule (no-cleanup) was tested and deliberately excluded: it failed to
prevent self-sabotage on configure-git-webserver despite STRICTLY FORBIDDEN
language, and caused a side-effect on polyglot-c-py by preventing legitimate
build artifact cleanup. The cleanup behavior is too deeply trained to override
via prompt rules alone.
* test: update prompt snapshots for new rules
* fix(cli): route PostHog networking through shared fetch
* remove unnecessary `as RequestInit` casts from PostHog fetch wrappers
PostHogFetchOptions is a structural subset of RequestInit, so the cast
is unnecessary. Also removes a stale comment about shared client support
in PostHogErrorProvider.
The --thinking flag now accepts an optional number argument to set a
custom thinking budget instead of always using the 1024 default.
cline "prompt" --thinking # 1024 tokens (default)
cline "prompt" --thinking 8000 # 8000 tokens
Invalid values get a warning and fall back to 1024.
* feat: move reasoning effort to model config and update model selection UX
* refactor: dedupe reasoning effort handling and drop lockfile churn
* refactor: default reasoning effort to low
* refactor(cli): sync mode-scoped thinking and reasoning writes
* fix: centralize reasoning effort normalization and avoid implicit openai effort
* fix: restore proto field number for codex credentials and reserve removed fields
- Keep openai_codex_oauth_credentials at field 46 (was incorrectly
changed to 47)
- Add reserved 146 in Settings for removed openai_reasoning_effort
- Add reserved 15 in UpdateSettingsRequest for removed openai_reasoning_effort
- Remove stale openai_reasoning_effort field from UpdateSettingsRequest
* fix: map medium reasoning effort to LOW for Gemini models
Gemini API only accepts LOW and HIGH thinking levels. MEDIUM exists in
the SDK enum but is rejected at the API level. Map medium to LOW and
update the default fallback accordingly.
Introduces a mechanism to save system prompts and task metadata to disk for debugging and analysis purposes.
- Added `writePromptMetadataArtifacts` to the `Task` class.
- Feature is enabled via the `CLINE_WRITE_PROMPT_ARTIFACTS` environment variable.
- Artifacts are saved to `.cline-prompt-artifacts` or a custom path defined by `CLINE_PROMPT_ARTIFACT_DIR`.
- Writes both a JSON manifest (containing task ID, model info, and timestamp) and the raw system prompt for every API request.
* fix: use vscode.env.asExternalUri for auth callback URLs in VS Code Web
The OAuth callback redirect was broken in VS Code Web (code serve-web)
environments because the callback URL used a raw vscode:// URI scheme,
which the OS would route to the local desktop VS Code app instead of
the web instance.
This change wraps both getCallbackUrl() and getIdeRedirectUri() with
vscode.env.asExternalUri() which properly transforms URIs based on the
environment:
- Desktop VS Code: unchanged (vscode://...)
- VS Code Remote SSH: adds remote authority for proper routing
- VS Code Web: transforms to HTTPS URL that routes through the web server
Fixes#5109 (remaining callback redirect issue)
Related: #2152
* fix: use HTTP-based auth callback for VS Code Web mode
In VS Code Web (code serve-web), vscode:// URIs redirect to the desktop
app instead of staying in the browser. This change uses AuthHandler
(local HTTP server) for the auth callback in web mode, matching how
CLI/standalone already handles auth.
- getCallbackUrl: use AuthHandler when UIKind.Web
- getIdeRedirectUri: return empty in web mode to avoid vscode:// redirect
* fix: add fallback for openExternal RPC for JetBrains compatibility
The openExternal host bridge RPC is not implemented in the JetBrains
plugin, causing sign-in to fail silently. This adds a fallback to the
'open' npm package when the host RPC fails with UNIMPLEMENTED.
Fixes#9164, #9137, #9138
The chat streaming UI refactor removed the loading indicator that
previously showed when an API request was in progress. This left users
staring at a frozen UI during the latency between sending a message
and receiving the first streamed content.
Changes:
- Add "Thinking..." shimmer in the Virtuoso Footer as the sole loading
indicator, covering both pre-api_req_started (backend processing) and
post-api_req_started (waiting for model response) states
- Filter out api_req_started messages that have no visible content
(no error/cancel). These rows rendered as invisible padding since
the PR removed the old API request accordion UI. Reasoning messages
already render as their own standalone ChatRows.
- Thread footerActive flag to MessageRenderer so the last message skips
pb-2.5 when the Footer is showing, keeping spacing consistent with
the pt-2.5 on every ChatRow
- Add stdinIsTTY check to shouldUsePlainTextMode() - Ink requires raw mode on stdin
- Only error on empty stdin when no prompt is provided (allows: cline 'prompt' < /dev/null)
- Fixes crash in GitHub Actions and other CI environments
- Cline CLI 2.0 now available. Install with `npm install -g cline`
- Anthopic Opus 4.6
- Minimax-2.1 and Kimi-k2.5 now available for free for a limited time promo
- Codex-5.3 through OpenAI Codex provider
- Fix read file tool to support reading large files
- Fix decimal input crash in OpenAI Compatible price fields (#8129)
- Fix build complete handlers when updating the api config
- Fixed missing provider from list
- Fixed Favorite Icon / Star from getting clipped in the task history view
- Make skills always enabled and remove feature toggle setting
Co-authored-by: Arafatkatze <arafat.da.khan@gmail.com>
* feat: add GPT-5.3 Codex model for ChatGPT subscription users
OpenAI released GPT-5.3 Codex today. Adding it to the OpenAI Codex
provider (ChatGPT Plus/Pro subscription) model list and setting it
as the new default.
Changes:
- Add gpt-5.3-codex to openAiCodexModels with same specs as 5.2
- Update default model to gpt-5.3-codex
- Update featured models in CLI and webview OpenRouter picker
* revert: remove gpt-5.3-codex from OpenRouter featured models
GPT-5.3 Codex is only available via ChatGPT subscription, not through
the OpenAI API or OpenRouter. Reverting featured model changes.
* feat: add Claude Opus 4.6 model support with 1M context window
Adds support for Claude Opus 4.6, Anthropic's latest model with:
- 200K base context window with optional 1M context variant
- Tiered pricing for >200K context (2x input/output pricing)
- Extended thinking/reasoning support
- Prompt caching support
Changes:
- Added model definitions for Anthropic, Bedrock, and Vertex providers
- Added OpenRouter 1M variant support
- Updated thinking models lists across all provider UIs
- Added context window switcher for Opus 4.6
- Updated JP cross-region inference models list
* feat: update featured model to Opus 4.6 in model picker
* chore: add changeset for Claude Opus 4.6
* fix: correct Opus 4.6 model IDs (no date suffix)
---------
Co-authored-by: Robin Newhouse <robin@cline.bot>
Use refs instead of state values in useInput callback to avoid stale
closures. Also manually update textInputRef before calling setCursorPos
so the bounds check uses the correct new text length.
ChatView was returning empty string when the model ID key didn't exist
in state, causing first-time CLI users to see a blank model name. Added
fallback to getProviderDefaultModelId() to match WelcomeView's behavior.
Previously the animated robot only became static when the user scrolled.
Now it also becomes static when clicking or dragging, giving users more
ways to dismiss the animation. Renamed onScroll to onInteraction to
reflect the broader scope.
* chore: update biome configuration and linting rules
Update @biomejs/biome package to latest version: 2.3.14
- Change $schema to point to local node_modules for better IDE performance and stability.
- Enable and promote several linting rules from "off" to "info" or "warn" across correctness, style, suspicious, and complexity categories.
- Update file inclusion/exclusion patterns to use more explicit formatting and set ignoreUnknown to true.
- Improve code quality enforcement by surfacing potential issues such as non-null assertions, useless constructors, and implicit any types.
* package-lock udpate
* includes tailwind
* useIterableCallbackReturn
* fix: use vscode.env.openExternal for auth in remote environments
Fixes#5109
The OAuth authentication flow was broken in VS Code Server and remote
environments because the code used the npm 'open' package directly, which
tries to launch a browser on the server itself (which has no display).
This change routes browser URL opening through VS Code's native
vscode.env.openExternal() API via the HostBridge pattern, which properly
forwards URLs to the user's local machine in remote environments.
Changes:
- Added openExternal RPC to proto/host/env.proto
- Created VS Code handler using vscode.env.openExternal()
- Updated src/utils/env.ts to use HostProvider.env.openExternal()
- Added openExternal to CLI CliEnvServiceClient (uses npm 'open')
- Added openExternal to CLI ACPEnvServiceClient (uses npm 'open')
Related issues: #5394, #2152, #7971
* chore: add changeset for vscode server auth fix
* refactor: extract shared openUrlInBrowser utility for CLI
* add auth option to get API-KEY for hicap from hicap dashboard website
* remove default hicap model selection
* change url hicap get api keys, add useEffect when update hicapApiKey
* add changeset
Remove conditional checks that skipped dependency installation when
cache was hit. The npm cache speeds up npm ci but does not replace
the need to run it - node_modules still needs to be populated.
- this was breaking the publish npm workflow when we try to run npm
publish from the dist-standalone folder (dist-standalone doesn't have
the esbuilt.ts file)
- we don't need this script anyway because we use the npm-main.yaml
workflow to publish the cli
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
* fix(cli): prevent hang when spawned without TTY
When the CLI is spawned as a child process without a TTY (e.g., from
spawn() in smoke tests or CI), process.stdin.isTTY is false even when
nothing is piped to stdin. This caused readStdinIfPiped() to wait up
to 5 minutes for input that would never arrive.
Fix by using fs.fstatSync(0) to check if stdin is actually a FIFO
(pipe) or file before waiting. This correctly handles:
- Spawned processes without TTY → returns immediately
- Actual piped input (echo "x" | cline) → waits and reads
- stdin from /dev/null → returns immediately
* chore: add changeset
* test(cli): add tests for stdin type detection
* Add ACP editor integrations documentation with JetBrains and Neovim video demos
* Add Model Orchestration documentation with --config and --thinking flags
- Document --config and --thinking flags in CLI reference
- Create new model-orchestration.mdx sample page
- Add patterns for CI/CD review, task phase optimization, and multi-model consensus
- Link to production GitHub Actions workflow
- Update samples overview with new card
- Update docs navigation
* Add Worktree Workflows documentation with --cwd flag
- Document --cwd flag in CLI reference
- Create comprehensive worktree-workflows.mdx sample page
- Add patterns for parallel execution and cross-worktree piping
- Include real-world examples and best practices
- Add CLI section to features/worktrees.mdx for discoverability
- Update samples overview and navigation
- Cross-link between CLI and VS Code worktree docs
* Remove broken image references from worktrees documentation
- Remove worktrees-overview.png Frame (image not available)
- Remove worktrees-merge.png Frame (image not available)
- Documentation remains fully functional with comprehensive text explanations
* Remove accidentally committed local test file
- Delete src/test/verify-platformio-mcp.ts which was causing CI failures
- File contained TypeScript errors and hardcoded local paths
- Was meant for local testing only, should not have been committed
* Add native JetBrains plugin recommendation to ACP docs
- Add prominent Note recommending native JetBrains plugin
- Link directly to JetBrains installation section
- Position ACP setup as an alternative approach
- Keep all existing ACP content and video
* docs: refine CLI reference formatting and ACP title
Improve CLI reference readability with clearer headings and descriptions, and clarify the ACP editor integration page title for better discovery.docs: refine CLI reference formatting and ACP title
Improve CLI reference readability with clearer headings and descriptions, and clarify the ACP editor integration page title for better discovery.
* Fix CLI 2.0 syntax in model-orchestration.mdx
- Updated issue analysis pipeline to use shell variables for passing context
- Added explanatory note about why direct piping doesn't work
- Corrected example to complete each phase before starting the next
- All examples now use proper CLI 2.0 syntax
* Completely rewrite cli-reference.mdx with accurate CLI 2.0 information
- Removed all outdated CLI 1.0 content (instance management, Cline Core architecture, gRPC references)
- Added accurate CLI 2.0 commands: task, history, config, auth, update, version, dev
- Corrected all command flags and options based on actual man page
- Added proper examples for all commands
- Included environment variables documentation (CLINE_DIR, CLINE_COMMAND_PERMISSIONS)
- Added shell completion instructions
- Removed incorrect three-layer architecture description
- All content now matches cli/man/cline.1.md source of truth
Fixes outdated documentation issue mentioned in PR#9036
* Fix MDX syntax error in cli-reference.mdx
- Replace angle bracket URLs with proper markdown links
- MDX parser was interpreting <https://...> as invalid HTML tags
- Now uses [url](url) format which is proper MDX syntax
Fixes deployment validation error
* docs: Add GitHub PR Review sample and modernize Actions integration
* fix: Add cline installation step to PR review workflow
- Fix CI/CD failure by actually installing cline before running it
- Update docs model ID to match workflow (claude-opus-4-5-20251101)
- Change from 'npx cline version' to 'npm install -g cline' + 'cline version'
---------
Co-authored-by: Renee Huang <renee@cline.bot>
applyProviderConfig is async and for Cline/OpenRouter providers it
awaits fetching model data before setting state. When switching to
an already-configured provider (Cline, OCA), the call wasn't awaited,
so refreshModelIds() ran before the model ID was set in state,
causing the model to not update to the default.
- Added applyBedrockConfig to provider-config.ts for AWS Bedrock setup
- AuthView saveConfiguration now uses applyProviderConfig/applyBedrockConfig
- SettingsPanelContent handleBedrockComplete now uses applyBedrockConfig
- Removed duplicate Bedrock config building code from both components
- Cleaned up unused imports
# Conflicts:
# cli/src/components/SettingsPanelContent.tsx
applyProviderConfig calls flushPendingState internally, so any state
set after it needs its own flush. Added explicit flush after setting
welcomeViewCompleted in OCA and OpenAI Codex auth success handlers.
Simplifies OCA, Cline, and OpenAI Codex auth success handlers in
AuthView to use the shared applyProviderConfig utility instead of
manually constructing provider config objects.
This removes duplicated logic around mode-specific provider keys
and model ID keys that applyProviderConfig already handles.
* feat: add authentication support to oca provider in CLI
This change integrates the OcaAuthService into the AuthView component. It adds a new 'oca_auth' step to the authentication flow, allowing users to select 'oca' as a provider and initiate the authentication request via OcaAuthService.
* fix(cli): add subscription to OCA auth status updates
The OCA auth flow was missing the subscription mechanism to know when
browser auth completes. Without this, the CLI would spin indefinitely
after opening the browser.
Added a useEffect that subscribes to OcaAuthService.subscribeToAuthStatusUpdate
when in oca_auth step. When auth succeeds (user.uid present), saves the
provider config and transitions to success.
* fix(cli): add OCA auth support to SettingsPanelContent
AuthView only handles onboarding. Users also need to be able to switch
to OCA provider from the settings panel after initial setup.
Added:
- handleOcaLogin callback to start OAuth flow
- useEffect subscription to OCA auth status updates
- Case in handleProviderSelect for "oca" provider
- Escape key handling to cancel OCA auth
- UI for "Waiting for OCA sign-in..." state
- isWaitingForOcaAuth to input disabled check
* refactor(cli): extract OCA auth logic into useOcaAuth hook
Reduces code duplication between AuthView and SettingsPanelContent by
extracting the OCA auth subscription and state management into a
reusable hook.
The hook handles:
- Starting the OAuth flow (initialize + createAuthRequest)
- Subscribing to auth status updates
- Tracking waiting state
- Calling onSuccess callback when auth completes
- Exposing isAuthenticated for checking existing sessions
Both components now use the hook with their own onSuccess handlers
for component-specific state updates.
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* fix: apply models cache retrieval across model refresh functions
This change introduces a unified caching mechanism for model information retrieved from various API providers (Groq, OpenRouter, Vercel). Each service now first checks if the data is available in the shared StateManager's cache before making an API request. This improves performance by leveraging cached results and reduces redundant network calls when refreshing models multiple times. The cache is stored in memory for quick access during subsequent calls within a single execution context.
Changes made:
1. Added import of `StateManager` to each relevant model refresh file.
2. Implemented initial cache check logic at the beginning of each function.
3. Updated error handling and logging consistency across services.
4. Added storage back into StateManager's cache after successful API retrieval for Groq, Vercel AI Gateway only (OpenRouter update already handled).
* promises
* add vercelModels
* feat: add 1-hour TTL to model cache
Adds a time-to-live mechanism to the model info cache so that:
- Duplicate fetches are still prevented within a reasonable window
- Users can get new models after 1 hour without restarting VS Code
Changes:
- Add MODEL_CACHE_TTL_MS constant (1 hour)
- Update cache structure to include timestamp alongside data
- Update setModelsCache to store timestamp with data
- Update getModelsCache to check TTL and invalidate expired cache
- Update getModelInfo to also respect TTL
---------
Co-authored-by: Arafatkatze <arafat.da.khan@gmail.com>
* feat: display markdown table in UI
Simplify the handlePartialBlock method in AttemptCompletionHandler by:
- Removing conditional logic for command vs no-command cases
- Always displaying partial result if present
- Deferring command handling to the final execution step
This fixes an issue where attempt completion response doesn't get streamed to the UI during partial result.
Also replaced react-remark with react-markdown and remark-gfm dependencies to MarkdownBlock in UI for enhanced markdown rendering support with GitHub Flavored Markdown features, including displaying table.
* add changeset
* Update src/core/task/tools/handlers/AttemptCompletionHandler.ts
handlePartialBlock hard-codes the partial flag to true when calling uiHelpers.say(...). For consistency with other tool handlers and to avoid incorrect behavior if this method is ever invoked with a non-partial block, pass block.partial through instead.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Robin Newhouse <robin@cline.bot>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* chore: add CLI type checking and caching to ci workflow
- Added a new cache step for CLI dependencies in the GitHub Actions test workflow to improve build performance.
- Included a step to install CLI dependencies using `npm ci`.
- Updated the `ci:check-all` script in `package.json` to include CLI type checking.
- Added a `cli:typecheck` script to handle type checking within the CLI directory.
* Fix type and import issues for cli
* Includes CI tests in test workflow
* use npx npm-run-all
* update ci:check-all
* ci: skip npm ci steps on cache hit in test workflow
Update the test workflow to conditionally run npm installation steps only when a cache hit is not found. This optimization reduces CI execution time by avoiding redundant dependency installations when the node_modules are already restored from cache.
* ci: update cache keys and add dependency verification in test workflow
Updated the cache keys for root, webview-ui, cli, and testing-platform dependencies by adding a version prefix (v1). This ensures a clean cache state and helps avoid potential corruption or mismatch issues.
Additionally, added a verification step in the test job to log cache hit status and check for the presence of key dependencies like biome and globby. This helps diagnose issues where the cache might be restored but dependencies are not correctly available for subsequent steps.
* update Verify and fix root dependencies
* fix type check script
* add isSettingsKey check
* update settingskey set
* apply feedback
* npx
* feat: flashing dot for streaming chat messages in CI (#9054)
Introduce an ink-spinner to the DotRow component to provide visual feedback when messages are being streamed. This improves the CLI user experience by clearly indicating that a tool call or message is currently in progress.
- Add `flashing` prop to `DotRow` component
- Replace static dot with `toggle8` spinner when `flashing` is true
- Update `ChatMessage` to pass `flashing` state based on `isStreaming` and `partial` message properties
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* ci: simplify dependency caching using built-in npm cache
Replace manual actions/cache steps with setup-node's built-in npm caching feature across all workflow jobs. This change:
- Removes redundant cache action steps for root, webview-ui, cli, and testing-platform dependencies
- Uses setup-node's native `cache: 'npm'` option with `cache-dependency-path` to handle multiple package-lock.json files
- Eliminates conditional installation steps based on cache hits
- Reduces workflow complexity and maintenance overhead while maintaining caching functionality
The built-in caching provides the same performance benefits with less configuration and better integration with the Node.js setup action.
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* docs: restructure CLI reference to web-friendly format
Replace embedded man page format with structured markdown sections
for better readability. Simplify description, reorganize commands and
options into clear categories, and update Next Steps navigation cards.
* Add ACP editor integrations documentation (#9036)
* Add ACP editor integrations documentation with JetBrains and Neovim video demos
* Add Model Orchestration documentation with --config and --thinking flags
- Document --config and --thinking flags in CLI reference
- Create new model-orchestration.mdx sample page
- Add patterns for CI/CD review, task phase optimization, and multi-model consensus
- Link to production GitHub Actions workflow
- Update samples overview with new card
- Update docs navigation
* Add Worktree Workflows documentation with --cwd flag
- Document --cwd flag in CLI reference
- Create comprehensive worktree-workflows.mdx sample page
- Add patterns for parallel execution and cross-worktree piping
- Include real-world examples and best practices
- Add CLI section to features/worktrees.mdx for discoverability
- Update samples overview and navigation
- Cross-link between CLI and VS Code worktree docs
* Remove broken image references from worktrees documentation
- Remove worktrees-overview.png Frame (image not available)
- Remove worktrees-merge.png Frame (image not available)
- Documentation remains fully functional with comprehensive text explanations
* Remove accidentally committed local test file
- Delete src/test/verify-platformio-mcp.ts which was causing CI failures
- File contained TypeScript errors and hardcoded local paths
- Was meant for local testing only, should not have been committed
* Add native JetBrains plugin recommendation to ACP docs
- Add prominent Note recommending native JetBrains plugin
- Link directly to JetBrains installation section
- Position ACP setup as an alternative approach
- Keep all existing ACP content and video
* docs: refine CLI reference formatting and ACP title
Improve CLI reference readability with clearer headings and descriptions, and clarify the ACP editor integration page title for better discovery.docs: refine CLI reference formatting and ACP title
Improve CLI reference readability with clearer headings and descriptions, and clarify the ACP editor integration page title for better discovery.
* Fix CLI 2.0 syntax in model-orchestration.mdx
- Updated issue analysis pipeline to use shell variables for passing context
- Added explanatory note about why direct piping doesn't work
- Corrected example to complete each phase before starting the next
- All examples now use proper CLI 2.0 syntax
* Completely rewrite cli-reference.mdx with accurate CLI 2.0 information
- Removed all outdated CLI 1.0 content (instance management, Cline Core architecture, gRPC references)
- Added accurate CLI 2.0 commands: task, history, config, auth, update, version, dev
- Corrected all command flags and options based on actual man page
- Added proper examples for all commands
- Included environment variables documentation (CLINE_DIR, CLINE_COMMAND_PERMISSIONS)
- Added shell completion instructions
- Removed incorrect three-layer architecture description
- All content now matches cli/man/cline.1.md source of truth
Fixes outdated documentation issue mentioned in PR#9036
* Fix MDX syntax error in cli-reference.mdx
- Replace angle bracket URLs with proper markdown links
- MDX parser was interpreting <https://...> as invalid HTML tags
- Now uses [url](url) format which is proper MDX syntax
Fixes deployment validation error
---------
Co-authored-by: Renee Huang <renee@cline.bot>
* docs: enhance interactive mode documentation with structured settings overview
* docs: restructure and improve CLI reference documentation
- Reorganize command structure with clearer global options section
- Add mode behavior table explaining interactive vs plain text modes
- Improve option descriptions with consistent formatting
- Add horizontal rules between sections for better readability
- Document timeout option and environment variables more clearly
- Add Tips & Tricks section for common usage patterns
- Update frontmatter description to reflect content changes
* docs: improve ACP editor integrations page with editor descriptions
- Update page title to be more concise ("ACP: Editor Integrations")
- Remove redundant H1 header that duplicated the title
- Add introductory descriptions for JetBrains, Neovim, and Zed sections
- Rename "Zed Editor" section to just "Zed" for consistency
* docs: expand CLI reference with modes of operation and agent behavior
* Update docs/cline-cli/cli-reference-deprecated.mdx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Tony Loehr <turingxo@gmail.com>
Co-authored-by: Renee Huang <renee@cline.bot>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: add API key support for Cline provider
Add support for authenticating with Cline provider using an API key as an alternative to account-based authentication. This change allows users to configure Cline with either a direct API key or through the existing account authentication flow.
Changes:
- Add `clineApiKey` option to ClineHandler and pass through API configuration
- Update authentication check to accept either API key or account ID
- Modify provider configuration detection to check both auth methods
- Remove automatic Cline auth flow trigger on provider selection
- Add `clineApiKey` to provider-to-API-key mapping for proper key management
This provides more flexibility in authentication methods while maintaining backward compatibility with existing account-based authentication.
* promise all
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
When navigating to subpages within the Settings panel (model picker,
provider picker, language picker, etc.), the Panel header now shows
"Esc to go back" instead of "Esc to close" and hides the arrow key
navigation hint since tabs cannot be switched while in a subpage.
description: Create a GitHub pull request following project conventions. Use when the user asks to create a PR, submit changes for review, or open a pull request. Handles commit analysis, branch management, and PR creation using the gh CLI tool.
description: Create a GitHub pull request following project conventions. Use when the user asks to create a PR, submit changes for review, or open a pull request. Handles commit analysis, branch management, PR template usage, and PR creation using the gh CLI tool.
---
# Create Pull Request
@@ -147,14 +147,29 @@ When filling out the template:
### Create PR with gh CLI
**Use a temporary file for the PR body** to avoid shell escaping issues, newline problems, and other command-line flakiness:
1. Write the PR body to a temporary file:
```
/tmp/pr-body.md
```
2. Create the PR using the file:
```bash
gh pr create --title "PR_TITLE" --body-file /tmp/pr-body.md --base main
```
3. Clean up the temporary file:
```bash
rm /tmp/pr-body.md
```
For draft PRs:
```bash
gh pr create --title "PR_TITLE" --body "PR_BODY" --base main
gh pr create --title "PR_TITLE" --body-file /tmp/pr-body.md --base main --draft
```
Alternatively, create as draft if the user wants review before marking ready:
```bash
gh pr create --title "PR_TITLE" --body "PR_BODY" --base main --draft
```
**Why use a file?** Passing complex markdown with newlines, special characters, and checkboxes directly via `--body` is error-prone. The `--body-file` flag handles all content reliably.
The CLI lives in `cli/` and uses React Ink for terminal UI.
- If needed, look at `cli/src/constants/colors.ts` for re-used terminal colors, e.g. `COLORS.primaryBlue` highlight color (selections, spinners, success states).
- Never use `dimColor` with gray (e.g. `<Text color="gray" dimColor>`) - it's too hard to read. Use `color="gray"` for secondary text and normal foreground (no color) for primary text.
- When thinking about how to handle state or messages from core, look at webview for how it communicates with the vs code extension.
- When updating the webview, consider and suggest to the user to update the CLI TUI since we want to provide a similar experience to our terminal users as we do our vs code extension users.
## Adding New API Providers
When adding a new API provider to the extension, you must also update the CLI:
1.**Update `cli/src/components/ModelPicker.tsx`**: Add the provider to the `providerModels` map so `getDefaultModelId()` returns the correct default model. Import the models and default ID from `@shared/api`:
```typescript
import { newProviderDefaultModelId, newProviderModels } from "@/shared/api"
2. **Use `applyProviderConfig()` for auth flows**: When implementing OAuth or other auth flows for the provider, use the shared utility at `cli/src/utils/provider-config.ts`:
```typescript
import { applyProviderConfig } from "../utils/provider-config"
This handles setting provider, default model, API key mapping, state persistence, and rebuilding the API handler.
3. **Provider-specific auth**: If the provider uses OAuth (like `openai-codex`), add handling in `SettingsPanelContent.tsx`'s `handleProviderSelect` callback. See the existing Codex OAuth flow as a reference.
All via `POST localhost:19229/api` with `{"method":"...", "params":{...}}`:
- **`launch`** / **`shutdown`** — lifecycle
- **`ui.screenshot`** — screenshot to `/tmp/cline-debug/`; returns `{path}` — **use `read_file` on the path to examine, do NOT `open` the file** (Preview.app covers the VSCode window)
- **`web.evaluate`** `{expression}` — eval in webview
- **`web.post_message`** `{message}` — send postMessage to extension host via exposed vsCodeApi
- **`wait_for_pause`** `{timeout?}` — block until breakpoint hit
- **`ui.locator`** `{role?, testId?, text?, frame?}` — Playwright locator (auto-retries on stale sidebar frame)
- **`ui.react_input`** `{text, selector?, clear?, submit?}` — set React textarea value via `execCommand('insertText')`; works reliably across multiple tasks
- **⚠️ Dismiss promotional overlays FIRST**: On fresh launches, full-screen promo overlays block the sidebar. **Dismiss immediately after `ui.open_sidebar`**, before any other interaction or screenshot. May need to run twice:
- **Screenshots — don't open the file**: `ui.screenshot` and `ui.sidebar_screenshot` save PNGs to `/tmp/cline-debug/` and return the `{path}`. Use `read_file` on that path to examine screenshots. Running `open <path>` launches Preview.app on macOS which covers the VSCode window.
- **Scripts count = 0 after launch**: CDP connects after extension host starts, so scripts parsed during startup aren't tracked. Breakpoints still work via sourcemap resolution.
- **Port 9230**: Extension host inspector. If another VSCode instance uses this port, the harness will fail to connect. Kill other debug instances first.
- **macOS only** for now (Playwright Electron launch behavior).
- **Webview CDP**: `connect_webview` may fail depending on Electron version. `web.evaluate` still works via Playwright's `frame.evaluate()` fallback.
- **Sourcemap paths**: esbuild outputs relative paths like `../src/extension.ts` in the sourcemap. The resolver handles this, but if a file isn't found, use `ext.source_files` to see exact paths.
- **OAuth with fake codes**: Browser capture intercepts the URL but doesn't provide a valid auth code. For real OAuth testing, open the captured URL in a browser. For unit testing, mock the token exchange.
See `src/dev/debug-harness/README.md` for full API reference.
@@ -14,10 +14,53 @@ This file is the secret sauce for working effectively in this codebase. It captu
## Miscellaneous
- This is a VS Code extension—check `package.json` for available scripts before trying to verify builds (e.g., `npm run compile`, not `npm run build`).
- When creating PRs, if the change is user-facing and significant enough to warrant a changelogentry, run `npm run changeset` and create a patch changeset. Never create minor or major version bumps. Skip changesets for trivial fixes, internal refactors, or minor UI tweaks that users wouldn't notice.
- When creating PRs, contributors should not create changelog-entry files. Maintainers handle release versioning and changelog curation during the release process.
- When adding new feature flags, see this PR as a reference https://github.com/cline/cline/pull/7566
- Additional instructions about making requests: @.clinerules/network.md
## Searching the Codebase — Avoiding Build Output
Several directories contain build output or generated code that produces
noisy or unusable results with `search_files` / `grep`:
| Directory | What it is | Why it's a problem |
|-----------|-----------|-------------------|
| `out/` | esbuild bundle output | Mirrors `src/` structure as minified JS — every search gets duplicate hits on single-line files |
| `dist/` | Packaged extension | Entire extension bundled into one minified `extension.js` (~1 long line) |
When adding a new provider (e.g., "openai-codex"), you must update the proto conversion layer in THREE places or the provider will silently reset to Anthropic:
1.`proto/cline/models.proto` - Add to the `ApiProvider` enum (e.g., `OPENAI_CODEX = 40;`)
2.`convertApiProviderToProto()` in `src/shared/proto-conversions/models/api-configuration-conversion.ts` - Add case mapping string to proto enum
3.`convertProtoToApiProvider()` in the same file - Add case mapping proto enum back to string
**Why this matters:** Without these, the provider string hits the `default` case and returns `ANTHROPIC`. The webview, provider list, and handler all work fine, but the state silently resets when it round-trips through proto serialization. No error is thrown.
**Other files to update when adding a provider:**
-`src/shared/api.ts` - Add to `ApiProvider` union type, define models
-`src/shared/providers/providers.json` - Add to provider list for dropdown
-`src/core/api/index.ts` - Register handler in `createHandlerForProvider()`
-`webview-ui/src/components/settings/utils/providerUtils.ts` - Add cases in `getModelsForProvider()` and `normalizeApiConfiguration()`
-`webview-ui/src/utils/validate.ts` - Add validation case
## Responses API Providers (OpenAI Codex, OpenAI Native)
Providers using OpenAI's Responses API require native tool calling. XML tools don't work with the Responses API.
**Symptoms of broken native tool calling:**
- Tools get called multiple times (e.g., `ask_followup_question` asks the same question twice)
- Tool arguments get duplicated or malformed
- The model responds but tools aren't recognized
**Root causes to check:**
1.**Provider missing from `isNextGenModelProvider()`** in `src/utils/model-utils.ts`. The native variant matchers (e.g., `native-gpt-5/config.ts`) call this function. If your provider isn't in the list, the matcher returns false and falls back to XML tools.
2.**Model missing `apiFormat: ApiFormat.OPENAI_RESPONSES`** in its model info (`src/shared/api.ts`). This property signals that the model requires native tool calling. The task runner in `src/core/task/index.ts` checks this and forces `enableNativeToolCalls: true` regardless of user settings.
**When adding a new Responses API provider:**
1. Add provider to `isNextGenModelProvider()` list in `src/utils/model-utils.ts`
2. Set `apiFormat: ApiFormat.OPENAI_RESPONSES` on all models that use the Responses API
3. The variant matcher and task runner will handle the rest automatically
## Adding Tools to System Prompt
This is tricky—multiple prompt variants and configs. **Always search for existing similar tools first and follow their pattern.** Look at the full chain from prompt definition → variant configs → handler → UI before implementing.
1.**Add to `ClineDefaultTool` enum** in `src/shared/tools.ts`
2.**Tool definition** in `src/core/prompts/system-prompt/tools/` (create file like `generate_explanation.ts`)
- Define variants for each `ModelFamily` (generic, next-gen, xs, etc.)
- **Fallback behavior**: If a variant isn't defined for a model family, `ClineToolSet.getToolByNameWithFallback()` automatically falls back to GENERIC. So you only need to export `[GENERIC]` unless the tool needs model-specific behavior.
3.**Register in `src/core/prompts/system-prompt/tools/init.ts`** - Import and spread into `allToolVariants`
4.**Add to variant configs** - Each model family has its own config in `src/core/prompts/system-prompt/variants/*/config.ts`. Add your tool's enum to the `.tools()` list:
**How overrides work:** Variants can override components via `componentOverrides` in their `config.ts`, or provide a custom template in `template.ts` (e.g., `next-gen/template.ts` exports `rules_template`). If no override, the shared component from `components/` is used.
**Example: Adding a rule to RULES section**
1. Check if variant overrides rules: look for `rules_template` in `variants/*/template.ts` or `componentOverrides.RULES` in `config.ts`
2. If shared: modify `components/rules.ts`
3. If overridden: modify that variant's template
4. XS variant is special—has heavily condensed inline content in `template.ts`
**After any changes, regenerate snapshots:**
```bash
UPDATE_SNAPSHOTS=true npm run test:unit
```
Snapshots live in `__tests__/__snapshots__/`. Tests validate across model families and context variations (browser, MCP, focus chain).
Adding a new key to global state requires updates in multiple places. Missing any step causes silent failures.
@@ -147,6 +103,17 @@ Required steps:
Common mistake: Adding only the return value without the `context.globalState.get()` call. This compiles but the value is always `undefined` on load.
Settings plumbing gotcha: if a key is user-toggleable from settings, wire both controller update paths:
- `src/core/controller/state/updateSettings.ts` for webview `updateSetting(...)`
- `src/core/controller/state/updateSettingsCli.ts` for CLI/ACP settings updates
Missing one path causes a toggle to appear to change in one surface while the backend state stays unchanged.
Webview toggle gotcha: settings changes must also round-trip back in state payloads.
- Add the field to `UpdateSettingsRequest` in `proto/cline/state.proto` (for webview update requests), then run `npm run protos`
- Include the key in `Controller.getStateToPostToWebview()` (`src/core/controller/index.ts`)
- Ensure `ExtensionState` and webview defaults include the key (`src/shared/ExtensionMessage.ts`, `webview-ui/src/context/ExtensionStateContext.tsx`)
If this round-trip wiring is missing, the backend value can update but the toggle in webview appears stuck or reverts.
## StateManager Cache vs Direct globalState Access
StateManager uses an in-memory cache populated during `StateManager.initialize(context)` in `common.ts`. For most state, use `controller.stateManager.setGlobalState()`/`getGlobalStateKey()`.
To ensure Cline works correctly in all environments (VSCode, JetBrains, CLI) and with various network configurations (especially corporate proxies), strictly follow these guidelines for all network activity.
In extension code, do NOT use the global `fetch` or a default `axios` instance. (Note, `shared/net.ts` is exempt from these rules because it sets up the fetch wrappers.) In Webview code, you SHOULD use global `fetch`.
Global `fetch` and default `axios` do not automatically pick up proxy configurations in all environments (specifically JetBrains and CLI). You MUST use the provided utilities in `@/shared/net` which handle proxy agent configuration. In the webview, the browser/embedder handles proxies.
## Guidelines
### 1. Using `fetch`
Instead of `fetch(...)`, import the proxy-aware wrapper:
Global settings, secrets and workspace state are stored in **file-backed JSON stores** under `~/.cline/data/`. This is the shared storage layer used by VSCode, CLI, and JetBrains.
In-memory cache on top of `StorageContext`. All runtime reads hit the cache; writes update cache immediately and debounce-flush to disk.
## ⚠️ Do NOT Use VSCode's ExtensionContext for Storage
**Do not** read from or write to `context.globalState`, `context.workspaceState`, or `context.secrets` for persistent data. These are VSCode-specific and not available on CLI or JetBrains.
Remember that your data may be read by a different client than the one that wrote it. For example, a value written by Cline in JetBrains may be read by Cline CLI.
On VSCode startup, a migration copies data from VSCode's `ExtensionContext` storage into the file-backed stores. This runs in `src/common.ts` before `StateManager.initialize()`.
- **Sentinel**: `__vscodeMigrationVersion` key in global state and workspace state — prevents re-migration.
- **Merge strategy**: File store wins. Existing values are never overwritten.
- **Safe downgrade**: VSCode storage is NOT cleared, so older extension versions still work.
## Adding New Storage Keys
1. Add to `src/shared/storage/state-keys.ts` (see existing patterns)
2. Read/write via `StateManager` (NOT via `context.globalState`)
3. If adding a secret, add to `SecretKeys` array in `state-keys.ts`
@@ -19,7 +19,7 @@ Review and address all comments on the current branch's PR.
- Inline comments: `gh api repos/{owner}/{repo}/pulls/{pr_number}/comments`
- General comments: `gh pr view {pr_number} --json comments,reviews`
4. Present a summary of all comments with your recommendation for each (apply, skip, or respond). Ignore bot noise (changeset-bot, CI status, etc.).
4. Present a summary of all comments with your recommendation for each (apply, skip, or respond). Ignore bot noise (release automation, CI status, etc.).
The goal of this workflow is to take a changeset for a release of Cline, an autonomous coding agent extension that plugs right into your IDE, and write the updated announcement component, and the updated changelog.
For reference, here are some examples of how we converted previous changesets to announcement components / changelogs.
- 3.14
<changeset>
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
claude-dev@3.14.0
Minor Changes
77c9863: create clinerules folder if its currently a file and creating new rule
0ffb7dd: disabling shift hint for now & improving tooltip behavior
79b76fd: Add support for custom model ID in AWS Bedrock provider, enabling use of Application Inference Profile.
eb6e481: Full support for LaTeX rendering
df37f29: Add support for custom API request timeout. Previously, timeouts were hardcoded to 30 seconds for providers like Ollama or 15 seconds for OpenRouter and Cline. Now users can set a custom timeout value in milliseconds through the settings interface.
e4d26be: allow cursorrules and windsurfrules
c5de50f: Fix Handle @withRetry() SyntaxError when running extension locally issue
61d2f42: enabled pricing calculation for gemini and vertex + more robust caching & cache tracking for gemini & vertex
aed152b: add truncation notice when truncating manually
2fe2405: Migrate Cline Tools Section to new docs
19cc8bc: Add a timeout setting for the terminal connection, allowing users to adjust this if they are having timeout issues
03d4410: Added copy button to code blocks.
c78fe23: addressed race condition in terminal command usage
91e222f: add checkpoints after more messages
14230e7: add newrule slash command
1c7d33a: Add remote config with posthog allowing for disabling new features until they're reading, making for a better developer experience.
4196c14: add cache ui for open router and cline provider
d97424f: showing expanded task by default
5294e78: Refactor to not pass a message for showing the MCP View from the servers modal
70cc437: Fix Windows path issue: Correct handling of import.meta.url to avoid leading slash in pathname
4b697d8: Migrate the addRemoteServer to protobus
Patch Changes
c63d9a1: updated drag and drop text to say "drop" instead of "drag"
459adf0: Add markdown copy to chat
74ec823: Minor UX improvement to drag and drop ux
b0961f4: Remove linear pull request action
e9ce384: searchCommits protobus migration
5802b68: createRuleFile protobus migration
df7f9fc: Add dependsOn to more blocks in the tasks.json
41ae732: Fix for git commit mentions in repos with no git commits
7e78445: Adding args to allow Cursor to open workspaces (for checkpoint testing/development)
bdfda6f: feat(bedrock): Introduce Amazon Nova Premier
65243ad: Introduce UI library for future UI development
4565e06: checkIsImageURL migrated to protobus
5a8e9d8: protobus migration for openImage
deeda6e: Lowering Gemini cache TTL time
db0b022: Adding UI to show openrouter balance next to provider
4650ffa: deleteRuleFile protobus migration
d4bd755: fix cost calculation
</changeset>
<changelog>
## [3.14.0]
- Add UI to show openrouter balance next to provider
- Add support for custom model ID in AWS Bedrock provider, enabling use of Application Inference Profile (Thanks @clicube!)
- Add more robust caching & cache tracking for gemini & vertex providers
- Add support for LaTeX rendering
- Add support for custom API request timeout. Timeouts were 15-30s, but can now be configured via settings for OpenRouter/Cline & Ollama (Thanks @WingsDrafterwork!)
- Add truncation notice when truncating manually
- Add a timeout setting for the terminal connection, allowing users to set a time to wait for terminal startup
- Add copy button to code blocks
- Add copy button to markdown blocks (Thanks @weshoke!)
- Add checkpoints to more messages
- Add slash command to create a new rules file (/newrule)
- Add cache ui for open router and cline provider
- Add Amazon Nova Premier model to Bedrock (Thanks @watany!)
- Add support for cursorrules and windsurfrules
- Add support for batch history deletion (Thanks @danix800!)
- Improve Drag & Drop experience
- Create clinerules folder creating new rule if it's needed
- Enable pricing calculation for gemini and vertex providers
- Refactor message handling to not show the MCP View of the server modal
- Migrate the addRemoteServer to protobus (Thanks @DaveFres!)
- Update task header to be expanded by default
- Update Gemini cache TTL time to 15 minutes
- Fix race condition in terminal command usage
- Fix to correctly handle `import.meta.url`, avoiding leading slash in pathname for Windows (Thanks @DaveFres!)
2964388: Added copy button to MermaidBlock component
75143a7: Add the ability to fetch from global cline rules files
Patch Changes
a0252e7: convert inline style to tailwind css of file SettingsView.tsx
ab59bd9: Add stream options back to xai provider
7276f50: Icons to indicate an action is occuring outside of the users workspace
0b19ba6: update to NEW model
</changeset>
<changelog>
## [3.13.0]
- Add Cline rules popover under the chat field, allowing you to easily add, enable & disable workspace level or global rule files
- Add new slash command menu letting you type “/“ to do quick actions like creating new tasks
- Add ability to edit past messages, with options to restore your workspace back to that point
- Allow sending a message when selecting an option provided by the question or plan tool
- Add command to jump to Cline's chat input
- Add support for OpenAI o3 & 4o-mini (Thanks @PeterDaveHello and @arafatkatze!)
- Add baseURL option for Google Gemini provider (Thanks @owengo and @olivierhub!)
- Add support for Azure's DeepSeek model. (Thanks @yt3trees!)
- Add ability for models that support it to receive image responses from MCP servers (Thanks @rikaaa0928!)
- Improve search and replace diff editing by making it more flexible with models that fail to follow structured output instructions. (Thanks @chi-cat!)
- Add detection of Ctrl+C termination in terminal, improving output reading issues
- Fix issue where some commands with large output would cause UI to freeze
We have a changeset PR that automatically generated as new unreleased PRs are merged into main, the PR is always called "Changeset version bump" and the author is github-actions.
The Changeset PR description looks something like this:
<changeset-pr-description>
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing). If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
# Releases
## claude-dev@3.16.0
### Minor Changes
- c6e8b04: Recent task list is now collapsible, allowing users to hide their recent tasks (e.g. when sharing their screen).
- aabe4ae: Add detection for new users to display special components
- 6c18d51: adds global endpoint for vertex ai users
- 080ed7c: Add Tailwind CSS IntelliSense to the the recommended extensions list
- 5147e28: new workflow feature
### Patch Changes
- c0b3c69: fix eternal loading states when the last message is a checkpoint
- 570ece3: selectImages protos migration
- 8d8452e: askResponse protobus migration
- cd1ff2a: Finishing the migration of Vscode Advanced settings to Settings Webview
</changeset-pr-description>
The changeset pr is ALWAYS on the following branch: `changeset-release/main`.
I have the `gh` command line tool set up and authenticated, so you have everything you need.
The first step is to get the full diff from the changeset PR to look at the changes that were automatically made to the `CHANGELOG.md` file. By default it will automatically add a new section to the changelog.md file with the new version. The problem with the automatically generated section is that it just takes the text that the developers threw into their changeset files for each corresponding PR, and they can be pretty vague and bad. Additionally there's some stuff that is totally irrelevant for the end user, like minor refactoring changes. So I manually typically go in and update this section to be a proper changelog that will show up in our patchnotes. You can look at how the rest of the file is done because those are all good examples of us updating this to use good language for the end user. We usually put new features up top (and the most exciting flagship features at the very top), and then bug fixes/improvements at the bottom. Having some basic organization to the ordering of the bullet points by content is nice. But use common sense.
To handle this process effectively, do the following:
For each of the automatically generated bullet points in the Changelog.md, you should
1. Take the commit hash at the start of the bullet point, and use the `gh` command line tool find the PR that it was associated with.
2. Use the `gh` command to get the PR title/description/discussion to understand the context surrounding the PR.
3. Use the `gh` command line tool to get the full PR diff to fully understand the changes made in the code.
4. Synthesize that knowledge to determine (a) whether or not this change is relevant to end users and (b) what the text & ordering of the line should be.
5. Update the `CHANGELOG.md` accordingly
Do this for every single item in the list from the autogenerated bullet points. We want to be diligent and have a full understanding of every feature so we can make the best changelog ever!
Here are some principles for good changelogs from keepchangelog.com, a handy guide:
<keepachangelog-pinciples-for-good-changelogs>
### Guiding Principles
- Changelogs are for humans, not machines.
- There should be an entry for every single version.
- The same types of changes should be grouped.
- The latest version comes first.
### Bullet points in the changelog should follow these principles:
- Types of changes
- Added for new features.
- Changed for changes in existing functionality.
- Deprecated for soon-to-be removed features.
- Removed for now removed features.
- Fixed for any bug fixes.
- Security in case of vulnerabilities.
</keepachangelog-pinciples-for-good-changelogs>
Lastly, when developers make a PR, they typically make a changeset. And they have 3 options when making the changeset:
1. Patch
2. Minor
3. Major
Sometimes they label something as minor when really it should just be a patch. Or vice versa. Because of this, the automatic version bump may be incorrect. So when starting out this workflow, you should use the <ask_followup_question> tool to confirm with me whether or not this should be a patch bump (show the old version number and what the proposed new version number would be) or a minor bump. Part of the release process is making sure the version in package.json that is automatically changed actually corresponds with what we decided the bump should actually be based on the features. ALL these modifications happen in the `changeset-release/main` branch btw.
<important_note>
Before doing any of this, make sure you check out the `changeset-release/main` and pull the most recent up to date changes. Then perform all this work in that branch.
New announcement banners should ONLY be made for minor version bumps or higher. That's another reason why double checking if the changelog warrants the bump is important.
Also, SUPER important: For any external contributors that aren't part of the cline github organization, we always want to add a (Thanks @username!) at the end of the changelog to attribute them properly. We're an open source project and it's ethical to do this.
</important_note>
Once the changelog looks good, and the version number looks good, we gotta double check that the version number in the changelog has the brackets around it. And as a final step, double check the package.json version number matches the latest number in the changelog. And as the ultimate final step we run `npm run install:all` to make sure the package version number permiates through the lock file.
<detailed_sequence_of_steps>
# Cline Release Process - Detailed Sequence of Steps
## Before Starting
1. First, examine the changeset PR without checking it out:
```bash
gh pr view changeset-release/main
```
2. View the PR diff to see the auto-generated CHANGELOG.md changes:
# Check if user is a member of the Cline organization
# this command is a bit finnicky, but it 100% works.
# if you see a `Error executing command: The command ran successfully, but we couldn't capture its output. Please proceed accordingly.` error, just retry it until you actually get the output
# don't make any assumptions, just retry the command to actually get the output and determine if they're external or not.
# no output means they are an external contributor, otherwise if there is output they are an internal contributor (part of our github org)
gh api "orgs/cline/members" --jq "map(.login)" | grep -i "pashpashpash"
```
d. View the full PR diff to understand code changes:
```bash
gh pr diff <PR-number> > pr-diff-<PR-number>.txt
cat pr-diff-<PR-number>.txt
```
## Updating the Changelog
5. Based on PR analysis, update the CHANGELOG.md with user-friendly descriptions:
- Use the `<replace_in_file>` tool to edit the CHANGELOG.md file
- Group by feature type (Added, Changed, Fixed)
- Put most exciting features at the top
- Move bug fixes and small improvements to the bottom
- Use clear, end-user focused language
- For external contributors, add attribution at the end of the relevant entry: `(Thanks @username!)`
## Version Number Verification
6. Confirm the version bump is appropriate:
- Check package.json to verify the auto-generated version number:
```bash
cat package.json | grep "\"version\""
```
- If the feature set doesn't warrant a minor bump, use the `<replace_in_file>` tool to modify package.json
7. Ensure the version in CHANGELOG.md has brackets around it:
```
## [3.16.0]
```
## Creating the Announcement (for minor/major versions only)
8. If this is a minor version bump, create/update the announcement component:
- Use the `<replace_in_file>` tool to edit the src/views/components/announcement.tsx file
- Update the highlights based on key features
- Move previous version highlights to the "Previous Updates" section
- Use the previous announcement components as reference for structure
## Finalizing the Release
9. Update dependencies with the new version number:
@@ -89,16 +89,9 @@ On the main branch, create a commit that updates:
2. **package.json** - Update the version field to the new version
3. **Delete changesets** for the commits being included in the hotfix. This prevents the changeset bot from including duplicate entries in the next regular release.
3. No changelog-entry file cleanup is needed. Contributors do not create changelog-entry files in this repo.
Find and delete the changeset files associated with the selected commits:
```bash
ls .changeset/
```
Each changeset file in `.changeset/` corresponds to a PR. Read them to identify which ones belong to the commits you're hotfixing, then delete those files.
**Skip running `npm run install:all`** - the automation handles outdated lockfiles.
**Skip running `npm run install:all`** - release automation handles lockfile consistency as needed.
Commit with message format: `v{VERSION} Release Notes (hotfix)`
@@ -107,7 +100,7 @@ In the commit body, mention:
- List the cherry-picked commits that will be included
So until the settings page is update, and this is added to settings in a way that's clean and doesn't confuse new users, I don't think we can merge this. Please bear with us.
</request_changes_comment>
<request_changes_comment>
Also, don't forget to add a changeset since this fixes a user-facing bug.
The architectural change is solid - moving the focus logic to the command handlers makes sense. Just don't want to introduce subtle timing issues by removing those timeouts.
- Adding enums (e.g. `ClineSay`) → also update `src/shared/proto-conversions/cline-message.ts`.
## Adding API Providers (silent failure risk)
Three proto conversion updates are **required** or the provider silently resets to Anthropic:
1.`proto/cline/models.proto` — add to `ApiProvider` enum.
2.`convertApiProviderToProto()` in `src/shared/proto-conversions/models/api-configuration-conversion.ts`.
3.`convertProtoToApiProvider()` in the same file.
Also update: `src/shared/api.ts`, `src/shared/providers/providers.json`, `src/core/api/index.ts`, `webview-ui/.../providerUtils.ts`, `webview-ui/.../validate.ts`, `webview-ui/.../ApiOptions.tsx`, and `cli/src/components/ModelPicker.tsx`.
For Responses API providers: add to `isNextGenModelProvider()` in `src/utils/model-utils.ts` and set `apiFormat: ApiFormat.OPENAI_RESPONSES` on models.
## Adding Tools to System Prompt (5+ file chain)
1. Add enum to `ClineDefaultTool` in `src/shared/tools.ts`.
2. Create definition in `src/core/prompts/system-prompt/tools/` (export `[GENERIC]` minimum).
3. Register in `src/core/prompts/system-prompt/tools/init.ts`.
4. Whitelist in `src/core/prompts/system-prompt/variants/*/config.ts` for each model family.
5. Handler in `src/core/task/tools/handlers/`, wire in `ToolExecutor.ts`.
6. If tool has UI: add `ClineSay` enum in proto → `ExtensionMessage.ts` → `cline-message.ts` → `ChatRow.tsx`.
7. Regenerate snapshots: `UPDATE_SNAPSHOTS=true npm run test:unit`.
## Modifying System Prompt
Modular: `components/` (shared) + `variants/` (model-specific) + `templates/` (`{{PLACEHOLDER}}`). Variants override components via `componentOverrides` in `config.ts` or custom `template.ts`. XS variant is heavily condensed inline. Always regenerate snapshots after changes.
## Global State Keys (silent failure risk)
Adding a key requires: type in `src/shared/storage/state-keys.ts`, read via `context.globalState.get()` in `src/core/storage/utils/state-helpers.ts``readGlobalStateFromDisk()`, and add to return object. Missing the `.get()` call compiles fine but value is always `undefined`.
Search thoroughly for existing issues that match this one:
gh issue list --search "<keywords from the issue>" --state all --limit 30
gh issue list --search "<error messages>" --state all --limit 20
gh issue list --search "<affected feature/component>" --state all --limit 20
For each relevant issue you find, read it including its comments:
gh issue view <number> --comments
You're looking for:
- **Duplicates**: Issues describing the same problem. Link to them and explain why you think they're duplicates. If closed, check how they were resolved - the solution might apply here.
- **Related issues**: Similar problems or context that could help. Pull useful information from their comments (workarounds others found, debugging steps that helped, maintainer explanations). Link to them and explain the connection.
If there are closed issues with solutions, surface those solutions prominently - this might immediately solve the user's problem.
### Analyze recent changes (ALWAYS DO THIS)
Many issues are regressions from recent releases. **Always** check what changed recently:
gh release list --limit 10
gh pr list --state merged --limit 50 --json number,title,mergedAt,author,body
Look for PRs merged in the last few weeks that might correlate with the issue. If you find a likely connection:
- If you find a regression, call it out explicitly: which PR/commit likely caused it, who authored it, what changed, and suggest a fix direction if you can see one.
- If you don't find anything related, still mention it: "I analyzed recent PRs and releases but didn't find any changes that seem related to this issue."
### Search the codebase
Find the relevant code:
- Use grep/find to locate code related to the issue
- Key areas: `src/api/` (providers/models), `src/core/prompts/` (tools/prompts), platform-specific code for VS Code vs JetBrains
### Find documentation
Cline docs are at **https://docs.cline.bot/** and built with Mintlify from the `docs/` directory.
The URL structure maps directly to the file structure:
Cross-reference with GitHub usernames. Include in your response (@mention, do NOT assign):
| SME | Reason |
|-----|--------|
| @username1 | Authored PR #X which modified this area |
| @username2 | Primary contributor to affected file |
## Weak model detection
Many issues are caused by users running small or non-frontier models that don't tool-call reliably. Signs include:
- Model failing to use tools correctly
- Nonsensical or malformed responses
- User is running a small/local model or older model version
If this looks like a weak model issue, kindly suggest they try reproducing with Claude Sonnet and report back if it persists. Link to https://docs.cline.bot/getting-started/selecting-your-model if helpful. Still label and triage normally.
## Your comment
Write a single comment as a helpful community member. Be conversational, not robotic. Include what's relevant:
- **Helpful response** - Answer their question, suggest a fix, provide a workaround. If you found solutions in related closed issues, surface those prominently.
- **Duplicates and related issues** - Link to any you found and explain why they're duplicates/related. Summarize useful context from their comments.
- **Regression analysis** - If this looks like a regression, explain what change likely caused it, link to the PR/commit, and tag the author.
- **Clarifying questions** - If you need more info, ask specific questions. Don't ask for things already provided.
- **SME table** - Include the table above if this needs engineering attention. Don't tag people for questions with obvious answers or weak-model issues.
- **Context for maintainers** - Relevant code paths, what you found. Keep it concise.
- **Docs links** - If there's relevant documentation, link to it naturally in your response as a recommendation (e.g., "For more details, check out [the Ollama setup guide](url)"). Do NOT add a "Sources" section at the end - integrate doc links into your response where they're helpful.
- **Possible Duplicates section** - ALWAYS include a "Possible Duplicates" section at the end of your comment listing issues that might be duplicates so maintainers can quickly close if appropriate. If none found, say "No obvious duplicates found."
## Labels
First, retrieve all available labels and read their descriptions to understand what each is for:
gh label list --json name,description --limit 100
Then apply the appropriate labels based on your analysis. Only use labels from the list above—do not create new labels.
- **This is a one-time automated response** - you will NOT see their reply or respond again. Never say things like "I can help you", "let me know", "once I have that info", or "I can give you more targeted help" - you won't be there to follow up. If you ask clarifying questions, frame them for the maintainers who will follow up, e.g., "If you can share X, that would help the maintainers diagnose this."
- Don't be formulaic. Respond to what the issue actually needs.
- Surface solutions from past issues - often the fastest path to helping.
- Connecting regressions to specific changes is extremely valuable.
You're a GitHub PR reviewer for the open source Cline repository. Your goal is to give the PR author helpful feedback and give maintainers the context they need to review efficiently.
Cross-reference git authors with GitHub usernames. Include an SME table in your response:
| SME | Reason |
|-----|--------|
| @username1 | Authored PR #X which modified this area |
| @username2 | Primary contributor to affected file (15 commits in 6 months) |
| @username3 | Reviewed similar PR #Y with extensive feedback |
## Deep code review
This is the most important part. Don't just look for syntax issues - understand what the PR is trying to achieve and whether the implementation is the right approach.
Step 1: Understand the intent
Read the PR description and understand what the author is trying to accomplish. What problem are they solving? What feature are they adding?
Step 2: Form your own opinion first
Before analyzing their code, think about how YOU would implement this feature or fix. What files would you touch? What patterns would you follow? What edge cases would you handle?
Step 3: Compare approaches
Now look at their implementation. How does it compare to what you would have done?
- Is their approach better in some ways? Note what they did well.
- Is their approach missing something? Be specific about what and why.
- Are there edge cases they haven't considered?
- Does it follow the patterns established in similar parts of the codebase?
Step 4: Look at the bigger picture
- What other files or systems does this change interact with?
- Could this break anything else?
- Is there additional work needed beyond this PR to complete the feature?
- Does this fit well with the overall architecture?
Step 5: Find reference implementations
Look for similar changes in the codebase:
```bash
git log --oneline --all --grep="<relevant keywords>" | head -20
git log --oneline -- <similar files> | head -20
```
If this is adding a new API provider, look at how other providers are implemented.
If this is adding a new feature, look at how similar features were added.
Note where their implementation aligns with or diverges from established patterns.
Step 6: Standard code review checks
- DRY: Is there duplicated code that could be extracted?
- Error handling: Are errors handled appropriately?
- Security: Any injection risks, credential exposure, unsafe dependencies?
- Performance: Any obvious inefficiencies, memory leaks, N+1 patterns?
- Types: Is TypeScript used correctly? Any unsafe type assertions?
- Naming: Are variables and functions named clearly?
- Comments: Is complex logic explained? Are there outdated comments?
## Inline code suggestions
For specific code improvements, use GitHub's suggestion syntax via `gh api`.
This creates suggestions the author can commit with one click.
Single-line suggestion:
```bash
gh api repos/${{ github.repository }}/pulls/${{ steps.pr.outputs.number }}/reviews \
"body": "This can be simplified:\n\n```suggestion\nconst simplified = doThing();\n```"
}
]'
```
Use inline suggestions for concrete improvements. Use regular comments for questions or broader feedback.
## Post your review
After your investigation, post a single helpful comment that helps the author and gives maintainers context.
Start by noting the commit hash you reviewed:
```bash
git rev-parse --short HEAD
```
Include this at the top of your comment: "Reviewed at commit: <short hash>"
Then thank them for their contribution. Be conversational, not robotic.
Include what's relevant:
- In-depth explanation of what the PR does - Be comprehensive. A maintainer should be able to read this section and fully understand the author's intent, why they made the changes, how they implemented it, and what files/systems are affected. Don't just summarize - explain.
- Related issues/PRs you found that provide useful context (link to them)
- Your review findings (issues to address, suggestions, etc.)
- Clear next steps for the author
Include a "For Maintainers" section with:
- Anything else useful to help the maintainer resolve this PR
- Related issues/PRs with context on why they're relevant
- Open issues this PR might fix that weren't linked in the description
- Your recommendation: merge as-is, needs changes, needs discussion, close, etc.
- SME table - who should review this and why
For the SME table:
| SME | Reason |
|-----|--------|
| @username | Primary contributor to affected files |
- This is a one-time automated response - you will NOT see their reply or respond again. Never say things like "let me know if you have questions", "I can help you with", or "feel free to ask" - you won't be there to follow up. Frame any questions for the maintainers who will follow up.
- Be helpful and welcoming - Many contributors are new to the project
- Be specific - Point to exact lines and suggest fixes, don't give vague feedback
- Think deeply - Don't just surface-level review, understand the intent and evaluate the approach
- Use inline suggestions - Make it easy for authors to accept changes
- You're a first-pass reviewer - A human maintainer will do final approval
echo "(no test output captured — process may have been killed before output was flushed)" >> $GITHUB_STEP_SUMMARY
fi
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Debugging" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **TUI traces** are attached as artifacts below — download and inspect them to see terminal state at the point of failure." >> $GITHUB_STEP_SUMMARY
echo "- **To view a trace replay/Run a TUI Trace: ** run \`npx tui-test show-trace path/to/trace/file\` in your terminal" >> $GITHUB_STEP_SUMMARY
echo "- **Full test log** is also attached as an artifact." >> $GITHUB_STEP_SUMMARY
echo "- Tests run with \`retries: 2\` so any failure shown is a consistent failure, not a flake." >> $GITHUB_STEP_SUMMARY
"gh api repos/${{ github.repository }}/pulls/${{ steps.pr.outputs.number }}/comments *",
"gh api repos/${{ github.repository }}/pulls/${{ steps.pr.outputs.number }}/reviews *"
]
}
run:|
npx cline --yolo 'You'\''re a GitHub PR reviewer for the open source Cline repository. Your goal is to give the PR author helpful feedback and give maintainers the context they need to review efficiently.
Cross-reference git authors with GitHub usernames. Include an SME table in your response:
| SME | Reason |
|-----|--------|
| @username1 | Authored PR #X which modified this area |
| @username2 | Primary contributor to affected file (15 commits in 6 months) |
| @username3 | Reviewed similar PR #Y with extensive feedback |
## Bash command usage
Don'\''t use operators like `|`, `&&`, or `;` - run each command separately and analyze the output.
When referencing command outputs, quote them properly to avoid formatting issues.
## Deep code review
This is the most important part. Don'\''t just look for syntax issues - understand what the PR is trying to achieve and whether the implementation is the right approach.
Step 1: Understand the intent
Read the PR description and understand what the author is trying to accomplish. What problem are they solving? What feature are they adding?
Step 2: Form your own opinion first
Before analyzing their code, think about how YOU would implement this feature or fix. What files would you touch? What patterns would you follow? What edge cases would you handle?
Step 3: Compare approaches
Now look at their implementation. How does it compare to what you would have done?
- Is their approach better in some ways? Note what they did well.
- Is their approach missing something? Be specific about what and why.
- Are there edge cases they haven'\''t considered?
- Does it follow the patterns established in similar parts of the codebase?
Step 4: Look at the bigger picture
- What other files or systems does this change interact with?
- Could this break anything else?
- Is there additional work needed beyond this PR to complete the feature?
- Does this fit well with the overall architecture?
Step 5: Find reference implementations
Look for similar changes in the codebase:
```bash
git log --oneline --all --grep='\''<relevant keywords>'\'' | head -20
git log --oneline -- <similar files> | head -20
```
If this is adding a new API provider, look at how other providers are implemented.
If this is adding a new feature, look at how similar features were added.
Note where their implementation aligns with or diverges from established patterns.
Step 6: Standard code review checks
- DRY: Is there duplicated code that could be extracted?
- Error handling: Are errors handled appropriately?
- Security: Any injection risks, credential exposure, unsafe dependencies?
- Performance: Any obvious inefficiencies, memory leaks, N+1 patterns?
- Types: Is TypeScript used correctly? Any unsafe type assertions?
- Naming: Are variables and functions named clearly?
- Comments: Is complex logic explained? Are there outdated comments?
## Inline code suggestions
For specific code improvements, use GitHub'\''s suggestion syntax via `gh api`.
This creates suggestions the author can commit with one click.
Single-line suggestion:
```bash
gh api repos/'"${GITHUB_REPO}"'/pulls/'"${PR_NUMBER}"'/reviews \
"body": "This can be simplified:\n\n```suggestion\nconst simplified = doThing();\n```"
}
]'\''
```
Use inline suggestions for concrete improvements. Use regular comments for questions or broader feedback.
## Post your review
After your investigation, post a single helpful comment that helps the author and gives maintainers context.
Start by noting the commit hash you reviewed:
```bash
git rev-parse --short HEAD
```
Include this at the top of your comment: "Reviewed at commit: <short hash>"
Then thank them for their contribution. Be conversational, not robotic.
Include what'\''s relevant:
- In-depth explanation of what the PR does - Be comprehensive. A maintainer should be able to read this section and fully understand the author'\''s intent, why they made the changes, how they implemented it, and what files/systems are affected. Don'\''t just summarize - explain.
- Related issues/PRs you found that provide useful context (link to them)
- Your review findings (issues to address, suggestions, etc.)
- Clear next steps for the author
Include a '\''For Maintainers'\'' section with:
- Anything else useful to help the maintainer resolve this PR
- Related issues/PRs with context on why they'\''re relevant
- Open issues this PR might fix that weren'\''t linked in the description
- Your recommendation: merge as-is, needs changes, needs discussion, close, etc.
- SME table - who should review this and why
For the SME table:
| SME | Reason |
|-----|--------|
| @username | Primary contributor to affected files |
- This is a one-time automated response - you will NOT see their reply or respond again. Never say things like '\''let me know if you have questions'\'', '\''I can help you with'\'', or '\''feel free to ask'\'' - you won'\''t be there to follow up. Frame any questions for the maintainers who will follow up.
- Be helpful and welcoming - Many contributors are new to the project
- Be specific - Point to exact lines and suggest fixes, don'\''t give vague feedback
- Think deeply - Don'\''t just surface-level review, understand the intent and evaluate the approach
- Use inline suggestions - Make it easy for authors to accept changes
- You'\''re a first-pass reviewer - A human maintainer will do final approval'
# Ignore all webview-ui files except the build directory (https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/frameworks/hello-world-react-cra/.vscodeignore)
- Restore VS Code foreground terminal support and settings.
- Add latest OpenAI, SAP AI Core, and Z AI models.
### Fixed
- Fix hook template JSON escaping.
- Improve ripgrep file search error handling.
### Changed
- Remove hardcoded model lists from docs.
## [3.81.0]
### Added
- Add GPT-5.5 model support for OpenAI Codex subscription users.
### Fixed
- Remove hardcoded "What’s New" fallback items in webview; only remote-configured welcome banners are shown.
### Changed
- Improve cline-core memory diagnostics used by the extension runtime:
- enable near-heap-limit heap snapshots
- add periodic memory usage logging
- log discovered heap snapshots on abnormal exits for easier OOM debugging
## [3.80.0]
### Added
- Wire up remote `globalSkills` from enterprise remote config with full UI, toggle support, and system prompt integration — enterprise-managed skills now appear under a dedicated "Enterprise Skills" section and support `alwaysEnabled` enforcement
- Onboarding flow now uses dynamically fetched recommended models instead of a hardcoded list, with a fallback to the welcome view on failure
- Add dedicated "Quota Exceeded" error message in the chat error UI when Cline account spend caps are hit
### Fixed
- Fix OOM crashes during long conversations by setting `--max-old-space-size=8192` for the cline-core Node.js process (was defaulting to ~2 GB)
- Show detailed error information in the chat error row instead of a generic caught error message
- Update `axios` to 1.15.0 across all packages
### Changed
- Remove foreground terminal mode — all task command execution now defaults to background mode, removing the VS Code integrated terminal dependency and related settings UI
- Remove old hardcoded announcement banners
## [3.79.0]
### Added
- Add Claude Opus 4.7 model support
- Add Azure Blob Storage as a storage provider
- Add `globalSkills` to remote config
- Inline value reuse in user-level remote-config discovery
### Fixed
- Fix cache reflection for Cline and Vercel API handlers
- Fix stuck `command_output` ask when terminal command ends unexpectedly
- Add `use_subagents` to system prompt for GLM, Hermes, and XS models
- Fix action injection security risk
### Changed
- Remove deprecated evals tool
## [3.78.0]
### Added
- Add a dedicated "Spend Limit Reached" error UI when spend caps are hit
- Docs updates
### Fixed
- Show actual `read_file` line ranges in chat UI
## [3.77.0]
### Added
- Add "Lazy Teammate Mode" experimental toggle
-`read_file` tool now supports chunked reading for targeted file access
### Fixed
- Exclude `new_task` tool from system prompt in yolo/headless mode
- Fix Kanban demo video formatting
### Changed
- Polish `Notification` hook functionality
## [3.76.0]
### Added
- Add Cline Kanban launch modal in webview; CLI now launches Kanban by default with a migration view
- Fix build complete handlers when updating the api config
- Fixed missing provider from list
- Fixed Favorite Icon / Star from getting clipped in the task history view
### Changed
- Make skills always enabled and remove feature toggle setting
## [3.56.0]
### Added
-__CLI authentication:__ Added Vercel AI Gateway and Cline API key provider support for headless CI/automation workflows
-__New model:__ Added Kimi-K2.5 model to Moonshot provider (262K context, image support, prompt caching)
-__Prompt variant:__ Added Trinity Large prompt variant for improved tool-calling support
-__OpenTelemetry:__ Added support for custom headers on metrics and logs endpoints
-__Social links:__ Added community icons (X, Discord, GitHub, Reddit, LinkedIn) to the What's New modal
-**CLI authentication:** Added Vercel AI Gateway and Cline API key provider support for headless CI/automation workflows
-**New model:** Added Kimi-K2.5 model to Moonshot provider (262K context, image support, prompt caching)
-**Prompt variant:** Added Trinity Large prompt variant for improved tool-calling support
-**OpenTelemetry:** Added support for custom headers on metrics and logs endpoints
-**Social links:** Added community icons (X, Discord, GitHub, Reddit, LinkedIn) to the What's New modal
### Fixed
-__LiteLLM:__ Fixed thinking configuration not appearing for reasoning-capable models
-__OpenTelemetry:__ Fixed endpoint path handling (no longer incorrectly appends `/v1/logs` or `/v1/metrics`) and ensured logs are sent regardless of VSCode telemetry settings
-__CLI auth:__ Fixed `cline auth` displaying incorrect provider information after configuration
-**LiteLLM:** Fixed thinking configuration not appearing for reasoning-capable models
-**OpenTelemetry:** Fixed endpoint path handling (no longer incorrectly appends `/v1/logs` or `/v1/metrics`) and ensured logs are sent regardless of VSCode telemetry settings
-**CLI auth:** Fixed `cline auth` displaying incorrect provider information after configuration
### Changed
-__Hooks:__ Hook scripts now run from the workspace repository root instead of filesystem root
-__Default settings:__ Enabled multi-root workspaces, parallel tool calling, and skills by default; disabled strict plan mode by default
-__Settings UI:__ Refreshed feature settings section with collapsible design
-**Hooks:** Hook scripts now run from the workspace repository root instead of filesystem root
-**Default settings:** Enabled multi-root workspaces, parallel tool calling, and skills by default; disabled strict plan mode by default
-**Settings UI:** Refreshed feature settings section with collapsible design
We actively patch only the most recent minor release of Cline. Older versions receive fixes at our discretion.
## Reporting a Vulnerability
We appreciate your efforts to responsibly disclose your findings and will make every effort to acknowledge your contributions.
To report a security issue, please submit your report through our [Bugcrowd Vulnerability Disclosure Program](https://bugcrowd.com/engagements/clinebot-vdp-ess). Bugcrowd will manage communication and triage on our behalf.
When reporting, please include:
- A short summary of the issue
- Steps to reproduce or a proof of concept
- Any logs, stack traces, or screenshots that might help us understand the problem
Please keep the details private until a resolution has been reached.
## Escalation
If you are unable to submit through Bugcrowd, you may send an email to security@cline.bot.
- Restore foreground terminal support and settings.
- Add latest OpenAI, SAP AI Core, and Z AI models.
### Fixed
- Fix hook template JSON escaping.
- Improve ripgrep file search error handling.
### Changed
- Remove hardcoded model lists from docs.
## [2.17.0]
### Added
- Add GPT-5.5 model support for OpenAI Codex subscription users.
### Changed
- Improve `cline-core` runtime memory diagnostics used by CLI:
- enable near-heap-limit heap snapshots
- add periodic memory usage logging
- log discovered heap snapshots on abnormal exits for easier OOM debugging
## [2.16.0]
### Added
- Wire up remote `globalSkills` from enterprise remote config with full toggle support and system prompt integration — enterprise-managed skills now support `alwaysEnabled` enforcement
- Add dedicated "Quota Exceeded" error message when Cline account spend caps are hit
### Fixed
- Fix OOM crashes during long conversations by setting `--max-old-space-size=8192` for the cline-core Node.js process (was defaulting to ~2 GB)
- Show detailed error information instead of a generic caught error message
- Update `axios` to 1.15.0 across all packages
### Changed
- Remove dead ACP terminal setter stubs as part of foreground terminal mode removal
## [2.15.0]
### Added
- Add Claude Opus 4.7 model support
- Inline value reuse in user-level remote-config discovery
- Add `globalSkills` to remote config
### Fixed
- Stabilize Windows CI test path handling
## [2.14.0]
### Added
- Simplify unified `cline update` flow for `cline` and `kanban`
- Docs updates
### Fixed
- Update Kanban migration view copy
## [2.12.0]
### Added
-`read_file` tool now supports chunked reading for targeted file access
### Fixed
- Exclude `new_task` tool from system prompt in yolo/headless mode
### Changed
- Polish `Notification` hook functionality
## [2.9.0]
### Added
- Latency improvements for remote workspaces
## [2.8.2]
### Fixed
- Use `kanban@latest` in `cline kanban` to always fetch the newest version
## [2.8.1]
### Added
- Implement dynamic free model detection for Cline API
- Add file read deduplication cache to prevent repeated reads
- Add feature tips tooltip during thinking state
### Fixed
- Fix flaky CLI Enter-key handling across Windows/test environments
- Replace error message when not logged in to Cline
- Align ClineRulesToggleModal padding with ServersToggleModal
- Skip WebP for GLM and Devstral models running through llama.cpp
- Respect user-configured context window in LiteLLM getModel()
- Honor explicit model IDs outside static catalog in W&B provider
- Add missing Fireworks serverless models and pricing
## [2.8.0]
### Added
- Added W&B Inference by CoreWeave as a new API provider with 17 models including DeepSeek-V3.1, Llama 4, and Qwen3-Coder
- Added CLI TUI end-to-end test suite
### Fixed
- Claude Code: handle rate limit events, empty content arrays, error results, and unknown content types without crashing
- CLI: `/q` and `/exit` slash commands now execute immediately on Enter without requiring the slash menu to be visible
- CLI: slash command filtering now prioritizes exact and prefix matches over fuzzy matches
## [2.7.0]
### Added
- Added MCP add shortcuts for stdio and HTTP servers
- Added `--continue` for the current directory
- Added `--auto-condense` flag for AI-powered context compaction
- Added `--hooks-dir` flag for runtime hook injection
- Enabled error autocapture
- Prompt rules now include test verification guidance and make `CLI_RULES` language-agnostic
### Fixed
- Fixed remount behavior so TUI remounts only on width resize
- Fixed startup prompt replay on resize remount
- Fixed task flags so they are applied before the welcome TUI mounts
### Changed
- Hooks: reintroduced feature toggle
## [2.6.1]
### Added
- Added GPT-5.4 models for ChatGPT subscription users
- Hooks: Added a `Notification` hook for attention and completion boundaries
- Added `--hooks-dir` CLI flag for runtime hook injection
- Added `--auto-approve-all` CLI flag for interactive mode
### Fixed
- Handle streamable HTTP MCP reconnects more reliably
## [2.6.0]
### Added
- Hook payloads now include `model.provider` and `model.slug`
- Token/cost updates now happen immediately as usage chunks arrive, not after tool execution
### Fixed
- Improve subagent context compaction logic
- Subagent stream retry delay increased to reduce noise from transient failures
- State serialization errors are now caught and logged instead of crashing
- Removed incorrect `max_tokens` from OpenRouter requests
## [2.5.2]
### Added
- Added Windows PowerShell support for hooks (execution, resolution, and management), improving hook behavior on Windows for CLI and shared core workflows.
### Fixed
- Restored GPT-OSS native file editing for OpenAI-compatible models used through shared core tooling.
- Improved OpenRouter context overflow error handling so auto-compaction triggers correctly for wrapped 400 errors.
- Hardened checkpoint recovery by retrying nested git restore and preventing silent `.git_disabled` leftovers.
- Added a User-Agent header for requests to the Cline back-end to improve request handling consistency.
## [2.5.1]
### Added
- Expanded CLI markdown rendering support (headings, lists, blockquotes, fenced code blocks, links, and nested lists).
### Fixed
- Fixed CLI headless auth provider model metadata loading for Cline and Vercel AI Gateway by fetching model info from API with cache fallback.
- Increased flaky CLI import test timeout on Windows CI to reduce intermittent test failures.
## [2.5.0]
### Added
- Added Cline SDK API interface for programmatic access to Cline features and tools, enabling integration into custom applications.
- Added Codex 5.3 model support
### Fixed
- Fix OpenAI Codex by setting `store` to `false`
- Use `isLocatedInPath()` instead of string matching for path containment checks
## [2.4.3]
### Added
- Add /q command to quit CLI
- Fetch featured models from backend with local fallback
### Fixed
- Fix auth check for ACP mode
- Fix Cline auth with ACP flag
- Fix yolo mode to not persist yolo setting to disk
## [2.4.2]
### Added
- Gemini-3.1 Pro Preview
### Patch Changes
- VSCode uses shared files for global, workspace and secret state.
## [2.4.1]
### Fixed
- Fix infinite retry loop when write_to_file fails with missing content parameter. Provides progressive guidance to the model, escalating from suggestions to hard stops, with context window awareness to break the loop.
## [2.4.0]
### Added
- Adding Anthropic Sonnet 4.6
- Allows users to enter custom aws region when selecting bedrock as a provider in CLI
- Keep reasoning rows visible when low-stakes tool groups start immediately after reasoning.
- Restore reasoning trace visibility in chat and improve the thinking row UX so streamed reasoning is visible, then collapsible after completion.
### Fixed
- Banners now display immediately when opening the extension instead of requiring user interaction first
- Resolved 17 security vulnerabilities including high-severity DoS issues in dependencies (body-parser, axios, qs, tar, and others)
## [2.2.2]
- Allows users to enter custom aws region when selecting bedrock as a provider
- Prevent Parent Container Scrolling In Dropdowns
## [2.2.1]
- Added Minimax 2.5 Free Promo
- Fixed Response chaining for OpenAI's Responses API
## [2.2.0]
### Added
- Subagent: replace legacy subagents with the native `use_subagents` tool
- Bundle `endpoints.json` support so packaged distributions can ship required endpoints out-of-the-box
- Amazon Bedrock: support parallel tool calling
- New "double-check completion" experimental feature to verify work before marking tasks complete
- CLI: new task controls/flags including custom `--thinking` token budget and `--max-consecutive-mistakes` for yolo runs
- Remote config: new UI/options (including connection/test buttons) and support for syncing deletion of remotely configured MCP servers
- Vertex / Claude Code: add 1M context model options for Claude Opus 4.6
- ZAI/GLM: add GLM-5
### Fixed
- CLI: handle stdin redirection correctly in CI/headless environments
- CLI: preserve OAuth callback paths during auth redirects
- VS Code Web: generate auth callback URLs via `vscode.env.asExternalUri` (OAuth callback reliability)
- Terminal: surface command exit codes in results and improve long-running `execute_command` timeout behavior
- UI: add loading indicator and fix `api_req_started` rendering
- Task streaming: prevent duplicate streamed text rows after completion
- API: preserve selected Vercel model when model metadata is missing
- Telemetry: route PostHog networking through proxy-aware shared fetch and ensure telemetry flushes on shutdown
- CI: increase Windows E2E test timeout to reduce flakiness
### Changed
- Settings/model UX: move "reasoning effort" into model configuration and expose it in settings
- CLI provider selection: limit provider list to those remotely configured
- UI: consolidate ViewHeader component/styling across views
- Tools: add auto-approval support for `attempt_completion` commands
- Remotely configured MCP server schema now supports custom headers
## [2.1.0]
### Minor Changes
- 42ce100: Add Generate API Key on Hicap Provider selection
### Patch Changes
- 195294f: Add support for bundled endpoints.json in enterprise distributions. Extensions can now include a pre-configured endpoints.json file that automatically switches Cline to self-hosted mode. Includes packaging scripts for VSIX, NPM, and JetBrains plugins.
- a1f2601: Replace the LiteLLM model list with a selector
- 739d75a: Add Claude Code provider support for Claude Opus 4.6 and Sonnet 4.5 1M variants via both full model names and aliases (`opus[1m]`, `sonnet[1m]`), and align the `opus` alias with Opus 4.6.
- 8440380: Add GitHub Actions workflow to build CLI from any commit for testing
- b1a8db2: fix(cli): prevent hang when spawned without TTY
- 7c87017: Add Claude Opus 4.6 model support
- d116ac5: Supports rendering markdown table in chat view.
- 6d8fb85: Fix CLI crashing in CI environments and with stdin redirection (e.g., `cline "prompt" < /dev/null`). Now checks both stdin and stdout TTY status before using Ink, and only errors on empty stdin when no prompt is provided.
- 70a9904: Fix JetBrains sign-in regression by adding fallback for openExternal RPC
- f440f3a: fix: use vscode.env.openExternal for auth in remote environments
Fixes OAuth authentication in VS Code Server and remote environments by routing browser URL opening through VS Code's native openExternal API instead of the npm 'open' package.
- 70a9904: fix: use vscode.env.asExternalUri for auth callback URLs only in VS Code Web
Fixes OAuth callback redirect in VS Code Web (`code serve-web`, Codespaces) by using `vscode.env.asExternalUri()` to resolve the callback URI. This is gated behind a `vscode.env.uiKind === UIKind.Web` check so regular desktop VS Code continues to use the `vscode://` URI directly. The `getCallbackUrl` API now accepts a `path` parameter so the full callback URI (including route) is resolved correctly, and callers pass their path directly instead of appending after.
- 5308ded: Updating script documentation and removing unnecessary continue on error
- b514f18: Prevent duplicate streamed text rows when a partial text update arrives after the same text was already finalized.
- 26391c9: Fix Bedrock model id
- d19a877: Unify ViewHeader Styles Across All Views
- 5dcaa8c: Add Vertex Claude Opus 4.6 1M model option and global endpoint support, and pass the 1M beta header for Vertex Claude requests.
Cline supports API providers like ChatGPT, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure, GCP Vertex, Cerebras and Groq. You can also configure any OpenAI compatible API, or use a local model through LM Studio/Ollama. If you're using a Cline Account, you'll always have access to the newest models as soon as they're available.
Cline supports API providers like ChatGPT, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure, GCP Vertex, Cerebras, Groq, and Moonshot. You can also configure any OpenAI compatible API, or use a local model through LM Studio/Ollama. If you're using a Cline Account, you'll always have access to the newest models as soon as they're available.
<!-- Transparent pixel to create line break after floating image -->
@@ -79,4 +79,3 @@ Get the same Cline experience with enterprise-grade controls: SSO (SAML/OIDC), g
it("renders basic markdown elements correctly with appropriate styling",()=>{
constmessage: ClineMessage={
ts: Date.now(),
type:"say",
say:"text",
text:"# Heading 1\n\nThis is a **bold** and *italic* text with `inline code`.\n\n- List item 1\n- List item 2\n\n> Blockquote\n\n```javascript\nconst x = 1;\n```",
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.