From 779f117237b42bcbb4d4761638b6a6d0d2697f39 Mon Sep 17 00:00:00 2001 From: cte Date: Wed, 30 Jul 2025 11:41:34 -0700 Subject: [PATCH 1/2] Miscellaneous cleanup --- README.vscode.md | 1 - apps/web-evals/package.json | 2 +- apps/web-roo-code/package.json | 3 +- packages/cloud/src/CloudService.ts | 6 ++- src/core/task/Task.ts | 7 ++-- src/core/webview/ClineProvider.ts | 37 +++++++++---------- src/extension/api.ts | 2 +- src/package.json | 2 +- .../marketplace/MarketplaceManager.ts | 15 +++++--- src/shared/ProfileValidator.ts | 1 + 10 files changed, 42 insertions(+), 34 deletions(-) delete mode 100644 README.vscode.md diff --git a/README.vscode.md b/README.vscode.md deleted file mode 100644 index 2afed2a9c6..0000000000 --- a/README.vscode.md +++ /dev/null @@ -1 +0,0 @@ -readme test diff --git a/apps/web-evals/package.json b/apps/web-evals/package.json index b210fa085e..df8efec115 100644 --- a/apps/web-evals/package.json +++ b/apps/web-evals/package.json @@ -9,7 +9,7 @@ "format": "prettier --write src", "build": "next build", "start": "next start", - "clean": "rimraf .next .turbo" + "clean": "rimraf tsconfig.tsbuildinfo .next .turbo" }, "dependencies": { "@hookform/resolvers": "^5.1.1", diff --git a/apps/web-roo-code/package.json b/apps/web-roo-code/package.json index 02812dc471..8495dd961a 100644 --- a/apps/web-roo-code/package.json +++ b/apps/web-roo-code/package.json @@ -7,7 +7,8 @@ "check-types": "tsc --noEmit", "dev": "next dev", "build": "next build", - "start": "next start" + "start": "next start", + "clean": "rimraf .next .turbo" }, "dependencies": { "@radix-ui/react-dialog": "^1.1.14", diff --git a/packages/cloud/src/CloudService.ts b/packages/cloud/src/CloudService.ts index 9a32a16fcb..30d1545b23 100644 --- a/packages/cloud/src/CloudService.ts +++ b/packages/cloud/src/CloudService.ts @@ -48,6 +48,7 @@ export class CloudService { try { const cloudToken = process.env.ROO_CODE_CLOUD_TOKEN + if (cloudToken && cloudToken.length > 0) { this.authService = new StaticTokenAuthService(this.context, cloudToken, this.log) } else { @@ -62,8 +63,9 @@ export class CloudService { this.authService.on("logged-out", this.authListener) this.authService.on("user-info", this.authListener) - // Check for static settings environment variable + // Check for static settings environment variable. const staticOrgSettings = process.env.ROO_CODE_CLOUD_ORG_SETTINGS + if (staticOrgSettings && staticOrgSettings.length > 0) { this.settingsService = new StaticSettingsService(staticOrgSettings, this.log) } else { @@ -73,12 +75,12 @@ export class CloudService { () => this.callbacks.stateChanged?.(), this.log, ) + cloudSettingsService.initialize() this.settingsService = cloudSettingsService } this.telemetryClient = new TelemetryClient(this.authService, this.settingsService) - this.shareService = new ShareService(this.authService, this.settingsService, this.log) try { diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index edbde32ea7..2b4dd5b41c 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -96,7 +96,7 @@ import { restoreTodoListForTask } from "../tools/updateTodoListTool" // Constants const MAX_EXPONENTIAL_BACKOFF_SECONDS = 600 // 10 minutes -export type ClineEvents = { +export type TaskEvents = { message: [{ action: "created" | "updated"; message: ClineMessage }] taskStarted: [] taskModeSwitched: [taskId: string, mode: string] @@ -125,10 +125,10 @@ export type TaskOptions = { rootTask?: Task parentTask?: Task taskNumber?: number - onCreated?: (cline: Task) => void + onCreated?: (task: Task) => void } -export class Task extends EventEmitter { +export class Task extends EventEmitter { todoList?: TodoItem[] readonly taskId: string readonly instanceId: string @@ -137,6 +137,7 @@ export class Task extends EventEmitter { readonly parentTask: Task | undefined = undefined readonly taskNumber: number readonly workspacePath: string + /** * The mode associated with this task. Persisted across sessions * to maintain user context when reopening tasks from history. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 280ab61a06..5e1aa86f31 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -78,13 +78,7 @@ import { getWorkspaceGitInfo } from "../../utils/git" */ export type ClineProviderEvents = { - clineCreated: [cline: Task] -} - -class OrganizationAllowListViolationError extends Error { - constructor(message: string) { - super(message) - } + taskCreated: [task: Task] } export class ClineProvider @@ -380,6 +374,7 @@ export class ClineProvider // Errors from terminal commands seem to get swallowed / ignored. vscode.window.showErrorMessage(error.message) } + throw error } } @@ -526,7 +521,7 @@ export class ClineProvider // of tasks, each one being a sub task of the previous one until the main // task is finished. public async initClineWithTask( - task?: string, + text?: string, images?: string[], parentTask?: Task, options: Partial< @@ -549,30 +544,30 @@ export class ClineProvider throw new OrganizationAllowListViolationError(t("common:errors.violated_organization_allowlist")) } - const cline = new Task({ + const task = new Task({ provider: this, apiConfiguration, enableDiff, enableCheckpoints, fuzzyMatchThreshold, consecutiveMistakeLimit: apiConfiguration.consecutiveMistakeLimit, - task, + task: text, images, experiments, rootTask: this.clineStack.length > 0 ? this.clineStack[0] : undefined, parentTask, taskNumber: this.clineStack.length + 1, - onCreated: (cline) => this.emit("clineCreated", cline), + onCreated: (instance) => this.emit("taskCreated", instance), ...options, }) - await this.addClineToStack(cline) + await this.addClineToStack(task) this.log( - `[subtasks] ${cline.parentTask ? "child" : "parent"} task ${cline.taskId}.${cline.instanceId} instantiated`, + `[subtasks] ${task.parentTask ? "child" : "parent"} task ${task.taskId}.${task.instanceId} instantiated`, ) - return cline + return task } public async initClineWithHistoryItem(historyItem: HistoryItem & { rootTask?: Task; parentTask?: Task }) { @@ -629,7 +624,7 @@ export class ClineProvider experiments, } = await this.getState() - const cline = new Task({ + const task = new Task({ provider: this, apiConfiguration, enableDiff, @@ -641,14 +636,16 @@ export class ClineProvider rootTask: historyItem.rootTask, parentTask: historyItem.parentTask, taskNumber: historyItem.number, - onCreated: (cline) => this.emit("clineCreated", cline), + onCreated: (instance) => this.emit("taskCreated", instance), }) - await this.addClineToStack(cline) + await this.addClineToStack(task) + this.log( - `[subtasks] ${cline.parentTask ? "child" : "parent"} task ${cline.taskId}.${cline.instanceId} instantiated`, + `[subtasks] ${task.parentTask ? "child" : "parent"} task ${task.taskId}.${task.instanceId} instantiated`, ) - return cline + + return task } public async postMessageToWebview(message: ExtensionMessage) { @@ -1979,3 +1976,5 @@ export class ClineProvider } } } + +class OrganizationAllowListViolationError extends Error {} diff --git a/src/extension/api.ts b/src/extension/api.ts index 7027cb963a..fba10d041a 100644 --- a/src/extension/api.ts +++ b/src/extension/api.ts @@ -214,7 +214,7 @@ export class API extends EventEmitter implements RooCodeAPI { } private registerListeners(provider: ClineProvider) { - provider.on("clineCreated", (cline) => { + provider.on("taskCreated", (cline) => { cline.on("taskStarted", async () => { this.emit(RooCodeEventName.TaskStarted, cline.taskId) this.taskMap.set(cline.taskId, provider) diff --git a/src/package.json b/src/package.json index 8b350ac838..f5ccd17023 100644 --- a/src/package.json +++ b/src/package.json @@ -407,7 +407,7 @@ "publish:marketplace": "vsce publish --no-dependencies && ovsx publish --no-dependencies", "watch:bundle": "pnpm bundle --watch", "watch:tsc": "cd .. && tsc --noEmit --watch --project src/tsconfig.json", - "clean": "rimraf README.md CHANGELOG.md LICENSE dist mock .turbo" + "clean": "rimraf README.md CHANGELOG.md LICENSE dist logs mock .turbo" }, "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", diff --git a/src/services/marketplace/MarketplaceManager.ts b/src/services/marketplace/MarketplaceManager.ts index 6cd174a577..800eba62e0 100644 --- a/src/services/marketplace/MarketplaceManager.ts +++ b/src/services/marketplace/MarketplaceManager.ts @@ -1,16 +1,20 @@ -import * as vscode from "vscode" import * as fs from "fs/promises" import * as path from "path" + +import * as vscode from "vscode" import * as yaml from "yaml" -import { RemoteConfigLoader } from "./RemoteConfigLoader" -import { SimpleInstaller } from "./SimpleInstaller" + import type { MarketplaceItem, MarketplaceItemType, McpMarketplaceItem, OrganizationSettings } from "@roo-code/types" +import { TelemetryService } from "@roo-code/telemetry" +import { CloudService } from "@roo-code/cloud" + import { GlobalFileNames } from "../../shared/globalFileNames" import { ensureSettingsDirectoryExists } from "../../utils/globalContext" import { t } from "../../i18n" -import { TelemetryService } from "@roo-code/telemetry" import type { CustomModesManager } from "../../core/config/CustomModesManager" -import { CloudService } from "@roo-code/cloud" + +import { RemoteConfigLoader } from "./RemoteConfigLoader" +import { SimpleInstaller } from "./SimpleInstaller" export interface MarketplaceItemsResponse { organizationMcps: MarketplaceItem[] @@ -35,6 +39,7 @@ export class MarketplaceManager { const errors: string[] = [] let orgSettings: OrganizationSettings | undefined + try { if (CloudService.hasInstance() && CloudService.instance.isAuthenticated()) { orgSettings = CloudService.instance.getOrganizationSettings() diff --git a/src/shared/ProfileValidator.ts b/src/shared/ProfileValidator.ts index 2ebf9bb3ab..9cfba84aae 100644 --- a/src/shared/ProfileValidator.ts +++ b/src/shared/ProfileValidator.ts @@ -41,6 +41,7 @@ export class ProfileValidator { } const providerAllowList = allowList.providers[providerName] + if (!providerAllowList) { return false } From e70bb390f1844b0538ff130ec465d5bd1eb5b4dc Mon Sep 17 00:00:00 2001 From: cte Date: Wed, 30 Jul 2025 15:58:50 -0700 Subject: [PATCH 2/2] More cleanup --- .roo/rules/rules.md | 3 ++- src/core/task/Task.ts | 38 +++++++++++++++++++------------ src/core/webview/ClineProvider.ts | 11 +++++---- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/.roo/rules/rules.md b/.roo/rules/rules.md index 2323f03354..5726770a28 100644 --- a/.roo/rules/rules.md +++ b/.roo/rules/rules.md @@ -4,7 +4,7 @@ - Before attempting completion, always make sure that any code changes have test coverage - Ensure all tests pass before submitting changes - - The vitest framework is used for testing; the `describe`, `test`, `it`, etc functions are defined by default in `tsconfig.json` and therefore don't need to be imported + - The vitest framework is used for testing; the `vi`, `describe`, `test`, `it`, etc functions are defined by default in `tsconfig.json` and therefore don't need to be imported from `vitest` - Tests must be run from the same directory as the `package.json` file that specifies `vitest` in `devDependencies` - Run tests with: `npx vitest run ` - Do NOT run tests from project root - this causes "vitest: command not found" error @@ -18,6 +18,7 @@ - Never disable any lint rules without explicit user approval 3. Styling Guidelines: + - Use Tailwind CSS classes instead of inline style objects for new markup - VSCode CSS variables must be added to webview-ui/src/index.css before using them in Tailwind classes - Example: `
` instead of style objects diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 2b4dd5b41c..38c67b5021 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -93,7 +93,6 @@ import { getMessagesSinceLastSummary, summarizeConversation } from "../condense" import { maybeRemoveImageBlocks } from "../../api/transform/image-cleaning" import { restoreTodoListForTask } from "../tools/updateTodoListTool" -// Constants const MAX_EXPONENTIAL_BACKOFF_SECONDS = 600 // 10 minutes export type TaskEvents = { @@ -110,6 +109,10 @@ export type TaskEvents = { taskToolFailed: [taskId: string, tool: ToolName, error: string] } +export type TaskEventHandlers = { + [K in keyof TaskEvents]: (...args: TaskEvents[K]) => void | Promise +} + export type TaskOptions = { provider: ClineProvider apiConfiguration: ProviderSettings @@ -280,10 +283,12 @@ export class Task extends EventEmitter { } this.taskId = historyItem ? historyItem.id : crypto.randomUUID() - // normal use-case is usually retry similar history task with new workspace + + // Normal use-case is usually retry similar history task with new workspace. this.workspacePath = parentTask ? parentTask.workspacePath : getWorkspacePath(path.join(os.homedir(), "Desktop")) + this.instanceId = crypto.randomUUID().slice(0, 8) this.taskNumber = -1 @@ -312,25 +317,26 @@ export class Task extends EventEmitter { this.parentTask = parentTask this.taskNumber = taskNumber - // Store the task's mode when it's created - // For history items, use the stored mode; for new tasks, we'll set it after getting state + // Store the task's mode when it's created. + // For history items, use the stored mode; for new tasks, we'll set it + // after getting state. if (historyItem) { this._taskMode = historyItem.mode || defaultModeSlug this.taskModeReady = Promise.resolve() TelemetryService.instance.captureTaskRestarted(this.taskId) } else { - // For new tasks, don't set the mode yet - wait for async initialization + // For new tasks, don't set the mode yet - wait for async initialization. this._taskMode = undefined this.taskModeReady = this.initializeTaskMode(provider) TelemetryService.instance.captureTaskCreated(this.taskId) } - // Only set up diff strategy if diff is enabled + // Only set up diff strategy if diff is enabled. if (this.diffEnabled) { - // Default to old strategy, will be updated if experiment is enabled + // Default to old strategy, will be updated if experiment is enabled. this.diffStrategy = new MultiSearchReplaceDiffStrategy(this.fuzzyMatchThreshold) - // Check experiment asynchronously and update strategy if needed + // Check experiment asynchronously and update strategy if needed. provider.getState().then((state) => { const isMultiFileApplyDiffEnabled = experiments.isEnabled( state.experiments ?? {}, @@ -1231,7 +1237,7 @@ export class Task extends EventEmitter { } } catch (error) { console.error("Error disposing RooIgnoreController:", error) - // This is the critical one for the leak fix + // This is the critical one for the leak fix. } try { @@ -1241,7 +1247,7 @@ export class Task extends EventEmitter { } try { - // If we're not streaming then `abortStream` won't be called + // If we're not streaming then `abortStream` won't be called. if (this.isStreaming && this.diffViewProvider.isEditing) { this.diffViewProvider.revertChanges().catch(console.error) } @@ -1848,6 +1854,7 @@ export class Task extends EventEmitter { public async *attemptApiRequest(retryAttempt: number = 0): ApiStream { const state = await this.providerRef.deref()?.getState() + const { apiConfiguration, autoApprovalEnabled, @@ -1859,21 +1866,24 @@ export class Task extends EventEmitter { profileThresholds = {}, } = state ?? {} - // Get condensing configuration for automatic triggers + // Get condensing configuration for automatic triggers. const customCondensingPrompt = state?.customCondensingPrompt const condensingApiConfigId = state?.condensingApiConfigId const listApiConfigMeta = state?.listApiConfigMeta - // Determine API handler to use for condensing + // Determine API handler to use for condensing. let condensingApiHandler: ApiHandler | undefined + if (condensingApiConfigId && listApiConfigMeta && Array.isArray(listApiConfigMeta)) { - // Using type assertion for the id property to avoid implicit any + // Using type assertion for the id property to avoid implicit any. const matchingConfig = listApiConfigMeta.find((config: any) => config.id === condensingApiConfigId) + if (matchingConfig) { const profile = await this.providerRef.deref()?.providerSettingsManager.getProfile({ id: condensingApiConfigId, }) - // Ensure profile and apiProvider exist before trying to build handler + + // Ensure profile and apiProvider exist before trying to build handler. if (profile && profile.apiProvider) { condensingApiHandler = buildApiHandler(profile) } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 5e1aa86f31..64367c3084 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -23,12 +23,12 @@ import { type TerminalActionPromptType, type HistoryItem, type CloudUserInfo, - type MarketplaceItem, requestyDefaultModelId, openRouterDefaultModelId, glamaDefaultModelId, ORGANIZATION_ALLOW_ALL, DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT, + DEFAULT_WRITE_DELAY_MS, } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" import { CloudService, getRooCodeApiUrl } from "@roo-code/cloud" @@ -41,9 +41,8 @@ import { supportPrompt } from "../../shared/support-prompt" import { GlobalFileNames } from "../../shared/globalFileNames" import { ExtensionMessage, MarketplaceInstalledMetadata } from "../../shared/ExtensionMessage" import { Mode, defaultModeSlug, getModeBySlug } from "../../shared/modes" -import { experimentDefault, experiments, EXPERIMENT_IDS } from "../../shared/experiments" +import { experimentDefault } from "../../shared/experiments" import { formatLanguage } from "../../shared/language" -import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" import { Terminal } from "../../integrations/terminal/Terminal" import { downloadTask } from "../../integrations/misc/export-markdown" import { getTheme } from "../../integrations/theme/getTheme" @@ -1977,4 +1976,8 @@ export class ClineProvider } } -class OrganizationAllowListViolationError extends Error {} +class OrganizationAllowListViolationError extends Error { + constructor(message: string) { + super(message) + } +}