diff --git a/packages/cloud/src/CloudService.ts b/packages/cloud/src/CloudService.ts index 8c8320cba7f..171b9128586 100644 --- a/packages/cloud/src/CloudService.ts +++ b/packages/cloud/src/CloudService.ts @@ -248,6 +248,11 @@ export class CloudService extends EventEmitter implements Di return this.settingsService!.updateUserSettings(settings) } + public isTaskSyncEnabled(): boolean { + this.ensureInitialized() + return this.settingsService!.isTaskSyncEnabled() + } + // TelemetryClient public captureEvent(event: TelemetryEvent): void { diff --git a/packages/cloud/src/CloudSettingsService.ts b/packages/cloud/src/CloudSettingsService.ts index 4117dbb0bdf..fb96b5ec3b6 100644 --- a/packages/cloud/src/CloudSettingsService.ts +++ b/packages/cloud/src/CloudSettingsService.ts @@ -266,6 +266,21 @@ export class CloudSettingsService extends EventEmitter im } } + public isTaskSyncEnabled(): boolean { + // Org settings take precedence + if (this.authService.getStoredOrganizationId()) { + return this.settings?.cloudSettings?.recordTaskMessages ?? false + } + + // User settings default to true if unspecified + const userSettings = this.userSettings + if (userSettings) { + return userSettings.settings.taskSyncEnabled ?? true + } + + return false + } + private async removeSettings(): Promise { this.settings = undefined this.userSettings = undefined diff --git a/packages/cloud/src/StaticSettingsService.ts b/packages/cloud/src/StaticSettingsService.ts index 29d8071703d..492a0a8d4b6 100644 --- a/packages/cloud/src/StaticSettingsService.ts +++ b/packages/cloud/src/StaticSettingsService.ts @@ -51,6 +51,7 @@ export class StaticSettingsService implements SettingsService { }, settings: { extensionBridgeEnabled: true, + taskSyncEnabled: true, }, version: 1, } @@ -65,6 +66,7 @@ export class StaticSettingsService implements SettingsService { public getUserSettingsConfig(): UserSettingsConfig { return { extensionBridgeEnabled: true, + taskSyncEnabled: true, } } @@ -72,6 +74,11 @@ export class StaticSettingsService implements SettingsService { throw new Error("User settings updates are not supported in static mode") } + public isTaskSyncEnabled(): boolean { + // Static settings always enable task sync + return true + } + public dispose(): void { // No resources to clean up for static settings. } diff --git a/packages/cloud/src/TelemetryClient.ts b/packages/cloud/src/TelemetryClient.ts index 4be44720ea0..6afd1189901 100644 --- a/packages/cloud/src/TelemetryClient.ts +++ b/packages/cloud/src/TelemetryClient.ts @@ -233,9 +233,9 @@ export class CloudTelemetryClient extends BaseTelemetryClient { return false } - // Only record message telemetry if a cloud account is present and explicitly configured to record messages + // Only record message telemetry if task sync is enabled if (eventName === TelemetryEventName.TASK_MESSAGE) { - return this.settingsService.getSettings()?.cloudSettings?.recordTaskMessages || false + return this.settingsService.isTaskSyncEnabled() } // Other telemetry types are capturable at this point diff --git a/packages/cloud/src/__tests__/CloudService.test.ts b/packages/cloud/src/__tests__/CloudService.test.ts index a9df02d6645..4e0283eac7d 100644 --- a/packages/cloud/src/__tests__/CloudService.test.ts +++ b/packages/cloud/src/__tests__/CloudService.test.ts @@ -59,6 +59,7 @@ describe("CloudService", () => { initialize: ReturnType getSettings: ReturnType getAllowList: ReturnType + isTaskSyncEnabled: ReturnType dispose: ReturnType on: ReturnType off: ReturnType @@ -130,6 +131,7 @@ describe("CloudService", () => { initialize: vi.fn(), getSettings: vi.fn(), getAllowList: vi.fn(), + isTaskSyncEnabled: vi.fn().mockReturnValue(true), dispose: vi.fn(), on: vi.fn(), off: vi.fn(), @@ -343,6 +345,12 @@ describe("CloudService", () => { cloudService.getAllowList() expect(mockSettingsService.getAllowList).toHaveBeenCalled() }) + + it("should delegate isTaskSyncEnabled to SettingsService", () => { + const result = cloudService.isTaskSyncEnabled() + expect(mockSettingsService.isTaskSyncEnabled).toHaveBeenCalled() + expect(result).toBe(true) + }) }) describe("error handling", () => { diff --git a/packages/cloud/src/__tests__/CloudSettingsService.test.ts b/packages/cloud/src/__tests__/CloudSettingsService.test.ts index 49d61f85ced..092e45bbe8c 100644 --- a/packages/cloud/src/__tests__/CloudSettingsService.test.ts +++ b/packages/cloud/src/__tests__/CloudSettingsService.test.ts @@ -20,6 +20,7 @@ describe("CloudSettingsService", () => { getSessionToken: ReturnType hasActiveSession: ReturnType on: ReturnType + getStoredOrganizationId: ReturnType } let mockRefreshTimer: { start: ReturnType @@ -63,6 +64,7 @@ describe("CloudSettingsService", () => { getSessionToken: vi.fn(), hasActiveSession: vi.fn().mockReturnValue(false), on: vi.fn(), + getStoredOrganizationId: vi.fn().mockReturnValue(null), } mockRefreshTimer = { @@ -532,4 +534,191 @@ describe("CloudSettingsService", () => { expect(mockContext.globalState.update).toHaveBeenCalledWith("user-settings", undefined) }) }) + + describe("isTaskSyncEnabled", () => { + beforeEach(async () => { + await cloudSettingsService.initialize() + }) + + it("should return true when org recordTaskMessages is true", () => { + // Set up mock settings with org recordTaskMessages = true + const mockSettings = { + version: 1, + cloudSettings: { + recordTaskMessages: true, + }, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + // Mock that user has organization ID (indicating org settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue("org-123") + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(true) + }) + + it("should return false when org recordTaskMessages is false", () => { + // Set up mock settings with org recordTaskMessages = false + const mockSettings = { + version: 1, + cloudSettings: { + recordTaskMessages: false, + }, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + // Mock that user has organization ID (indicating org settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue("org-123") + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(false) + }) + + it("should fall back to user taskSyncEnabled when org recordTaskMessages is undefined", () => { + // Set up mock settings with org recordTaskMessages undefined + const mockSettings = { + version: 1, + cloudSettings: {}, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + const mockUserSettings = { + version: 1, + features: {}, + settings: { + taskSyncEnabled: true, + }, + } + + // Mock that user has no organization ID (indicating user settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue(null) + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + ;(cloudSettingsService as unknown as { userSettings: typeof mockUserSettings }).userSettings = + mockUserSettings + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(true) + }) + + it("should return false when user taskSyncEnabled is false", () => { + // Set up mock settings with org recordTaskMessages undefined + const mockSettings = { + version: 1, + cloudSettings: {}, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + const mockUserSettings = { + version: 1, + features: {}, + settings: { + taskSyncEnabled: false, + }, + } + + // Mock that user has no organization ID (indicating user settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue(null) + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + ;(cloudSettingsService as unknown as { userSettings: typeof mockUserSettings }).userSettings = + mockUserSettings + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(false) + }) + + it("should return true when user taskSyncEnabled is undefined (default)", () => { + // Set up mock settings with org recordTaskMessages undefined + const mockSettings = { + version: 1, + cloudSettings: {}, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + const mockUserSettings = { + version: 1, + features: {}, + settings: {}, + } + + // Mock that user has no organization ID (indicating user settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue(null) + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + ;(cloudSettingsService as unknown as { userSettings: typeof mockUserSettings }).userSettings = + mockUserSettings + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(true) + }) + + it("should return false when no settings are available", () => { + // Mock that user has no organization ID + mockAuthService.getStoredOrganizationId.mockReturnValue(null) + + // Clear both settings + ;(cloudSettingsService as unknown as { settings: undefined }).settings = undefined + ;(cloudSettingsService as unknown as { userSettings: undefined }).userSettings = undefined + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(false) + }) + + it("should return false when only org settings are available but cloudSettings is undefined", () => { + const mockSettings = { + version: 1, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + // Mock that user has organization ID (indicating org settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue("org-123") + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + ;(cloudSettingsService as unknown as { userSettings: undefined }).userSettings = undefined + + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(false) + }) + + it("should prioritize org settings over user settings", () => { + // Set up conflicting settings: org = false, user = true + const mockSettings = { + version: 1, + cloudSettings: { + recordTaskMessages: false, + }, + defaultSettings: {}, + allowList: { allowAll: true, providers: {} }, + } + + const mockUserSettings = { + version: 1, + features: {}, + settings: { + taskSyncEnabled: true, + }, + } + + // Mock that user has organization ID (indicating org settings should be used) + mockAuthService.getStoredOrganizationId.mockReturnValue("org-123") + + // Use reflection to set private settings + ;(cloudSettingsService as unknown as { settings: typeof mockSettings }).settings = mockSettings + ;(cloudSettingsService as unknown as { userSettings: typeof mockUserSettings }).userSettings = + mockUserSettings + + // Should return false (org setting takes precedence) + expect(cloudSettingsService.isTaskSyncEnabled()).toBe(false) + }) + }) }) diff --git a/packages/cloud/src/__tests__/StaticSettingsService.test.ts b/packages/cloud/src/__tests__/StaticSettingsService.test.ts index f2c94a5f061..7b2a6dbbb5f 100644 --- a/packages/cloud/src/__tests__/StaticSettingsService.test.ts +++ b/packages/cloud/src/__tests__/StaticSettingsService.test.ts @@ -98,5 +98,28 @@ describe("StaticSettingsService", () => { expect(mockLog).not.toHaveBeenCalled() }) + + describe("isTaskSyncEnabled", () => { + it("should always return true", () => { + const service = new StaticSettingsService(validBase64) + expect(service.isTaskSyncEnabled()).toBe(true) + }) + + it("should return true regardless of settings content", () => { + // Create settings with different content + const differentSettings = { + version: 2, + cloudSettings: { + recordTaskMessages: false, + }, + defaultSettings: {}, + allowList: { allowAll: false, providers: {} }, + } + const differentBase64 = Buffer.from(JSON.stringify(differentSettings)).toString("base64") + + const service = new StaticSettingsService(differentBase64) + expect(service.isTaskSyncEnabled()).toBe(true) + }) + }) }) }) diff --git a/packages/cloud/src/__tests__/TelemetryClient.test.ts b/packages/cloud/src/__tests__/TelemetryClient.test.ts index 6078e601dd7..96be400e0d6 100644 --- a/packages/cloud/src/__tests__/TelemetryClient.test.ts +++ b/packages/cloud/src/__tests__/TelemetryClient.test.ts @@ -35,6 +35,14 @@ describe("TelemetryClient", () => { recordTaskMessages: true, }, }), + getUserSettings: vi.fn().mockReturnValue({ + features: {}, + settings: { + taskSyncEnabled: true, + }, + version: 1, + }), + isTaskSyncEnabled: vi.fn().mockReturnValue(true), } mockFetch.mockResolvedValue({ @@ -76,12 +84,8 @@ describe("TelemetryClient", () => { expect(isEventCapturable(TelemetryEventName.TASK_CONVERSATION_MESSAGE)).toBe(false) }) - it("should return true for TASK_MESSAGE events when recordTaskMessages is true", () => { - mockSettingsService.getSettings.mockReturnValue({ - cloudSettings: { - recordTaskMessages: true, - }, - }) + it("should return true for TASK_MESSAGE events when isTaskSyncEnabled returns true", () => { + mockSettingsService.isTaskSyncEnabled.mockReturnValue(true) const client = new TelemetryClient(mockAuthService, mockSettingsService) @@ -91,55 +95,11 @@ describe("TelemetryClient", () => { ).bind(client) expect(isEventCapturable(TelemetryEventName.TASK_MESSAGE)).toBe(true) + expect(mockSettingsService.isTaskSyncEnabled).toHaveBeenCalled() }) - it("should return false for TASK_MESSAGE events when recordTaskMessages is false", () => { - mockSettingsService.getSettings.mockReturnValue({ - cloudSettings: { - recordTaskMessages: false, - }, - }) - - const client = new TelemetryClient(mockAuthService, mockSettingsService) - - const isEventCapturable = getPrivateProperty<(eventName: TelemetryEventName) => boolean>( - client, - "isEventCapturable", - ).bind(client) - - expect(isEventCapturable(TelemetryEventName.TASK_MESSAGE)).toBe(false) - }) - - it("should return false for TASK_MESSAGE events when recordTaskMessages is undefined", () => { - mockSettingsService.getSettings.mockReturnValue({ - cloudSettings: {}, - }) - - const client = new TelemetryClient(mockAuthService, mockSettingsService) - - const isEventCapturable = getPrivateProperty<(eventName: TelemetryEventName) => boolean>( - client, - "isEventCapturable", - ).bind(client) - - expect(isEventCapturable(TelemetryEventName.TASK_MESSAGE)).toBe(false) - }) - - it("should return false for TASK_MESSAGE events when cloudSettings is undefined", () => { - mockSettingsService.getSettings.mockReturnValue({}) - - const client = new TelemetryClient(mockAuthService, mockSettingsService) - - const isEventCapturable = getPrivateProperty<(eventName: TelemetryEventName) => boolean>( - client, - "isEventCapturable", - ).bind(client) - - expect(isEventCapturable(TelemetryEventName.TASK_MESSAGE)).toBe(false) - }) - - it("should return false for TASK_MESSAGE events when getSettings returns undefined", () => { - mockSettingsService.getSettings.mockReturnValue(undefined) + it("should return false for TASK_MESSAGE events when isTaskSyncEnabled returns false", () => { + mockSettingsService.isTaskSyncEnabled.mockReturnValue(false) const client = new TelemetryClient(mockAuthService, mockSettingsService) @@ -149,6 +109,7 @@ describe("TelemetryClient", () => { ).bind(client) expect(isEventCapturable(TelemetryEventName.TASK_MESSAGE)).toBe(false) + expect(mockSettingsService.isTaskSyncEnabled).toHaveBeenCalled() }) }) @@ -273,10 +234,8 @@ describe("TelemetryClient", () => { expect(mockFetch).not.toHaveBeenCalled() }) - it("should not capture TASK_MESSAGE events when recordTaskMessages is undefined", async () => { - mockSettingsService.getSettings.mockReturnValue({ - cloudSettings: {}, - }) + it("should not capture TASK_MESSAGE events when isTaskSyncEnabled returns false", async () => { + mockSettingsService.isTaskSyncEnabled.mockReturnValue(false) const client = new TelemetryClient(mockAuthService, mockSettingsService) @@ -294,6 +253,7 @@ describe("TelemetryClient", () => { }) expect(mockFetch).not.toHaveBeenCalled() + expect(mockSettingsService.isTaskSyncEnabled).toHaveBeenCalled() }) it("should not send request when schema validation fails", async () => { @@ -353,12 +313,8 @@ describe("TelemetryClient", () => { ) }) - it("should attempt to capture TASK_MESSAGE events when recordTaskMessages is true", async () => { - mockSettingsService.getSettings.mockReturnValue({ - cloudSettings: { - recordTaskMessages: true, - }, - }) + it("should attempt to capture TASK_MESSAGE events when isTaskSyncEnabled returns true", async () => { + mockSettingsService.isTaskSyncEnabled.mockReturnValue(true) const eventProperties = { appName: "roo-code", @@ -389,6 +345,7 @@ describe("TelemetryClient", () => { properties: eventProperties, }) + expect(mockSettingsService.isTaskSyncEnabled).toHaveBeenCalled() expect(mockFetch).toHaveBeenCalledWith( "https://app.roocode.com/api/events", expect.objectContaining({ diff --git a/packages/types/src/cloud.ts b/packages/types/src/cloud.ts index a566e4ec6ab..693868d4866 100644 --- a/packages/types/src/cloud.ts +++ b/packages/types/src/cloud.ts @@ -303,6 +303,14 @@ export interface SettingsService { */ updateUserSettings(settings: Partial): Promise + /** + * Determines if task sync/recording is enabled based on organization and user settings + * Organization settings take precedence over user settings. + * User settings default to true if unspecified. + * @returns true if task sync is enabled, false otherwise + */ + isTaskSyncEnabled(): boolean + /** * Dispose of the settings service and clean up resources */ diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts index f1c4b81c487..3f3d2b4bdb7 100644 --- a/packages/types/src/global-settings.ts +++ b/packages/types/src/global-settings.ts @@ -138,8 +138,6 @@ export const globalSettingsSchema = z.object({ mcpEnabled: z.boolean().optional(), enableMcpServerCreation: z.boolean().optional(), - remoteControlEnabled: z.boolean().optional(), - mode: z.string().optional(), modeApiConfigs: z.record(z.string(), z.string()).optional(), customModes: z.array(modeConfigSchema).optional(), @@ -316,8 +314,6 @@ export const EVALS_SETTINGS: RooCodeSettings = { mcpEnabled: false, - remoteControlEnabled: false, - mode: "code", // "architect", customModes: [], diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index dbd6283beeb..f453b57dbaf 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -867,7 +867,7 @@ export class ClineProvider fuzzyMatchThreshold, experiments, cloudUserInfo, - remoteControlEnabled, + taskSyncEnabled, } = await this.getState() const task = new Task({ @@ -884,7 +884,7 @@ export class ClineProvider taskNumber: historyItem.number, workspacePath: historyItem.workspace, onCreated: this.taskCreationCallback, - enableBridge: BridgeOrchestrator.isEnabled(cloudUserInfo, remoteControlEnabled), + enableBridge: BridgeOrchestrator.isEnabled(cloudUserInfo, taskSyncEnabled), }) await this.addClineToStack(task) @@ -1777,10 +1777,12 @@ export class ClineProvider includeDiagnosticMessages, maxDiagnosticMessages, includeTaskHistoryInEnhance, + taskSyncEnabled, remoteControlEnabled, openRouterImageApiKey, openRouterImageGenerationSelectedModel, openRouterUseMiddleOutTransform, + featureRoomoteControlEnabled, } = await this.getState() const telemetryKey = process.env.POSTHOG_API_KEY @@ -1912,10 +1914,12 @@ export class ClineProvider includeDiagnosticMessages: includeDiagnosticMessages ?? true, maxDiagnosticMessages: maxDiagnosticMessages ?? 50, includeTaskHistoryInEnhance: includeTaskHistoryInEnhance ?? true, + taskSyncEnabled, remoteControlEnabled, openRouterImageApiKey, openRouterImageGenerationSelectedModel, openRouterUseMiddleOutTransform, + featureRoomoteControlEnabled, } } @@ -2003,6 +2007,16 @@ export class ClineProvider ) } + let taskSyncEnabled: boolean = false + + try { + taskSyncEnabled = CloudService.instance.isTaskSyncEnabled() + } catch (error) { + console.error( + `[getState] failed to get task sync enabled state: ${error instanceof Error ? error.message : String(error)}`, + ) + } + // Return the same structure as before. return { apiConfiguration: providerSettings, @@ -2110,6 +2124,7 @@ export class ClineProvider includeDiagnosticMessages: stateValues.includeDiagnosticMessages ?? true, maxDiagnosticMessages: stateValues.maxDiagnosticMessages ?? 50, includeTaskHistoryInEnhance: stateValues.includeTaskHistoryInEnhance ?? true, + taskSyncEnabled, remoteControlEnabled: (() => { try { const cloudSettings = CloudService.instance.getUserSettings() @@ -2123,6 +2138,18 @@ export class ClineProvider })(), openRouterImageApiKey: stateValues.openRouterImageApiKey, openRouterImageGenerationSelectedModel: stateValues.openRouterImageGenerationSelectedModel, + featureRoomoteControlEnabled: (() => { + try { + const userSettings = CloudService.instance.getUserSettings() + const hasOrganization = cloudUserInfo?.organizationId != null + return hasOrganization || (userSettings?.features?.roomoteControlEnabled ?? false) + } catch (error) { + console.error( + `[getState] failed to get featureRoomoteControlEnabled: ${error instanceof Error ? error.message : String(error)}`, + ) + return false + } + })(), } } diff --git a/src/core/webview/__tests__/ClineProvider.spec.ts b/src/core/webview/__tests__/ClineProvider.spec.ts index cd41ce09ce9..bd4608c6eb2 100644 --- a/src/core/webview/__tests__/ClineProvider.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.spec.ts @@ -554,6 +554,9 @@ describe("ClineProvider", () => { diagnosticsEnabled: true, openRouterImageApiKey: undefined, openRouterImageGenerationSelectedModel: undefined, + remoteControlEnabled: false, + taskSyncEnabled: false, + featureRoomoteControlEnabled: false, } const message: ExtensionMessage = { diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index d88d10d22a6..9a17cc4c947 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -11,6 +11,7 @@ import { type ClineMessage, type TelemetrySetting, TelemetryEventName, + UserSettingsConfig, } from "@roo-code/types" import { CloudService } from "@roo-code/cloud" import { TelemetryService } from "@roo-code/telemetry" @@ -1188,16 +1189,21 @@ export const webviewMessageHandler = async ( `CloudService#updateUserSettings failed: ${error instanceof Error ? error.message : String(error)}`, ) } - + break + case "taskSyncEnabled": + const enabled = message.bool ?? false + const updatedSettings: Partial = { + taskSyncEnabled: enabled, + } + // If disabling task sync, also disable remote control + if (!enabled) { + updatedSettings.extensionBridgeEnabled = false + } try { - await provider.remoteControlEnabled(message.bool ?? false) + await CloudService.instance.updateUserSettings(updatedSettings) } catch (error) { - provider.log( - `ClineProvider#remoteControlEnabled failed: ${error instanceof Error ? error.message : String(error)}`, - ) + provider.log(`Failed to update cloud settings for task sync: ${error}`) } - - await provider.postStateToWebview() break case "refreshAllMcpServers": { const mcpHub = provider.getMcpHub() diff --git a/src/extension.ts b/src/extension.ts index c1f8e0764e5..26a8f9d6e2f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -133,7 +133,7 @@ export async function activate(context: vscode.ExtensionContext) { if (data.state === "logged-out") { try { - await BridgeOrchestrator.disconnect() + await provider.remoteControlEnabled(false) cloudLogger("[CloudService] BridgeOrchestrator disconnected on logout") } catch (error) { cloudLogger( @@ -148,20 +148,7 @@ export async function activate(context: vscode.ExtensionContext) { if (userInfo && CloudService.instance.cloudAPI) { try { - const config = await CloudService.instance.cloudAPI.bridgeConfig() - - const isCloudAgent = - typeof process.env.ROO_CODE_CLOUD_TOKEN === "string" && process.env.ROO_CODE_CLOUD_TOKEN.length > 0 - - const remoteControlEnabled = isCloudAgent - ? true - : (CloudService.instance.getUserSettings()?.settings?.extensionBridgeEnabled ?? false) - - await BridgeOrchestrator.connectOrDisconnect(userInfo, remoteControlEnabled, { - ...config, - provider, - sessionId: vscode.env.sessionId, - }) + provider.remoteControlEnabled(CloudService.instance.isTaskSyncEnabled()) } catch (error) { cloudLogger( `[CloudService] BridgeOrchestrator#connectOrDisconnect failed on settings change: ${error instanceof Error ? error.message : String(error)}`, @@ -181,20 +168,7 @@ export async function activate(context: vscode.ExtensionContext) { } try { - const config = await CloudService.instance.cloudAPI.bridgeConfig() - - const isCloudAgent = - typeof process.env.ROO_CODE_CLOUD_TOKEN === "string" && process.env.ROO_CODE_CLOUD_TOKEN.length > 0 - - const remoteControlEnabled = isCloudAgent - ? true - : (CloudService.instance.getUserSettings()?.settings?.extensionBridgeEnabled ?? false) - - await BridgeOrchestrator.connectOrDisconnect(userInfo, remoteControlEnabled, { - ...config, - provider, - sessionId: vscode.env.sessionId, - }) + provider.remoteControlEnabled(CloudService.instance.isTaskSyncEnabled()) } catch (error) { cloudLogger( `[CloudService] BridgeOrchestrator#connectOrDisconnect failed on user change: ${error instanceof Error ? error.message : String(error)}`, diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 1565bb8c525..0ee4361c3e7 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -278,7 +278,6 @@ export type ExtensionState = Pick< | "profileThresholds" | "includeDiagnosticMessages" | "maxDiagnosticMessages" - | "remoteControlEnabled" | "openRouterImageGenerationSelectedModel" | "includeTaskHistoryInEnhance" > & { @@ -342,6 +341,9 @@ export type ExtensionState = Pick< mcpServers?: McpServer[] hasSystemPromptOverride?: boolean mdmCompliant?: boolean + remoteControlEnabled: boolean + taskSyncEnabled: boolean + featureRoomoteControlEnabled: boolean } export interface ClineSayTool { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index ae8c72dd04f..aee5510c474 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -134,6 +134,7 @@ export interface WebviewMessage { | "mcpEnabled" | "enableMcpServerCreation" | "remoteControlEnabled" + | "taskSyncEnabled" | "searchCommits" | "alwaysApproveResubmit" | "requestDelaySeconds" diff --git a/webview-ui/src/components/cloud/CloudView.tsx b/webview-ui/src/components/cloud/CloudView.tsx index 8ca1a951234..5841f2efe9b 100644 --- a/webview-ui/src/components/cloud/CloudView.tsx +++ b/webview-ui/src/components/cloud/CloudView.tsx @@ -23,7 +23,13 @@ type CloudViewProps = { export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: CloudViewProps) => { const { t } = useAppTranslation() - const { remoteControlEnabled, setRemoteControlEnabled } = useExtensionState() + const { + remoteControlEnabled, + setRemoteControlEnabled, + taskSyncEnabled, + setTaskSyncEnabled, + featureRoomoteControlEnabled, + } = useExtensionState() const wasAuthenticatedRef = useRef(false) const timeoutRef = useRef(null) const manualUrlInputRef = useRef(null) @@ -142,6 +148,12 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl vscode.postMessage({ type: "remoteControlEnabled", bool: newValue }) } + const handleTaskSyncToggle = () => { + const newValue = !taskSyncEnabled + setTaskSyncEnabled(newValue) + vscode.postMessage({ type: "taskSyncEnabled", bool: newValue }) + } + return (
@@ -188,24 +200,62 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl
)} - {userInfo?.extensionBridgeEnabled && ( -
-
- - {t("cloud:remoteControl")} -
-
- {t("cloud:remoteControlDescription")} + {/* Task Sync Toggle - Always shown when authenticated */} +
+
+ + {t("cloud:taskSync")} +
+
+ {t("cloud:taskSyncDescription")} +
+ {userInfo?.organizationId && ( +
+ {t("cloud:taskSyncManagedByOrganization")}
-
+ )} + + {/* Remote Control Toggle - Only shown when both extensionBridgeEnabled and featureRoomoteControlEnabled are true */} + {userInfo?.extensionBridgeEnabled && featureRoomoteControlEnabled && ( + <> +
+ + + {t("cloud:remoteControl")} + +
+
+ {t("cloud:remoteControlDescription")} + {!taskSyncEnabled && ( +
+ {t("cloud:remoteControlRequiresTaskSync")} +
+ )} +
+ + )} + + {/* Info text about usage metrics */} +
+ {t("cloud:usageMetricsAlwaysReported")}
- )} + +
+
diff --git a/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx b/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx index 212cfbc612d..439dbb90839 100644 --- a/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx +++ b/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx @@ -17,9 +17,14 @@ vi.mock("@src/i18n/TranslationContext", () => ({ "cloud:logOut": "Log out", "cloud:connect": "Connect Now", "cloud:visitCloudWebsite": "Visit Roo Code Cloud", + "cloud:taskSync": "Task sync", + "cloud:taskSyncDescription": "Sync your tasks for viewing and sharing on Roo Code Cloud", + "cloud:taskSyncManagedByOrganization": "Task sync is managed by your organization", "cloud:remoteControl": "Roomote Control", "cloud:remoteControlDescription": "Enable following and interacting with tasks in this workspace with Roo Code Cloud", + "cloud:remoteControlRequiresTaskSync": "Task sync must be enabled to use Roomote Control", + "cloud:usageMetricsAlwaysReported": "Model usage info is always reported when logged in", "cloud:profilePicture": "Profile picture", "cloud:cloudUrlPillLabel": "Roo Code Cloud URL: ", } @@ -43,11 +48,17 @@ vi.mock("@src/utils/TelemetryClient", () => ({ })) // Mock the extension state context +const mockExtensionState = { + remoteControlEnabled: false, + setRemoteControlEnabled: vi.fn(), + taskSyncEnabled: true, + setTaskSyncEnabled: vi.fn(), + featureRoomoteControlEnabled: true, // Default to true for tests + setFeatureRoomoteControlEnabled: vi.fn(), +} + vi.mock("@src/context/ExtensionStateContext", () => ({ - useExtensionState: () => ({ - remoteControlEnabled: false, - setRemoteControlEnabled: vi.fn(), - }), + useExtensionState: () => mockExtensionState, })) // Mock window global for images @@ -105,7 +116,7 @@ describe("CloudView", () => { expect(screen.getByText("test@example.com")).toBeInTheDocument() }) - it("should display remote control toggle when user has extension bridge enabled", () => { + it("should display remote control toggle when user has extension bridge enabled and roomote control enabled", () => { const mockUserInfo = { name: "Test User", email: "test@example.com", @@ -150,6 +161,65 @@ describe("CloudView", () => { expect(screen.queryByText("Roomote Control")).not.toBeInTheDocument() }) + it("should not display remote control toggle when roomote control is disabled", () => { + // Temporarily override the mock for this specific test + const originalFeatureRoomoteControlEnabled = mockExtensionState.featureRoomoteControlEnabled + mockExtensionState.featureRoomoteControlEnabled = false + + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + extensionBridgeEnabled: true, // Bridge enabled but roomote control disabled + } + + render( + {}} + />, + ) + + // Check that the remote control toggle is NOT displayed + expect(screen.queryByTestId("remote-control-toggle")).not.toBeInTheDocument() + expect(screen.queryByText("Roomote Control")).not.toBeInTheDocument() + + // Restore the original value + mockExtensionState.featureRoomoteControlEnabled = originalFeatureRoomoteControlEnabled + }) + + it("should display remote control toggle for organization users (simulating backend logic)", () => { + // This test simulates what the ClineProvider would do: + // Organization users are treated as having featureRoomoteControlEnabled true + const originalFeatureRoomoteControlEnabled = mockExtensionState.featureRoomoteControlEnabled + mockExtensionState.featureRoomoteControlEnabled = true // Simulating ClineProvider logic for org users + + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + organizationId: "org-123", // User is in an organization + extensionBridgeEnabled: true, + } + + render( + {}} + />, + ) + + // Check that the remote control toggle IS displayed for organization users + // (The ClineProvider would set featureRoomoteControlEnabled to true for org users) + expect(screen.getByTestId("remote-control-toggle")).toBeInTheDocument() + expect(screen.getByText("Roomote Control")).toBeInTheDocument() + + // Restore the original value + mockExtensionState.featureRoomoteControlEnabled = originalFeatureRoomoteControlEnabled + }) + it("should not display cloud URL pill when pointing to production", () => { const mockUserInfo = { name: "Test User", @@ -215,4 +285,79 @@ describe("CloudView", () => { // Check that the cloud URL pill is NOT displayed when cloudApiUrl is undefined expect(screen.queryByText(/Roo Code Cloud URL:/)).not.toBeInTheDocument() }) + + it("should disable task sync toggle for organization users", () => { + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + organizationId: "org-123", + organizationName: "Test Organization", + } + + render( + {}} + />, + ) + + // Check that the task sync toggle is disabled for organization users + const taskSyncToggle = screen.getByTestId("task-sync-toggle") + expect(taskSyncToggle).toBeInTheDocument() + expect(taskSyncToggle).toHaveAttribute("tabindex", "-1") + + // Check that the organization message is displayed + expect(screen.getByText("Task sync is managed by your organization")).toBeInTheDocument() + }) + + it("should enable task sync toggle for non-organization users", () => { + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + // No organizationId - regular user + } + + render( + {}} + />, + ) + + // Check that the task sync toggle is enabled for non-organization users + const taskSyncToggle = screen.getByTestId("task-sync-toggle") + expect(taskSyncToggle).toBeInTheDocument() + expect(taskSyncToggle).toHaveAttribute("tabindex", "0") + + // Check that the organization message is NOT displayed + expect(screen.queryByText("Task sync is managed by your organization")).not.toBeInTheDocument() + }) + + it("should show task sync state correctly for organization users", () => { + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + organizationId: "org-123", + organizationName: "Test Organization", + } + + // Test with task sync enabled + render( + {}} + />, + ) + + // Check that the toggle shows the current state (enabled in this case) + const taskSyncToggle = screen.getByTestId("task-sync-toggle") + expect(taskSyncToggle).toHaveAttribute("aria-checked", "true") + expect(taskSyncToggle).toHaveAttribute("tabindex", "-1") + }) }) diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 2f4af84f580..5534686db66 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -101,6 +101,10 @@ export interface ExtensionStateContextType extends ExtensionState { setEnableMcpServerCreation: (value: boolean) => void remoteControlEnabled: boolean setRemoteControlEnabled: (value: boolean) => void + taskSyncEnabled: boolean + setTaskSyncEnabled: (value: boolean) => void + featureRoomoteControlEnabled: boolean + setFeatureRoomoteControlEnabled: (value: boolean) => void alwaysApproveResubmit?: boolean setAlwaysApproveResubmit: (value: boolean) => void requestDelaySeconds: number @@ -201,6 +205,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode mcpEnabled: true, enableMcpServerCreation: false, remoteControlEnabled: false, + taskSyncEnabled: false, + featureRoomoteControlEnabled: false, alwaysApproveResubmit: false, requestDelaySeconds: 5, currentApiConfigName: "default", @@ -417,6 +423,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs, remoteControlEnabled: state.remoteControlEnabled ?? false, + taskSyncEnabled: state.taskSyncEnabled, + featureRoomoteControlEnabled: state.featureRoomoteControlEnabled ?? false, setExperimentEnabled: (id, enabled) => setState((prevState) => ({ ...prevState, experiments: { ...prevState.experiments, [id]: enabled } })), setApiConfiguration, @@ -464,6 +472,9 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode setEnableMcpServerCreation: (value) => setState((prevState) => ({ ...prevState, enableMcpServerCreation: value })), setRemoteControlEnabled: (value) => setState((prevState) => ({ ...prevState, remoteControlEnabled: value })), + setTaskSyncEnabled: (value) => setState((prevState) => ({ ...prevState, taskSyncEnabled: value }) as any), + setFeatureRoomoteControlEnabled: (value) => + setState((prevState) => ({ ...prevState, featureRoomoteControlEnabled: value })), setAlwaysApproveResubmit: (value) => setState((prevState) => ({ ...prevState, alwaysApproveResubmit: value })), setRequestDelaySeconds: (value) => setState((prevState) => ({ ...prevState, requestDelaySeconds: value })), setCurrentApiConfigName: (value) => setState((prevState) => ({ ...prevState, currentApiConfigName: value })), diff --git a/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx b/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx index c45b997622b..33d7dc0ec7a 100644 --- a/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx +++ b/webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx @@ -211,6 +211,9 @@ describe("mergeExtensionState", () => { hasOpenedModeSelector: false, // Add the new required property maxImageFileSize: 5, maxTotalImageSize: 20, + remoteControlEnabled: false, + taskSyncEnabled: false, + featureRoomoteControlEnabled: false, } const prevState: ExtensionState = { diff --git a/webview-ui/src/i18n/locales/ca/cloud.json b/webview-ui/src/i18n/locales/ca/cloud.json index 94c12d75e14..80c82895748 100644 --- a/webview-ui/src/i18n/locales/ca/cloud.json +++ b/webview-ui/src/i18n/locales/ca/cloud.json @@ -6,14 +6,18 @@ "signIn": "Connecta't a Roo Code Cloud", "connect": "Connecta", "cloudBenefitsTitle": "Connecta't a Roo Code Cloud", - "cloudBenefitsSubtitle": "Sincronitza els teus prompts i telemetria per habilitar:", - "cloudBenefitHistory": "Historial de tasques en línia", - "cloudBenefitSharing": "Funcions de compartició i col·laboració", - "cloudBenefitMetrics": "Mètriques d'ús basades en tasques, tokens i costos", "cloudBenefitWalkaway": "Segueix i controla tasques des de qualsevol lloc amb Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Permet seguir i interactuar amb tasques en aquest espai de treball amb Roo Code Cloud", + "cloudBenefitSharing": "Comparteix tasques amb altres", + "cloudBenefitHistory": "Accedeix al teu historial de tasques", + "cloudBenefitMetrics": "Obtén una visió holística del teu consum de tokens", "visitCloudWebsite": "Visita Roo Code Cloud", + "taskSync": "Sincronització de tasques", + "taskSyncDescription": "Sincronitza les teves tasques per veure-les i compartir-les a Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Permet controlar tasques des de Roo Code Cloud", + "remoteControlRequiresTaskSync": "La sincronització de tasques ha d'estar habilitada per utilitzar Roomote Control", + "taskSyncManagedByOrganization": "La sincronització de tasques la gestiona la teva organització", + "usageMetricsAlwaysReported": "La informació d'ús del model sempre es reporta quan s'ha iniciat sessió", "cloudUrlPillLabel": "URL de Roo Code Cloud", "authWaiting": "Esperant que es completi l'autenticació...", "havingTrouble": "Tens problemes?", diff --git a/webview-ui/src/i18n/locales/de/cloud.json b/webview-ui/src/i18n/locales/de/cloud.json index e76245f4304..9273497e858 100644 --- a/webview-ui/src/i18n/locales/de/cloud.json +++ b/webview-ui/src/i18n/locales/de/cloud.json @@ -4,19 +4,23 @@ "logOut": "Abmelden", "testApiAuthentication": "API-Authentifizierung testen", "signIn": "Mit Roo Code Cloud verbinden", - "connect": "Verbinden", + "connect": "Jetzt verbinden", "cloudBenefitsTitle": "Mit Roo Code Cloud verbinden", - "cloudBenefitsSubtitle": "Synchronisiere deine Prompts und Telemetrie, um folgendes zu aktivieren:", - "cloudBenefitHistory": "Online-Aufgabenverlauf", - "cloudBenefitSharing": "Freigabe- und Kollaborationsfunktionen", - "cloudBenefitMetrics": "Aufgaben-, Token- und kostenbasierte Nutzungsmetriken", "cloudBenefitWalkaway": "Verfolge und steuere Aufgaben von überall mit Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Ermöglicht das Verfolgen und Interagieren mit Aufgaben in diesem Arbeitsbereich mit Roo Code Cloud", + "cloudBenefitSharing": "Aufgaben mit anderen teilen", + "cloudBenefitHistory": "Auf deinen Aufgabenverlauf zugreifen", + "cloudBenefitMetrics": "Erhalte einen ganzheitlichen Überblick über deinen Token-Verbrauch", "visitCloudWebsite": "Roo Code Cloud besuchen", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "Aufgabensynchronisierung", + "taskSyncDescription": "Synchronisiere deine Aufgaben zum Anzeigen und Teilen in Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Ermöglicht die Steuerung von Aufgaben über Roo Code Cloud", + "remoteControlRequiresTaskSync": "Die Aufgabensynchronisierung muss aktiviert sein, um Roomote Control zu verwenden", + "taskSyncManagedByOrganization": "Die Aufgabensynchronisierung wird von deiner Organisation verwaltet", + "usageMetricsAlwaysReported": "Modellnutzungsinformationen werden bei Anmeldung immer gemeldet", "authWaiting": "Warte auf Abschluss der Authentifizierung...", "havingTrouble": "Probleme?", "pasteCallbackUrl": "Kopiere die Redirect-URL aus deinem Browser und füge sie hier ein:", - "startOver": "Von vorne beginnen" + "startOver": "Von vorne beginnen", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/en/cloud.json b/webview-ui/src/i18n/locales/en/cloud.json index c436f50bc44..dde103a2c2c 100644 --- a/webview-ui/src/i18n/locales/en/cloud.json +++ b/webview-ui/src/i18n/locales/en/cloud.json @@ -11,8 +11,13 @@ "cloudBenefitHistory": "Access your task history", "cloudBenefitMetrics": "Get a holistic view of your token consumption", "visitCloudWebsite": "Visit Roo Code Cloud", + "taskSync": "Task sync", + "taskSyncDescription": "Sync your tasks for viewing and sharing on Roo Code Cloud", "remoteControl": "Roomote Control", - "remoteControlDescription": "Enable following and interacting with tasks in this workspace with Roo Code Cloud", + "remoteControlDescription": "Allow controlling tasks from Roo Code Cloud", + "remoteControlRequiresTaskSync": "Task sync must be enabled to use Roomote Control", + "taskSyncManagedByOrganization": "Task sync is managed by your organization", + "usageMetricsAlwaysReported": "Model usage info is always reported when logged in", "cloudUrlPillLabel": "Roo Code Cloud URL", "authWaiting": "Waiting for browser authentication...", "havingTrouble": "Having trouble?", diff --git a/webview-ui/src/i18n/locales/es/cloud.json b/webview-ui/src/i18n/locales/es/cloud.json index 1515a2a9173..0d831862ef1 100644 --- a/webview-ui/src/i18n/locales/es/cloud.json +++ b/webview-ui/src/i18n/locales/es/cloud.json @@ -4,19 +4,23 @@ "logOut": "Cerrar sesión", "testApiAuthentication": "Probar autenticación de API", "signIn": "Conectar a Roo Code Cloud", - "connect": "Conectar", + "connect": "Conectar ahora", "cloudBenefitsTitle": "Conectar a Roo Code Cloud", - "cloudBenefitsSubtitle": "Sincroniza tus prompts y telemetría para habilitar:", - "cloudBenefitHistory": "Historial de tareas en línea", - "cloudBenefitSharing": "Funciones de compartir y colaboración", - "cloudBenefitMetrics": "Métricas de uso basadas en tareas, tokens y costos", "cloudBenefitWalkaway": "Sigue y controla tareas desde cualquier lugar con Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Permite seguir e interactuar con tareas en este espacio de trabajo con Roo Code Cloud", + "cloudBenefitSharing": "Comparte tareas con otros", + "cloudBenefitHistory": "Accede a tu historial de tareas", + "cloudBenefitMetrics": "Obtén una visión holística de tu consumo de tokens", "visitCloudWebsite": "Visitar Roo Code Cloud", - "cloudUrlPillLabel": "URL de Roo Code Cloud", + "taskSync": "Sincronización de tareas", + "taskSyncDescription": "Sincroniza tus tareas para verlas y compartirlas en Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Permite controlar tareas desde Roo Code Cloud", + "remoteControlRequiresTaskSync": "La sincronización de tareas debe estar habilitada para usar Roomote Control", + "taskSyncManagedByOrganization": "La sincronización de tareas es gestionada por tu organización", + "usageMetricsAlwaysReported": "La información de uso del modelo siempre se reporta cuando se ha iniciado sesión", "authWaiting": "Esperando que se complete la autenticación...", "havingTrouble": "¿Tienes problemas?", "pasteCallbackUrl": "Copia la URL de redirect desde tu navegador y pégala aquí:", - "startOver": "Empezar de nuevo" + "startOver": "Empezar de nuevo", + "cloudUrlPillLabel": "URL de Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/fr/cloud.json b/webview-ui/src/i18n/locales/fr/cloud.json index 5ed35af6a7e..9bff2d63b09 100644 --- a/webview-ui/src/i18n/locales/fr/cloud.json +++ b/webview-ui/src/i18n/locales/fr/cloud.json @@ -4,19 +4,23 @@ "logOut": "Déconnexion", "testApiAuthentication": "Tester l'authentification API", "signIn": "Se connecter à Roo Code Cloud", - "connect": "Se connecter", + "connect": "Se connecter maintenant", "cloudBenefitsTitle": "Se connecter à Roo Code Cloud", - "cloudBenefitsSubtitle": "Synchronise tes prompts et télémétrie pour activer :", - "cloudBenefitHistory": "Historique des tâches en ligne", - "cloudBenefitSharing": "Fonctionnalités de partage et collaboration", - "cloudBenefitMetrics": "Métriques d'utilisation basées sur les tâches, tokens et coûts", "cloudBenefitWalkaway": "Suivez et contrôlez les tâches depuis n'importe où avec Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Permet de suivre et d'interagir avec les tâches dans cet espace de travail avec Roo Code Cloud", + "cloudBenefitSharing": "Partagez des tâches avec d'autres", + "cloudBenefitHistory": "Accédez à votre historique de tâches", + "cloudBenefitMetrics": "Obtenez une vue holistique de votre consommation de tokens", "visitCloudWebsite": "Visiter Roo Code Cloud", - "cloudUrlPillLabel": "URL de Roo Code Cloud", + "taskSync": "Synchronisation des tâches", + "taskSyncDescription": "Synchronisez vos tâches pour les visualiser et les partager sur Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Permet de contrôler les tâches depuis Roo Code Cloud", + "remoteControlRequiresTaskSync": "La synchronisation des tâches doit être activée pour utiliser Roomote Control", + "taskSyncManagedByOrganization": "La synchronisation des tâches est gérée par votre organisation", + "usageMetricsAlwaysReported": "Les informations d'utilisation du modèle sont toujours signalées lors de la connexion", "authWaiting": "En attente de la fin de l'authentification...", "havingTrouble": "Des difficultés ?", "pasteCallbackUrl": "Copie l'URL de redirect depuis ton navigateur et colle-la ici :", - "startOver": "Recommencer" + "startOver": "Recommencer", + "cloudUrlPillLabel": "URL de Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/hi/cloud.json b/webview-ui/src/i18n/locales/hi/cloud.json index c10e7de35cc..8cf0cea57ea 100644 --- a/webview-ui/src/i18n/locales/hi/cloud.json +++ b/webview-ui/src/i18n/locales/hi/cloud.json @@ -4,19 +4,23 @@ "logOut": "लॉग आउट", "testApiAuthentication": "API प्रमाणीकरण का परीक्षण करें", "signIn": "Roo Code Cloud से कनेक्ट करें", - "connect": "कनेक्ट करें", + "connect": "अभी कनेक्ट करें", "cloudBenefitsTitle": "Roo Code Cloud से कनेक्ट करें", - "cloudBenefitsSubtitle": "निम्नलिखित को सक्षम करने के लिए अपने prompts और telemetry को sync करें:", - "cloudBenefitHistory": "ऑनलाइन कार्य इतिहास", - "cloudBenefitSharing": "साझाकरण और सहयोग सुविधाएं", - "cloudBenefitMetrics": "कार्य, token और लागत आधारित उपयोग मेट्रिक्स", "cloudBenefitWalkaway": "Roomote Control के साथ कहीं से भी कार्यों को फॉलो और नियंत्रित करें", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloud के साथ इस वर्कस्पेस में कार्यों को फॉलो और इंटरैक्ट करने की सुविधा दें", + "cloudBenefitSharing": "दूसरों के साथ कार्य साझा करें", + "cloudBenefitHistory": "अपने कार्य इतिहास तक पहुंचें", + "cloudBenefitMetrics": "अपने टोकन उपभोग का समग्र दृश्य प्राप्त करें", "visitCloudWebsite": "Roo Code Cloud पर जाएं", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "कार्य सिंक", + "taskSyncDescription": "Roo Code Cloud पर देखने और साझा करने के लिए अपने कार्यों को सिंक करें", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Roo Code Cloud से कार्यों को नियंत्रित करने की अनुमति दें", + "remoteControlRequiresTaskSync": "Roomote Control का उपयोग करने के लिए कार्य सिंक सक्षम होना चाहिए", + "taskSyncManagedByOrganization": "कार्य सिंक आपके संगठन द्वारा प्रबंधित किया जाता है", + "usageMetricsAlwaysReported": "लॉग इन होने पर मॉडल उपयोग जानकारी हमेशा रिपोर्ट की जाती है", "authWaiting": "प्रमाणीकरण पूरा होने की प्रतीक्षा कर रहे हैं...", "havingTrouble": "समस्या हो रही है?", "pasteCallbackUrl": "अपने ब्राउज़र से redirect URL कॉपी करें और यहाँ पेस्ट करें:", - "startOver": "फिर से शुरू करें" + "startOver": "फिर से शुरू करें", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/id/cloud.json b/webview-ui/src/i18n/locales/id/cloud.json index 27ea5c4bb78..c5390d0ce56 100644 --- a/webview-ui/src/i18n/locales/id/cloud.json +++ b/webview-ui/src/i18n/locales/id/cloud.json @@ -4,19 +4,23 @@ "logOut": "Keluar", "testApiAuthentication": "Uji Autentikasi API", "signIn": "Hubungkan ke Roo Code Cloud", - "connect": "Hubungkan", + "connect": "Hubungkan Sekarang", "cloudBenefitsTitle": "Hubungkan ke Roo Code Cloud", - "cloudBenefitsSubtitle": "Sinkronkan prompt dan telemetri kamu untuk mengaktifkan:", - "cloudBenefitHistory": "Riwayat tugas online", - "cloudBenefitSharing": "Fitur berbagi dan kolaborasi", - "cloudBenefitMetrics": "Metrik penggunaan berdasarkan tugas, token, dan biaya", "cloudBenefitWalkaway": "Ikuti dan kontrol tugas dari mana saja dengan Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Memungkinkan mengikuti dan berinteraksi dengan tugas di workspace ini dengan Roo Code Cloud", + "cloudBenefitSharing": "Bagikan tugas dengan orang lain", + "cloudBenefitHistory": "Akses riwayat tugas Anda", + "cloudBenefitMetrics": "Dapatkan tampilan holistik konsumsi token Anda", "visitCloudWebsite": "Kunjungi Roo Code Cloud", - "cloudUrlPillLabel": "URL Roo Code Cloud", + "taskSync": "Sinkronisasi tugas", + "taskSyncDescription": "Sinkronkan tugas Anda untuk melihat dan berbagi di Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Izinkan mengontrol tugas dari Roo Code Cloud", + "remoteControlRequiresTaskSync": "Sinkronisasi tugas harus diaktifkan untuk menggunakan Roomote Control", + "taskSyncManagedByOrganization": "Sinkronisasi tugas dikelola oleh organisasi Anda", + "usageMetricsAlwaysReported": "Informasi penggunaan model selalu dilaporkan saat masuk", "authWaiting": "Menunggu autentikasi selesai...", "havingTrouble": "Ada masalah?", "pasteCallbackUrl": "Salin URL redirect dari browser dan tempel di sini:", - "startOver": "Mulai dari awal" + "startOver": "Mulai dari awal", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/it/cloud.json b/webview-ui/src/i18n/locales/it/cloud.json index 74bd07144cd..bfb9c74f7a7 100644 --- a/webview-ui/src/i18n/locales/it/cloud.json +++ b/webview-ui/src/i18n/locales/it/cloud.json @@ -4,19 +4,23 @@ "logOut": "Disconnetti", "testApiAuthentication": "Verifica autenticazione API", "signIn": "Connetti a Roo Code Cloud", - "connect": "Connetti", + "connect": "Connetti ora", "cloudBenefitsTitle": "Connetti a Roo Code Cloud", - "cloudBenefitsSubtitle": "Sincronizza i tuoi prompt e telemetria per abilitare:", - "cloudBenefitHistory": "Cronologia attività online", - "cloudBenefitSharing": "Funzionalità di condivisione e collaborazione", - "cloudBenefitMetrics": "Metriche di utilizzo basate su attività, token e costi", "cloudBenefitWalkaway": "Segui e controlla le attività da qualsiasi luogo con Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Abilita il monitoraggio e l'interazione con le attività in questo workspace con Roo Code Cloud", + "cloudBenefitSharing": "Condividi attività con altri", + "cloudBenefitHistory": "Accedi alla cronologia delle tue attività", + "cloudBenefitMetrics": "Ottieni una visione olistica del tuo consumo di token", "visitCloudWebsite": "Visita Roo Code Cloud", - "cloudUrlPillLabel": "URL di Roo Code Cloud", + "taskSync": "Sincronizzazione attività", + "taskSyncDescription": "Sincronizza le tue attività per visualizzarle e condividerle su Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Consenti il controllo delle attività da Roo Code Cloud", + "remoteControlRequiresTaskSync": "La sincronizzazione delle attività deve essere abilitata per utilizzare Roomote Control", + "taskSyncManagedByOrganization": "La sincronizzazione delle attività è gestita dalla tua organizzazione", + "usageMetricsAlwaysReported": "Le informazioni sull'utilizzo del modello vengono sempre segnalate quando si è connessi", "authWaiting": "In attesa del completamento dell'autenticazione...", "havingTrouble": "Hai problemi?", "pasteCallbackUrl": "Copia l'URL di redirect dal tuo browser e incollalo qui:", - "startOver": "Ricomincia" + "startOver": "Ricomincia", + "cloudUrlPillLabel": "URL di Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/ja/cloud.json b/webview-ui/src/i18n/locales/ja/cloud.json index 1ab89d04358..90d5f61881a 100644 --- a/webview-ui/src/i18n/locales/ja/cloud.json +++ b/webview-ui/src/i18n/locales/ja/cloud.json @@ -4,19 +4,23 @@ "logOut": "ログアウト", "testApiAuthentication": "API認証をテスト", "signIn": "Roo Code Cloud に接続", - "connect": "接続", + "connect": "今すぐ接続", "cloudBenefitsTitle": "Roo Code Cloudに接続", - "cloudBenefitsSubtitle": "プロンプトとテレメトリを同期して以下を有効にする:", - "cloudBenefitHistory": "オンラインタスク履歴", - "cloudBenefitSharing": "共有とコラボレーション機能", - "cloudBenefitMetrics": "タスク、Token、コストベースの使用メトリクス", "cloudBenefitWalkaway": "Roomote Controlでどこからでもタスクをフォローし制御", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloudでこのワークスペースのタスクをフォローし操作することを有効にする", + "cloudBenefitSharing": "他の人とタスクを共有", + "cloudBenefitHistory": "タスク履歴にアクセス", + "cloudBenefitMetrics": "トークン消費の全体像を把握", "visitCloudWebsite": "Roo Code Cloudを訪問", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "タスク同期", + "taskSyncDescription": "Roo Code Cloudでタスクを表示・共有するために同期", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Roo Code Cloudからタスクを制御できるようにする", + "remoteControlRequiresTaskSync": "Roomote Controlを使用するにはタ스크同期を有効にする必要があります", + "taskSyncManagedByOrganization": "タスク同期は組織によって管理されます", + "usageMetricsAlwaysReported": "ログイン時にはモデル使用情報が常に報告されます", "authWaiting": "認証完了をお待ちください...", "havingTrouble": "問題が発生していますか?", "pasteCallbackUrl": "ブラウザからリダイレクトURLをコピーし、ここに貼り付けてください:", - "startOver": "最初からやり直す" + "startOver": "最初からやり直す", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/ko/cloud.json b/webview-ui/src/i18n/locales/ko/cloud.json index 96b4760ee31..32017672a5f 100644 --- a/webview-ui/src/i18n/locales/ko/cloud.json +++ b/webview-ui/src/i18n/locales/ko/cloud.json @@ -4,19 +4,23 @@ "logOut": "로그아웃", "testApiAuthentication": "API 인증 테스트", "signIn": "Roo Code Cloud에 연결", - "connect": "연결", + "connect": "지금 연결", "cloudBenefitsTitle": "Roo Code Cloud에 연결", - "cloudBenefitsSubtitle": "프롬프트와 텔레메트리를 동기화하여 다음을 활성화:", - "cloudBenefitHistory": "온라인 작업 기록", - "cloudBenefitSharing": "공유 및 협업 기능", - "cloudBenefitMetrics": "작업, 토큰, 비용 기반 사용 메트릭", "cloudBenefitWalkaway": "Roomote Control로 어디서나 작업을 팔로우하고 제어하세요", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Roo Code Cloud로 이 워크스페이스의 작업을 팔로우하고 상호작용할 수 있게 합니다", + "cloudBenefitSharing": "다른 사람과 작업 공유", + "cloudBenefitHistory": "작업 기록에 액세스", + "cloudBenefitMetrics": "토큰 소비에 대한 전체적인 보기 얻기", "visitCloudWebsite": "Roo Code Cloud 방문", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "작업 동기화", + "taskSyncDescription": "Roo Code Cloud에서 보고 공유할 수 있도록 작업을 동기화", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Roo Code Cloud에서 작업을 제어할 수 있도록 허용", + "remoteControlRequiresTaskSync": "Roomote Control을 사용하려면 작업 동기화가 활성화되어야 합니다", + "taskSyncManagedByOrganization": "작업 동기화는 조직에서 관리합니다", + "usageMetricsAlwaysReported": "로그인 시 모델 사용 정보가 항상 보고됩니다", "authWaiting": "인증 완료를 기다리는 중...", "havingTrouble": "문제가 있나요?", "pasteCallbackUrl": "브라우저에서 리다이렉트 URL을 복사하여 여기에 붙여넣으세요:", - "startOver": "다시 시작" + "startOver": "다시 시작", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/nl/cloud.json b/webview-ui/src/i18n/locales/nl/cloud.json index 5c2651d44aa..00d6bb965e2 100644 --- a/webview-ui/src/i18n/locales/nl/cloud.json +++ b/webview-ui/src/i18n/locales/nl/cloud.json @@ -4,19 +4,23 @@ "logOut": "Uitloggen", "testApiAuthentication": "API-authenticatie testen", "signIn": "Verbind met Roo Code Cloud", - "connect": "Verbinden", + "connect": "Nu verbinden", "cloudBenefitsTitle": "Verbind met Roo Code Cloud", - "cloudBenefitsSubtitle": "Synchroniseer je prompts en telemetrie om het volgende in te schakelen:", - "cloudBenefitHistory": "Online taakgeschiedenis", - "cloudBenefitSharing": "Deel- en samenwerkingsfuncties", - "cloudBenefitMetrics": "Taak-, token- en kostengebaseerde gebruiksstatistieken", "cloudBenefitWalkaway": "Volg en beheer taken van overal met Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Schakel het volgen en interacteren met taken in deze workspace in met Roo Code Cloud", + "cloudBenefitSharing": "Deel taken met anderen", + "cloudBenefitHistory": "Toegang tot je taakgeschiedenis", + "cloudBenefitMetrics": "Krijg een holistisch overzicht van je tokenverbruik", "visitCloudWebsite": "Bezoek Roo Code Cloud", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "Taaksynchronisatie", + "taskSyncDescription": "Synchroniseer je taken om ze te bekijken en delen op Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Sta toe taken te besturen vanuit Roo Code Cloud", + "remoteControlRequiresTaskSync": "Taaksynchronisatie moet ingeschakeld zijn om Roomote Control te gebruiken", + "taskSyncManagedByOrganization": "Taaksynchronisatie wordt beheerd door uw organisatie", + "usageMetricsAlwaysReported": "Modelgebruiksinformatie wordt altijd gerapporteerd wanneer ingelogd", "authWaiting": "Wachten tot authenticatie voltooid is...", "havingTrouble": "Problemen?", "pasteCallbackUrl": "Kopieer de redirect-URL uit je browser en plak hem hier:", - "startOver": "Opnieuw beginnen" + "startOver": "Opnieuw beginnen", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/pl/cloud.json b/webview-ui/src/i18n/locales/pl/cloud.json index 0cb860ee1f2..193397dc3b8 100644 --- a/webview-ui/src/i18n/locales/pl/cloud.json +++ b/webview-ui/src/i18n/locales/pl/cloud.json @@ -4,19 +4,23 @@ "logOut": "Wyloguj", "testApiAuthentication": "Testuj uwierzytelnianie API", "signIn": "Połącz z Roo Code Cloud", - "connect": "Połącz", + "connect": "Połącz teraz", "cloudBenefitsTitle": "Połącz z Roo Code Cloud", - "cloudBenefitsSubtitle": "Synchronizuj swoje prompty i telemetrię, aby włączyć:", - "cloudBenefitHistory": "Historia zadań online", - "cloudBenefitSharing": "Funkcje udostępniania i współpracy", - "cloudBenefitMetrics": "Metryki użycia oparte na zadaniach, tokenach i kosztach", "cloudBenefitWalkaway": "Śledź i kontroluj zadania z dowolnego miejsca za pomocą Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Umożliwia śledzenie i interakcję z zadaniami w tym obszarze roboczym za pomocą Roo Code Cloud", + "cloudBenefitSharing": "Udostępniaj zadania innym", + "cloudBenefitHistory": "Uzyskaj dostęp do historii zadań", + "cloudBenefitMetrics": "Uzyskaj całościowy widok zużycia tokenów", "visitCloudWebsite": "Odwiedź Roo Code Cloud", - "cloudUrlPillLabel": "URL Roo Code Cloud", + "taskSync": "Synchronizacja zadań", + "taskSyncDescription": "Synchronizuj swoje zadania, aby przeglądać i udostępniać je w Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Pozwól kontrolować zadania z Roo Code Cloud", + "remoteControlRequiresTaskSync": "Synchronizacja zadań musi być włączona, aby używać Roomote Control", + "taskSyncManagedByOrganization": "Synchronizacja zadań jest zarządzana przez Twoją organizację", + "usageMetricsAlwaysReported": "Informacje o użyciu modelu są zawsze raportowane po zalogowaniu", "authWaiting": "Oczekiwanie na zakończenie uwierzytelniania...", "havingTrouble": "Masz problemy?", "pasteCallbackUrl": "Skopiuj URL redirect z przeglądarki i wklej tutaj:", - "startOver": "Zacznij od nowa" + "startOver": "Zacznij od nowa", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/pt-BR/cloud.json b/webview-ui/src/i18n/locales/pt-BR/cloud.json index 7e0a29e38b4..0d542a56fb0 100644 --- a/webview-ui/src/i18n/locales/pt-BR/cloud.json +++ b/webview-ui/src/i18n/locales/pt-BR/cloud.json @@ -4,19 +4,23 @@ "logOut": "Sair", "testApiAuthentication": "Testar Autenticação de API", "signIn": "Conectar ao Roo Code Cloud", - "connect": "Conectar", + "connect": "Conectar Agora", "cloudBenefitsTitle": "Conectar ao Roo Code Cloud", - "cloudBenefitsSubtitle": "Sincronize seus prompts e telemetria para habilitar:", - "cloudBenefitHistory": "Histórico de tarefas online", - "cloudBenefitSharing": "Recursos de compartilhamento e colaboração", - "cloudBenefitMetrics": "Métricas de uso baseadas em tarefas, tokens e custos", "cloudBenefitWalkaway": "Acompanhe e controle tarefas de qualquer lugar com Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Permite acompanhar e interagir com tarefas neste workspace com Roo Code Cloud", + "cloudBenefitSharing": "Compartilhe tarefas com outros", + "cloudBenefitHistory": "Acesse seu histórico de tarefas", + "cloudBenefitMetrics": "Obtenha uma visão holística do seu consumo de tokens", "visitCloudWebsite": "Visitar Roo Code Cloud", - "cloudUrlPillLabel": "URL do Roo Code Cloud ", + "taskSync": "Sincronização de tarefas", + "taskSyncDescription": "Sincronize suas tarefas para visualizar e compartilhar no Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Permite controlar tarefas a partir do Roo Code Cloud", + "remoteControlRequiresTaskSync": "A sincronização de tarefas deve estar habilitada para usar o Roomote Control", + "taskSyncManagedByOrganization": "A sincronização de tarefas é gerenciada pela sua organização", + "usageMetricsAlwaysReported": "As informações de uso do modelo são sempre reportadas quando conectado", "authWaiting": "Aguardando conclusão da autenticação...", "havingTrouble": "Tendo problemas?", "pasteCallbackUrl": "Copie a URL de redirect do seu navegador e cole aqui:", - "startOver": "Recomeçar" + "startOver": "Recomeçar", + "cloudUrlPillLabel": "URL do Roo Code Cloud " } diff --git a/webview-ui/src/i18n/locales/ru/cloud.json b/webview-ui/src/i18n/locales/ru/cloud.json index b30d6064a23..e814b8ecad3 100644 --- a/webview-ui/src/i18n/locales/ru/cloud.json +++ b/webview-ui/src/i18n/locales/ru/cloud.json @@ -4,19 +4,23 @@ "logOut": "Выход", "testApiAuthentication": "Проверить аутентификацию API", "signIn": "Подключиться к Roo Code Cloud", - "connect": "Подключиться", + "connect": "Подключиться сейчас", "cloudBenefitsTitle": "Подключиться к Roo Code Cloud", - "cloudBenefitsSubtitle": "Синхронизируй свои промпты и телеметрию, чтобы включить:", - "cloudBenefitHistory": "Онлайн-история задач", - "cloudBenefitSharing": "Функции обмена и совместной работы", - "cloudBenefitMetrics": "Метрики использования на основе задач, токенов и затрат", "cloudBenefitWalkaway": "Отслеживайте и управляйте задачами откуда угодно с Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Позволяет отслеживать и взаимодействовать с задачами в этом рабочем пространстве с Roo Code Cloud", + "cloudBenefitSharing": "Делитесь задачами с другими", + "cloudBenefitHistory": "Получите доступ к истории задач", + "cloudBenefitMetrics": "Получите целостное представление о потреблении токенов", "visitCloudWebsite": "Посетить Roo Code Cloud", - "cloudUrlPillLabel": "URL Roo Code Cloud", + "taskSync": "Синхронизация задач", + "taskSyncDescription": "Синхронизируйте свои задачи для просмотра и обмена в Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Разрешить управление задачами из Roo Code Cloud", + "remoteControlRequiresTaskSync": "Для использования Roomote Control должна быть включена синхронизация задач", + "taskSyncManagedByOrganization": "Синхронизация задач управляется вашей организацией", + "usageMetricsAlwaysReported": "Информация об использовании модели всегда сообщается при входе в систему", "authWaiting": "Ожидание завершения аутентификации...", "havingTrouble": "Проблемы?", "pasteCallbackUrl": "Скопируй URL перенаправления из браузера и вставь его сюда:", - "startOver": "Начать заново" + "startOver": "Начать заново", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/tr/cloud.json b/webview-ui/src/i18n/locales/tr/cloud.json index c82661163f2..6f3a2bc8816 100644 --- a/webview-ui/src/i18n/locales/tr/cloud.json +++ b/webview-ui/src/i18n/locales/tr/cloud.json @@ -4,19 +4,23 @@ "logOut": "Çıkış yap", "testApiAuthentication": "API Kimlik Doğrulamayı Test Et", "signIn": "Roo Code Cloud'a bağlan", - "connect": "Bağlan", + "connect": "Şimdi Bağlan", "cloudBenefitsTitle": "Roo Code Cloud'a bağlan", - "cloudBenefitsSubtitle": "Aşağıdakileri etkinleştirmek için promptlarını ve telemetriyi senkronize et:", - "cloudBenefitHistory": "Çevrimiçi görev geçmişi", - "cloudBenefitSharing": "Paylaşım ve işbirliği özellikleri", - "cloudBenefitMetrics": "Görev, token ve maliyet tabanlı kullanım metrikleri", "cloudBenefitWalkaway": "Roomote Control ile görevleri her yerden takip et ve kontrol et", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Bu çalışma alanındaki görevleri Roo Code Cloud ile takip etme ve etkileşim kurma imkanı sağlar", + "cloudBenefitSharing": "Görevleri başkalarıyla paylaş", + "cloudBenefitHistory": "Görev geçmişine eriş", + "cloudBenefitMetrics": "Token tüketiminizin bütünsel görünümünü elde edin", "visitCloudWebsite": "Roo Code Cloud'u ziyaret et", - "cloudUrlPillLabel": "Roo Code Cloud URL'si", + "taskSync": "Görev senkronizasyonu", + "taskSyncDescription": "Görevlerinizi Roo Code Cloud'da görüntülemek ve paylaşmak için senkronize edin", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Roo Code Cloud'dan görevleri kontrol etmeye izin ver", + "remoteControlRequiresTaskSync": "Roomote Control'ü kullanmak için görev senkronizasyonu etkinleştirilmelidir", + "taskSyncManagedByOrganization": "Görev senkronizasyonu kuruluşunuz tarafından yönetilir", + "usageMetricsAlwaysReported": "Oturum açıldığında model kullanım bilgileri her zaman raporlanır", "authWaiting": "Kimlik doğrulama tamamlanması bekleniyor...", "havingTrouble": "Sorun yaşıyor musun?", "pasteCallbackUrl": "Tarayıcından redirect URL'sini kopyala ve buraya yapıştır:", - "startOver": "Baştan başla" + "startOver": "Baştan başla", + "cloudUrlPillLabel": "Roo Code Cloud URL'si" } diff --git a/webview-ui/src/i18n/locales/vi/cloud.json b/webview-ui/src/i18n/locales/vi/cloud.json index ee5c2683b0c..376727426a7 100644 --- a/webview-ui/src/i18n/locales/vi/cloud.json +++ b/webview-ui/src/i18n/locales/vi/cloud.json @@ -4,19 +4,23 @@ "logOut": "Đăng xuất", "testApiAuthentication": "Kiểm tra xác thực API", "signIn": "Kết nối với Roo Code Cloud", - "connect": "Kết nối", + "connect": "Kết nối ngay", "cloudBenefitsTitle": "Kết nối với Roo Code Cloud", - "cloudBenefitsSubtitle": "Đồng bộ prompts và telemetry của bạn để kích hoạt:", - "cloudBenefitHistory": "Lịch sử tác vụ trực tuyến", - "cloudBenefitSharing": "Tính năng chia sẻ và cộng tác", - "cloudBenefitMetrics": "Số liệu sử dụng dựa trên tác vụ, token và chi phí", "cloudBenefitWalkaway": "Theo dõi và điều khiển tác vụ từ bất kỳ đâu với Roomote Control", - "remoteControl": "Roomote Control", - "remoteControlDescription": "Cho phép theo dõi và tương tác với các tác vụ trong workspace này với Roo Code Cloud", + "cloudBenefitSharing": "Chia sẻ tác vụ với người khác", + "cloudBenefitHistory": "Truy cập lịch sử tác vụ của bạn", + "cloudBenefitMetrics": "Có cái nhìn toàn diện về mức tiêu thụ token của bạn", "visitCloudWebsite": "Truy cập Roo Code Cloud", - "cloudUrlPillLabel": "URL Roo Code Cloud", + "taskSync": "Đồng bộ tác vụ", + "taskSyncDescription": "Đồng bộ tác vụ của bạn để xem và chia sẻ trên Roo Code Cloud", + "remoteControl": "Roomote Control", + "remoteControlDescription": "Cho phép điều khiển tác vụ từ Roo Code Cloud", + "remoteControlRequiresTaskSync": "Đồng bộ tác vụ phải được bật để sử dụng Roomote Control", + "taskSyncManagedByOrganization": "Việc đồng bộ hóa công việc được quản lý bởi tổ chức của bạn", + "usageMetricsAlwaysReported": "Thông tin sử dụng mô hình luôn được báo cáo khi đăng nhập", "authWaiting": "Đang chờ hoàn tất xác thực...", "havingTrouble": "Gặp vấn đề?", "pasteCallbackUrl": "Sao chép URL redirect từ trình duyệt và dán vào đây:", - "startOver": "Bắt đầu lại" + "startOver": "Bắt đầu lại", + "cloudUrlPillLabel": "URL Roo Code Cloud" } diff --git a/webview-ui/src/i18n/locales/zh-CN/cloud.json b/webview-ui/src/i18n/locales/zh-CN/cloud.json index c42647a0967..98c816f20a7 100644 --- a/webview-ui/src/i18n/locales/zh-CN/cloud.json +++ b/webview-ui/src/i18n/locales/zh-CN/cloud.json @@ -4,19 +4,23 @@ "logOut": "退出登录", "testApiAuthentication": "测试 API 认证", "signIn": "连接到 Roo Code Cloud", - "connect": "连接", + "connect": "立即连接", "cloudBenefitsTitle": "连接到 Roo Code Cloud", - "cloudBenefitsSubtitle": "同步你的提示词和遥测数据以启用:", - "cloudBenefitHistory": "在线任务历史", - "cloudBenefitSharing": "共享和协作功能", - "cloudBenefitMetrics": "基于任务、Token 和成本的使用指标", "cloudBenefitWalkaway": "使用 Roomote Control 随时随地跟踪和控制任务", - "remoteControl": "Roomote Control", - "remoteControlDescription": "允许通过 Roo Code Cloud 跟踪和操作此工作区中的任务", + "cloudBenefitSharing": "与他人共享任务", + "cloudBenefitHistory": "访问您的任务历史", + "cloudBenefitMetrics": "获取您的令牌消耗的整体视图", "visitCloudWebsite": "访问 Roo Code Cloud", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "任务同步", + "taskSyncDescription": "同步您的任务以在 Roo Code Cloud 上查看和共享", + "remoteControl": "Roomote Control", + "remoteControlDescription": "允许从 Roo Code Cloud 控制任务", + "remoteControlRequiresTaskSync": "必须启用任务同步才能使用 Roomote Control", + "taskSyncManagedByOrganization": "任务同步由您的组织管理", + "usageMetricsAlwaysReported": "登录时始终报告模型使用信息", "authWaiting": "等待身份验证完成...", "havingTrouble": "遇到问题?", "pasteCallbackUrl": "从浏览器复制重定向 URL 并粘贴到这里:", - "startOver": "重新开始" + "startOver": "重新开始", + "cloudUrlPillLabel": "Roo Code Cloud URL" } diff --git a/webview-ui/src/i18n/locales/zh-TW/cloud.json b/webview-ui/src/i18n/locales/zh-TW/cloud.json index efb2b25ad99..00e9f71621e 100644 --- a/webview-ui/src/i18n/locales/zh-TW/cloud.json +++ b/webview-ui/src/i18n/locales/zh-TW/cloud.json @@ -3,20 +3,24 @@ "profilePicture": "個人圖片", "logOut": "登出", "testApiAuthentication": "測試 API 認證", - "signIn": "登入 Roo Code Cloud", - "connect": "連線", + "signIn": "連線至 Roo Code Cloud", + "connect": "立即連線", "cloudBenefitsTitle": "連線至 Roo Code Cloud", - "cloudBenefitsSubtitle": "同步您的提示詞和遙測資料以啟用:", - "cloudBenefitHistory": "線上工作歷史紀錄", - "cloudBenefitSharing": "分享和協作功能", - "cloudBenefitMetrics": "基於工作任務、Token 和成本的用量指標", - "cloudBenefitWalkaway": "使用 Roomote Control 隨時隨地追蹤和控制工作", - "remoteControl": "Roomote Control", - "remoteControlDescription": "允許透過 Roo Code Cloud 追蹤和操作此工作區中的工作", + "cloudBenefitWalkaway": "使用 Roomote Control 隨時隨地追蹤和控制任務", + "cloudBenefitSharing": "與他人分享任務", + "cloudBenefitHistory": "存取您的任務歷史", + "cloudBenefitMetrics": "獲得您的代幣消耗的整體視圖", "visitCloudWebsite": "造訪 Roo Code Cloud", - "cloudUrlPillLabel": "Roo Code Cloud URL", + "taskSync": "任務同步", + "taskSyncDescription": "同步您的任務以在 Roo Code Cloud 上檢視和分享", + "remoteControl": "Roomote Control", + "remoteControlDescription": "允許從 Roo Code Cloud 控制任務", + "remoteControlRequiresTaskSync": "必須啟用任務同步才能使用 Roomote Control", + "taskSyncManagedByOrganization": "工作同步由您的組織管理", + "usageMetricsAlwaysReported": "登入時始終報告模型使用資訊", "authWaiting": "等待身份驗證完成...", "havingTrouble": "遇到問題?", "pasteCallbackUrl": "從瀏覽器複製重新導向 URL 並貼上到這裡:", - "startOver": "重新開始" + "startOver": "重新開始", + "cloudUrlPillLabel": "Roo Code Cloud URL" }