Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
7 changes: 6 additions & 1 deletion src/core/tools/newTaskTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } f
import { Task } from "../task/Task"
import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
import { formatResponse } from "../prompts/responses"
import { t } from "../../i18n"

export async function newTaskTool(
cline: Task,
Expand Down Expand Up @@ -43,7 +44,7 @@ export async function newTaskTool(

cline.consecutiveMistakeCount = 0
// Un-escape one level of backslashes before '@' for hierarchical subtasks
// Un-escape one level: \\@ -> \@ (removes one backslash for hierarchical subtasks)
// Un-escape one level: \\@ -> \@ (removes one backslash for hierarchical subtasks)
const unescapedMessage = message.replace(/\\\\@/g, "\\@")

// Verify the mode exists
Expand Down Expand Up @@ -86,6 +87,10 @@ export async function newTaskTool(
await delay(500)

const newCline = await provider.initClineWithTask(unescapedMessage, undefined, cline)
if (!newCline) {
pushToolResult(t("tools:newTask.errors.policy_restriction"))
return
}
cline.emit("taskSpawned", newCline.taskId)

pushToolResult(`Successfully created new task in ${targetMode.name} mode with message: ${unescapedMessage}`)
Expand Down
32 changes: 32 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { MarketplaceManager } from "../../services/marketplace"
import { ShadowCheckpointService } from "../../services/checkpoints/ShadowCheckpointService"
import { CodeIndexManager } from "../../services/code-index/manager"
import type { IndexProgressUpdate } from "../../services/code-index/interfaces/manager"
import { MdmService } from "../../services/mdm/MdmService"
import { fileExistsAtPath } from "../../utils/fs"
import { setTtsEnabled, setTtsSpeed } from "../../utils/tts"
import { ContextProxy } from "../config/ContextProxy"
Expand Down Expand Up @@ -103,6 +104,7 @@ export class ClineProvider
}
protected mcpHub?: McpHub // Change from private to protected
private marketplaceManager: MarketplaceManager
private mdmService?: MdmService

public isViewLaunched = false
public settingsImportedAt?: number
Expand All @@ -116,13 +118,15 @@ export class ClineProvider
private readonly renderContext: "sidebar" | "editor" = "sidebar",
public readonly contextProxy: ContextProxy,
public readonly codeIndexManager?: CodeIndexManager,
mdmService?: MdmService,
) {
super()

this.log("ClineProvider instantiated")
ClineProvider.activeInstances.add(this)

this.codeIndexManager = codeIndexManager
this.mdmService = mdmService
this.updateGlobalState("codebaseIndexModels", EMBEDDING_MODEL_PROFILES)

// Start configuration loading (which might trigger indexing) in the background.
Expand Down Expand Up @@ -525,6 +529,11 @@ export class ClineProvider
>
> = {},
) {
// Check MDM compliance before proceeding
if (!this.checkMdmCompliance()) {
return // Block task creation if not compliant
}

const {
apiConfiguration,
organizationAllowList,
Expand Down Expand Up @@ -1700,6 +1709,29 @@ export class ClineProvider
return this.mcpHub
}

/**
* Check if the current state is compliant with MDM policy
* @returns true if compliant, false if blocked
*/
public checkMdmCompliance(): boolean {
if (!this.mdmService) {
return true // No MDM service, allow operation
}

const compliance = this.mdmService.isCompliant()

if (!compliance.compliant) {
vscode.window.showErrorMessage(compliance.reason, "Sign In").then((selection) => {
if (selection === "Sign In") {
this.postMessageToWebview({ type: "action", action: "accountButtonClicked" })
}
})
return false
}

return true
}

/**
* Returns properties to be included in every telemetry event
* This method is called by the telemetry service to get context information
Expand Down
6 changes: 5 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider"
import { TerminalRegistry } from "./integrations/terminal/TerminalRegistry"
import { McpServerManager } from "./services/mcp/McpServerManager"
import { CodeIndexManager } from "./services/code-index/manager"
import { MdmService } from "./services/mdm/MdmService"
import { migrateSettings } from "./utils/migrateSettings"
import { API } from "./extension/api"

Expand Down Expand Up @@ -78,6 +79,9 @@ export async function activate(context: vscode.ExtensionContext) {
log: cloudLogger,
})

// Initialize MDM service
const mdmService = await MdmService.createInstance(cloudLogger)

// Initialize i18n for internationalization support
initializeI18n(context.globalState.get("language") ?? formatLanguage(vscode.env.language))

Expand All @@ -103,7 +107,7 @@ export async function activate(context: vscode.ExtensionContext) {
)
}

const provider = new ClineProvider(context, outputChannel, "sidebar", contextProxy, codeIndexManager)
const provider = new ClineProvider(context, outputChannel, "sidebar", contextProxy, codeIndexManager, mdmService)
TelemetryService.instance.setProvider(provider)

if (codeIndexManager) {
Expand Down
8 changes: 6 additions & 2 deletions src/extension/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,15 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
await provider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
await provider.postMessageToWebview({ type: "invoke", invoke: "newChat", text, images })

const { taskId } = await provider.initClineWithTask(text, images, undefined, {
const cline = await provider.initClineWithTask(text, images, undefined, {
consecutiveMistakeLimit: Number.MAX_SAFE_INTEGER,
})

return taskId
if (!cline) {
throw new Error("Failed to create task due to policy restrictions")
}

return cline.taskId
}

public async resumeTask(taskId: string): Promise<void> {
Expand Down
7 changes: 7 additions & 0 deletions src/i18n/locales/ca/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Clau API de Groq",
"getGroqApiKey": "Obté la clau API de Groq"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "La teva organització requereix autenticació de Roo Code Cloud. Si us plau, inicia sessió per continuar.",
"organization_mismatch": "Has d'estar autenticat amb el compte de Roo Code Cloud de la teva organització.",
"verification_failed": "No s'ha pogut verificar l'autenticació de l'organització."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/ca/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo sembla estar atrapat en un bucle, intentant la mateixa acció ({{toolName}}) repetidament. Això podria indicar un problema amb la seva estratègia actual. Considera reformular la tasca, proporcionar instruccions més específiques o guiar-lo cap a un enfocament diferent.",
"codebaseSearch": {
"approval": "Cercant '{{query}}' a la base de codi..."
},
"newTask": {
"errors": {
"policy_restriction": "No s'ha pogut crear una nova tasca a causa de restriccions de política."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/de/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Groq API-Schlüssel",
"getGroqApiKey": "Groq API-Schlüssel erhalten"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "Deine Organisation erfordert eine Roo Code Cloud-Authentifizierung. Bitte melde dich an, um fortzufahren.",
"organization_mismatch": "Du musst mit dem Roo Code Cloud-Konto deiner Organisation authentifiziert sein.",
"verification_failed": "Die Organisationsauthentifizierung konnte nicht verifiziert werden."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/de/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo scheint in einer Schleife festzustecken und versucht wiederholt dieselbe Aktion ({{toolName}}). Dies könnte auf ein Problem mit der aktuellen Strategie hindeuten. Überlege dir, die Aufgabe umzuformulieren, genauere Anweisungen zu geben oder Roo zu einem anderen Ansatz zu führen.",
"codebaseSearch": {
"approval": "Suche nach '{{query}}' im Codebase..."
},
"newTask": {
"errors": {
"policy_restriction": "Neue Aufgabe konnte aufgrund von Richtlinienbeschränkungen nicht erstellt werden."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,12 @@
"input": {
"task_prompt": "What should Roo do?",
"task_placeholder": "Type your task here"
},
"mdm": {
"errors": {
"cloud_auth_required": "Your organization requires Roo Code Cloud authentication. Please sign in to continue.",
"organization_mismatch": "You must be authenticated with your organization's Roo Code Cloud account.",
"verification_failed": "Unable to verify organization authentication."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/en/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo appears to be stuck in a loop, attempting the same action ({{toolName}}) repeatedly. This might indicate a problem with its current strategy. Consider rephrasing the task, providing more specific instructions, or guiding it towards a different approach.",
"codebaseSearch": {
"approval": "Searching for '{{query}}' in codebase..."
},
"newTask": {
"errors": {
"policy_restriction": "Failed to create new task due to policy restrictions."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/es/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Clave API de Groq",
"getGroqApiKey": "Obtener clave API de Groq"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "Tu organización requiere autenticación de Roo Code Cloud. Por favor, inicia sesión para continuar.",
"organization_mismatch": "Debes estar autenticado con la cuenta de Roo Code Cloud de tu organización.",
"verification_failed": "No se pudo verificar la autenticación de la organización."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/es/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo parece estar atrapado en un bucle, intentando la misma acción ({{toolName}}) repetidamente. Esto podría indicar un problema con su estrategia actual. Considera reformular la tarea, proporcionar instrucciones más específicas o guiarlo hacia un enfoque diferente.",
"codebaseSearch": {
"approval": "Buscando '{{query}}' en la base de código..."
},
"newTask": {
"errors": {
"policy_restriction": "No se pudo crear una nueva tarea debido a restricciones de política."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/fr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Clé API Groq",
"getGroqApiKey": "Obtenir la clé API Groq"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "Votre organisation nécessite une authentification Roo Code Cloud. Veuillez vous connecter pour continuer.",
"organization_mismatch": "Vous devez être authentifié avec le compte Roo Code Cloud de votre organisation.",
"verification_failed": "Impossible de vérifier l'authentification de l'organisation."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/fr/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo semble être bloqué dans une boucle, tentant la même action ({{toolName}}) de façon répétée. Cela pourrait indiquer un problème avec sa stratégie actuelle. Envisage de reformuler la tâche, de fournir des instructions plus spécifiques ou de le guider vers une approche différente.",
"codebaseSearch": {
"approval": "Recherche de '{{query}}' dans la base de code..."
},
"newTask": {
"errors": {
"policy_restriction": "Impossible de créer une nouvelle tâche en raison de restrictions de politique."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/hi/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "ग्रोक एपीआई कुंजी",
"getGroqApiKey": "ग्रोक एपीआई कुंजी प्राप्त करें"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "आपके संगठन को Roo Code Cloud प्रमाणीकरण की आवश्यकता है। कृपया जारी रखने के लिए साइन इन करें।",
"organization_mismatch": "आपको अपने संगठन के Roo Code Cloud खाते से प्रमाणित होना होगा।",
"verification_failed": "संगठन प्रमाणीकरण सत्यापित करने में असमर्थ।"
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/hi/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo एक लूप में फंसा हुआ लगता है, बार-बार एक ही क्रिया ({{toolName}}) को दोहरा रहा है। यह उसकी वर्तमान रणनीति में किसी समस्या का संकेत हो सकता है। कार्य को पुनः परिभाषित करने, अधिक विशिष्ट निर्देश देने, या उसे एक अलग दृष्टिकोण की ओर मार्गदर्शित करने पर विचार करें।",
"codebaseSearch": {
"approval": "कोडबेस में '{{query}}' खोज रहा है..."
},
"newTask": {
"errors": {
"policy_restriction": "नीति प्रतिबंधों के कारण नया कार्य बनाने में विफल।"
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/id/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,12 @@
"input": {
"task_prompt": "Apa yang harus Roo lakukan?",
"task_placeholder": "Ketik tugas kamu di sini"
},
"mdm": {
"errors": {
"cloud_auth_required": "Organisasi kamu memerlukan autentikasi Roo Code Cloud. Silakan masuk untuk melanjutkan.",
"organization_mismatch": "Kamu harus diautentikasi dengan akun Roo Code Cloud organisasi kamu.",
"verification_failed": "Tidak dapat memverifikasi autentikasi organisasi."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/id/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@
},
"searchFiles": {
"workspaceBoundaryError": "Tidak dapat mencari di luar workspace. Path '{{path}}' berada di luar workspace saat ini."
},
"newTask": {
"errors": {
"policy_restriction": "Gagal membuat tugas baru karena pembatasan kebijakan."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/it/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Chiave API Groq",
"getGroqApiKey": "Ottieni chiave API Groq"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "La tua organizzazione richiede l'autenticazione Roo Code Cloud. Accedi per continuare.",
"organization_mismatch": "Devi essere autenticato con l'account Roo Code Cloud della tua organizzazione.",
"verification_failed": "Impossibile verificare l'autenticazione dell'organizzazione."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/it/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo sembra essere bloccato in un ciclo, tentando ripetutamente la stessa azione ({{toolName}}). Questo potrebbe indicare un problema con la sua strategia attuale. Considera di riformulare l'attività, fornire istruzioni più specifiche o guidarlo verso un approccio diverso.",
"codebaseSearch": {
"approval": "Ricerca di '{{query}}' nella base di codice..."
},
"newTask": {
"errors": {
"policy_restriction": "Impossibile creare una nuova attività a causa di restrizioni di policy."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/ja/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Groq APIキー",
"getGroqApiKey": "Groq APIキーを取得"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "あなたの組織では Roo Code Cloud 認証が必要です。続行するにはサインインしてください。",
"organization_mismatch": "組織の Roo Code Cloud アカウントで認証する必要があります。",
"verification_failed": "組織認証の確認ができませんでした。"
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/ja/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Rooが同じ操作({{toolName}})を繰り返し試みるループに陥っているようです。これは現在の方法に問題がある可能性を示しています。タスクの言い換え、より具体的な指示の提供、または別のアプローチへの誘導を検討してください。",
"codebaseSearch": {
"approval": "コードベースで '{{query}}' を検索中..."
},
"newTask": {
"errors": {
"policy_restriction": "ポリシー制限により新しいタスクを作成できませんでした。"
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/ko/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,12 @@
"groqApiKey": "Groq API 키",
"getGroqApiKey": "Groq API 키 받기"
}
},
"mdm": {
"errors": {
"cloud_auth_required": "조직에서 Roo Code Cloud 인증이 필요합니다. 계속하려면 로그인하세요.",
"organization_mismatch": "조직의 Roo Code Cloud 계정으로 인증해야 합니다.",
"verification_failed": "조직 인증을 확인할 수 없습니다."
}
}
}
5 changes: 5 additions & 0 deletions src/i18n/locales/ko/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"toolRepetitionLimitReached": "Roo가 같은 동작({{toolName}})을 반복적으로 시도하면서 루프에 갇힌 것 같습니다. 이는 현재 전략에 문제가 있을 수 있음을 나타냅니다. 작업을 다시 표현하거나, 더 구체적인 지침을 제공하거나, 다른 접근 방식으로 안내해 보세요.",
"codebaseSearch": {
"approval": "코드베이스에서 '{{query}}' 검색 중..."
},
"newTask": {
"errors": {
"policy_restriction": "정책 제한으로 인해 새 작업을 생성하지 못했습니다."
}
}
}
7 changes: 7 additions & 0 deletions src/i18n/locales/nl/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,12 @@
"input": {
"task_prompt": "Wat moet Roo doen?",
"task_placeholder": "Typ hier je taak"
},
"mdm": {
"errors": {
"cloud_auth_required": "Je organisatie vereist Roo Code Cloud-authenticatie. Log in om door te gaan.",
"organization_mismatch": "Je moet geauthenticeerd zijn met het Roo Code Cloud-account van je organisatie.",
"verification_failed": "Kan organisatie-authenticatie niet verifiëren."
}
}
}
Loading