mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
feat: separate Task Sync and Roomote Control settings
- Add new taskSyncEnabled setting to control task content syncing - Keep remoteControlEnabled for Roomote Control functionality - Task Sync controls whether task content is sent to cloud - Roomote Control controls whether cloud can send instructions back - Roomote Control now depends on Task Sync being enabled - Usage metrics (tokens, cost) always reported regardless of settings - Update UI with two separate toggles and clear descriptions - Add info text explaining usage metrics are always reported
This commit is contained in:
parent
d7896924a9
commit
aa37e379ca
9 changed files with 103 additions and 21 deletions
|
|
@ -162,6 +162,7 @@ export type UserFeatures = z.infer<typeof userFeaturesSchema>
|
|||
|
||||
export const userSettingsConfigSchema = z.object({
|
||||
extensionBridgeEnabled: z.boolean().optional(),
|
||||
taskSyncEnabled: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export type UserSettingsConfig = z.infer<typeof userSettingsConfigSchema>
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ export const globalSettingsSchema = z.object({
|
|||
enableMcpServerCreation: z.boolean().optional(),
|
||||
|
||||
remoteControlEnabled: z.boolean().optional(),
|
||||
taskSyncEnabled: z.boolean().optional(),
|
||||
|
||||
mode: z.string().optional(),
|
||||
modeApiConfigs: z.record(z.string(), z.string()).optional(),
|
||||
|
|
@ -316,6 +317,7 @@ export const EVALS_SETTINGS: RooCodeSettings = {
|
|||
mcpEnabled: false,
|
||||
|
||||
remoteControlEnabled: false,
|
||||
taskSyncEnabled: true, // Default to true for backward compatibility
|
||||
|
||||
mode: "code", // "architect",
|
||||
|
||||
|
|
|
|||
|
|
@ -607,7 +607,11 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
this.emit(RooCodeEventName.Message, { action: "created", message })
|
||||
await this.saveClineMessages()
|
||||
|
||||
const shouldCaptureMessage = message.partial !== true && CloudService.isEnabled()
|
||||
// Check if we should capture the message
|
||||
// Only capture if: not partial, cloud is enabled, and taskSyncEnabled is true
|
||||
const state = await this.providerRef.deref()?.getState()
|
||||
const taskSyncEnabled = state?.taskSyncEnabled ?? true // Default to true for backward compatibility
|
||||
const shouldCaptureMessage = message.partial !== true && CloudService.isEnabled() && taskSyncEnabled
|
||||
|
||||
if (shouldCaptureMessage) {
|
||||
CloudService.instance.captureEvent({
|
||||
|
|
@ -640,7 +644,11 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
await provider?.postMessageToWebview({ type: "messageUpdated", clineMessage: message })
|
||||
this.emit(RooCodeEventName.Message, { action: "updated", message })
|
||||
|
||||
const shouldCaptureMessage = message.partial !== true && CloudService.isEnabled()
|
||||
// Check if we should capture the message
|
||||
// Only capture if: not partial, cloud is enabled, and taskSyncEnabled is true
|
||||
const state = await this.providerRef.deref()?.getState()
|
||||
const taskSyncEnabled = state?.taskSyncEnabled ?? true // Default to true for backward compatibility
|
||||
const shouldCaptureMessage = message.partial !== true && CloudService.isEnabled() && taskSyncEnabled
|
||||
|
||||
if (shouldCaptureMessage) {
|
||||
CloudService.instance.captureEvent({
|
||||
|
|
|
|||
|
|
@ -965,6 +965,17 @@ export const webviewMessageHandler = async (
|
|||
await provider.remoteControlEnabled(message.bool ?? false)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "taskSyncEnabled":
|
||||
try {
|
||||
await CloudService.instance.updateUserSettings({
|
||||
taskSyncEnabled: message.bool ?? true,
|
||||
})
|
||||
} catch (error) {
|
||||
provider.log(`Failed to update cloud settings for task sync: ${error}`)
|
||||
}
|
||||
await updateGlobalState("taskSyncEnabled", message.bool ?? true)
|
||||
await provider.postStateToWebview()
|
||||
break
|
||||
case "refreshAllMcpServers": {
|
||||
const mcpHub = provider.getMcpHub()
|
||||
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ export type ExtensionState = Pick<
|
|||
| "includeDiagnosticMessages"
|
||||
| "maxDiagnosticMessages"
|
||||
| "remoteControlEnabled"
|
||||
| "taskSyncEnabled"
|
||||
| "openRouterImageGenerationSelectedModel"
|
||||
| "includeTaskHistoryInEnhance"
|
||||
> & {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ export interface WebviewMessage {
|
|||
| "mcpEnabled"
|
||||
| "enableMcpServerCreation"
|
||||
| "remoteControlEnabled"
|
||||
| "taskSyncEnabled"
|
||||
| "searchCommits"
|
||||
| "alwaysApproveResubmit"
|
||||
| "requestDelaySeconds"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ type CloudViewProps = {
|
|||
|
||||
export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: CloudViewProps) => {
|
||||
const { t } = useAppTranslation()
|
||||
const { remoteControlEnabled, setRemoteControlEnabled } = useExtensionState()
|
||||
const { remoteControlEnabled, setRemoteControlEnabled, taskSyncEnabled, setTaskSyncEnabled } = useExtensionState()
|
||||
const wasAuthenticatedRef = useRef(false)
|
||||
|
||||
const rooLogoUri = (window as any).IMAGES_BASE_URI + "/roo-logo.svg"
|
||||
|
|
@ -75,6 +75,17 @@ 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 })
|
||||
// If disabling task sync, also disable remote control
|
||||
if (!newValue && remoteControlEnabled) {
|
||||
setRemoteControlEnabled(false)
|
||||
vscode.postMessage({ type: "remoteControlEnabled", bool: false })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
|
|
@ -121,24 +132,56 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl
|
|||
</div>
|
||||
)}
|
||||
|
||||
{userInfo?.extensionBridgeEnabled && (
|
||||
<div className="border-t border-vscode-widget-border pt-4 mt-4">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<ToggleSwitch
|
||||
checked={remoteControlEnabled}
|
||||
onChange={handleRemoteControlToggle}
|
||||
size="medium"
|
||||
aria-label={t("cloud:remoteControl")}
|
||||
data-testid="remote-control-toggle"
|
||||
/>
|
||||
<span className="font-medium text-vscode-foreground">{t("cloud:remoteControl")}</span>
|
||||
</div>
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
|
||||
{t("cloud:remoteControlDescription")}
|
||||
</div>
|
||||
<hr className="border-vscode-widget-border mb-4" />
|
||||
{/* Task Sync Toggle - Always shown when authenticated */}
|
||||
<div className="border-t border-vscode-widget-border pt-4 mt-4">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<ToggleSwitch
|
||||
checked={taskSyncEnabled}
|
||||
onChange={handleTaskSyncToggle}
|
||||
size="medium"
|
||||
aria-label={t("cloud:taskSync")}
|
||||
data-testid="task-sync-toggle"
|
||||
/>
|
||||
<span className="font-medium text-vscode-foreground">{t("cloud:taskSync")}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
|
||||
{t("cloud:taskSyncDescription")}
|
||||
</div>
|
||||
|
||||
{/* Remote Control Toggle - Only shown when extensionBridgeEnabled is true */}
|
||||
{userInfo?.extensionBridgeEnabled && (
|
||||
<>
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<ToggleSwitch
|
||||
checked={remoteControlEnabled}
|
||||
onChange={handleRemoteControlToggle}
|
||||
size="medium"
|
||||
aria-label={t("cloud:remoteControl")}
|
||||
data-testid="remote-control-toggle"
|
||||
disabled={!taskSyncEnabled}
|
||||
/>
|
||||
<span className="font-medium text-vscode-foreground">
|
||||
{t("cloud:remoteControl")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
|
||||
{t("cloud:remoteControlDescription")}
|
||||
{!taskSyncEnabled && (
|
||||
<div className="text-vscode-errorForeground mt-2">
|
||||
{t("cloud:remoteControlRequiresTaskSync")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Info text about usage metrics */}
|
||||
<div className="text-vscode-descriptionForeground text-sm mt-4 mb-4 ml-8 italic">
|
||||
{t("cloud:usageMetricsAlwaysReported")}
|
||||
</div>
|
||||
|
||||
<hr className="border-vscode-widget-border mb-4" />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 mt-4">
|
||||
<VSCodeButton appearance="secondary" onClick={handleVisitCloudWebsite} className="w-full">
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ export interface ExtensionStateContextType extends ExtensionState {
|
|||
setEnableMcpServerCreation: (value: boolean) => void
|
||||
remoteControlEnabled: boolean
|
||||
setRemoteControlEnabled: (value: boolean) => void
|
||||
taskSyncEnabled: boolean
|
||||
setTaskSyncEnabled: (value: boolean) => void
|
||||
alwaysApproveResubmit?: boolean
|
||||
setAlwaysApproveResubmit: (value: boolean) => void
|
||||
requestDelaySeconds: number
|
||||
|
|
@ -299,6 +301,13 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
setState((prevState) => mergeExtensionState(prevState, newState))
|
||||
setShowWelcome(!checkExistKey(newState.apiConfiguration))
|
||||
setDidHydrateState(true)
|
||||
// Update taskSyncEnabled if present in state message
|
||||
if ((newState as any).taskSyncEnabled !== undefined) {
|
||||
setState(
|
||||
(prevState) =>
|
||||
({ ...prevState, taskSyncEnabled: (newState as any).taskSyncEnabled }) as any,
|
||||
)
|
||||
}
|
||||
// Update alwaysAllowFollowupQuestions if present in state message
|
||||
if ((newState as any).alwaysAllowFollowupQuestions !== undefined) {
|
||||
setAlwaysAllowFollowupQuestions((newState as any).alwaysAllowFollowupQuestions)
|
||||
|
|
@ -417,6 +426,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
alwaysAllowFollowupQuestions,
|
||||
followupAutoApproveTimeoutMs,
|
||||
remoteControlEnabled: state.remoteControlEnabled ?? false,
|
||||
taskSyncEnabled: (state as any).taskSyncEnabled ?? true,
|
||||
setExperimentEnabled: (id, enabled) =>
|
||||
setState((prevState) => ({ ...prevState, experiments: { ...prevState.experiments, [id]: enabled } })),
|
||||
setApiConfiguration,
|
||||
|
|
@ -464,6 +474,7 @@ 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),
|
||||
setAlwaysApproveResubmit: (value) => setState((prevState) => ({ ...prevState, alwaysApproveResubmit: value })),
|
||||
setRequestDelaySeconds: (value) => setState((prevState) => ({ ...prevState, requestDelaySeconds: value })),
|
||||
setCurrentApiConfigName: (value) => setState((prevState) => ({ ...prevState, currentApiConfigName: value })),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,11 @@
|
|||
"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",
|
||||
"usageMetricsAlwaysReported": "Model usage info is always reported when logged in",
|
||||
"cloudUrlPillLabel": "Roo Code Cloud URL"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue