Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
8c2d125
FCO: resolve conflicts, integrate types + UI, and fix provider.getCur…
hannesrudolph Aug 27, 2025
c051c2c
fix: add missing UI translations; id locale consistency; lazy-init VS…
hannesrudolph Aug 27, 2025
c6418ac
fix(windows): use GIT_WORK_TREE for ShadowCheckpointService to avoid …
hannesrudolph Aug 27, 2025
728bc79
fix(windows): normalize worktree comparison for checkpoints on Window…
hannesrudolph Aug 27, 2025
73cd31b
test(windows): relax workspace worktree equality check; log and conti…
hannesrudolph Aug 27, 2025
5f5cdf1
fix(settings): move FCO toggle to Experimental, adopt debounced actio…
hannesrudolph Aug 27, 2025
d6bf409
test(checkpoints): stabilize diff path on macOS CI by using workspace…
hannesrudolph Aug 27, 2025
39d2ca2
style(webview): replace remaining inline styles in FilesChangedOvervi…
hannesrudolph Aug 28, 2025
46683d3
chore(shared): dedupe WebviewMessage.type union; add WebviewMessagePa…
hannesrudolph Aug 28, 2025
877404a
Bug fixes and test cases added
playcations Aug 1, 2025
709a702
Fix type issues in FCOMessageHandler
playcations Aug 31, 2025
390c500
Apply remaining FCO edge case fixes from backup branch
playcations Aug 31, 2025
90d9306
Apply missing FCO theming changes from backup branch
playcations Aug 31, 2025
b4086b1
Chat-only edits are not tracked
playcations Sep 1, 2025
3048471
Ignore empty tool usage
playcations Sep 1, 2025
bb2ae8d
ix: code quality improvements for FCO feature and address more comments
playcations Sep 1, 2025
de2a236
Switched to tailwind for FilesChangedOverview
playcations Sep 1, 2025
8715471
Removed UI from settings, Files Changed now stacked properly under Todo
playcations Sep 1, 2025
1b19967
possible checkpoint memory leak
playcations Sep 1, 2025
32dafd3
removed initial checkpoint creation
playcations Sep 1, 2025
21661d7
Files Changed Overview updating after file edits using tool calls.
playcations Sep 2, 2025
11dd48a
Simplify FileChangeManager architecture with proper accept and rejec…
playcations Sep 3, 2025
602a4fe
Add type for RooCodeEventName.TaskSpawned (#7465)
mrubens Aug 27, 2025
6842fff
Fix GPT-5 Responses API issues with condensing and image support (#7067)
daniel-lxs Aug 28, 2025
3eb9d12
Bump cloud to 0.25.0 (#7475)
mrubens Aug 28, 2025
ea51c04
feat: add image generation tool with OpenRouter integration (#7474)
daniel-lxs Aug 28, 2025
e8d5e91
Release v3.26.2 (#7490)
mrubens Aug 28, 2025
09d8ff7
Support free imagegen (#7493)
mrubens Aug 28, 2025
1dabac2
feat: update OpenRouter API to support input/output modalities and fi…
daniel-lxs Aug 28, 2025
67af3ba
Add padding to image model picker (#7494)
mrubens Aug 28, 2025
94b4a5c
fix: prevent dirty state on initial mount in ImageGenerationSettings …
daniel-lxs Aug 28, 2025
8d94af5
Changeset version bump (#7491)
github-actions[bot] Aug 28, 2025
af00c62
Move @roo-code/cloud to the Roo-Code repo (#7503)
cte Aug 28, 2025
2b7e259
Refactor the extension bridge (#7515)
cte Aug 29, 2025
3f51a57
Implement deferred task subscriptions (#7517)
cte Aug 29, 2025
5ddd463
feat: add optional input image parameter to image generation tool (#7…
roomote[bot] Aug 29, 2025
5236675
feat: sync extension bridge settings with cloud (#7535)
roomote[bot] Aug 29, 2025
a96fe08
refactor: flatten image generation settings structure (#7536)
daniel-lxs Aug 29, 2025
3d14f87
chore: add changeset for v3.26.3 (#7541)
mrubens Aug 29, 2025
0126507
Changeset version bump (#7542)
github-actions[bot] Aug 29, 2025
47855ed
Mode and provider profile selector (#7545)
cte Aug 29, 2025
3725917
Putting the Roo in Roo-leases (#7546)
mrubens Aug 30, 2025
feb0cc1
feat: optimize memory usage for image handling in webview (#7556)
daniel-lxs Aug 30, 2025
b5eec19
feat: rename Account tab to Cloud tab (#7558)
roomote[bot] Aug 30, 2025
81d5f9d
feat: add Ollama API key support for Turbo mode (#7425)
roomote[bot] Aug 30, 2025
08d92f8
Disconnect extension bridge on logout (#7563)
mrubens Sep 1, 2025
64cb7e6
v3.26.4 (#7579)
mrubens Sep 1, 2025
313ff47
Update contributors list (#7462)
github-actions[bot] Sep 1, 2025
114008b
Changeset version bump (#7580)
github-actions[bot] Sep 1, 2025
e063d63
feat: add configurable embedding batch size for code indexing (#7464)
roomote[bot] Sep 2, 2025
a840116
Shows a pill with the base Roo Code Cloud URL when not pointing to pr…
brunobergher Sep 2, 2025
b801673
Cloud: fix provider syncing (#7603)
jr Sep 2, 2025
6569710
fix: add cache reporting support for OpenAI-Native provider (#7602)
hannesrudolph Sep 2, 2025
4d90ad1
Fix TypeScript compilation errors and FileChangeManager logic after r…
playcations Sep 3, 2025
c467d53
fix: Add missing types for Files Changed Overview feature
roomote Sep 3, 2025
3dff339
fix: Add remaining missing types for Files Changed Overview feature
roomote Sep 3, 2025
d139c7b
fix: Complete type fixes for Files Changed Overview feature
roomote Sep 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,5 @@
# Roo Code Changelog

## [3.27.0] - 2025-09-05

![3.27.0 Release - Bug Fixes and Improvements](/releases/3.27.0-release.png)

- Add: User message editing and deletion functionality (thanks @NaccOll!)
- Add: Kimi K2-0905 model support in Chutes provider (#7700 by @pwilkin, PR by @app/roomote)
- Fix: Prevent stack overflow in codebase indexing for large projects (#7588 by @StarTrai1, PR by @daniel-lxs)
- Fix: Resolve race condition in Gemini Grounding Sources by improving code design (#6372 by @daniel-lxs, PR by @HahaBill)
- Fix: Preserve conversation context by retrying with full conversation on invalid previous_response_id (thanks @daniel-lxs!)
- Fix: Identify MCP and slash command config path in multiple folder workspaces (#6720 by @kfuglsang, PR by @NaccOll)
- Fix: Handle array paths from VSCode terminal profiles correctly (#7695 by @Amosvcc, PR by @app/roomote)
- Fix: Improve WelcomeView styling and readability (thanks @daniel-lxs!)
- Fix: Resolve CI e2e test ETIMEDOUT errors when downloading VS Code (thanks @daniel-lxs!)

## [3.26.7] - 2025-09-04

![3.26.7 Release - OpenAI Service Tiers](/releases/3.26.7-release.png)

- Feature: Add OpenAI Responses API service tiers (flex/priority) with UI selector and pricing (thanks @hannesrudolph!)
- Feature: Add DeepInfra as a model provider in Roo Code (#7661 by @Thachnh, PR by @Thachnh)
- Feature: Update kimi-k2-0905-preview and kimi-k2-turbo-preview models on the Moonshot provider (thanks @CellenLee!)
- Feature: Add kimi-k2-0905-preview to Groq, Moonshot, and Fireworks (thanks @daniel-lxs and Cline!)
- Fix: Prevent countdown timer from showing in history for answered follow-up questions (#7624 by @XuyiK, PR by @daniel-lxs)
- Fix: Moonshot's maximum return token count limited to 1024 issue resolved (#6936 by @greyishsong, PR by @wangxiaolong100)
- Fix: Add error transform to cryptic OpenAI SDK errors when API key is invalid (#7483 by @A0nameless0man, PR by @app/roomote)
- Fix: Validate MCP tool exists before execution (#7631 by @R-omk, PR by @app/roomote)
- Fix: Handle zsh glob qualifiers correctly (thanks @mrubens!)
- Fix: Handle zsh process substitution correctly (thanks @mrubens!)
- Fix: Minor zh-TW Traditional Chinese locale typo fix (thanks @PeterDaveHello!)

## [3.26.6] - 2025-09-03

![3.26.6 Release - Bug Fixes and Tool Improvements](/releases/3.26.6-release.png)

- Add experimental run_slash_command tool to let the model initiate slash commands (thanks @app/roomote!)
- Fix: use askApproval wrapper in insert_content and search_and_replace tools (#7648 by @hannesrudolph, PR by @app/roomote)
- Add Kimi K2 Turbo model configuration to moonshotModels (thanks @wangxiaolong100!)
- Fix: preserve scroll position when switching tabs in settings (thanks @DC-Dancao!)

## [3.26.5] - 2025-09-03

![3.26.5 Release - Enhanced AI Thinking Capabilities](/releases/3.26.5-release.png)

- feat: Add support for Qwen3 235B A22B Thinking 2507 model in chutes (thanks @mohammad154!)
- feat: Add auto-approve support for MCP access_resource tool (#7565 by @m-ibm, PR by @daniel-lxs)
- feat: Add configurable embedding batch size for code indexing (#7356 by @BenLampson, PR by @app/roomote)
- fix: Add cache reporting support for OpenAI-Native provider (thanks @hannesrudolph!)
- feat: Move message queue to the extension host for better performance (thanks @cte!)

## [3.26.4] - 2025-09-01

![3.26.4 Release - Memory Optimization](/releases/3.26.4-release.png)
Expand Down
82 changes: 41 additions & 41 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const getOpenRouterModels = async (): Promise<OpenRouterModelRecord> => {

return result.data.data
.filter((rawModel) => {
// Skip image generation models (models that output images).
// Skip image generation models (models that output images)
return !rawModel.architecture?.output_modalities?.includes("image")
})
.sort((a, b) => a.name.localeCompare(b.name))
Expand Down
82 changes: 41 additions & 41 deletions locales/ca/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/de/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/es/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/fr/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/hi/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/id/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/it/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/ja/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/ko/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/nl/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/pl/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/pt-BR/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/ru/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/tr/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/vi/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/zh-CN/README.md

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions locales/zh-TW/README.md

Large diffs are not rendered by default.

19 changes: 14 additions & 5 deletions packages/cloud/src/WebAuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,11 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
)?.email_address
}

let extensionBridgeEnabled = true
// Check for extension_bridge_enabled in user's public metadata
let extensionBridgeEnabled = false
if (userData.public_metadata?.extension_bridge_enabled === true) {
extensionBridgeEnabled = true
}

// Fetch organization info if user is in organization context
try {
Expand All @@ -579,7 +583,11 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
if (userMembership) {
this.setUserOrganizationInfo(userInfo, userMembership)

extensionBridgeEnabled = await this.isExtensionBridgeEnabledForOrganization(storedOrgId)
// Check organization public metadata for extension_bridge_enabled
// Organization setting takes precedence over user setting
if (await this.isExtensionBridgeEnabledForOrganization(storedOrgId)) {
extensionBridgeEnabled = true
}

this.log("[auth] User in organization context:", {
id: userMembership.organization.id,
Expand All @@ -600,9 +608,10 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
if (primaryOrgMembership) {
this.setUserOrganizationInfo(userInfo, primaryOrgMembership)

extensionBridgeEnabled = await this.isExtensionBridgeEnabledForOrganization(
primaryOrgMembership.organization.id,
)
// Check organization public metadata for extension_bridge_enabled
if (await this.isExtensionBridgeEnabledForOrganization(primaryOrgMembership.organization.id)) {
extensionBridgeEnabled = true
}

this.log("[auth] Legacy credentials: Found organization membership:", {
id: primaryOrgMembership.organization.id,
Expand Down
4 changes: 0 additions & 4 deletions packages/cloud/src/__mocks__/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ export const Uri = {
parse: vi.fn((uri: string) => ({ toString: () => uri })),
}

export const commands = {
executeCommand: vi.fn().mockResolvedValue(undefined),
}

export interface ExtensionContext {
secrets: {
get: (key: string) => Promise<string | undefined>
Expand Down
8 changes: 4 additions & 4 deletions packages/cloud/src/__tests__/WebAuthService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ describe("WebAuthService", () => {
name: "John Doe",
email: "[email protected]",
picture: "https://example.com/avatar.jpg",
extensionBridgeEnabled: true,
extensionBridgeEnabled: false,
},
})
})
Expand Down Expand Up @@ -725,7 +725,7 @@ describe("WebAuthService", () => {
name: "Jane Smith",
email: "[email protected]",
picture: "https://example.com/jane.jpg",
extensionBridgeEnabled: true,
extensionBridgeEnabled: false,
})
})

Expand Down Expand Up @@ -844,7 +844,7 @@ describe("WebAuthService", () => {
name: "John Doe",
email: undefined,
picture: undefined,
extensionBridgeEnabled: true,
extensionBridgeEnabled: false,
})
})
})
Expand Down Expand Up @@ -969,7 +969,7 @@ describe("WebAuthService", () => {
name: "Test User",
email: undefined,
picture: undefined,
extensionBridgeEnabled: true,
extensionBridgeEnabled: false,
},
})
})
Expand Down
38 changes: 4 additions & 34 deletions packages/cloud/src/bridge/BaseChannel.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import type { Socket } from "socket.io-client"
import * as vscode from "vscode"

import type { StaticAppProperties, GitProperties } from "@roo-code/types"

export interface BaseChannelOptions {
instanceId: string
appProperties: StaticAppProperties
gitProperties?: GitProperties
}

/**
* Abstract base class for communication channels in the bridge system.
Expand All @@ -20,13 +11,9 @@ export interface BaseChannelOptions {
export abstract class BaseChannel<TCommand = unknown, TEventName extends string = string, TEventData = unknown> {
protected socket: Socket | null = null
protected readonly instanceId: string
protected readonly appProperties: StaticAppProperties
protected readonly gitProperties?: GitProperties

constructor(options: BaseChannelOptions) {
this.instanceId = options.instanceId
this.appProperties = options.appProperties
this.gitProperties = options.gitProperties
constructor(instanceId: string) {
this.instanceId = instanceId
}

/**
Expand Down Expand Up @@ -94,26 +81,9 @@ export abstract class BaseChannel<TCommand = unknown, TEventName extends string
}

/**
* Handle incoming commands - template method that ensures common functionality
* is executed before subclass-specific logic.
*
* This method should be called by subclasses to handle commands.
* It will execute common functionality and then delegate to the abstract
* handleCommandImplementation method.
*/
public async handleCommand(command: TCommand): Promise<void> {
// Common functionality: focus the sidebar.
await vscode.commands.executeCommand(`${this.appProperties.appName}.SidebarProvider.focus`)

// Delegate to subclass-specific implementation.
await this.handleCommandImplementation(command)
}

/**
* Handle command-specific logic - must be implemented by subclasses.
* This method is called after common functionality has been executed.
* Handle incoming commands - must be implemented by subclasses.
*/
protected abstract handleCommandImplementation(command: TCommand): Promise<void>
public abstract handleCommand(command: TCommand): Promise<void>

/**
* Handle connection-specific logic.
Expand Down
129 changes: 54 additions & 75 deletions packages/cloud/src/bridge/BridgeOrchestrator.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import crypto from "crypto"
import os from "os"

import {
type TaskProviderLike,
type TaskLike,
type CloudUserInfo,
type ExtensionBridgeCommand,
type TaskBridgeCommand,
type StaticAppProperties,
type GitProperties,
ConnectionState,
ExtensionSocketEvents,
TaskSocketEvents,
Expand Down Expand Up @@ -42,8 +39,6 @@ export class BridgeOrchestrator {
private readonly token: string
private readonly provider: TaskProviderLike
private readonly instanceId: string
private readonly appProperties: StaticAppProperties
private readonly gitProperties?: GitProperties

// Components
private socketTransport: SocketTransport
Expand All @@ -66,72 +61,66 @@ export class BridgeOrchestrator {
public static async connectOrDisconnect(
userInfo: CloudUserInfo | null,
remoteControlEnabled: boolean | undefined,
options: BridgeOrchestratorOptions,
options?: BridgeOrchestratorOptions,
): Promise<void> {
if (BridgeOrchestrator.isEnabled(userInfo, remoteControlEnabled)) {
await BridgeOrchestrator.connect(options)
} else {
await BridgeOrchestrator.disconnect()
}
}

public static async connect(options: BridgeOrchestratorOptions) {
const isEnabled = BridgeOrchestrator.isEnabled(userInfo, remoteControlEnabled)
const instance = BridgeOrchestrator.instance

if (!instance) {
try {
console.log(`[BridgeOrchestrator#connectOrDisconnect] Connecting...`)
// Populate telemetry properties before registering the instance.
await options.provider.getTelemetryProperties()
if (isEnabled) {
if (!instance) {
if (!options) {
console.error(
`[BridgeOrchestrator#connectOrDisconnect] Cannot connect: options are required for connection`,
)
return
}
try {
console.log(`[BridgeOrchestrator#connectOrDisconnect] Connecting...`)
BridgeOrchestrator.instance = new BridgeOrchestrator(options)
await BridgeOrchestrator.instance.connect()
} catch (error) {
console.error(
`[BridgeOrchestrator#connectOrDisconnect] connect() failed: ${error instanceof Error ? error.message : String(error)}`,
)
}
} else {
if (
instance.connectionState === ConnectionState.FAILED ||
instance.connectionState === ConnectionState.DISCONNECTED
) {
console.log(
`[BridgeOrchestrator#connectOrDisconnect] Re-connecting... (state: ${instance.connectionState})`,
)

BridgeOrchestrator.instance = new BridgeOrchestrator(options)
await BridgeOrchestrator.instance.connect()
} catch (error) {
console.error(
`[BridgeOrchestrator#connectOrDisconnect] connect() failed: ${error instanceof Error ? error.message : String(error)}`,
)
instance.reconnect().catch((error) => {
console.error(
`[BridgeOrchestrator#connectOrDisconnect] reconnect() failed: ${error instanceof Error ? error.message : String(error)}`,
)
})
} else {
console.log(
`[BridgeOrchestrator#connectOrDisconnect] Already connected or connecting (state: ${instance.connectionState})`,
)
}
}
} else {
if (
instance.connectionState === ConnectionState.FAILED ||
instance.connectionState === ConnectionState.DISCONNECTED
) {
console.log(
`[BridgeOrchestrator#connectOrDisconnect] Re-connecting... (state: ${instance.connectionState})`,
)
if (instance) {
try {
console.log(
`[BridgeOrchestrator#connectOrDisconnect] Disconnecting... (state: ${instance.connectionState})`,
)

instance.reconnect().catch((error) => {
await instance.disconnect()
} catch (error) {
console.error(
`[BridgeOrchestrator#connectOrDisconnect] reconnect() failed: ${error instanceof Error ? error.message : String(error)}`,
`[BridgeOrchestrator#connectOrDisconnect] disconnect() failed: ${error instanceof Error ? error.message : String(error)}`,
)
})
} finally {
BridgeOrchestrator.instance = null
}
} else {
console.log(
`[BridgeOrchestrator#connectOrDisconnect] Already connected or connecting (state: ${instance.connectionState})`,
)
}
}
}

public static async disconnect() {
const instance = BridgeOrchestrator.instance

if (instance) {
try {
console.log(
`[BridgeOrchestrator#connectOrDisconnect] Disconnecting... (state: ${instance.connectionState})`,
)

await instance.disconnect()
} catch (error) {
console.error(
`[BridgeOrchestrator#connectOrDisconnect] disconnect() failed: ${error instanceof Error ? error.message : String(error)}`,
)
} finally {
BridgeOrchestrator.instance = null
console.log(`[BridgeOrchestrator#connectOrDisconnect] Already disconnected`)
}
} else {
console.log(`[BridgeOrchestrator#connectOrDisconnect] Already disconnected`)
}
}

Expand All @@ -157,8 +146,6 @@ export class BridgeOrchestrator {
this.token = options.token
this.provider = options.provider
this.instanceId = options.sessionId || crypto.randomUUID()
this.appProperties = { ...options.provider.appProperties, hostname: os.hostname() }
this.gitProperties = options.provider.gitProperties

this.socketTransport = new SocketTransport({
url: this.socketBridgeUrl,
Expand All @@ -179,19 +166,8 @@ export class BridgeOrchestrator {
onReconnect: () => this.handleReconnect(),
})

this.extensionChannel = new ExtensionChannel({
instanceId: this.instanceId,
appProperties: this.appProperties,
gitProperties: this.gitProperties,
userId: this.userId,
provider: this.provider,
})

this.taskChannel = new TaskChannel({
instanceId: this.instanceId,
appProperties: this.appProperties,
gitProperties: this.gitProperties,
})
this.extensionChannel = new ExtensionChannel(this.instanceId, this.userId, this.provider)
this.taskChannel = new TaskChannel(this.instanceId)
}

private setupSocketListeners() {
Expand Down Expand Up @@ -312,6 +288,9 @@ export class BridgeOrchestrator {
}

private async connect(): Promise<void> {
// Populate the app and git properties before registering the instance.
await this.provider.getTelemetryProperties()

await this.socketTransport.connect()
this.setupSocketListeners()
}
Expand Down
Loading
Loading