* fix: cancel backend auto-approval timeout when auto-approve is toggled off mid-countdown (#11439)
Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
* fix: prevent chat history loss during cloud/settings navigation (#11371) (#11372)
Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
* fix: preserve pasted images in chatbox during chat activity (#11375)
Co-authored-by: Roo Code <roomote@roocode.com>
* fix: resolve chat scroll anchoring and task-switch scroll race condit… (#11385)
* fix: avoid zsh process-substitution false positives in assignments (#11365)
* fix(editor): make tab close best-effort in DiffViewProvider.open (#11363)
* fix(checkpoints): canonicalize core.worktree comparison to prevent Windows path mismatch failures (#11346)
* fix: prevent double notification sound playback (#11283)
* fix: prevent false unsaved changes prompt with OpenAI Compatible headers (#8230) (#11334)
fix: prevent false unsaved changes prompt with OpenAI Compatible headers
Mark automatic header syncs in ApiOptions and OpenAICompatible as
non-user actions (isUserAction: false) and enhance SettingsView change
detection to skip automatic syncs with semantically equal values.
Root cause: two components (ApiOptions and OpenAICompatible) manage
openAiHeaders state and automatically sync it back on mount/remount.
These syncs were treated as user changes, triggering a false dirty state.
Co-authored-by: Robert McIntyre <robertjmcintyre@users.noreply.github.com>
* fix: remove noisy console.warn logs from NativeToolCallParser (#11264)
Remove two console.warn messages that fire excessively when loading tasks
from history:
- 'Attempting to finalize unknown tool call' in finalizeStreamingToolCall()
- 'Received chunk for unknown tool call' in processStreamingChunk()
The defensive null-return behavior is preserved; only the log output is removed.
* refactor: remove footgun prompting (file-based system prompt override) (#11387)
* refactor: delete orphaned per-provider caching transform files (#11388)
* feat: add disabledTools setting to globally disable native tools (#11277)
* feat: add disabledTools setting to globally disable native tools
Add a disabledTools field to GlobalSettings that allows disabling specific
native tools by name. This enables cloud agents to be configured with
restricted tool access.
Schema:
- Add disabledTools: z.array(toolNamesSchema).optional() to globalSettingsSchema
- Add disabledTools to organizationDefaultSettingsSchema.pick()
- Add disabledTools to ExtensionState Pick type
Prompt generation (tool filtering):
- Add disabledTools to BuildToolsOptions interface
- Pass disabledTools through filterSettings to filterNativeToolsForMode()
- Remove disabled tools from allowedToolNames set in filterNativeToolsForMode()
Execution-time validation (safety net):
- Extract disabledTools from state in presentAssistantMessage
- Convert disabledTools to toolRequirements format for validateToolUse()
Wiring:
- Add disabledTools to ClineProvider getState() and getStateToPostToWebview()
- Pass disabledTools to all buildNativeToolsArrayWithRestrictions() call sites
EXT-778
* fix: check toolRequirements before ALWAYS_AVAILABLE_TOOLS
Moves the toolRequirements check before the ALWAYS_AVAILABLE_TOOLS
early-return in isToolAllowedForMode(). This ensures disabledTools
can block always-available tools (switch_mode, new_task, etc.) at
execution time, making the validation layer consistent with the
filtering layer.
* feat: add support for .agents/skills directory (#11181)
* feat: add support for .agents/skills directory
This change adds support for discovering skills from the .agents/skills
directory, following the Agent Skills convention for sharing skills
across different AI coding tools.
Priority order (later entries override earlier ones):
1. Global ~/.agents/skills (shared across AI coding tools, lowest priority)
2. Project .agents/skills
3. Global ~/.roo/skills (Roo-specific)
4. Project .roo/skills (highest priority)
Changes:
- Add getGlobalAgentsDirectory() and getProjectAgentsDirectoryForCwd()
functions to roo-config
- Update SkillsManager.getSkillsDirectories() to include .agents/skills
- Update SkillsManager.setupFileWatchers() to watch .agents/skills
- Add tests for new functionality
* fix: clarify skill priority comment to match actual behavior
* fix: clarify skill priority comment to explain Map.set replacement mechanism
---------
Co-authored-by: Roo Code <roomote@roocode.com>
* feat(history): render nested subtasks as recursive tree (#11299)
* feat(history): render nested subtasks as recursive tree
* fix(lockfile): resolve missing ai-sdk provider entry
* fix: address review feedback — dedupe countAll, increase SubtaskRow max-h
- HistoryView: replace local countAll with imported countAllSubtasks from types.ts
- SubtaskRow: increase nested children max-h from 500px to 2000px to match TaskGroupItem
* perf(refactor): consolidate getState calls in resolveWebviewView (#11320)
* perf(refactor): consolidate getState calls in resolveWebviewView
Replace three separate this.getState().then() calls with a single
await this.getState() and destructuring. This avoids running the
full getState() method (CloudService calls, ContextProxy reads, etc.)
three times during webview view resolution.
* fix: keep getState consolidation non-blocking to avoid delaying webview render
---------
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
* fix: harden command auto-approval against inline JS false positives (#11382)
* feat: rename search_and_replace tool to edit and unify edit-family UI (#11296)
* Revert "refactor: delete orphaned per-provider caching transform files (#11388)"
This reverts commit 13a45b0361.
* chore: regenerate built-in-skills.ts with updated formatting
* fix: add missing maxReadFileLine property to test baseState
The ExtensionState type now requires maxReadFileLine property (added in commit 63e3f769a).
Update the test to include this property with the default value of -1 (unlimited reading).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: add pnpm serve command for code-server development (#10964)
Co-authored-by: Roo Code <roomote@roocode.com>
* chore: remove Feature Request from issue template options (#11141)
Co-authored-by: Roo Code <roomote@roocode.com>
* refactor(docs-extractor): simplify mode to focus on raw fact extraction (#11129)
* Add cli support for linux (#11167)
* fix: replace heredocs with echo statements in cli-release workflow (#11168)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Drop MacOS-13 cli support (#11169)
* fix(cli): correct example in install script (#11170)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Kimi K2.5 model to Fireworks provider (#11177)
* feat(cli): improve dev experience and roo provider API key support (#11203)
- Allow --api-key and ROO_API_KEY env var for the roo provider instead of
requiring cloud auth token
- Switch dev/start scripts to use tsx for running directly from source
without building first
- Fix path resolution (version.ts, extension.ts, extension-host.ts) to
work from both source and bundled locations
- Disable debug log file (~/.roo/cli-debug.log) unless --debug is passed
- Update README with complete env var table and dev workflow docs
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Roo Code CLI v0.0.50 (#11204)
* Roo Code CLI v0.0.50
* docs(cli): add --exit-on-error to changelog
---------
Co-authored-by: Roo Code <roomote@roocode.com>
* feat(cli): update default model from Opus 4.5 to Opus 4.6 (#11273)
Co-authored-by: Roo Code <roomote@roocode.com>
* feat(web): replace Roomote Control with Linear Integration in cloud features grid (#11280)
Co-authored-by: Roo Code <roomote@roocode.com>
* Add linux-arm64 for the roo cli (#11314)
* chore: clean up repo-facing mode rules (#11410)
* Make CLI auto-approve by default with require-approval opt-in (#11424)
Co-authored-by: Roo Code <roomote@roocode.com>
* Add new code owners to CODEOWNERS file
* Update next.js (#11108)
* feat(web): Replace bespoke navigation menu with shadcn navigation menu (#11117)
Co-authored-by: Roo Code <roomote@roocode.com>
---------
Co-authored-by: SannidhyaSah <sah_sannidhya@outlook.com>
Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
Co-authored-by: 0xMink <dennis@dennismink.com>
Co-authored-by: Robert McIntyre <robertjmcintyre@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
Co-authored-by: Chris Estreich <cestreich@gmail.com>
Revert to pre-AI-SDK state (commit 67e568f6b)
This commit reverts the codebase to the state before AI SDK migration work began.
Target commit: 67e568f6b - refactor: replace fetch_instructions with skill tool and built-in skills (#10913)
Date: January 29, 2026
This removes approximately 152 commits of AI SDK migration work.
A follow-up PR will add back bug fixes and features that are unrelated to AI SDK.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: race conditions in subtask delegation system
Comprehensive fix for race conditions and error handling gaps in the subtask
delegation system. Addresses multiple failure modes that could leave parent
tasks permanently stuck in 'delegated' status, causing nested subtasks to hang.
Key fixes:
- Remove initialStatus from taskMetadata rebuild (eliminates status overwrites)
- Persist delegation metadata to per-task files (resolves globalState eviction)
- Add delegationInProgress mutex guard (prevents concurrent delegation ops)
- TOCTOU race fixes with fresh re-reads before writes
- Abort-aware pWaitFor predicate (prevents false 60s timeout on user input)
- Remove silent .catch(() => {}) — all errors now logged unless task is aborting
- Single-attempt delegation with parent repair on failure (no retry band-aids)
- Cancel debouncedEmitTokenUsage in dispose() (prevents zombie callbacks)
- new_task isolation truncation for parallel tool calls
* fix: write all 6 delegation fields in every saveDelegationMeta call site
* fix: align delegation tests with single-attempt implementation (no retry)
* fix: resolve race condition in new_task delegation that loses parent task history
When delegateParentAndOpenChild creates a child task via createTask(), the
Task constructor fires startTask() as a fire-and-forget async call. The child
immediately begins its task loop and eventually calls saveClineMessages() →
updateTaskHistory(), which reads globalState, modifies it, and writes back.
Meanwhile, delegateParentAndOpenChild persists the parent's delegation
metadata (status: 'delegated', delegatedToId, awaitingChildId, childIds) via
a separate updateTaskHistory() call AFTER createTask() returns.
These two concurrent read-modify-write operations on globalState race: the
last writer wins, overwriting the other's changes. When the child's write
lands last, the parent's delegation fields are lost, making the parent task
unresumable when the child finishes.
Fix: create the child task with startTask: false, persist the parent's
delegation metadata first, then manually call child.start(). This ensures
the parent metadata is safely in globalState before the child begins writing.
* docs: clarify Task.start() only handles new tasks, not history resume
* refactor: remove 9 low-usage providers (Phase 0)
Remove Cerebras, Chutes, DeepInfra, Doubao, Featherless, Groq,
Hugging Face, IO Intelligence, and Unbound providers from the codebase.
Each provider removal includes: handler, tests, model definitions,
type schemas, UI settings components, fetchers, i18n references,
and all wiring in shared registration/config files.
- Delete 42 provider-specific files (handlers, tests, fetchers, UI components)
- Remove @ai-sdk/cerebras and @ai-sdk/groq npm dependencies
- Clean provider references from 68 shared files across src/, packages/types/,
webview-ui/, and apps/cli/
- Remove ~490 dead i18n translation keys across 36 locale files
- Add docs/ai-sdk-migration-guide.md with updated migration status
- All TypeScript checks pass, 6505 tests pass with 0 failures
* feat: show retired-provider message for removed provider profiles
Preserve API profiles that reference removed providers instead of
silently stripping their apiProvider. When a user selects a profile
configured for a retired provider, the settings UI now shows an
empathetic message explaining the removal instead of the provider
configuration form.
- Add retiredProviderNames array and isRetiredProvider() helper to
packages/types/src/provider-settings.ts
- Update ProviderSettingsManager sanitization to preserve retired
providers (only strip truly unknown values)
- Update ContextProxy sanitization to preserve retired providers
- Render retired-provider message in ApiOptions.tsx when selected
provider is in the retired list
- Add tests for sanitization, ContextProxy, and UI behavior
* feat: add retired-provider warning banner in chat view
* Revert "feat: add retired-provider warning banner in chat view"
This reverts commit dd593e1056.
* feat: show retired-provider message as inline chat response
* fix: show retired provider warning on home screen
Move WarningRow outside {task && ...} conditional so it renders
regardless of task state. Preserve user input on retired provider
intercept so text isn't lost when switching providers.
- Move showRetiredProviderWarning WarningRow to unconditional render
area near ProfileViolationWarning
- Remove setInputValue/setSelectedImages clearing from retired
provider early return in handleSendMessage
- Delete unused RetiredProviderWarning.tsx (dead code)
* fix: address PR review — passthrough retired-provider fields and i18n strings
- Use passthrough() in saveConfig() and load() so legacy provider-specific
fields (e.g. groqApiKey, deepInfraModelId) are preserved instead of
silently stripped by strict Zod parse()
- Move hardcoded English strings in ApiOptions.tsx and ChatView.tsx to
i18n translation keys (settings:providers.retiredProviderMessage,
chat:retiredProvider.{title,message,openSettings})
- Update tests to assert legacy provider-specific fields survive
save and load round-trips
* i18n: add retired-provider translations for all 17 locales
Translate providers.retiredProviderMessage (settings) and
retiredProvider.{title,message,openSettings} (chat) into ca, de, es,
fr, hi, id, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW.
* test: update ApiOptions retired-provider test to expect i18n key
* feat: add disabledTools setting to globally disable native tools
Add a disabledTools field to GlobalSettings that allows disabling specific
native tools by name. This enables cloud agents to be configured with
restricted tool access.
Schema:
- Add disabledTools: z.array(toolNamesSchema).optional() to globalSettingsSchema
- Add disabledTools to organizationDefaultSettingsSchema.pick()
- Add disabledTools to ExtensionState Pick type
Prompt generation (tool filtering):
- Add disabledTools to BuildToolsOptions interface
- Pass disabledTools through filterSettings to filterNativeToolsForMode()
- Remove disabled tools from allowedToolNames set in filterNativeToolsForMode()
Execution-time validation (safety net):
- Extract disabledTools from state in presentAssistantMessage
- Convert disabledTools to toolRequirements format for validateToolUse()
Wiring:
- Add disabledTools to ClineProvider getState() and getStateToPostToWebview()
- Pass disabledTools to all buildNativeToolsArrayWithRestrictions() call sites
EXT-778
* fix: check toolRequirements before ALWAYS_AVAILABLE_TOOLS
Moves the toolRequirements check before the ALWAYS_AVAILABLE_TOOLS
early-return in isToolAllowedForMode(). This ensures disabledTools
can block always-available tools (switch_mode, new_task, etc.) at
execution time, making the validation layer consistent with the
filtering layer.
* fix: capture and round-trip thinking signature for Bedrock Claude models
Bedrock handler streams reasoning text from Claude's extended thinking but
never captures the cryptographic signature. This causes 400 errors on
multi-turn conversations with tool use: 'Expected thinking or
redacted_thinking, but found tool_use'.
Changes:
- bedrock.ts: Capture reasoningContent.signature from Converse API stream
deltas, implement getThoughtSignature() so Task.ts stores it as a proper
thinking content block
- bedrock-converse-format.ts: Convert thinking blocks to Bedrock's
reasoningContent format with signature, skip reasoning/redacted_thinking/
thoughtSignature blocks that aren't valid for the API
* fix: add redacted_thinking round-trip, fix interface types, add tests
Address PR review feedback:
- Update ContentBlockDeltaEvent interface to include signature and
redactedContent fields (removes type assertions)
- Add 6 tests for thinking/reasoning block conversions in
bedrock-converse-format.ts
Also add redacted_thinking round-trip support:
- bedrock.ts: Capture redactedContent from stream deltas, base64 encode,
expose via getRedactedThinkingBlocks()
- Task.ts: Insert redacted_thinking blocks after thinking block in
assistant messages
- bedrock-converse-format.ts: Convert redacted_thinking blocks back to
reasoningContent.redactedContent (base64 → Uint8Array)
* refactor(task): append environment details into existing blocks
Add appendEnvironmentDetails() helper that merges environment details
into the last text block or tool_result instead of adding a standalone
trailing text block.
This avoids message shapes that can break interleaved-thinking models
like DeepSeek reasoner, which expect specific message structures.
Changes:
- Add appendEnvironmentDetails() and removeEnvironmentDetailsBlocks() helpers
- Update Task.resumeAfterDelegation() to use the helper
- Update Task.recursivelyMakeClineRequests() to use the helper
- Add comprehensive unit tests (26 test cases)
* fix: use named import for Anthropic SDK to match codebase convention
* fix(ai-sdk): preserve reasoning parts in message conversion
* fix(ai-sdk): convert message-level reasoning_content to reasoning part
* fix(task): remove invalid openai-compatible from reasoning allowlist
* feat: add isAiSdkProvider() method for dynamic AI SDK provider detection
- Add isAiSdkProvider() method to ApiHandler interface
- Default implementation in BaseProvider returns false
- Override to return true in 11 AI SDK providers:
deepseek, fireworks, mistral, groq, xai, cerebras,
sambanova, huggingface, gemini, vertex, openai-compatible
- Update Task.ts to use dynamic detection instead of hardcoded Set
- Add method to FakeAIHandler and update test mocks
* fix: handle reasoning parts in flattenAiSdkMessagesToStringContent
- Strip reasoning parts when flattening messages for string-only models
- Allow flattening when message contains only text and reasoning parts
- Add tests for reasoning part handling in string-only model contexts
This addresses the review feedback about ensuring flattenAiSdkMessagesToStringContent
works correctly when reasoning parts are present (e.g., SambaNova DeepSeek).
---------
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
* fix(ai-sdk): preserve reasoning parts in message conversion
* fix(ai-sdk): convert message-level reasoning_content to reasoning part
* fix(task): remove invalid openai-compatible from reasoning allowlist
* feat(condense): add smart code folding with tree-sitter signatures
At context condensation time, use tree-sitter to generate folded code
signatures (function definitions, class declarations) for files read
during the conversation. Each file is included as its own <system-reminder>
block in the condensed summary, preserving structural awareness without
consuming excessive tokens.
- Add getFilesReadByRoo() method to FileContextTracker
- Create generateFoldedFileContext() using tree-sitter parsing
- Update summarizeConversation() to accept array of file sections
- Each file gets its own content block in the summary message
- Add comprehensive test coverage (12 tests)
* fix: skip tree-sitter error strings in folded file context
- Add isTreeSitterErrorString helper to detect error messages
- Skip files that return error strings instead of embedding them
- Add test for error string handling
* refactor: move generateFoldedFileContext() inside summarizeConversation()
- Update summarizeConversation() to accept filesReadByRoo, cwd, rooIgnoreController instead of pre-generated sections
- Move folded file context generation inside summarizeConversation() (lines 319-339)
- Update ContextManagementOptions type and manageContext() to pass new parameters
- Remove generateFoldedFileContext from Task.ts imports - folding now handled internally
- Update all tests to use new parameter signature
- Reduces Task.ts complexity by moving folding logic to summarization module
* fix: prioritize most recently read files in folded context
Files are now sorted by roo_read_date descending before folded context
generation, so if the character budget runs out, the most relevant
(recently read) files are included and older files are skipped.
* refactor: improve code quality in condense module
- Convert summarizeConversation to use options object instead of 11 positional params
- Extract duplicated getFilesReadByRoo error handling into helper method
- Remove unnecessary re-export of generateFoldedFileContext
- Update all test files to use new options object pattern
* fix: address roomote feedback - batch error logging and early budget exit
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
* fix: convert orphaned tool_results to text blocks after condensing
When condensing occurs after assistant sends tool_uses but before user responds,
the tool_use blocks get condensed away. User messages containing tool_results that
reference condensed tool_use_ids become orphaned and get filtered out by
getEffectiveApiHistory, causing user feedback to be lost.
This fix enhances the existing check in addToApiConversationHistory to detect when
the previous effective message is not an assistant and converts any tool_result
blocks to text blocks, preventing them from being filtered as orphans.
The conversion happens at the latest possible moment (message insertion) because:
- Tool results are created before we know if condensing will occur
- We need actual effective history state to make the decision
- This is the last checkpoint before orphan filtering happens
* Only include environment details in summary for automatic condensing
For automatic condensing (during attemptApiRequest), environment details
are included in the summary because the API request is already in progress
and the next user message won't have fresh environment details injected.
For manual condensing (via condenseContext button), environment details
are NOT included because fresh details will be injected on the very next
turn via getEnvironmentDetails() in recursivelyMakeClineRequests().
This uses the existing isAutomaticTrigger flag to differentiate behavior.
---------
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
* chore: remove MULTI_FILE_APPLY_DIFF experiment
Remove the 'Enable concurrent file edits' experimental feature that
allowed editing multiple files in a single apply_diff call.
- Remove multiFileApplyDiff from experiment types and config
- Delete MultiFileSearchReplaceDiffStrategy class and tests
- Delete MultiApplyDiffTool wrapper and tests
- Remove experiment-specific code paths in Task.ts, generateSystemPrompt.ts, and presentAssistantMessage.ts
- Remove special handling in ExperimentalSettings.tsx
- Remove translations from all 18 locale files
The existing MultiSearchReplaceDiffStrategy continues to handle
multiple SEARCH/REPLACE blocks within a single file.
* fix: remove unused EXPERIMENT_IDS/experiments import from Task.ts
Addresses review feedback: removes the unused imports from
src/core/task/Task.ts that were left over after removing the
MULTI_FILE_APPLY_DIFF experiment routing code.
* fix(condense): remove custom condensing model option
Remove the ability to specify a different model/API configuration for
condensing conversations. Modern conversations include provider-specific
data (tool calls, reasoning blocks, thought signatures) that only the
originating model can properly understand and summarize.
Changes:
- Remove condensingApiHandler parameter from summarizeConversation()
- Remove condensingApiConfigId from context management and Task
- Remove API config dropdown for CONDENSE in settings UI
- Update telemetry to remove usedCustomApiHandler parameter
- Update related tests
Users can still customize the CONDENSE prompt text; only model selection
is removed.
* fix: remove condensingApiConfigId from types and test fixtures
---------
Co-authored-by: Roo Code <roomote@roocode.com>
* feat: warn users when too many MCP tools are enabled
- Add WarningRow component for displaying generic warnings with icon, title, message, and optional docs link
- Add TooManyToolsWarning component that shows when users have more than 40 MCP tools enabled
- Add MAX_MCP_TOOLS_THRESHOLD constant (40)
- Add i18n translations for the warning message
- Integrate warning into ChatView to display after task header
- Add comprehensive tests for both components
Closes ROO-542
* Moves constant to the right place
* Move it to the backend
* i18n
* Add actionlink that takes you to MCP settings in this case
* Add to MCP settings too
* Bump max tools up to 60 since github itself has 50+
* DRY
* Fix test
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Bruno Bergher <bruno@roocode.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>