mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Miscellaneous cleanup (#6453)
This commit is contained in:
parent
b8dc31581c
commit
cb6dccab95
11 changed files with 74 additions and 52 deletions
|
|
@ -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 <relative-path-from-workspace-root>`
|
||||
- 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: `<div className="text-md text-vscode-descriptionForeground mb-2" />` instead of style objects
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
readme test
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -93,10 +93,9 @@ 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 ClineEvents = {
|
||||
export type TaskEvents = {
|
||||
message: [{ action: "created" | "updated"; message: ClineMessage }]
|
||||
taskStarted: []
|
||||
taskModeSwitched: [taskId: string, mode: string]
|
||||
|
|
@ -110,6 +109,10 @@ export type ClineEvents = {
|
|||
taskToolFailed: [taskId: string, tool: ToolName, error: string]
|
||||
}
|
||||
|
||||
export type TaskEventHandlers = {
|
||||
[K in keyof TaskEvents]: (...args: TaskEvents[K]) => void | Promise<void>
|
||||
}
|
||||
|
||||
export type TaskOptions = {
|
||||
provider: ClineProvider
|
||||
apiConfiguration: ProviderSettings
|
||||
|
|
@ -125,10 +128,10 @@ export type TaskOptions = {
|
|||
rootTask?: Task
|
||||
parentTask?: Task
|
||||
taskNumber?: number
|
||||
onCreated?: (cline: Task) => void
|
||||
onCreated?: (task: Task) => void
|
||||
}
|
||||
|
||||
export class Task extends EventEmitter<ClineEvents> {
|
||||
export class Task extends EventEmitter<TaskEvents> {
|
||||
todoList?: TodoItem[]
|
||||
readonly taskId: string
|
||||
readonly instanceId: string
|
||||
|
|
@ -137,6 +140,7 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
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.
|
||||
|
|
@ -279,10 +283,12 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
}
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -311,25 +317,26 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
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 ?? {},
|
||||
|
|
@ -1230,7 +1237,7 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
}
|
||||
} 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 {
|
||||
|
|
@ -1240,7 +1247,7 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
@ -1847,6 +1854,7 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
|
||||
public async *attemptApiRequest(retryAttempt: number = 0): ApiStream {
|
||||
const state = await this.providerRef.deref()?.getState()
|
||||
|
||||
const {
|
||||
apiConfiguration,
|
||||
autoApprovalEnabled,
|
||||
|
|
@ -1858,21 +1866,24 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -78,13 +77,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 +373,7 @@ export class ClineProvider
|
|||
// Errors from terminal commands seem to get swallowed / ignored.
|
||||
vscode.window.showErrorMessage(error.message)
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
|
@ -526,7 +520,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 +543,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 +623,7 @@ export class ClineProvider
|
|||
experiments,
|
||||
} = await this.getState()
|
||||
|
||||
const cline = new Task({
|
||||
const task = new Task({
|
||||
provider: this,
|
||||
apiConfiguration,
|
||||
enableDiff,
|
||||
|
|
@ -641,14 +635,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) {
|
||||
|
|
@ -1999,3 +1995,9 @@ export class ClineProvider
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OrganizationAllowListViolationError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ export class API extends EventEmitter<RooCodeEvents> 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)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export class ProfileValidator {
|
|||
}
|
||||
|
||||
const providerAllowList = allowList.providers[providerName]
|
||||
|
||||
if (!providerAllowList) {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue