Просмотр исходного кода

Move more types to @roo-code/types (for the cli) (#10583)

Chris Estreich 1 неделя назад
Родитель
Сommit
3171ffc809
89 измененных файлов с 1135 добавлено и 1058 удалено
  1. 1 2
      apps/vscode-e2e/package.json
  2. 4 2
      package.json
  3. 1 1
      packages/types/npm/package.metadata.json
  4. 1 1
      packages/types/package.json
  5. 13 0
      packages/types/src/git.ts
  6. 2 0
      packages/types/src/index.ts
  7. 5 0
      packages/types/src/marketplace.ts
  8. 90 1
      packages/types/src/mcp.ts
  9. 5 0
      packages/types/src/model.ts
  10. 2 1
      packages/types/src/provider-settings.ts
  11. 644 0
      packages/types/src/vscode-extension-host.ts
  12. 110 116
      pnpm-lock.yaml
  13. 1 2
      src/api/providers/fetchers/huggingface.ts
  14. 1 3
      src/api/providers/fetchers/io-intelligence.ts
  15. 1 1
      src/api/providers/fetchers/litellm.ts
  16. 2 2
      src/api/providers/fetchers/modelCache.ts
  17. 4 2
      src/api/providers/fetchers/modelEndpointCache.ts
  18. 1 2
      src/api/providers/fetchers/roo.ts
  19. 3 1
      src/api/providers/huggingface.ts
  20. 3 2
      src/api/providers/openrouter.ts
  21. 2 1
      src/api/providers/requesty.ts
  22. 8 6
      src/api/providers/roo.ts
  23. 2 2
      src/api/providers/router-provider.ts
  24. 9 3
      src/core/auto-approval/index.ts
  25. 1 3
      src/core/auto-approval/mcp.ts
  26. 5 2
      src/core/prompts/tools/native-tools/__tests__/mcp_server.spec.ts
  27. 34 6
      src/core/webview/ClineProvider.ts
  28. 4 1
      src/core/webview/__tests__/ClineProvider.spec.ts
  29. 2 1
      src/core/webview/__tests__/webviewMessageHandler.spec.ts
  30. 19 18
      src/core/webview/webviewMessageHandler.ts
  31. 0 1
      src/package.json
  32. 21 11
      src/services/mcp/McpHub.ts
  33. 0 344
      src/shared/ExtensionMessage.ts
  34. 1 311
      src/shared/WebviewMessage.ts
  35. 0 6
      src/shared/api.ts
  36. 0 83
      src/shared/mcp.ts
  37. 4 14
      src/utils/git.ts
  38. 0 1
      webview-ui/package.json
  39. 2 2
      webview-ui/src/App.tsx
  40. 1 1
      webview-ui/src/__tests__/command-autocomplete.spec.ts
  41. 2 1
      webview-ui/src/components/browser-session/BrowserPanelStateProvider.tsx
  42. 9 5
      webview-ui/src/components/browser-session/BrowserSessionPanel.tsx
  43. 2 1
      webview-ui/src/components/chat/ChatTextArea.tsx
  44. 2 3
      webview-ui/src/components/chat/ChatView.tsx
  45. 1 3
      webview-ui/src/components/chat/CommandExecution.tsx
  46. 4 4
      webview-ui/src/components/chat/ContextMenu.tsx
  47. 6 3
      webview-ui/src/components/chat/McpExecution.tsx
  48. 1 1
      webview-ui/src/components/chat/SlashCommandItem.tsx
  49. 1 1
      webview-ui/src/components/chat/SlashCommandItemSimple.tsx
  50. 2 2
      webview-ui/src/components/chat/__tests__/SlashCommandItemSimple.spec.tsx
  51. 5 3
      webview-ui/src/components/cloud/OrganizationSwitcher.tsx
  52. 2 2
      webview-ui/src/components/marketplace/MarketplaceViewStateManager.ts
  53. 2 1
      webview-ui/src/components/mcp/McpEnabledToggle.tsx
  54. 1 1
      webview-ui/src/components/mcp/McpErrorRow.tsx
  55. 1 1
      webview-ui/src/components/mcp/McpResourceRow.tsx
  56. 1 1
      webview-ui/src/components/mcp/McpToolRow.tsx
  57. 1 1
      webview-ui/src/components/mcp/McpView.tsx
  58. 1 1
      webview-ui/src/components/settings/SlashCommandsSettings.tsx
  59. 1 1
      webview-ui/src/components/settings/TerminalSettings.tsx
  60. 1 1
      webview-ui/src/components/settings/__tests__/SlashCommandsSettings.spec.tsx
  61. 1 3
      webview-ui/src/components/settings/providers/Chutes.tsx
  62. 3 0
      webview-ui/src/components/settings/providers/ClaudeCode.tsx
  63. 6 3
      webview-ui/src/components/settings/providers/DeepInfra.tsx
  64. 1 2
      webview-ui/src/components/settings/providers/HuggingFace.tsx
  65. 1 3
      webview-ui/src/components/settings/providers/LMStudio.tsx
  66. 6 2
      webview-ui/src/components/settings/providers/LiteLLM.tsx
  67. 1 3
      webview-ui/src/components/settings/providers/Mistral.tsx
  68. 1 4
      webview-ui/src/components/settings/providers/Ollama.tsx
  69. 1 2
      webview-ui/src/components/settings/providers/OpenAICompatible.tsx
  70. 6 3
      webview-ui/src/components/settings/providers/OpenRouter.tsx
  71. 1 0
      webview-ui/src/components/settings/providers/QwenCode.tsx
  72. 6 3
      webview-ui/src/components/settings/providers/Requesty.tsx
  73. 6 3
      webview-ui/src/components/settings/providers/Roo.tsx
  74. 6 3
      webview-ui/src/components/settings/providers/Unbound.tsx
  75. 1 3
      webview-ui/src/components/settings/providers/VSCodeLM.tsx
  76. 6 3
      webview-ui/src/components/settings/providers/VercelAiGateway.tsx
  77. 1 1
      webview-ui/src/components/settings/providers/ZAi.tsx
  78. 1 2
      webview-ui/src/components/ui/hooks/useLmStudioModels.ts
  79. 1 2
      webview-ui/src/components/ui/hooks/useOllamaModels.ts
  80. 3 1
      webview-ui/src/components/ui/hooks/useRooCreditBalance.ts
  81. 1 2
      webview-ui/src/components/ui/hooks/useRouterModels.ts
  82. 2 2
      webview-ui/src/components/ui/hooks/useSelectedModel.ts
  83. 1 1
      webview-ui/src/components/welcome/RooHero.tsx
  84. 7 3
      webview-ui/src/context/ExtensionStateContext.tsx
  85. 6 3
      webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx
  86. 1 3
      webview-ui/src/utils/__tests__/validate.spec.ts
  87. 1 2
      webview-ui/src/utils/context-mentions.ts
  88. 1 1
      webview-ui/src/utils/mcp.ts
  89. 1 2
      webview-ui/src/utils/validate.ts

+ 1 - 2
apps/vscode-e2e/package.json

@@ -20,7 +20,6 @@
 		"@vscode/test-electron": "^2.4.0",
 		"glob": "^11.1.0",
 		"mocha": "^11.1.0",
-		"rimraf": "^6.0.1",
-		"typescript": "5.8.3"
+		"rimraf": "^6.0.1"
 	}
 }

+ 4 - 2
package.json

@@ -45,7 +45,7 @@
 		"rimraf": "^6.0.1",
 		"tsx": "^4.19.3",
 		"turbo": "^2.5.6",
-		"typescript": "^5.4.5"
+		"typescript": "5.8.3"
 	},
 	"lint-staged": {
 		"*.{js,jsx,ts,tsx,json,css,md}": [
@@ -63,7 +63,9 @@
 			"brace-expansion": "^2.0.2",
 			"form-data": ">=4.0.4",
 			"bluebird": ">=3.7.2",
-			"glob": ">=11.1.0"
+			"glob": ">=11.1.0",
+			"@types/react": "^18.3.23",
+			"@types/react-dom": "^18.3.5"
 		}
 	}
 }

+ 1 - 1
packages/types/npm/package.metadata.json

@@ -1,6 +1,6 @@
 {
 	"name": "@roo-code/types",
-	"version": "1.99.0",
+	"version": "1.100.0",
 	"description": "TypeScript type definitions for Roo Code.",
 	"publishConfig": {
 		"access": "public",

+ 1 - 1
packages/types/package.json

@@ -30,7 +30,7 @@
 		"@roo-code/config-typescript": "workspace:^",
 		"@types/node": "^24.1.0",
 		"globals": "^16.3.0",
-		"tsup": "^8.3.5",
+		"tsup": "^8.4.0",
 		"vitest": "^3.2.3"
 	}
 }

+ 13 - 0
packages/types/src/git.ts

@@ -0,0 +1,13 @@
+export interface GitRepositoryInfo {
+	repositoryUrl?: string
+	repositoryName?: string
+	defaultBranch?: string
+}
+
+export interface GitCommit {
+	hash: string
+	shortHash: string
+	subject: string
+	author: string
+	date: string
+}

+ 2 - 0
packages/types/src/index.ts

@@ -7,6 +7,7 @@ export * from "./custom-tool.js"
 export * from "./events.js"
 export * from "./experiment.js"
 export * from "./followup.js"
+export * from "./git.js"
 export * from "./global-settings.js"
 export * from "./history.js"
 export * from "./image-generation.js"
@@ -24,6 +25,7 @@ export * from "./terminal.js"
 export * from "./tool.js"
 export * from "./tool-params.js"
 export * from "./type-fu.js"
+export * from "./vscode-extension-host.js"
 export * from "./vscode.js"
 
 export * from "./providers/index.js"

+ 5 - 0
packages/types/src/marketplace.ts

@@ -86,3 +86,8 @@ export const installMarketplaceItemOptionsSchema = z.object({
 })
 
 export type InstallMarketplaceItemOptions = z.infer<typeof installMarketplaceItemOptionsSchema>
+
+export interface MarketplaceInstalledMetadata {
+	project: Record<string, { type: string }>
+	global: Record<string, { type: string }>
+}

+ 90 - 1
packages/types/src/mcp.ts

@@ -1,8 +1,9 @@
 import { z } from "zod"
 
 /**
- * MCP Server Use Types
+ * McpServerUse
  */
+
 export interface McpServerUse {
 	type: string
 	serverName: string
@@ -39,3 +40,91 @@ export const mcpExecutionStatusSchema = z.discriminatedUnion("status", [
 ])
 
 export type McpExecutionStatus = z.infer<typeof mcpExecutionStatusSchema>
+
+/**
+ * McpServer
+ */
+
+export type McpServer = {
+	name: string
+	config: string
+	status: "connected" | "connecting" | "disconnected"
+	error?: string
+	errorHistory?: McpErrorEntry[]
+	tools?: McpTool[]
+	resources?: McpResource[]
+	resourceTemplates?: McpResourceTemplate[]
+	disabled?: boolean
+	timeout?: number
+	source?: "global" | "project"
+	projectPath?: string
+	instructions?: string
+}
+
+export type McpTool = {
+	name: string
+	description?: string
+	inputSchema?: object
+	alwaysAllow?: boolean
+	enabledForPrompt?: boolean
+}
+
+export type McpResource = {
+	uri: string
+	name: string
+	mimeType?: string
+	description?: string
+}
+
+export type McpResourceTemplate = {
+	uriTemplate: string
+	name: string
+	description?: string
+	mimeType?: string
+}
+
+export type McpResourceResponse = {
+	_meta?: Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
+	contents: Array<{
+		uri: string
+		mimeType?: string
+		text?: string
+		blob?: string
+	}>
+}
+
+export type McpToolCallResponse = {
+	_meta?: Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
+	content: Array<
+		| {
+				type: "text"
+				text: string
+		  }
+		| {
+				type: "image"
+				data: string
+				mimeType: string
+		  }
+		| {
+				type: "audio"
+				data: string
+				mimeType: string
+		  }
+		| {
+				type: "resource"
+				resource: {
+					uri: string
+					mimeType?: string
+					text?: string
+					blob?: string
+				}
+		  }
+	>
+	isError?: boolean
+}
+
+export type McpErrorEntry = {
+	message: string
+	timestamp: number
+	level: "error" | "warn" | "info"
+}

+ 5 - 0
packages/types/src/model.ts

@@ -1,4 +1,5 @@
 import { z } from "zod"
+import { DynamicProvider, LocalProvider } from "./provider-settings.js"
 
 /**
  * ReasoningEffort
@@ -140,3 +141,7 @@ export const modelInfoSchema = z.object({
 })
 
 export type ModelInfo = z.infer<typeof modelInfoSchema>
+
+export type ModelRecord = Record<string, ModelInfo>
+
+export type RouterModels = Record<DynamicProvider | LocalProvider, ModelRecord>

+ 2 - 1
packages/types/src/provider-settings.ts

@@ -407,7 +407,8 @@ const qwenCodeSchema = apiModelIdProviderModelSchema.extend({
 })
 
 const rooSchema = apiModelIdProviderModelSchema.extend({
-	// No additional fields needed - uses cloud authentication.
+	// Can use cloud authentication or provide an API key (cli).
+	rooApiKey: z.string().optional(),
 })
 
 const vercelAiGatewaySchema = baseProviderSettingsSchema.extend({

+ 644 - 0
packages/types/src/vscode-extension-host.ts

@@ -0,0 +1,644 @@
+import { z } from "zod"
+
+import type { GlobalSettings, RooCodeSettings } from "./global-settings.js"
+import type { ProviderSettings, ProviderSettingsEntry } from "./provider-settings.js"
+import type { HistoryItem } from "./history.js"
+import type { ModeConfig, PromptComponent } from "./mode.js"
+import type { TelemetrySetting } from "./telemetry.js"
+import type { Experiments } from "./experiment.js"
+import type { ClineMessage, QueuedMessage } from "./message.js"
+import {
+	type MarketplaceItem,
+	type MarketplaceInstalledMetadata,
+	type InstallMarketplaceItemOptions,
+	marketplaceItemSchema,
+} from "./marketplace.js"
+import type { TodoItem } from "./todo.js"
+import type { CloudUserInfo, CloudOrganizationMembership, OrganizationAllowList, ShareVisibility } from "./cloud.js"
+import type { SerializedCustomToolDefinition } from "./custom-tool.js"
+import type { GitCommit } from "./git.js"
+import type { McpServer } from "./mcp.js"
+import type { ModelRecord, RouterModels } from "./model.js"
+
+/**
+ * ExtensionMessage
+ * Extension -> Webview | CLI
+ */
+export interface ExtensionMessage {
+	type:
+		| "action"
+		| "state"
+		| "selectedImages"
+		| "theme"
+		| "workspaceUpdated"
+		| "invoke"
+		| "messageUpdated"
+		| "mcpServers"
+		| "enhancedPrompt"
+		| "commitSearchResults"
+		| "listApiConfig"
+		| "routerModels"
+		| "openAiModels"
+		| "ollamaModels"
+		| "lmStudioModels"
+		| "vsCodeLmModels"
+		| "huggingFaceModels"
+		| "vsCodeLmApiAvailable"
+		| "updatePrompt"
+		| "systemPrompt"
+		| "autoApprovalEnabled"
+		| "updateCustomMode"
+		| "deleteCustomMode"
+		| "exportModeResult"
+		| "importModeResult"
+		| "checkRulesDirectoryResult"
+		| "deleteCustomModeCheck"
+		| "currentCheckpointUpdated"
+		| "checkpointInitWarning"
+		| "browserToolEnabled"
+		| "browserConnectionResult"
+		| "remoteBrowserEnabled"
+		| "ttsStart"
+		| "ttsStop"
+		| "maxReadFileLine"
+		| "fileSearchResults"
+		| "toggleApiConfigPin"
+		| "acceptInput"
+		| "setHistoryPreviewCollapsed"
+		| "commandExecutionStatus"
+		| "mcpExecutionStatus"
+		| "vsCodeSetting"
+		| "authenticatedUser"
+		| "condenseTaskContextStarted"
+		| "condenseTaskContextResponse"
+		| "singleRouterModelFetchResponse"
+		| "rooCreditBalance"
+		| "indexingStatusUpdate"
+		| "indexCleared"
+		| "codebaseIndexConfig"
+		| "marketplaceInstallResult"
+		| "marketplaceRemoveResult"
+		| "marketplaceData"
+		| "shareTaskSuccess"
+		| "codeIndexSettingsSaved"
+		| "codeIndexSecretStatus"
+		| "showDeleteMessageDialog"
+		| "showEditMessageDialog"
+		| "commands"
+		| "insertTextIntoTextarea"
+		| "dismissedUpsells"
+		| "organizationSwitchResult"
+		| "interactionRequired"
+		| "browserSessionUpdate"
+		| "browserSessionNavigate"
+		| "claudeCodeRateLimits"
+		| "customToolsResult"
+		| "modes"
+	text?: string
+	payload?: any // eslint-disable-line @typescript-eslint/no-explicit-any
+	checkpointWarning?: {
+		type: "WAIT_TIMEOUT" | "INIT_TIMEOUT"
+		timeout: number
+	}
+	action?:
+		| "chatButtonClicked"
+		| "settingsButtonClicked"
+		| "historyButtonClicked"
+		| "marketplaceButtonClicked"
+		| "cloudButtonClicked"
+		| "didBecomeVisible"
+		| "focusInput"
+		| "switchTab"
+		| "toggleAutoApprove"
+	invoke?: "newChat" | "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" | "setChatBoxMessage"
+	state?: ExtensionState
+	images?: string[]
+	filePaths?: string[]
+	openedTabs?: Array<{
+		label: string
+		isActive: boolean
+		path?: string
+	}>
+	clineMessage?: ClineMessage
+	routerModels?: RouterModels
+	openAiModels?: string[]
+	ollamaModels?: ModelRecord
+	lmStudioModels?: ModelRecord
+	vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[]
+	huggingFaceModels?: Array<{
+		id: string
+		object: string
+		created: number
+		owned_by: string
+		providers: Array<{
+			provider: string
+			status: "live" | "staging" | "error"
+			supports_tools?: boolean
+			supports_structured_output?: boolean
+			context_length?: number
+			pricing?: {
+				input: number
+				output: number
+			}
+		}>
+	}>
+	mcpServers?: McpServer[]
+	commits?: GitCommit[]
+	listApiConfig?: ProviderSettingsEntry[]
+	mode?: string
+	customMode?: ModeConfig
+	slug?: string
+	success?: boolean
+	values?: Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
+	requestId?: string
+	promptText?: string
+	results?:
+		| { path: string; type: "file" | "folder"; label?: string }[]
+		| { name: string; description?: string; argumentHint?: string; source: "global" | "project" | "built-in" }[]
+	error?: string
+	setting?: string
+	value?: any // eslint-disable-line @typescript-eslint/no-explicit-any
+	hasContent?: boolean
+	items?: MarketplaceItem[]
+	userInfo?: CloudUserInfo
+	organizationAllowList?: OrganizationAllowList
+	tab?: string
+	marketplaceItems?: MarketplaceItem[]
+	organizationMcps?: MarketplaceItem[]
+	marketplaceInstalledMetadata?: MarketplaceInstalledMetadata
+	errors?: string[]
+	visibility?: ShareVisibility
+	rulesFolderPath?: string
+	settings?: any // eslint-disable-line @typescript-eslint/no-explicit-any
+	messageTs?: number
+	hasCheckpoint?: boolean
+	context?: string
+	commands?: Command[]
+	queuedMessages?: QueuedMessage[]
+	list?: string[] // For dismissedUpsells
+	organizationId?: string | null // For organizationSwitchResult
+	browserSessionMessages?: ClineMessage[] // For browser session panel updates
+	isBrowserSessionActive?: boolean // For browser session panel updates
+	stepIndex?: number // For browserSessionNavigate: the target step index to display
+	tools?: SerializedCustomToolDefinition[] // For customToolsResult
+	modes?: { slug: string; name: string }[] // For modes response
+}
+
+export type ExtensionState = Pick<
+	GlobalSettings,
+	| "currentApiConfigName"
+	| "listApiConfigMeta"
+	| "pinnedApiConfigs"
+	| "customInstructions"
+	| "dismissedUpsells"
+	| "autoApprovalEnabled"
+	| "alwaysAllowReadOnly"
+	| "alwaysAllowReadOnlyOutsideWorkspace"
+	| "alwaysAllowWrite"
+	| "alwaysAllowWriteOutsideWorkspace"
+	| "alwaysAllowWriteProtected"
+	| "alwaysAllowBrowser"
+	| "alwaysAllowMcp"
+	| "alwaysAllowModeSwitch"
+	| "alwaysAllowSubtasks"
+	| "alwaysAllowFollowupQuestions"
+	| "alwaysAllowExecute"
+	| "followupAutoApproveTimeoutMs"
+	| "allowedCommands"
+	| "deniedCommands"
+	| "allowedMaxRequests"
+	| "allowedMaxCost"
+	| "browserToolEnabled"
+	| "browserViewportSize"
+	| "screenshotQuality"
+	| "remoteBrowserEnabled"
+	| "cachedChromeHostUrl"
+	| "remoteBrowserHost"
+	| "ttsEnabled"
+	| "ttsSpeed"
+	| "soundEnabled"
+	| "soundVolume"
+	| "maxConcurrentFileReads"
+	| "terminalOutputLineLimit"
+	| "terminalOutputCharacterLimit"
+	| "terminalShellIntegrationTimeout"
+	| "terminalShellIntegrationDisabled"
+	| "terminalCommandDelay"
+	| "terminalPowershellCounter"
+	| "terminalZshClearEolMark"
+	| "terminalZshOhMy"
+	| "terminalZshP10k"
+	| "terminalZdotdir"
+	| "terminalCompressProgressBar"
+	| "diagnosticsEnabled"
+	| "diffEnabled"
+	| "fuzzyMatchThreshold"
+	| "language"
+	| "modeApiConfigs"
+	| "customModePrompts"
+	| "customSupportPrompts"
+	| "enhancementApiConfigId"
+	| "condensingApiConfigId"
+	| "customCondensingPrompt"
+	| "codebaseIndexConfig"
+	| "codebaseIndexModels"
+	| "profileThresholds"
+	| "includeDiagnosticMessages"
+	| "maxDiagnosticMessages"
+	| "imageGenerationProvider"
+	| "openRouterImageGenerationSelectedModel"
+	| "includeTaskHistoryInEnhance"
+	| "reasoningBlockCollapsed"
+	| "enterBehavior"
+	| "includeCurrentTime"
+	| "includeCurrentCost"
+	| "maxGitStatusFiles"
+	| "requestDelaySeconds"
+> & {
+	version: string
+	clineMessages: ClineMessage[]
+	currentTaskItem?: HistoryItem
+	currentTaskTodos?: TodoItem[] // Initial todos for the current task
+	apiConfiguration: ProviderSettings
+	uriScheme?: string
+	shouldShowAnnouncement: boolean
+
+	taskHistory: HistoryItem[]
+
+	writeDelayMs: number
+
+	enableCheckpoints: boolean
+	checkpointTimeout: number // Timeout for checkpoint initialization in seconds (default: 15)
+	maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
+	maxWorkspaceFiles: number // Maximum number of files to include in current working directory details (0-500)
+	showRooIgnoredFiles: boolean // Whether to show .rooignore'd files in listings
+	enableSubfolderRules: boolean // Whether to load rules from subdirectories
+	maxReadFileLine: number // Maximum number of lines to read from a file before truncating
+	maxImageFileSize: number // Maximum size of image files to process in MB
+	maxTotalImageSize: number // Maximum total size for all images in a single read operation in MB
+
+	experiments: Experiments // Map of experiment IDs to their enabled state
+
+	mcpEnabled: boolean
+	enableMcpServerCreation: boolean
+
+	mode: string
+	customModes: ModeConfig[]
+	toolRequirements?: Record<string, boolean> // Map of tool names to their requirements (e.g. {"apply_diff": true} if diffEnabled)
+
+	cwd?: string // Current working directory
+	telemetrySetting: TelemetrySetting
+	telemetryKey?: string
+	machineId?: string
+
+	renderContext: "sidebar" | "editor"
+	settingsImportedAt?: number
+	historyPreviewCollapsed?: boolean
+
+	cloudUserInfo: CloudUserInfo | null
+	cloudIsAuthenticated: boolean
+	cloudAuthSkipModel?: boolean // Flag indicating auth completed without model selection (user should pick 3rd-party provider)
+	cloudApiUrl?: string
+	cloudOrganizations?: CloudOrganizationMembership[]
+	sharingEnabled: boolean
+	publicSharingEnabled: boolean
+	organizationAllowList: OrganizationAllowList
+	organizationSettingsVersion?: number
+
+	isBrowserSessionActive: boolean // Actual browser session state
+
+	autoCondenseContext: boolean
+	autoCondenseContextPercent: number
+	marketplaceItems?: MarketplaceItem[]
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	marketplaceInstalledMetadata?: { project: Record<string, any>; global: Record<string, any> }
+	profileThresholds: Record<string, number>
+	hasOpenedModeSelector: boolean
+	openRouterImageApiKey?: string
+	messageQueue?: QueuedMessage[]
+	lastShownAnnouncementId?: string
+	apiModelId?: string
+	mcpServers?: McpServer[]
+	hasSystemPromptOverride?: boolean
+	mdmCompliant?: boolean
+	remoteControlEnabled: boolean
+	taskSyncEnabled: boolean
+	featureRoomoteControlEnabled: boolean
+	claudeCodeIsAuthenticated?: boolean
+	debug?: boolean
+}
+
+export interface Command {
+	name: string
+	source: "global" | "project" | "built-in"
+	filePath?: string
+	description?: string
+	argumentHint?: string
+}
+
+/**
+ * WebviewMessage
+ * Webview | CLI -> Extension
+ */
+
+export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" | "objectResponse"
+
+export type AudioType = "notification" | "celebration" | "progress_loop"
+
+export interface UpdateTodoListPayload {
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	todos: any[]
+}
+
+export type EditQueuedMessagePayload = Pick<QueuedMessage, "id" | "text" | "images">
+
+export interface WebviewMessage {
+	type:
+		| "updateTodoList"
+		| "deleteMultipleTasksWithIds"
+		| "currentApiConfigName"
+		| "saveApiConfiguration"
+		| "upsertApiConfiguration"
+		| "deleteApiConfiguration"
+		| "loadApiConfiguration"
+		| "loadApiConfigurationById"
+		| "renameApiConfiguration"
+		| "getListApiConfiguration"
+		| "customInstructions"
+		| "webviewDidLaunch"
+		| "newTask"
+		| "askResponse"
+		| "terminalOperation"
+		| "clearTask"
+		| "didShowAnnouncement"
+		| "selectImages"
+		| "exportCurrentTask"
+		| "shareCurrentTask"
+		| "showTaskWithId"
+		| "deleteTaskWithId"
+		| "exportTaskWithId"
+		| "importSettings"
+		| "exportSettings"
+		| "resetState"
+		| "flushRouterModels"
+		| "requestRouterModels"
+		| "requestOpenAiModels"
+		| "requestOllamaModels"
+		| "requestLmStudioModels"
+		| "requestRooModels"
+		| "requestRooCreditBalance"
+		| "requestVsCodeLmModels"
+		| "requestHuggingFaceModels"
+		| "openImage"
+		| "saveImage"
+		| "openFile"
+		| "openMention"
+		| "cancelTask"
+		| "cancelAutoApproval"
+		| "updateVSCodeSetting"
+		| "getVSCodeSetting"
+		| "vsCodeSetting"
+		| "updateCondensingPrompt"
+		| "playSound"
+		| "playTts"
+		| "stopTts"
+		| "ttsEnabled"
+		| "ttsSpeed"
+		| "openKeyboardShortcuts"
+		| "openMcpSettings"
+		| "openProjectMcpSettings"
+		| "restartMcpServer"
+		| "refreshAllMcpServers"
+		| "toggleToolAlwaysAllow"
+		| "toggleToolEnabledForPrompt"
+		| "toggleMcpServer"
+		| "updateMcpTimeout"
+		| "enhancePrompt"
+		| "enhancedPrompt"
+		| "draggedImages"
+		| "deleteMessage"
+		| "deleteMessageConfirm"
+		| "submitEditedMessage"
+		| "editMessageConfirm"
+		| "enableMcpServerCreation"
+		| "remoteControlEnabled"
+		| "taskSyncEnabled"
+		| "searchCommits"
+		| "setApiConfigPassword"
+		| "mode"
+		| "updatePrompt"
+		| "getSystemPrompt"
+		| "copySystemPrompt"
+		| "systemPrompt"
+		| "enhancementApiConfigId"
+		| "autoApprovalEnabled"
+		| "updateCustomMode"
+		| "deleteCustomMode"
+		| "setopenAiCustomModelInfo"
+		| "openCustomModesSettings"
+		| "checkpointDiff"
+		| "checkpointRestore"
+		| "deleteMcpServer"
+		| "codebaseIndexEnabled"
+		| "telemetrySetting"
+		| "testBrowserConnection"
+		| "browserConnectionResult"
+		| "searchFiles"
+		| "toggleApiConfigPin"
+		| "hasOpenedModeSelector"
+		| "clearCloudAuthSkipModel"
+		| "cloudButtonClicked"
+		| "rooCloudSignIn"
+		| "cloudLandingPageSignIn"
+		| "rooCloudSignOut"
+		| "rooCloudManualUrl"
+		| "claudeCodeSignIn"
+		| "claudeCodeSignOut"
+		| "switchOrganization"
+		| "condenseTaskContextRequest"
+		| "requestIndexingStatus"
+		| "startIndexing"
+		| "clearIndexData"
+		| "indexingStatusUpdate"
+		| "indexCleared"
+		| "focusPanelRequest"
+		| "openExternal"
+		| "filterMarketplaceItems"
+		| "marketplaceButtonClicked"
+		| "installMarketplaceItem"
+		| "installMarketplaceItemWithParameters"
+		| "cancelMarketplaceInstall"
+		| "removeInstalledMarketplaceItem"
+		| "marketplaceInstallResult"
+		| "fetchMarketplaceData"
+		| "switchTab"
+		| "shareTaskSuccess"
+		| "exportMode"
+		| "exportModeResult"
+		| "importMode"
+		| "importModeResult"
+		| "checkRulesDirectory"
+		| "checkRulesDirectoryResult"
+		| "saveCodeIndexSettingsAtomic"
+		| "requestCodeIndexSecretStatus"
+		| "requestCommands"
+		| "openCommandFile"
+		| "deleteCommand"
+		| "createCommand"
+		| "insertTextIntoTextarea"
+		| "showMdmAuthRequiredNotification"
+		| "imageGenerationSettings"
+		| "queueMessage"
+		| "removeQueuedMessage"
+		| "editQueuedMessage"
+		| "dismissUpsell"
+		| "getDismissedUpsells"
+		| "updateSettings"
+		| "allowedCommands"
+		| "deniedCommands"
+		| "killBrowserSession"
+		| "openBrowserSessionPanel"
+		| "showBrowserSessionPanelAtStep"
+		| "refreshBrowserSessionPanel"
+		| "browserPanelDidLaunch"
+		| "openDebugApiHistory"
+		| "openDebugUiHistory"
+		| "downloadErrorDiagnostics"
+		| "requestClaudeCodeRateLimits"
+		| "refreshCustomTools"
+		| "requestModes"
+		| "switchMode"
+	text?: string
+	editedMessageContent?: string
+	tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "cloud"
+	disabled?: boolean
+	context?: string
+	dataUri?: string
+	askResponse?: ClineAskResponse
+	apiConfiguration?: ProviderSettings
+	images?: string[]
+	bool?: boolean
+	value?: number
+	stepIndex?: number
+	isLaunchAction?: boolean
+	forceShow?: boolean
+	commands?: string[]
+	audioType?: AudioType
+	serverName?: string
+	toolName?: string
+	alwaysAllow?: boolean
+	isEnabled?: boolean
+	mode?: string
+	promptMode?: string | "enhance"
+	customPrompt?: PromptComponent
+	dataUrls?: string[]
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	values?: Record<string, any>
+	query?: string
+	setting?: string
+	slug?: string
+	modeConfig?: ModeConfig
+	timeout?: number
+	payload?: WebViewMessagePayload
+	source?: "global" | "project"
+	requestId?: string
+	ids?: string[]
+	hasSystemPromptOverride?: boolean
+	terminalOperation?: "continue" | "abort"
+	messageTs?: number
+	restoreCheckpoint?: boolean
+	historyPreviewCollapsed?: boolean
+	filters?: { type?: string; search?: string; tags?: string[] }
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	settings?: any
+	url?: string // For openExternal
+	mpItem?: MarketplaceItem
+	mpInstallOptions?: InstallMarketplaceItemOptions
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	config?: Record<string, any> // Add config to the payload
+	visibility?: ShareVisibility // For share visibility
+	hasContent?: boolean // For checkRulesDirectoryResult
+	checkOnly?: boolean // For deleteCustomMode check
+	upsellId?: string // For dismissUpsell
+	list?: string[] // For dismissedUpsells response
+	organizationId?: string | null // For organization switching
+	useProviderSignup?: boolean // For rooCloudSignIn to use provider signup flow
+	codeIndexSettings?: {
+		// Global state settings
+		codebaseIndexEnabled: boolean
+		codebaseIndexQdrantUrl: string
+		codebaseIndexEmbedderProvider:
+			| "openai"
+			| "ollama"
+			| "openai-compatible"
+			| "gemini"
+			| "mistral"
+			| "vercel-ai-gateway"
+			| "bedrock"
+			| "openrouter"
+		codebaseIndexEmbedderBaseUrl?: string
+		codebaseIndexEmbedderModelId: string
+		codebaseIndexEmbedderModelDimension?: number // Generic dimension for all providers
+		codebaseIndexOpenAiCompatibleBaseUrl?: string
+		codebaseIndexBedrockRegion?: string
+		codebaseIndexBedrockProfile?: string
+		codebaseIndexSearchMaxResults?: number
+		codebaseIndexSearchMinScore?: number
+		codebaseIndexOpenRouterSpecificProvider?: string // OpenRouter provider routing
+
+		// Secret settings
+		codeIndexOpenAiKey?: string
+		codeIndexQdrantApiKey?: string
+		codebaseIndexOpenAiCompatibleApiKey?: string
+		codebaseIndexGeminiApiKey?: string
+		codebaseIndexMistralApiKey?: string
+		codebaseIndexVercelAiGatewayApiKey?: string
+		codebaseIndexOpenRouterApiKey?: string
+	}
+	updatedSettings?: RooCodeSettings
+}
+
+export const checkoutDiffPayloadSchema = z.object({
+	ts: z.number().optional(),
+	previousCommitHash: z.string().optional(),
+	commitHash: z.string(),
+	mode: z.enum(["full", "checkpoint", "from-init", "to-current"]),
+})
+
+export type CheckpointDiffPayload = z.infer<typeof checkoutDiffPayloadSchema>
+
+export const checkoutRestorePayloadSchema = z.object({
+	ts: z.number(),
+	commitHash: z.string(),
+	mode: z.enum(["preview", "restore"]),
+})
+
+export type CheckpointRestorePayload = z.infer<typeof checkoutRestorePayloadSchema>
+
+export interface IndexingStatusPayload {
+	state: "Standby" | "Indexing" | "Indexed" | "Error"
+	message: string
+}
+
+export interface IndexClearedPayload {
+	success: boolean
+	error?: string
+}
+
+export const installMarketplaceItemWithParametersPayloadSchema = z.object({
+	item: marketplaceItemSchema,
+	parameters: z.record(z.string(), z.any()),
+})
+
+export type InstallMarketplaceItemWithParametersPayload = z.infer<
+	typeof installMarketplaceItemWithParametersPayloadSchema
+>
+
+export type WebViewMessagePayload =
+	| CheckpointDiffPayload
+	| CheckpointRestorePayload
+	| IndexingStatusPayload
+	| IndexClearedPayload
+	| InstallMarketplaceItemWithParametersPayload
+	| UpdateTodoListPayload
+	| EditQueuedMessagePayload

+ 110 - 116
pnpm-lock.yaml

@@ -12,6 +12,8 @@ overrides:
   form-data: '>=4.0.4'
   bluebird: '>=3.7.2'
   glob: '>=11.1.0'
+  '@types/react': ^18.3.23
+  '@types/react-dom': ^18.3.5
 
 importers:
 
@@ -75,7 +77,7 @@ importers:
         specifier: ^2.5.6
         version: 2.5.6
       typescript:
-        specifier: ^5.4.5
+        specifier: 5.8.3
         version: 5.8.3
 
   apps/cli:
@@ -150,9 +152,6 @@ importers:
       rimraf:
         specifier: ^6.0.1
         version: 6.0.1
-      typescript:
-        specifier: 5.8.3
-        version: 5.8.3
 
   apps/vscode-nightly:
     devDependencies:
@@ -402,7 +401,7 @@ importers:
         specifier: ^18.3.23
         version: 18.3.23
       '@types/react-dom':
-        specifier: ^18.3.7
+        specifier: ^18.3.5
         version: 18.3.7(@types/[email protected])
       autoprefixer:
         specifier: ^10.4.21
@@ -681,7 +680,7 @@ importers:
         specifier: ^16.3.0
         version: 16.3.0
       tsup:
-        specifier: ^8.3.5
+        specifier: ^8.4.0
         version: 8.5.0([email protected])([email protected])([email protected])([email protected])([email protected])
       vitest:
         specifier: ^3.2.3
@@ -1050,9 +1049,6 @@ importers:
       tsx:
         specifier: ^4.19.3
         version: 4.19.4
-      typescript:
-        specifier: 5.8.3
-        version: 5.8.3
       vitest:
         specifier: ^3.2.3
         version: 3.2.4(@types/[email protected])(@types/[email protected])(@vitest/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
@@ -1318,9 +1314,6 @@ importers:
       jsdom:
         specifier: ^26.0.0
         version: 26.1.0
-      typescript:
-        specifier: 5.8.3
-        version: 5.8.3
       vite:
         specifier: 6.3.6
         version: 6.3.6(@types/[email protected])([email protected])([email protected])([email protected])([email protected])
@@ -2643,8 +2636,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-/uPs78OwxGxslYOG5TKeUsv9fZC0vo376cXSADdKirTmsLJU2au6L3n34c3p6W26rFDDDze/hwy4fYeNd0qdGA==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2656,8 +2649,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-2JMfHJf/eVnwq+2dewT3C0acmCWD3XiVA1Da+jTDqo342UlU13WvXtqHhG+yJw5JeQmu4ue2eMy6gcEArLBlcw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2669,8 +2662,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2682,8 +2675,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-xTaLKAO+XXMPK/BpVTSaAAhlefmvMSACjIhK9mGsImvX2ljcTDm8VGR1CuS1uYcNdR5J+oiOhoJZc5un6bh3VQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2695,8 +2688,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-O2mcG3gZNkJ/Ena34HurA3llPOEA/M4dJtIRMa6y/cknRDC8XY5UZBInKTsUwW5cUue9A4k0wi1XU5fKBzKe1w==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2708,8 +2701,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-PbhRFK4lIEw9ADonj48tiYWzkllz81TM7KVYyyMMw2cwHO7D5h4XKEblL8NlaRisTK3QTe6tBEhDccFUryxHBQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2721,8 +2714,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2734,7 +2727,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -2743,7 +2736,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -2752,8 +2745,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-ARFmqUyhIVS3+riWzwGTe7JLjqwqgnODBUZdqpWar/z1WFs9z76fuOs/2BOWCR+YboRn4/WN9aoaGVwqNRr8VA==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2765,8 +2758,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2778,7 +2771,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -2787,8 +2780,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2800,8 +2793,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2813,8 +2806,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2826,8 +2819,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-lzuyNjoWOoaMFE/VC5FnAAYM16JmQA8ZmucOXtlhm2kKR5TSU95YLAueQ4JYuRmUJmBvSqXaVFGIfuukybwZJQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2839,7 +2832,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -2848,8 +2841,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2861,8 +2854,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2879,7 +2872,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -2888,8 +2881,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2901,8 +2894,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-0zSiBAIFq9GSKoSH5PdEaQeRB3RnEGxC+H2P0egtnKoKKLNBH8VBHyVO6/jskhjAezhOIplyRUj7U2lds9A+Yg==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2914,8 +2907,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-84uqQV3omKDR076izYgcha6gdpN8m3z6w/AeJ83MSBJYVG/AbOHdLjAgsPZkeC/kt+k64moXFCnio8BbqXszlw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2927,8 +2920,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-7iqXaOWIjDBfIG7aq8CUEeCSsQMLFdn7VEE8TaFz704DtEzpPHR7w/uuzRflvKgltqSAImgcmxQ7fFX3X7wasg==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2940,8 +2933,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2953,8 +2946,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2966,8 +2959,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2979,8 +2972,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -2992,8 +2985,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3005,8 +2998,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-uHa+l/lKfxuDD2zjN/0peM/RhhSmRjr5YWdk/37EnSv1nJ88uvG85DPexSm8HdFQROd2VdERJ6ynXbkCFi+APw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3018,8 +3011,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3031,8 +3024,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-QzN9a36nKk2eZKMf9EBCia35x3TT+SOgZuzQBVIHyRrmYYi73VYBRK3zKwdJ6az/F5IZ6QlacGJBg7zfB85liA==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3044,8 +3037,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3057,8 +3050,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3070,8 +3063,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3083,8 +3076,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-/OOm58Gil4Ev5zT8LyVzqfBcij4dTHYdeyuF5lMHZ2bIp0Lk9oETocYiJ5QC0dHekEQnK6L/FNJCceeb4AkZ6Q==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3096,8 +3089,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-Izof3lPpbCfTM7WDta+LRkz31jem890VjEvpVRoWQNKpDUMMVffuyq854XPGP1KYGWWmjmYvHvPFeocWhFCy1w==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3109,8 +3102,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-Cp6hEmQtRJFci285vkdIJ+HCDLTRDk+25VhFwa1fcubywjMUE3PynBgtN5RLudOgSCYMlT4jizCXdmV+8J7Y2w==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3122,7 +3115,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3131,7 +3124,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3140,8 +3133,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3153,8 +3146,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-zYb+9dc9tkoN2JjBDIIPLQtk3gGyz8FMKoqYTb8EMVQ5a5hBcdHPECrsZVI4NpPAUOixhkoqg7Hj5ry5USowfA==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3166,8 +3159,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3179,7 +3172,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3188,7 +3181,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3197,7 +3190,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3206,7 +3199,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3215,7 +3208,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3224,7 +3217,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3233,7 +3226,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3242,7 +3235,7 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -3251,8 +3244,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-ORCmRUbNiZIv6uV5mhFrhsIKw4UX/N3syZtyqvry61tbGm4JlgQuSn0hk5TwCARsCjkcnuRkSdCE3xfb+ADHew==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3264,8 +3257,8 @@ packages:
   '@radix-ui/[email protected]':
     resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==}
     peerDependencies:
-      '@types/react': '*'
-      '@types/react-dom': '*'
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
     peerDependenciesMeta:
@@ -3989,8 +3982,8 @@ packages:
     engines: {node: '>=18'}
     peerDependencies:
       '@testing-library/dom': ^10.0.0
-      '@types/react': ^18.0.0 || ^19.0.0
-      '@types/react-dom': ^18.0.0 || ^19.0.0
+      '@types/react': ^18.3.23
+      '@types/react-dom': ^18.3.5
       react: ^18.0.0 || ^19.0.0
       react-dom: ^18.0.0 || ^19.0.0
     peerDependenciesMeta:
@@ -4247,7 +4240,7 @@ packages:
   '@types/[email protected]':
     resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
     peerDependencies:
-      '@types/react': ^18.0.0
+      '@types/react': ^18.3.23
 
   '@types/[email protected]':
     resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==}
@@ -8679,7 +8672,7 @@ packages:
   [email protected]:
     resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==}
     peerDependencies:
-      '@types/react': '>=18'
+      '@types/react': ^18.3.23
       react: '>=18'
 
   [email protected]:
@@ -8696,7 +8689,7 @@ packages:
     resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
     engines: {node: '>=10'}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
     peerDependenciesMeta:
       '@types/react':
@@ -8706,7 +8699,7 @@ packages:
     resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==}
     engines: {node: '>=10'}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -8722,7 +8715,7 @@ packages:
     resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
     engines: {node: '>=10'}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -9942,7 +9935,7 @@ packages:
     resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
     engines: {node: '>=10'}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -9979,7 +9972,7 @@ packages:
     resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
     engines: {node: '>=10'}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
     peerDependenciesMeta:
       '@types/react':
@@ -10183,7 +10176,7 @@ packages:
   [email protected]:
     resolution: {integrity: sha512-buw2OipqUl7GCBq1mxcAjUwoUsslGzVhdaxDPmEx27xzc3QAJJZHtT30QbakgZVJ1Jb3E6kcsguUIFEGxrgkyQ==}
     peerDependencies:
-      '@types/react': '*'
+      '@types/react': ^18.3.23
       react: ^17 || ^18 || ^19
 
   [email protected]:
@@ -10227,6 +10220,7 @@ packages:
   [email protected]:
     resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
     engines: {node: '>=18'}
+    deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
 
   [email protected]:
     resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==}
@@ -19866,12 +19860,12 @@ snapshots:
 
   [email protected]:
     dependencies:
-      ansi-styles: 6.2.1
+      ansi-styles: 6.2.3
       is-fullwidth-code-point: 4.0.0
 
   [email protected]:
     dependencies:
-      ansi-styles: 6.2.1
+      ansi-styles: 6.2.3
       is-fullwidth-code-point: 5.0.0
 
   [email protected]: {}
@@ -21255,7 +21249,7 @@ snapshots:
 
   [email protected]:
     dependencies:
-      ansi-styles: 6.2.1
+      ansi-styles: 6.2.3
       string-width: 7.2.0
       strip-ansi: 7.1.2
 

+ 1 - 2
src/api/providers/fetchers/huggingface.ts

@@ -3,14 +3,13 @@ import { z } from "zod"
 
 import {
 	type ModelInfo,
+	type ModelRecord,
 	HUGGINGFACE_API_URL,
 	HUGGINGFACE_CACHE_DURATION,
 	HUGGINGFACE_DEFAULT_MAX_TOKENS,
 	HUGGINGFACE_DEFAULT_CONTEXT_WINDOW,
 } from "@roo-code/types"
 
-import type { ModelRecord } from "../../../shared/api"
-
 const huggingFaceProviderSchema = z.object({
 	provider: z.string(),
 	status: z.enum(["live", "staging", "error"]),

+ 1 - 3
src/api/providers/fetchers/io-intelligence.ts

@@ -1,9 +1,7 @@
 import axios from "axios"
 import { z } from "zod"
 
-import { type ModelInfo, IO_INTELLIGENCE_CACHE_DURATION } from "@roo-code/types"
-
-import type { ModelRecord } from "../../../shared/api"
+import { type ModelInfo, type ModelRecord, IO_INTELLIGENCE_CACHE_DURATION } from "@roo-code/types"
 
 const ioIntelligenceModelSchema = z.object({
 	id: z.string(),

+ 1 - 1
src/api/providers/fetchers/litellm.ts

@@ -1,6 +1,6 @@
 import axios from "axios"
 
-import type { ModelRecord } from "../../../shared/api"
+import type { ModelRecord } from "@roo-code/types"
 
 import { DEFAULT_HEADERS } from "../constants"
 /**

+ 2 - 2
src/api/providers/fetchers/modelCache.ts

@@ -5,7 +5,7 @@ import * as fsSync from "fs"
 import NodeCache from "node-cache"
 import { z } from "zod"
 
-import type { ProviderName } from "@roo-code/types"
+import type { ProviderName, ModelRecord } from "@roo-code/types"
 import { modelInfoSchema, TelemetryEventName } from "@roo-code/types"
 import { TelemetryService } from "@roo-code/telemetry"
 
@@ -13,7 +13,7 @@ import { safeWriteJson } from "../../../utils/safeWriteJson"
 
 import { ContextProxy } from "../../../core/config/ContextProxy"
 import { getCacheDirectoryPath } from "../../../utils/storage"
-import type { RouterName, ModelRecord } from "../../../shared/api"
+import type { RouterName } from "../../../shared/api"
 import { fileExistsAtPath } from "../../../utils/fs"
 
 import { getOpenRouterModels } from "./openrouter"

+ 4 - 2
src/api/providers/fetchers/modelEndpointCache.ts

@@ -2,13 +2,15 @@ import * as path from "path"
 import fs from "fs/promises"
 
 import NodeCache from "node-cache"
-import { safeWriteJson } from "../../../utils/safeWriteJson"
 import sanitize from "sanitize-filename"
 
+import type { ModelRecord } from "@roo-code/types"
+
 import { ContextProxy } from "../../../core/config/ContextProxy"
+import { RouterName } from "../../../shared/api"
 import { getCacheDirectoryPath } from "../../../utils/storage"
-import { RouterName, ModelRecord } from "../../../shared/api"
 import { fileExistsAtPath } from "../../../utils/fs"
+import { safeWriteJson } from "../../../utils/safeWriteJson"
 
 import { getOpenRouterModelEndpoints } from "./openrouter"
 import { getModels } from "./modelCache"

+ 1 - 2
src/api/providers/fetchers/roo.ts

@@ -1,6 +1,5 @@
-import { RooModelsResponseSchema, type ModelInfo } from "@roo-code/types"
+import { RooModelsResponseSchema, type ModelInfo, type ModelRecord } from "@roo-code/types"
 
-import type { ModelRecord } from "../../../shared/api"
 import { parseApiPrice } from "../../../shared/cost"
 
 import { DEFAULT_HEADERS } from "../constants"

+ 3 - 1
src/api/providers/huggingface.ts

@@ -1,7 +1,9 @@
 import OpenAI from "openai"
 import { Anthropic } from "@anthropic-ai/sdk"
 
-import type { ApiHandlerOptions, ModelRecord } from "../../shared/api"
+import type { ModelRecord } from "@roo-code/types"
+
+import type { ApiHandlerOptions } from "../../shared/api"
 import { ApiStream } from "../transform/stream"
 import { convertToOpenAiMessages } from "../transform/openai-format"
 import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"

+ 3 - 2
src/api/providers/openrouter.ts

@@ -3,18 +3,19 @@ import OpenAI from "openai"
 import { z } from "zod"
 
 import {
+	type ModelRecord,
+	ApiProviderError,
 	openRouterDefaultModelId,
 	openRouterDefaultModelInfo,
 	OPENROUTER_DEFAULT_PROVIDER_NAME,
 	OPEN_ROUTER_PROMPT_CACHING_MODELS,
 	DEEP_SEEK_DEFAULT_TEMPERATURE,
-	ApiProviderError,
 } from "@roo-code/types"
 import { TelemetryService } from "@roo-code/telemetry"
 
 import { NativeToolCallParser } from "../../core/assistant-message/NativeToolCallParser"
 
-import type { ApiHandlerOptions, ModelRecord } from "../../shared/api"
+import type { ApiHandlerOptions } from "../../shared/api"
 
 import { convertToOpenAiMessages } from "../transform/openai-format"
 import { normalizeMistralToolCallId } from "../transform/mistral-format"

+ 2 - 1
src/api/providers/requesty.ts

@@ -3,13 +3,14 @@ import OpenAI from "openai"
 
 import {
 	type ModelInfo,
+	type ModelRecord,
 	requestyDefaultModelId,
 	requestyDefaultModelInfo,
 	TOOL_PROTOCOL,
 	NATIVE_TOOL_DEFAULTS,
 } from "@roo-code/types"
 
-import type { ApiHandlerOptions, ModelRecord } from "../../shared/api"
+import type { ApiHandlerOptions } from "../../shared/api"
 import { resolveToolProtocol } from "../../utils/resolveToolProtocol"
 import { calculateApiCostOpenAI } from "../../shared/cost"
 

+ 8 - 6
src/api/providers/roo.ts

@@ -2,11 +2,12 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import OpenAI from "openai"
 
 import { rooDefaultModelId, getApiProtocol, type ImageGenerationApiMethod } from "@roo-code/types"
-import { NativeToolCallParser } from "../../core/assistant-message/NativeToolCallParser"
 import { CloudService } from "@roo-code/cloud"
 
+import { NativeToolCallParser } from "../../core/assistant-message/NativeToolCallParser"
+
 import { Package } from "../../shared/package"
-import type { ApiHandlerOptions, ModelRecord } from "../../shared/api"
+import type { ApiHandlerOptions } from "../../shared/api"
 import { ApiStream } from "../transform/stream"
 import { getModelParams } from "../transform/model-params"
 import { convertToOpenAiMessages } from "../transform/openai-format"
@@ -41,7 +42,7 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
 	private currentReasoningDetails: any[] = []
 
 	constructor(options: ApiHandlerOptions) {
-		const sessionToken = getSessionToken()
+		const sessionToken = options.rooApiKey ?? getSessionToken()
 
 		let baseURL = process.env.ROO_CODE_PROVIDER_URL ?? "https://api.roocode.com/proxy"
 
@@ -63,6 +64,7 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
 
 		// Load dynamic models asynchronously - strip /v1 from baseURL for fetcher
 		this.fetcherBaseURL = baseURL.endsWith("/v1") ? baseURL.slice(0, -3) : baseURL
+
 		this.loadDynamicModels(this.fetcherBaseURL, sessionToken).catch((error) => {
 			console.error("[RooHandler] Failed to load dynamic models:", error)
 		})
@@ -109,7 +111,7 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
 		}
 
 		try {
-			this.client.apiKey = getSessionToken()
+			this.client.apiKey = this.options.rooApiKey ?? getSessionToken()
 			return this.client.chat.completions.create(rooParams, requestOptions)
 		} catch (error) {
 			throw handleOpenAIError(error, this.providerName)
@@ -332,7 +334,7 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
 	}
 	override async completePrompt(prompt: string): Promise<string> {
 		// Update API key before making request to ensure we use the latest session token
-		this.client.apiKey = getSessionToken()
+		this.client.apiKey = this.options.rooApiKey ?? getSessionToken()
 		return super.completePrompt(prompt)
 	}
 
@@ -399,7 +401,7 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<string> {
 		inputImage?: string,
 		apiMethod?: ImageGenerationApiMethod,
 	): Promise<ImageGenerationResult> {
-		const sessionToken = getSessionToken()
+		const sessionToken = this.options.rooApiKey ?? getSessionToken()
 
 		if (!sessionToken || sessionToken === "unauthenticated") {
 			return {

+ 2 - 2
src/api/providers/router-provider.ts

@@ -1,8 +1,8 @@
 import OpenAI from "openai"
 
-import { type ModelInfo, NATIVE_TOOL_DEFAULTS } from "@roo-code/types"
+import { type ModelInfo, type ModelRecord, NATIVE_TOOL_DEFAULTS } from "@roo-code/types"
 
-import { ApiHandlerOptions, RouterName, ModelRecord } from "../../shared/api"
+import { ApiHandlerOptions, RouterName } from "../../shared/api"
 
 import { BaseProvider } from "./base-provider"
 import { getModels, getModelsFromCache } from "./fetchers/modelCache"

+ 9 - 3
src/core/auto-approval/index.ts

@@ -1,6 +1,12 @@
-import { type ClineAsk, type McpServerUse, type FollowUpData, isNonBlockingAsk } from "@roo-code/types"
-
-import type { ClineSayTool, ExtensionState } from "../../shared/ExtensionMessage"
+import {
+	type ClineAsk,
+	type McpServerUse,
+	type FollowUpData,
+	type ExtensionState,
+	isNonBlockingAsk,
+} from "@roo-code/types"
+
+import type { ClineSayTool } from "../../shared/ExtensionMessage"
 import { ClineAskResponse } from "../../shared/WebviewMessage"
 
 import { isWriteToolAction, isReadOnlyToolAction } from "./tools"

+ 1 - 3
src/core/auto-approval/mcp.ts

@@ -1,6 +1,4 @@
-import type { McpServerUse } from "@roo-code/types"
-
-import type { McpServer, McpTool } from "../../shared/mcp"
+import type { McpServerUse, McpServer, McpTool } from "@roo-code/types"
 
 export function isMcpToolAlwaysAllowed(mcpServerUse: McpServerUse, mcpServers: McpServer[] | undefined): boolean {
 	if (mcpServerUse.type === "use_mcp_tool" && mcpServerUse.toolName) {

+ 5 - 2
src/core/prompts/tools/native-tools/__tests__/mcp_server.spec.ts

@@ -1,7 +1,10 @@
 import type OpenAI from "openai"
-import { getMcpServerTools } from "../mcp_server"
+
+import type { McpServer, McpTool } from "@roo-code/types"
+
 import type { McpHub } from "../../../../../services/mcp/McpHub"
-import type { McpServer, McpTool } from "../../../../../shared/mcp"
+
+import { getMcpServerTools } from "../mcp_server"
 
 // Helper type to access function tools
 type FunctionTool = OpenAI.Chat.ChatCompletionTool & { type: "function" }

+ 34 - 6
src/core/webview/ClineProvider.ts

@@ -34,6 +34,9 @@ import {
 	type CreateTaskOptions,
 	type TokenUsage,
 	type ToolUsage,
+	type ExtensionMessage,
+	type ExtensionState,
+	type MarketplaceInstalledMetadata,
 	RooCodeEventName,
 	requestyDefaultModelId,
 	openRouterDefaultModelId,
@@ -51,7 +54,6 @@ import { Package } from "../../shared/package"
 import { findLast } from "../../shared/array"
 import { supportPrompt } from "../../shared/support-prompt"
 import { GlobalFileNames } from "../../shared/globalFileNames"
-import type { ExtensionMessage, ExtensionState, MarketplaceInstalledMetadata } from "../../shared/ExtensionMessage"
 import { Mode, defaultModeSlug, getModeBySlug } from "../../shared/modes"
 import { experimentDefault } from "../../shared/experiments"
 import { formatLanguage } from "../../shared/language"
@@ -905,7 +907,18 @@ export class ClineProvider
 
 					if (profile?.name) {
 						try {
-							await this.activateProviderProfile({ name: profile.name })
+							// Check if the profile has actual API configuration (not just an id).
+							// In CLI mode, the ProviderSettingsManager may return empty default profiles
+							// that only contain 'id' and 'name' fields. Activating such a profile would
+							// overwrite the CLI's working API configuration with empty settings.
+							const fullProfile = await this.providerSettingsManager.getProfile({ name: profile.name })
+							const hasActualSettings = !!fullProfile.apiProvider
+
+							if (hasActualSettings) {
+								await this.activateProviderProfile({ name: profile.name })
+							} else {
+								// The task will continue with the current/default configuration.
+							}
 						} catch (error) {
 							// Log the error but continue with task restoration.
 							this.log(
@@ -1320,14 +1333,29 @@ export class ClineProvider
 			const profile = listApiConfig.find(({ id }) => id === savedConfigId)
 
 			if (profile?.name) {
-				await this.activateProviderProfile({ name: profile.name })
+				// Check if the profile has actual API configuration (not just an id).
+				// In CLI mode, the ProviderSettingsManager may return empty default profiles
+				// that only contain 'id' and 'name' fields. Activating such a profile would
+				// overwrite the CLI's working API configuration with empty settings.
+				// Skip activation if the profile has no apiProvider set - this indicates
+				// an unconfigured/empty profile.
+				const fullProfile = await this.providerSettingsManager.getProfile({ name: profile.name })
+				const hasActualSettings = !!fullProfile.apiProvider
+
+				if (hasActualSettings) {
+					await this.activateProviderProfile({ name: profile.name })
+				} else {
+					// The task will continue with the current/default configuration.
+				}
+			} else {
+				// The task will continue with the current/default configuration.
 			}
 		} else {
 			// If no saved config for this mode, save current config as default.
-			const currentApiConfigName = this.getGlobalState("currentApiConfigName")
+			const currentApiConfigNameAfter = this.getGlobalState("currentApiConfigName")
 
-			if (currentApiConfigName) {
-				const config = listApiConfig.find((c) => c.name === currentApiConfigName)
+			if (currentApiConfigNameAfter) {
+				const config = listApiConfig.find((c) => c.name === currentApiConfigNameAfter)
 
 				if (config?.id) {
 					await this.providerSettingsManager.setModeConfig(newMode, config.id)

+ 4 - 1
src/core/webview/__tests__/ClineProvider.spec.ts

@@ -7,12 +7,13 @@ import axios from "axios"
 import {
 	type ProviderSettingsEntry,
 	type ClineMessage,
+	type ExtensionMessage,
+	type ExtensionState,
 	ORGANIZATION_ALLOW_ALL,
 	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 } from "@roo-code/types"
 import { TelemetryService } from "@roo-code/telemetry"
 
-import { ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage"
 import { defaultModeSlug } from "../../../shared/modes"
 import { experimentDefault } from "../../../shared/experiments"
 import { setTtsEnabled } from "../../../utils/tts"
@@ -888,6 +889,7 @@ describe("ClineProvider", () => {
 			listConfig: vi.fn().mockResolvedValue([profile]),
 			activateProfile: vi.fn().mockResolvedValue(profile),
 			setModeConfig: vi.fn(),
+			getProfile: vi.fn().mockResolvedValue(profile),
 		} as any
 
 		// Switch to architect mode
@@ -1609,6 +1611,7 @@ describe("ClineProvider", () => {
 				listConfig: vi.fn().mockResolvedValue([profile]),
 				activateProfile: vi.fn().mockResolvedValue(profile),
 				setModeConfig: vi.fn(),
+				getProfile: vi.fn().mockResolvedValue(profile),
 			} as any
 
 			// Switch to architect mode

+ 2 - 1
src/core/webview/__tests__/webviewMessageHandler.spec.ts

@@ -10,10 +10,11 @@ vi.mock("../diagnosticsHandler", () => ({
 	generateErrorDiagnostics: vi.fn().mockResolvedValue({ success: true, filePath: "/tmp/diagnostics.json" }),
 }))
 
+import type { ModelRecord } from "@roo-code/types"
+
 import { webviewMessageHandler } from "../webviewMessageHandler"
 import type { ClineProvider } from "../ClineProvider"
 import { getModels } from "../../../api/providers/fetchers/modelCache"
-import type { ModelRecord } from "../../../shared/api"
 
 const mockGetModels = getModels as Mock<typeof getModels>
 

+ 19 - 18
src/core/webview/webviewMessageHandler.ts

@@ -12,9 +12,14 @@ import {
 	type ClineMessage,
 	type TelemetrySetting,
 	type UserSettingsConfig,
+	type ModelRecord,
+	type WebviewMessage,
+	type EditQueuedMessagePayload,
 	TelemetryEventName,
 	RooCodeSettings,
 	ExperimentId,
+	checkoutDiffPayloadSchema,
+	checkoutRestorePayloadSchema,
 } from "@roo-code/types"
 import { customToolRegistry } from "@roo-code/core"
 import { CloudService } from "@roo-code/cloud"
@@ -29,15 +34,9 @@ import { handleCheckpointRestoreOperation } from "./checkpointRestoreHandler"
 import { generateErrorDiagnostics } from "./diagnosticsHandler"
 import { changeLanguage, t } from "../../i18n"
 import { Package } from "../../shared/package"
-import { type RouterName, type ModelRecord, toRouterName } from "../../shared/api"
+import { type RouterName, toRouterName } from "../../shared/api"
 import { MessageEnhancer } from "./messageEnhancer"
 
-import {
-	type WebviewMessage,
-	type EditQueuedMessagePayload,
-	checkoutDiffPayloadSchema,
-	checkoutRestorePayloadSchema,
-} from "../../shared/WebviewMessage"
 import { checkExistKey } from "../../shared/checkExistApiConfig"
 import { experimentDefault } from "../../shared/experiments"
 import { Terminal } from "../../integrations/terminal/Terminal"
@@ -2884,7 +2883,7 @@ export const webviewMessageHandler = async (
 
 		case "switchTab": {
 			if (message.tab) {
-				// Capture tab shown event for all switchTab messages (which are user-initiated)
+				// Capture tab shown event for all switchTab messages (which are user-initiated).
 				if (TelemetryService.hasInstance()) {
 					TelemetryService.instance.captureTabShown(message.tab)
 				}
@@ -2903,7 +2902,6 @@ export const webviewMessageHandler = async (
 				const { getCommands } = await import("../../services/command/commands")
 				const commands = await getCommands(getCurrentCwd())
 
-				// Convert to the format expected by the frontend
 				const commandList = commands.map((command) => ({
 					name: command.name,
 					source: command.source,
@@ -2912,17 +2910,20 @@ export const webviewMessageHandler = async (
 					argumentHint: command.argumentHint,
 				}))
 
-				await provider.postMessageToWebview({
-					type: "commands",
-					commands: commandList,
-				})
+				await provider.postMessageToWebview({ type: "commands", commands: commandList })
 			} catch (error) {
 				provider.log(`Error fetching commands: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`)
-				// Send empty array on error
-				await provider.postMessageToWebview({
-					type: "commands",
-					commands: [],
-				})
+				await provider.postMessageToWebview({ type: "commands", commands: [] })
+			}
+			break
+		}
+		case "requestModes": {
+			try {
+				const modes = await provider.getModes()
+				await provider.postMessageToWebview({ type: "modes", modes })
+			} catch (error) {
+				provider.log(`Error fetching modes: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`)
+				await provider.postMessageToWebview({ type: "modes", modes: [] })
 			}
 			break
 		}

+ 0 - 1
src/package.json

@@ -565,7 +565,6 @@
 		"rimraf": "^6.0.1",
 		"tsup": "^8.4.0",
 		"tsx": "^4.19.3",
-		"typescript": "5.8.3",
 		"vitest": "^3.2.3",
 		"zod-to-ts": "^1.2.0"
 	}

+ 21 - 11
src/services/mcp/McpHub.ts

@@ -1,3 +1,7 @@
+import * as fs from "fs/promises"
+import * as path from "path"
+
+import * as vscode from "vscode"
 import { Client } from "@modelcontextprotocol/sdk/client/index.js"
 import { StdioClientTransport, getDefaultEnvironment } from "@modelcontextprotocol/sdk/client/stdio.js"
 import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"
@@ -13,22 +17,23 @@ import {
 import chokidar, { FSWatcher } from "chokidar"
 import delay from "delay"
 import deepEqual from "fast-deep-equal"
-import * as fs from "fs/promises"
-import * as path from "path"
-import * as vscode from "vscode"
 import { z } from "zod"
-import { t } from "../../i18n"
 
-import { ClineProvider } from "../../core/webview/ClineProvider"
-import { GlobalFileNames } from "../../shared/globalFileNames"
-import {
+import type {
 	McpResource,
 	McpResourceResponse,
 	McpResourceTemplate,
 	McpServer,
 	McpTool,
 	McpToolCallResponse,
-} from "../../shared/mcp"
+} from "@roo-code/types"
+
+import { t } from "../../i18n"
+
+import { ClineProvider } from "../../core/webview/ClineProvider"
+
+import { GlobalFileNames } from "../../shared/globalFileNames"
+
 import { fileExistsAtPath } from "../../utils/fs"
 import { arePathsEqual, getWorkspacePath } from "../../utils/path"
 import { injectVariables } from "../../utils/config"
@@ -1916,16 +1921,16 @@ export class McpHub {
 	async dispose(): Promise<void> {
 		// Prevent multiple disposals
 		if (this.isDisposed) {
-			console.log("McpHub: Already disposed.")
 			return
 		}
-		console.log("McpHub: Disposing...")
+
 		this.isDisposed = true
 
 		// Clear all debounce timers
 		for (const timer of this.configChangeDebounceTimers.values()) {
 			clearTimeout(timer)
 		}
+
 		this.configChangeDebounceTimers.clear()
 
 		// Clear flag reset timer and reset programmatic update flag
@@ -1933,9 +1938,10 @@ export class McpHub {
 			clearTimeout(this.flagResetTimer)
 			this.flagResetTimer = undefined
 		}
-		this.isProgrammaticUpdate = false
 
+		this.isProgrammaticUpdate = false
 		this.removeAllFileWatchers()
+
 		for (const connection of this.connections) {
 			try {
 				await this.deleteConnection(connection.server.name, connection.server.source)
@@ -1943,15 +1949,19 @@ export class McpHub {
 				console.error(`Failed to close connection for ${connection.server.name}:`, error)
 			}
 		}
+
 		this.connections = []
+
 		if (this.settingsWatcher) {
 			this.settingsWatcher.dispose()
 			this.settingsWatcher = undefined
 		}
+
 		if (this.projectMcpWatcher) {
 			this.projectMcpWatcher.dispose()
 			this.projectMcpWatcher = undefined
 		}
+
 		this.disposables.forEach((d) => d.dispose())
 	}
 }

+ 0 - 344
src/shared/ExtensionMessage.ts

@@ -1,44 +1,3 @@
-import type {
-	GlobalSettings,
-	ProviderSettingsEntry,
-	ProviderSettings,
-	HistoryItem,
-	ModeConfig,
-	TelemetrySetting,
-	Experiments,
-	ClineMessage,
-	MarketplaceItem,
-	TodoItem,
-	CloudUserInfo,
-	CloudOrganizationMembership,
-	OrganizationAllowList,
-	ShareVisibility,
-	QueuedMessage,
-	SerializedCustomToolDefinition,
-} from "@roo-code/types"
-
-import { GitCommit } from "../utils/git"
-
-import { McpServer } from "./mcp"
-import { Mode } from "./modes"
-import { ModelRecord, RouterModels } from "./api"
-
-// Command interface for frontend/backend communication
-export interface Command {
-	name: string
-	source: "global" | "project" | "built-in"
-	filePath?: string
-	description?: string
-	argumentHint?: string
-}
-
-// Type for marketplace installed metadata
-export interface MarketplaceInstalledMetadata {
-	project: Record<string, { type: string }>
-	global: Record<string, { type: string }>
-}
-
-// Indexing status types
 export interface IndexingStatus {
 	systemStatus: string
 	message?: string
@@ -60,309 +19,6 @@ export interface LanguageModelChatSelector {
 	id?: string
 }
 
-// Represents JSON data that is sent from extension to webview, called
-// ExtensionMessage and has 'type' enum which can be 'plusButtonClicked' or
-// 'settingsButtonClicked' or 'hello'. Webview will hold state.
-export interface ExtensionMessage {
-	type:
-		| "action"
-		| "state"
-		| "selectedImages"
-		| "theme"
-		| "workspaceUpdated"
-		| "invoke"
-		| "messageUpdated"
-		| "mcpServers"
-		| "enhancedPrompt"
-		| "commitSearchResults"
-		| "listApiConfig"
-		| "routerModels"
-		| "openAiModels"
-		| "ollamaModels"
-		| "lmStudioModels"
-		| "vsCodeLmModels"
-		| "huggingFaceModels"
-		| "vsCodeLmApiAvailable"
-		| "updatePrompt"
-		| "systemPrompt"
-		| "autoApprovalEnabled"
-		| "updateCustomMode"
-		| "deleteCustomMode"
-		| "exportModeResult"
-		| "importModeResult"
-		| "checkRulesDirectoryResult"
-		| "deleteCustomModeCheck"
-		| "currentCheckpointUpdated"
-		| "checkpointInitWarning"
-		| "browserToolEnabled"
-		| "browserConnectionResult"
-		| "remoteBrowserEnabled"
-		| "ttsStart"
-		| "ttsStop"
-		| "maxReadFileLine"
-		| "fileSearchResults"
-		| "toggleApiConfigPin"
-		| "acceptInput"
-		| "setHistoryPreviewCollapsed"
-		| "commandExecutionStatus"
-		| "mcpExecutionStatus"
-		| "vsCodeSetting"
-		| "authenticatedUser"
-		| "condenseTaskContextStarted"
-		| "condenseTaskContextResponse"
-		| "singleRouterModelFetchResponse"
-		| "rooCreditBalance"
-		| "indexingStatusUpdate"
-		| "indexCleared"
-		| "codebaseIndexConfig"
-		| "marketplaceInstallResult"
-		| "marketplaceRemoveResult"
-		| "marketplaceData"
-		| "shareTaskSuccess"
-		| "codeIndexSettingsSaved"
-		| "codeIndexSecretStatus"
-		| "showDeleteMessageDialog"
-		| "showEditMessageDialog"
-		| "commands"
-		| "insertTextIntoTextarea"
-		| "dismissedUpsells"
-		| "organizationSwitchResult"
-		| "interactionRequired"
-		| "browserSessionUpdate"
-		| "browserSessionNavigate"
-		| "claudeCodeRateLimits"
-		| "customToolsResult"
-	text?: string
-	payload?: any // Add a generic payload for now, can refine later
-	// Checkpoint warning message
-	checkpointWarning?: {
-		type: "WAIT_TIMEOUT" | "INIT_TIMEOUT"
-		timeout: number
-	}
-	action?:
-		| "chatButtonClicked"
-		| "settingsButtonClicked"
-		| "historyButtonClicked"
-		| "marketplaceButtonClicked"
-		| "cloudButtonClicked"
-		| "didBecomeVisible"
-		| "focusInput"
-		| "switchTab"
-		| "toggleAutoApprove"
-	invoke?: "newChat" | "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" | "setChatBoxMessage"
-	state?: ExtensionState
-	images?: string[]
-	filePaths?: string[]
-	openedTabs?: Array<{
-		label: string
-		isActive: boolean
-		path?: string
-	}>
-	clineMessage?: ClineMessage
-	routerModels?: RouterModels
-	openAiModels?: string[]
-	ollamaModels?: ModelRecord
-	lmStudioModels?: ModelRecord
-	vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[]
-	huggingFaceModels?: Array<{
-		id: string
-		object: string
-		created: number
-		owned_by: string
-		providers: Array<{
-			provider: string
-			status: "live" | "staging" | "error"
-			supports_tools?: boolean
-			supports_structured_output?: boolean
-			context_length?: number
-			pricing?: {
-				input: number
-				output: number
-			}
-		}>
-	}>
-	mcpServers?: McpServer[]
-	commits?: GitCommit[]
-	listApiConfig?: ProviderSettingsEntry[]
-	mode?: Mode
-	customMode?: ModeConfig
-	slug?: string
-	success?: boolean
-	values?: Record<string, any>
-	requestId?: string
-	promptText?: string
-	results?: { path: string; type: "file" | "folder"; label?: string }[]
-	error?: string
-	setting?: string
-	value?: any
-	hasContent?: boolean // For checkRulesDirectoryResult
-	items?: MarketplaceItem[]
-	userInfo?: CloudUserInfo
-	organizationAllowList?: OrganizationAllowList
-	tab?: string
-	marketplaceItems?: MarketplaceItem[]
-	organizationMcps?: MarketplaceItem[]
-	marketplaceInstalledMetadata?: MarketplaceInstalledMetadata
-	errors?: string[]
-	visibility?: ShareVisibility
-	rulesFolderPath?: string
-	settings?: any
-	messageTs?: number
-	hasCheckpoint?: boolean
-	context?: string
-	commands?: Command[]
-	queuedMessages?: QueuedMessage[]
-	list?: string[] // For dismissedUpsells
-	organizationId?: string | null // For organizationSwitchResult
-	browserSessionMessages?: ClineMessage[] // For browser session panel updates
-	isBrowserSessionActive?: boolean // For browser session panel updates
-	stepIndex?: number // For browserSessionNavigate: the target step index to display
-	tools?: SerializedCustomToolDefinition[] // For customToolsResult
-}
-
-export type ExtensionState = Pick<
-	GlobalSettings,
-	| "currentApiConfigName"
-	| "listApiConfigMeta"
-	| "pinnedApiConfigs"
-	| "customInstructions"
-	| "dismissedUpsells"
-	| "autoApprovalEnabled"
-	| "alwaysAllowReadOnly"
-	| "alwaysAllowReadOnlyOutsideWorkspace"
-	| "alwaysAllowWrite"
-	| "alwaysAllowWriteOutsideWorkspace"
-	| "alwaysAllowWriteProtected"
-	| "alwaysAllowBrowser"
-	| "alwaysAllowMcp"
-	| "alwaysAllowModeSwitch"
-	| "alwaysAllowSubtasks"
-	| "alwaysAllowFollowupQuestions"
-	| "alwaysAllowExecute"
-	| "followupAutoApproveTimeoutMs"
-	| "allowedCommands"
-	| "deniedCommands"
-	| "allowedMaxRequests"
-	| "allowedMaxCost"
-	| "browserToolEnabled"
-	| "browserViewportSize"
-	| "screenshotQuality"
-	| "remoteBrowserEnabled"
-	| "cachedChromeHostUrl"
-	| "remoteBrowserHost"
-	| "ttsEnabled"
-	| "ttsSpeed"
-	| "soundEnabled"
-	| "soundVolume"
-	| "maxConcurrentFileReads"
-	| "terminalOutputLineLimit"
-	| "terminalOutputCharacterLimit"
-	| "terminalShellIntegrationTimeout"
-	| "terminalShellIntegrationDisabled"
-	| "terminalCommandDelay"
-	| "terminalPowershellCounter"
-	| "terminalZshClearEolMark"
-	| "terminalZshOhMy"
-	| "terminalZshP10k"
-	| "terminalZdotdir"
-	| "terminalCompressProgressBar"
-	| "diagnosticsEnabled"
-	| "diffEnabled"
-	| "fuzzyMatchThreshold"
-	| "language"
-	| "modeApiConfigs"
-	| "customModePrompts"
-	| "customSupportPrompts"
-	| "enhancementApiConfigId"
-	| "condensingApiConfigId"
-	| "customCondensingPrompt"
-	| "codebaseIndexConfig"
-	| "codebaseIndexModels"
-	| "profileThresholds"
-	| "includeDiagnosticMessages"
-	| "maxDiagnosticMessages"
-	| "imageGenerationProvider"
-	| "openRouterImageGenerationSelectedModel"
-	| "includeTaskHistoryInEnhance"
-	| "reasoningBlockCollapsed"
-	| "enterBehavior"
-	| "includeCurrentTime"
-	| "includeCurrentCost"
-	| "maxGitStatusFiles"
-	| "requestDelaySeconds"
-> & {
-	version: string
-	clineMessages: ClineMessage[]
-	currentTaskItem?: HistoryItem
-	currentTaskTodos?: TodoItem[] // Initial todos for the current task
-	apiConfiguration: ProviderSettings
-	uriScheme?: string
-	shouldShowAnnouncement: boolean
-
-	taskHistory: HistoryItem[]
-
-	writeDelayMs: number
-
-	enableCheckpoints: boolean
-	checkpointTimeout: number // Timeout for checkpoint initialization in seconds (default: 15)
-	maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
-	maxWorkspaceFiles: number // Maximum number of files to include in current working directory details (0-500)
-	showRooIgnoredFiles: boolean // Whether to show .rooignore'd files in listings
-	enableSubfolderRules: boolean // Whether to load rules from subdirectories
-	maxReadFileLine: number // Maximum number of lines to read from a file before truncating
-	maxImageFileSize: number // Maximum size of image files to process in MB
-	maxTotalImageSize: number // Maximum total size for all images in a single read operation in MB
-
-	experiments: Experiments // Map of experiment IDs to their enabled state
-
-	mcpEnabled: boolean
-	enableMcpServerCreation: boolean
-
-	mode: Mode
-	customModes: ModeConfig[]
-	toolRequirements?: Record<string, boolean> // Map of tool names to their requirements (e.g. {"apply_diff": true} if diffEnabled)
-
-	cwd?: string // Current working directory
-	telemetrySetting: TelemetrySetting
-	telemetryKey?: string
-	machineId?: string
-
-	renderContext: "sidebar" | "editor"
-	settingsImportedAt?: number
-	historyPreviewCollapsed?: boolean
-
-	cloudUserInfo: CloudUserInfo | null
-	cloudIsAuthenticated: boolean
-	cloudAuthSkipModel?: boolean // Flag indicating auth completed without model selection (user should pick 3rd-party provider)
-	cloudApiUrl?: string
-	cloudOrganizations?: CloudOrganizationMembership[]
-	sharingEnabled: boolean
-	publicSharingEnabled: boolean
-	organizationAllowList: OrganizationAllowList
-	organizationSettingsVersion?: number
-
-	isBrowserSessionActive: boolean // Actual browser session state
-
-	autoCondenseContext: boolean
-	autoCondenseContextPercent: number
-	marketplaceItems?: MarketplaceItem[]
-	marketplaceInstalledMetadata?: { project: Record<string, any>; global: Record<string, any> }
-	profileThresholds: Record<string, number>
-	hasOpenedModeSelector: boolean
-	openRouterImageApiKey?: string
-	messageQueue?: QueuedMessage[]
-	lastShownAnnouncementId?: string
-	apiModelId?: string
-	mcpServers?: McpServer[]
-	hasSystemPromptOverride?: boolean
-	mdmCompliant?: boolean
-	remoteControlEnabled: boolean
-	taskSyncEnabled: boolean
-	featureRoomoteControlEnabled: boolean
-	claudeCodeIsAuthenticated?: boolean
-	debug?: boolean
-}
-
 export interface ClineSayTool {
 	tool:
 		| "editedExistingFile"

+ 1 - 311
src/shared/WebviewMessage.ts

@@ -1,313 +1,3 @@
-import { z } from "zod"
-
-import {
-	type RooCodeSettings,
-	type ProviderSettings,
-	type PromptComponent,
-	type ModeConfig,
-	type InstallMarketplaceItemOptions,
-	type MarketplaceItem,
-	type ShareVisibility,
-	type QueuedMessage,
-	marketplaceItemSchema,
-} from "@roo-code/types"
-
-import { Mode } from "./modes"
+export type { WebviewMessage, WebViewMessagePayload } from "@roo-code/types"
 
 export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" | "objectResponse"
-
-export type PromptMode = Mode | "enhance"
-
-export type AudioType = "notification" | "celebration" | "progress_loop"
-
-export interface UpdateTodoListPayload {
-	todos: any[]
-}
-
-export type EditQueuedMessagePayload = Pick<QueuedMessage, "id" | "text" | "images">
-
-export interface WebviewMessage {
-	type:
-		| "updateTodoList"
-		| "deleteMultipleTasksWithIds"
-		| "currentApiConfigName"
-		| "saveApiConfiguration"
-		| "upsertApiConfiguration"
-		| "deleteApiConfiguration"
-		| "loadApiConfiguration"
-		| "loadApiConfigurationById"
-		| "renameApiConfiguration"
-		| "getListApiConfiguration"
-		| "customInstructions"
-		| "webviewDidLaunch"
-		| "newTask"
-		| "askResponse"
-		| "terminalOperation"
-		| "clearTask"
-		| "didShowAnnouncement"
-		| "selectImages"
-		| "exportCurrentTask"
-		| "shareCurrentTask"
-		| "showTaskWithId"
-		| "deleteTaskWithId"
-		| "exportTaskWithId"
-		| "importSettings"
-		| "exportSettings"
-		| "resetState"
-		| "flushRouterModels"
-		| "requestRouterModels"
-		| "requestOpenAiModels"
-		| "requestOllamaModels"
-		| "requestLmStudioModels"
-		| "requestRooModels"
-		| "requestRooCreditBalance"
-		| "requestVsCodeLmModels"
-		| "requestHuggingFaceModels"
-		| "openImage"
-		| "saveImage"
-		| "openFile"
-		| "openMention"
-		| "cancelTask"
-		| "cancelAutoApproval"
-		| "updateVSCodeSetting"
-		| "getVSCodeSetting"
-		| "vsCodeSetting"
-		| "updateCondensingPrompt"
-		| "playSound"
-		| "playTts"
-		| "stopTts"
-		| "ttsEnabled"
-		| "ttsSpeed"
-		| "openKeyboardShortcuts"
-		| "openMcpSettings"
-		| "openProjectMcpSettings"
-		| "restartMcpServer"
-		| "refreshAllMcpServers"
-		| "toggleToolAlwaysAllow"
-		| "toggleToolEnabledForPrompt"
-		| "toggleMcpServer"
-		| "updateMcpTimeout"
-		| "enhancePrompt"
-		| "enhancedPrompt"
-		| "draggedImages"
-		| "deleteMessage"
-		| "deleteMessageConfirm"
-		| "submitEditedMessage"
-		| "editMessageConfirm"
-		| "enableMcpServerCreation"
-		| "remoteControlEnabled"
-		| "taskSyncEnabled"
-		| "searchCommits"
-		| "setApiConfigPassword"
-		| "mode"
-		| "updatePrompt"
-		| "getSystemPrompt"
-		| "copySystemPrompt"
-		| "systemPrompt"
-		| "enhancementApiConfigId"
-		| "autoApprovalEnabled"
-		| "updateCustomMode"
-		| "deleteCustomMode"
-		| "setopenAiCustomModelInfo"
-		| "openCustomModesSettings"
-		| "checkpointDiff"
-		| "checkpointRestore"
-		| "deleteMcpServer"
-		| "codebaseIndexEnabled"
-		| "telemetrySetting"
-		| "testBrowserConnection"
-		| "browserConnectionResult"
-		| "searchFiles"
-		| "toggleApiConfigPin"
-		| "hasOpenedModeSelector"
-		| "clearCloudAuthSkipModel"
-		| "cloudButtonClicked"
-		| "rooCloudSignIn"
-		| "cloudLandingPageSignIn"
-		| "rooCloudSignOut"
-		| "rooCloudManualUrl"
-		| "claudeCodeSignIn"
-		| "claudeCodeSignOut"
-		| "switchOrganization"
-		| "condenseTaskContextRequest"
-		| "requestIndexingStatus"
-		| "startIndexing"
-		| "clearIndexData"
-		| "indexingStatusUpdate"
-		| "indexCleared"
-		| "focusPanelRequest"
-		| "openExternal"
-		| "filterMarketplaceItems"
-		| "marketplaceButtonClicked"
-		| "installMarketplaceItem"
-		| "installMarketplaceItemWithParameters"
-		| "cancelMarketplaceInstall"
-		| "removeInstalledMarketplaceItem"
-		| "marketplaceInstallResult"
-		| "fetchMarketplaceData"
-		| "switchTab"
-		| "shareTaskSuccess"
-		| "exportMode"
-		| "exportModeResult"
-		| "importMode"
-		| "importModeResult"
-		| "checkRulesDirectory"
-		| "checkRulesDirectoryResult"
-		| "saveCodeIndexSettingsAtomic"
-		| "requestCodeIndexSecretStatus"
-		| "requestCommands"
-		| "openCommandFile"
-		| "deleteCommand"
-		| "createCommand"
-		| "insertTextIntoTextarea"
-		| "showMdmAuthRequiredNotification"
-		| "imageGenerationSettings"
-		| "queueMessage"
-		| "removeQueuedMessage"
-		| "editQueuedMessage"
-		| "dismissUpsell"
-		| "getDismissedUpsells"
-		| "updateSettings"
-		| "allowedCommands"
-		| "deniedCommands"
-		| "killBrowserSession"
-		| "openBrowserSessionPanel"
-		| "showBrowserSessionPanelAtStep"
-		| "refreshBrowserSessionPanel"
-		| "browserPanelDidLaunch"
-		| "openDebugApiHistory"
-		| "openDebugUiHistory"
-		| "downloadErrorDiagnostics"
-		| "requestClaudeCodeRateLimits"
-		| "refreshCustomTools"
-	text?: string
-	editedMessageContent?: string
-	tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "cloud"
-	disabled?: boolean
-	context?: string
-	dataUri?: string
-	askResponse?: ClineAskResponse
-	apiConfiguration?: ProviderSettings
-	images?: string[]
-	bool?: boolean
-	value?: number
-	stepIndex?: number
-	isLaunchAction?: boolean
-	forceShow?: boolean
-	commands?: string[]
-	audioType?: AudioType
-	serverName?: string
-	toolName?: string
-	alwaysAllow?: boolean
-	isEnabled?: boolean
-	mode?: Mode
-	promptMode?: PromptMode
-	customPrompt?: PromptComponent
-	dataUrls?: string[]
-	values?: Record<string, any>
-	query?: string
-	setting?: string
-	slug?: string
-	modeConfig?: ModeConfig
-	timeout?: number
-	payload?: WebViewMessagePayload
-	source?: "global" | "project"
-	requestId?: string
-	ids?: string[]
-	hasSystemPromptOverride?: boolean
-	terminalOperation?: "continue" | "abort"
-	messageTs?: number
-	restoreCheckpoint?: boolean
-	historyPreviewCollapsed?: boolean
-	filters?: { type?: string; search?: string; tags?: string[] }
-	settings?: any
-	url?: string // For openExternal
-	mpItem?: MarketplaceItem
-	mpInstallOptions?: InstallMarketplaceItemOptions
-	config?: Record<string, any> // Add config to the payload
-	visibility?: ShareVisibility // For share visibility
-	hasContent?: boolean // For checkRulesDirectoryResult
-	checkOnly?: boolean // For deleteCustomMode check
-	upsellId?: string // For dismissUpsell
-	list?: string[] // For dismissedUpsells response
-	organizationId?: string | null // For organization switching
-	useProviderSignup?: boolean // For rooCloudSignIn to use provider signup flow
-	codeIndexSettings?: {
-		// Global state settings
-		codebaseIndexEnabled: boolean
-		codebaseIndexQdrantUrl: string
-		codebaseIndexEmbedderProvider:
-			| "openai"
-			| "ollama"
-			| "openai-compatible"
-			| "gemini"
-			| "mistral"
-			| "vercel-ai-gateway"
-			| "bedrock"
-			| "openrouter"
-		codebaseIndexEmbedderBaseUrl?: string
-		codebaseIndexEmbedderModelId: string
-		codebaseIndexEmbedderModelDimension?: number // Generic dimension for all providers
-		codebaseIndexOpenAiCompatibleBaseUrl?: string
-		codebaseIndexBedrockRegion?: string
-		codebaseIndexBedrockProfile?: string
-		codebaseIndexSearchMaxResults?: number
-		codebaseIndexSearchMinScore?: number
-		codebaseIndexOpenRouterSpecificProvider?: string // OpenRouter provider routing
-
-		// Secret settings
-		codeIndexOpenAiKey?: string
-		codeIndexQdrantApiKey?: string
-		codebaseIndexOpenAiCompatibleApiKey?: string
-		codebaseIndexGeminiApiKey?: string
-		codebaseIndexMistralApiKey?: string
-		codebaseIndexVercelAiGatewayApiKey?: string
-		codebaseIndexOpenRouterApiKey?: string
-	}
-	updatedSettings?: RooCodeSettings
-}
-
-export const checkoutDiffPayloadSchema = z.object({
-	ts: z.number().optional(),
-	previousCommitHash: z.string().optional(),
-	commitHash: z.string(),
-	mode: z.enum(["full", "checkpoint", "from-init", "to-current"]),
-})
-
-export type CheckpointDiffPayload = z.infer<typeof checkoutDiffPayloadSchema>
-
-export const checkoutRestorePayloadSchema = z.object({
-	ts: z.number(),
-	commitHash: z.string(),
-	mode: z.enum(["preview", "restore"]),
-})
-
-export type CheckpointRestorePayload = z.infer<typeof checkoutRestorePayloadSchema>
-
-export interface IndexingStatusPayload {
-	state: "Standby" | "Indexing" | "Indexed" | "Error"
-	message: string
-}
-
-export interface IndexClearedPayload {
-	success: boolean
-	error?: string
-}
-
-export const installMarketplaceItemWithParametersPayloadSchema = z.object({
-	item: marketplaceItemSchema,
-	parameters: z.record(z.string(), z.any()),
-})
-
-export type InstallMarketplaceItemWithParametersPayload = z.infer<
-	typeof installMarketplaceItemWithParametersPayloadSchema
->
-
-export type WebViewMessagePayload =
-	| CheckpointDiffPayload
-	| CheckpointRestorePayload
-	| IndexingStatusPayload
-	| IndexClearedPayload
-	| InstallMarketplaceItemWithParametersPayload
-	| UpdateTodoListPayload
-	| EditQueuedMessagePayload

+ 0 - 6
src/shared/api.ts

@@ -39,12 +39,6 @@ export function toRouterName(value?: string): RouterName {
 	throw new Error(`Invalid router name: ${value}`)
 }
 
-// RouterModels
-
-export type ModelRecord = Record<string, ModelInfo>
-
-export type RouterModels = Record<RouterName, ModelRecord>
-
 // Reasoning
 
 export const shouldUseReasoningBudget = ({

+ 0 - 83
src/shared/mcp.ts

@@ -1,83 +0,0 @@
-export type McpErrorEntry = {
-	message: string
-	timestamp: number
-	level: "error" | "warn" | "info"
-}
-
-export type McpServer = {
-	name: string
-	config: string
-	status: "connected" | "connecting" | "disconnected"
-	error?: string
-	errorHistory?: McpErrorEntry[]
-	tools?: McpTool[]
-	resources?: McpResource[]
-	resourceTemplates?: McpResourceTemplate[]
-	disabled?: boolean
-	timeout?: number
-	source?: "global" | "project"
-	projectPath?: string
-	instructions?: string
-}
-
-export type McpTool = {
-	name: string
-	description?: string
-	inputSchema?: object
-	alwaysAllow?: boolean
-	enabledForPrompt?: boolean
-}
-
-export type McpResource = {
-	uri: string
-	name: string
-	mimeType?: string
-	description?: string
-}
-
-export type McpResourceTemplate = {
-	uriTemplate: string
-	name: string
-	description?: string
-	mimeType?: string
-}
-
-export type McpResourceResponse = {
-	_meta?: Record<string, any>
-	contents: Array<{
-		uri: string
-		mimeType?: string
-		text?: string
-		blob?: string
-	}>
-}
-
-export type McpToolCallResponse = {
-	_meta?: Record<string, any>
-	content: Array<
-		| {
-				type: "text"
-				text: string
-		  }
-		| {
-				type: "image"
-				data: string
-				mimeType: string
-		  }
-		| {
-				type: "audio"
-				data: string
-				mimeType: string
-		  }
-		| {
-				type: "resource"
-				resource: {
-					uri: string
-					mimeType?: string
-					text?: string
-					blob?: string
-				}
-		  }
-	>
-	isError?: boolean
-}

+ 4 - 14
src/utils/git.ts

@@ -3,24 +3,14 @@ import * as path from "path"
 import { promises as fs } from "fs"
 import { exec } from "child_process"
 import { promisify } from "util"
+
+import type { GitRepositoryInfo, GitCommit } from "@roo-code/types"
+
 import { truncateOutput } from "../integrations/misc/extract-text"
 
 const execAsync = promisify(exec)
-const GIT_OUTPUT_LINE_LIMIT = 500
 
-export interface GitRepositoryInfo {
-	repositoryUrl?: string
-	repositoryName?: string
-	defaultBranch?: string
-}
-
-export interface GitCommit {
-	hash: string
-	shortHash: string
-	subject: string
-	author: string
-	date: string
-}
+const GIT_OUTPUT_LINE_LIMIT = 500
 
 /**
  * Extracts git repository information from the workspace's .git directory

+ 0 - 1
webview-ui/package.json

@@ -102,7 +102,6 @@
 		"@vitest/ui": "^3.2.3",
 		"identity-obj-proxy": "^3.0.0",
 		"jsdom": "^26.0.0",
-		"typescript": "5.8.3",
 		"vite": "6.3.6",
 		"vitest": "^3.2.3"
 	}

+ 2 - 2
webview-ui/src/App.tsx

@@ -2,13 +2,13 @@ import React, { useCallback, useEffect, useRef, useState, useMemo } from "react"
 import { useEvent } from "react-use"
 import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
 
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import { type ExtensionMessage, TelemetryEventName } from "@roo-code/types"
+
 import TranslationProvider from "./i18n/TranslationContext"
 import { MarketplaceViewStateManager } from "./components/marketplace/MarketplaceViewStateManager"
 
 import { vscode } from "./utils/vscode"
 import { telemetryClient } from "./utils/TelemetryClient"
-import { TelemetryEventName } from "@roo-code/types"
 import { initializeSourceMaps, exposeSourceMapsForDebugging } from "./utils/sourceMapInitializer"
 import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext"
 import ChatView, { ChatViewRef } from "./components/chat/ChatView"

+ 1 - 1
webview-ui/src/__tests__/command-autocomplete.spec.ts

@@ -1,4 +1,4 @@
-import type { Command } from "@roo/ExtensionMessage"
+import type { Command } from "@roo-code/types"
 
 import { getContextMenuOptions, ContextMenuOptionType } from "../utils/context-mentions"
 

+ 2 - 1
webview-ui/src/components/browser-session/BrowserPanelStateProvider.tsx

@@ -1,5 +1,6 @@
 import React, { createContext, useContext, useState, useEffect, useCallback } from "react"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+
+import { type ExtensionMessage } from "@roo-code/types"
 
 interface BrowserPanelState {
 	browserViewportSize: string

+ 9 - 5
webview-ui/src/components/browser-session/BrowserSessionPanel.tsx

@@ -1,14 +1,18 @@
 import React, { useEffect, useState } from "react"
-import { type ClineMessage } from "@roo-code/types"
-import BrowserSessionRow from "../chat/BrowserSessionRow"
+
+import { type ClineMessage, type ExtensionMessage } from "@roo-code/types"
+
 import { TooltipProvider } from "@src/components/ui/tooltip"
-import ErrorBoundary from "../ErrorBoundary"
 import TranslationProvider from "@src/i18n/TranslationContext"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
-import { BrowserPanelStateProvider, useBrowserPanelState } from "./BrowserPanelStateProvider"
 import { vscode } from "@src/utils/vscode"
+
 import { ExtensionStateContextProvider } from "@/context/ExtensionStateContext"
 
+import BrowserSessionRow from "../chat/BrowserSessionRow"
+import ErrorBoundary from "../ErrorBoundary"
+
+import { BrowserPanelStateProvider, useBrowserPanelState } from "./BrowserPanelStateProvider"
+
 interface BrowserSessionPanelState {
 	messages: ClineMessage[]
 }

+ 2 - 1
webview-ui/src/components/chat/ChatTextArea.tsx

@@ -3,10 +3,11 @@ import { useEvent } from "react-use"
 import DynamicTextArea from "react-textarea-autosize"
 import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX } from "lucide-react"
 
+import type { ExtensionMessage } from "@roo-code/types"
+
 import { mentionRegex, mentionRegexGlobal, commandRegexGlobal, unescapeSpaces } from "@roo/context-mentions"
 import { WebviewMessage } from "@roo/WebviewMessage"
 import { Mode, getAllModes } from "@roo/modes"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
 
 import { vscode } from "@src/utils/vscode"
 import { useExtensionState } from "@src/context/ExtensionStateContext"

+ 2 - 3
webview-ui/src/components/chat/ChatView.tsx

@@ -11,15 +11,14 @@ import { Trans } from "react-i18next"
 import { useDebounceEffect } from "@src/utils/useDebounceEffect"
 import { appendImages } from "@src/utils/imageUtils"
 
-import type { ClineAsk, ClineMessage } from "@roo-code/types"
+import type { ClineAsk, ClineMessage, ExtensionMessage, AudioType } from "@roo-code/types"
 
-import { ClineSayTool, ExtensionMessage } from "@roo/ExtensionMessage"
+import { ClineSayTool } from "@roo/ExtensionMessage"
 import { findLast } from "@roo/array"
 import { SuggestionItem } from "@roo-code/types"
 import { combineApiRequests } from "@roo/combineApiRequests"
 import { combineCommandSequences } from "@roo/combineCommandSequences"
 import { getApiMetrics } from "@roo/getApiMetrics"
-import { AudioType } from "@roo/WebviewMessage"
 import { getAllModes } from "@roo/modes"
 import { ProfileValidator } from "@roo/ProfileValidator"
 import { getLatestTodo } from "@roo/todo"

+ 1 - 3
webview-ui/src/components/chat/CommandExecution.tsx

@@ -3,11 +3,9 @@ import { useEvent } from "react-use"
 import { t } from "i18next"
 import { ChevronDown, OctagonX } from "lucide-react"
 
-import { CommandExecutionStatus, commandExecutionStatusSchema } from "@roo-code/types"
+import { type ExtensionMessage, type CommandExecutionStatus, commandExecutionStatusSchema } from "@roo-code/types"
 
-import { ExtensionMessage } from "@roo/ExtensionMessage"
 import { safeJsonParse } from "@roo/safeJsonParse"
-
 import { COMMAND_OUTPUT_STRING } from "@roo/combineCommandSequences"
 import { parseCommand } from "@roo/parse-command"
 

+ 4 - 4
webview-ui/src/components/chat/ContextMenu.tsx

@@ -1,9 +1,10 @@
 import React, { useEffect, useMemo, useRef, useState } from "react"
 import { getIconForFilePath, getIconUrlByName, getIconForDirectoryPath } from "vscode-material-icons"
+import { Trans } from "react-i18next"
+import { t } from "i18next"
 import { Settings } from "lucide-react"
 
-import type { ModeConfig } from "@roo-code/types"
-import type { Command } from "@roo/ExtensionMessage"
+import type { ModeConfig, Command } from "@roo-code/types"
 
 import {
 	ContextMenuOptionType,
@@ -13,9 +14,8 @@ import {
 } from "@src/utils/context-mentions"
 import { removeLeadingNonAlphanumeric } from "@src/utils/removeLeadingNonAlphanumeric"
 import { vscode } from "@src/utils/vscode"
+
 import { buildDocLink } from "@/utils/docLinks"
-import { Trans } from "react-i18next"
-import { t } from "i18next"
 
 interface ContextMenuProps {
 	onSelect: (type: ContextMenuOptionType, value?: string) => void

+ 6 - 3
webview-ui/src/components/chat/McpExecution.tsx

@@ -3,13 +3,16 @@ import { Server, ChevronDown } from "lucide-react"
 import { useEvent } from "react-use"
 import { useTranslation } from "react-i18next"
 
-import { McpExecutionStatus, mcpExecutionStatusSchema } from "@roo-code/types"
-import { ExtensionMessage, ClineAskUseMcpServer } from "../../../../src/shared/ExtensionMessage"
-import { safeJsonParse } from "../../../../src/shared/safeJsonParse"
+import { type ExtensionMessage, type McpExecutionStatus, mcpExecutionStatusSchema } from "@roo-code/types"
+
 import { cn } from "@src/lib/utils"
 import { Button } from "@src/components/ui"
+
+import { ClineAskUseMcpServer } from "../../../../src/shared/ExtensionMessage"
+import { safeJsonParse } from "../../../../src/shared/safeJsonParse"
 import CodeBlock from "../common/CodeBlock"
 import McpToolRow from "../mcp/McpToolRow"
+
 import { Markdown } from "./Markdown"
 
 interface McpExecutionProps {

+ 1 - 1
webview-ui/src/components/chat/SlashCommandItem.tsx

@@ -1,7 +1,7 @@
 import React from "react"
 import { Edit, Trash2 } from "lucide-react"
 
-import type { Command } from "@roo/ExtensionMessage"
+import type { Command } from "@roo-code/types"
 
 import { useAppTranslation } from "@/i18n/TranslationContext"
 import { Button, StandardTooltip } from "@/components/ui"

+ 1 - 1
webview-ui/src/components/chat/SlashCommandItemSimple.tsx

@@ -1,6 +1,6 @@
 import React from "react"
 
-import type { Command } from "@roo/ExtensionMessage"
+import type { Command } from "@roo-code/types"
 
 interface SlashCommandItemSimpleProps {
 	command: Command

+ 2 - 2
webview-ui/src/components/chat/__tests__/SlashCommandItemSimple.spec.tsx

@@ -1,6 +1,6 @@
-import { render, screen, fireEvent } from "@/utils/test-utils"
+import type { Command } from "@roo-code/types"
 
-import type { Command } from "@roo/ExtensionMessage"
+import { render, screen, fireEvent } from "@/utils/test-utils"
 
 import { SlashCommandItemSimple } from "../SlashCommandItemSimple"
 

+ 5 - 3
webview-ui/src/components/cloud/OrganizationSwitcher.tsx

@@ -1,10 +1,12 @@
 import { useState, useEffect } from "react"
 import { Building2, User, Plus } from "lucide-react"
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectSeparator } from "@/components/ui/select"
-import { type CloudUserInfo, type CloudOrganizationMembership } from "@roo-code/types"
+
+import { type CloudUserInfo, type CloudOrganizationMembership, type ExtensionMessage } from "@roo-code/types"
+
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { vscode } from "@src/utils/vscode"
-import { type ExtensionMessage } from "@roo/ExtensionMessage"
+
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectSeparator } from "@/components/ui/select"
 
 type OrganizationSwitcherProps = {
 	userInfo: CloudUserInfo

+ 2 - 2
webview-ui/src/components/marketplace/MarketplaceViewStateManager.ts

@@ -11,10 +11,10 @@
  * 3. Using minimal state updates to avoid resetting scroll position
  */
 
-import { MarketplaceItem } from "@roo-code/types"
+import { MarketplaceItem, MarketplaceInstalledMetadata } from "@roo-code/types"
+
 import { vscode } from "../../utils/vscode"
 import { WebviewMessage } from "../../../../src/shared/WebviewMessage"
-import type { MarketplaceInstalledMetadata } from "../../../../src/shared/ExtensionMessage"
 
 export interface ViewState {
 	allItems: MarketplaceItem[]

+ 2 - 1
webview-ui/src/components/mcp/McpEnabledToggle.tsx

@@ -1,5 +1,6 @@
-import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
 import { FormEvent } from "react"
+import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
+
 import { useExtensionState } from "@src/context/ExtensionStateContext"
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { vscode } from "@src/utils/vscode"

+ 1 - 1
webview-ui/src/components/mcp/McpErrorRow.tsx

@@ -1,7 +1,7 @@
 import { useMemo } from "react"
 import { formatRelative } from "date-fns"
 
-import type { McpErrorEntry } from "@roo/mcp"
+import type { McpErrorEntry } from "@roo-code/types"
 
 type McpErrorRowProps = {
 	error: McpErrorEntry

+ 1 - 1
webview-ui/src/components/mcp/McpResourceRow.tsx

@@ -1,4 +1,4 @@
-import { McpResource, McpResourceTemplate } from "@roo/mcp"
+import type { McpResource, McpResourceTemplate } from "@roo-code/types"
 
 type McpResourceRowProps = {
 	item: McpResource | McpResourceTemplate

+ 1 - 1
webview-ui/src/components/mcp/McpToolRow.tsx

@@ -1,6 +1,6 @@
 import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
 
-import { McpTool } from "@roo/mcp"
+import type { McpTool } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { vscode } from "@src/utils/vscode"

+ 1 - 1
webview-ui/src/components/mcp/McpView.tsx

@@ -9,7 +9,7 @@ import {
 } from "@vscode/webview-ui-toolkit/react"
 import { Webhook } from "lucide-react"
 
-import { McpServer } from "@roo/mcp"
+import type { McpServer } from "@roo-code/types"
 
 import { vscode } from "@src/utils/vscode"
 import { useExtensionState } from "@src/context/ExtensionStateContext"

+ 1 - 1
webview-ui/src/components/settings/SlashCommandsSettings.tsx

@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react"
 import { Plus, Globe, Folder, Settings, SquareSlash } from "lucide-react"
 import { Trans } from "react-i18next"
 
-import type { Command } from "@roo/ExtensionMessage"
+import type { Command } from "@roo-code/types"
 
 import { useAppTranslation } from "@/i18n/TranslationContext"
 import { useExtensionState } from "@/context/ExtensionStateContext"

+ 1 - 1
webview-ui/src/components/settings/TerminalSettings.tsx

@@ -7,7 +7,7 @@ import { Trans } from "react-i18next"
 import { buildDocLink } from "@src/utils/docLinks"
 import { useEvent, useMount } from "react-use"
 
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import { type ExtensionMessage } from "@roo-code/types"
 
 import { cn } from "@/lib/utils"
 import { Slider } from "@/components/ui"

+ 1 - 1
webview-ui/src/components/settings/__tests__/SlashCommandsSettings.spec.tsx

@@ -1,7 +1,7 @@
 import { render, screen, fireEvent, waitFor } from "@/utils/test-utils"
 import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
 
-import type { Command } from "@roo/ExtensionMessage"
+import type { Command } from "@roo-code/types"
 
 import { ExtensionStateContextProvider } from "@/context/ExtensionStateContext"
 import { vscode } from "@/utils/vscode"

+ 1 - 3
webview-ui/src/components/settings/providers/Chutes.tsx

@@ -1,14 +1,12 @@
 import { useCallback } from "react"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import type { ProviderSettings, OrganizationAllowList } from "@roo-code/types"
+import type { ProviderSettings, OrganizationAllowList, RouterModels } from "@roo-code/types"
 import { chutesDefaultModelId } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"
 
-import type { RouterModels } from "@roo/api"
-
 import { ModelPicker } from "../ModelPicker"
 import { inputEventTransform } from "../transforms"
 

+ 3 - 0
webview-ui/src/components/settings/providers/ClaudeCode.tsx

@@ -1,8 +1,11 @@
 import React from "react"
+
 import { type ProviderSettings, claudeCodeDefaultModelId, claudeCodeModels } from "@roo-code/types"
+
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { Button } from "@src/components/ui"
 import { vscode } from "@src/utils/vscode"
+
 import { ModelPicker } from "../ModelPicker"
 import { ClaudeCodeRateLimitDashboard } from "./ClaudeCodeRateLimitDashboard"
 

+ 6 - 3
webview-ui/src/components/settings/providers/DeepInfra.tsx

@@ -1,9 +1,12 @@
 import { useCallback, useEffect, useState } from "react"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import { OrganizationAllowList, type ProviderSettings, deepInfraDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import {
+	type OrganizationAllowList,
+	type ProviderSettings,
+	type RouterModels,
+	deepInfraDefaultModelId,
+} from "@roo-code/types"
 
 import { vscode } from "@src/utils/vscode"
 import { useAppTranslation } from "@src/i18n/TranslationContext"

+ 1 - 2
webview-ui/src/components/settings/providers/HuggingFace.tsx

@@ -2,9 +2,8 @@ import { useCallback, useState, useEffect, useMemo } from "react"
 import { useEvent } from "react-use"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import type { ProviderSettings } from "@roo-code/types"
+import type { ProviderSettings, ExtensionMessage } from "@roo-code/types"
 
-import { ExtensionMessage } from "@roo/ExtensionMessage"
 import { vscode } from "@src/utils/vscode"
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"

+ 1 - 3
webview-ui/src/components/settings/providers/LMStudio.tsx

@@ -4,15 +4,13 @@ import { Trans } from "react-i18next"
 import { Checkbox } from "vscrui"
 import { VSCodeLink, VSCodeRadio, VSCodeRadioGroup, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import type { ProviderSettings } from "@roo-code/types"
+import type { ProviderSettings, ExtensionMessage, ModelRecord } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
 import { useRouterModels } from "@src/components/ui/hooks/useRouterModels"
 import { vscode } from "@src/utils/vscode"
 
 import { inputEventTransform } from "../transforms"
-import { ModelRecord } from "@roo/api"
 
 type LMStudioProps = {
 	apiConfiguration: ProviderSettings

+ 6 - 2
webview-ui/src/components/settings/providers/LiteLLM.tsx

@@ -1,10 +1,14 @@
 import { useCallback, useState, useEffect, useRef } from "react"
 import { VSCodeTextField, VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
 
-import { type ProviderSettings, type OrganizationAllowList, litellmDefaultModelId } from "@roo-code/types"
+import {
+	type ProviderSettings,
+	type OrganizationAllowList,
+	type ExtensionMessage,
+	litellmDefaultModelId,
+} from "@roo-code/types"
 
 import { RouterName } from "@roo/api"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
 
 import { vscode } from "@src/utils/vscode"
 import { useExtensionState } from "@src/context/ExtensionStateContext"

+ 1 - 3
webview-ui/src/components/settings/providers/Mistral.tsx

@@ -1,9 +1,7 @@
 import { useCallback } from "react"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import { type ProviderSettings, mistralDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import { type ProviderSettings, type RouterModels, mistralDefaultModelId } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"

+ 1 - 4
webview-ui/src/components/settings/providers/Ollama.tsx

@@ -2,16 +2,13 @@ import { useState, useCallback, useMemo, useEffect } from "react"
 import { useEvent } from "react-use"
 import { VSCodeTextField, VSCodeRadioGroup, VSCodeRadio } from "@vscode/webview-ui-toolkit/react"
 
-import type { ProviderSettings } from "@roo-code/types"
-
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import type { ProviderSettings, ExtensionMessage, ModelRecord } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { useRouterModels } from "@src/components/ui/hooks/useRouterModels"
 import { vscode } from "@src/utils/vscode"
 
 import { inputEventTransform } from "../transforms"
-import { ModelRecord } from "@roo/api"
 
 type OllamaProps = {
 	apiConfiguration: ProviderSettings

+ 1 - 2
webview-ui/src/components/settings/providers/OpenAICompatible.tsx

@@ -8,12 +8,11 @@ import {
 	type ModelInfo,
 	type ReasoningEffort,
 	type OrganizationAllowList,
+	type ExtensionMessage,
 	azureOpenAiDefaultApiVersion,
 	openAiModelInfoSaneDefaults,
 } from "@roo-code/types"
 
-import { ExtensionMessage } from "@roo/ExtensionMessage"
-
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { Button, StandardTooltip } from "@src/components/ui"
 

+ 6 - 3
webview-ui/src/components/settings/providers/OpenRouter.tsx

@@ -2,9 +2,12 @@ import { useCallback, useState } from "react"
 import { Checkbox } from "vscrui"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import { type ProviderSettings, type OrganizationAllowList, openRouterDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import {
+	type ProviderSettings,
+	type OrganizationAllowList,
+	type RouterModels,
+	openRouterDefaultModelId,
+} from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { getOpenRouterAuthUrl } from "@src/oauth/urls"

+ 1 - 0
webview-ui/src/components/settings/providers/QwenCode.tsx

@@ -1,5 +1,6 @@
 import React from "react"
 import { VSCodeTextField, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
+
 import { type ProviderSettings } from "@roo-code/types"
 
 interface QwenCodeProps {

+ 6 - 3
webview-ui/src/components/settings/providers/Requesty.tsx

@@ -1,9 +1,12 @@
 import { useCallback, useEffect, useState } from "react"
 import { VSCodeCheckbox, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import { type ProviderSettings, type OrganizationAllowList, requestyDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import {
+	type ProviderSettings,
+	type OrganizationAllowList,
+	type RouterModels,
+	requestyDefaultModelId,
+} from "@roo-code/types"
 
 import { vscode } from "@src/utils/vscode"
 import { useAppTranslation } from "@src/i18n/TranslationContext"

+ 6 - 3
webview-ui/src/components/settings/providers/Roo.tsx

@@ -1,6 +1,9 @@
-import { type ProviderSettings, type OrganizationAllowList, rooDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import {
+	type ProviderSettings,
+	type OrganizationAllowList,
+	type RouterModels,
+	rooDefaultModelId,
+} from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { vscode } from "@src/utils/vscode"

+ 6 - 3
webview-ui/src/components/settings/providers/Unbound.tsx

@@ -2,9 +2,12 @@ import { useCallback, useState, useRef } from "react"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 import { useQueryClient } from "@tanstack/react-query"
 
-import { type ProviderSettings, type OrganizationAllowList, unboundDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import {
+	type ProviderSettings,
+	type OrganizationAllowList,
+	type RouterModels,
+	unboundDefaultModelId,
+} from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"

+ 1 - 3
webview-ui/src/components/settings/providers/VSCodeLM.tsx

@@ -2,9 +2,7 @@ import { useState, useCallback } from "react"
 import { useEvent } from "react-use"
 import { LanguageModelChatSelector } from "vscode"
 
-import type { ProviderSettings } from "@roo-code/types"
-
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import type { ProviderSettings, ExtensionMessage } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui"

+ 6 - 3
webview-ui/src/components/settings/providers/VercelAiGateway.tsx

@@ -1,9 +1,12 @@
 import { useCallback } from "react"
 import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
 
-import { type ProviderSettings, type OrganizationAllowList, vercelAiGatewayDefaultModelId } from "@roo-code/types"
-
-import type { RouterModels } from "@roo/api"
+import {
+	type ProviderSettings,
+	type OrganizationAllowList,
+	type RouterModels,
+	vercelAiGatewayDefaultModelId,
+} from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"

+ 1 - 1
webview-ui/src/components/settings/providers/ZAi.tsx

@@ -1,7 +1,7 @@
 import { useCallback } from "react"
 import { VSCodeTextField, VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"
 
-import { zaiApiLineConfigs, zaiApiLineSchema, type ProviderSettings } from "@roo-code/types"
+import { type ProviderSettings, zaiApiLineConfigs, zaiApiLineSchema } from "@roo-code/types"
 
 import { useAppTranslation } from "@src/i18n/TranslationContext"
 import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"

+ 1 - 2
webview-ui/src/components/ui/hooks/useLmStudioModels.ts

@@ -1,7 +1,6 @@
 import { useQuery } from "@tanstack/react-query"
 
-import { ModelRecord } from "@roo/api"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import { type ModelRecord, type ExtensionMessage } from "@roo-code/types"
 
 import { vscode } from "@src/utils/vscode"
 

+ 1 - 2
webview-ui/src/components/ui/hooks/useOllamaModels.ts

@@ -1,7 +1,6 @@
 import { useQuery } from "@tanstack/react-query"
 
-import { ModelRecord } from "@roo/api"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import { type ModelRecord, type ExtensionMessage } from "@roo-code/types"
 
 import { vscode } from "@src/utils/vscode"
 

+ 3 - 1
webview-ui/src/components/ui/hooks/useRooCreditBalance.ts

@@ -1,5 +1,7 @@
 import { useEffect, useState } from "react"
-import type { ExtensionMessage } from "@roo/ExtensionMessage"
+
+import type { ExtensionMessage } from "@roo-code/types"
+
 import { vscode } from "@src/utils/vscode"
 
 /**

+ 1 - 2
webview-ui/src/components/ui/hooks/useRouterModels.ts

@@ -1,7 +1,6 @@
 import { useQuery } from "@tanstack/react-query"
 
-import { RouterModels } from "@roo/api"
-import { ExtensionMessage } from "@roo/ExtensionMessage"
+import { type RouterModels, type ExtensionMessage } from "@roo-code/types"
 
 import { vscode } from "@src/utils/vscode"
 

+ 2 - 2
webview-ui/src/components/ui/hooks/useSelectedModel.ts

@@ -2,6 +2,8 @@ import {
 	type ProviderName,
 	type ProviderSettings,
 	type ModelInfo,
+	type ModelRecord,
+	type RouterModels,
 	anthropicModels,
 	bedrockModels,
 	cerebrasModels,
@@ -36,8 +38,6 @@ import {
 	NATIVE_TOOL_DEFAULTS,
 } from "@roo-code/types"
 
-import type { ModelRecord, RouterModels } from "@roo/api"
-
 import { useRouterModels } from "./useRouterModels"
 import { useOpenRouterModelProviders } from "./useOpenRouterModelProviders"
 import { useLmStudioModels } from "./useLmStudioModels"

+ 1 - 1
webview-ui/src/components/welcome/RooHero.tsx

@@ -23,7 +23,7 @@ const RooHero = () => {
 					maskSize: "contain",
 					animation: isHovered ? "smooth-bounce 1s ease-in-out infinite" : "none",
 				}}
-					className="z-5 mr-auto translate-y-0 transition-transform duration-500">
+				className="z-5 mr-auto translate-y-0 transition-transform duration-500">
 				<img src={imagesBaseUri + "/roo-logo.svg"} alt="Roo logo" className="h-8 opacity-0" />
 			</div>
 			<div

+ 7 - 3
webview-ui/src/context/ExtensionStateContext.tsx

@@ -10,18 +10,22 @@ import {
 	type TelemetrySetting,
 	type OrganizationAllowList,
 	type CloudOrganizationMembership,
+	type ExtensionMessage,
+	type ExtensionState,
+	type MarketplaceInstalledMetadata,
+	type Command,
+	type McpServer,
+	RouterModels,
 	ORGANIZATION_ALLOW_ALL,
 	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
 } from "@roo-code/types"
 
-import { ExtensionMessage, ExtensionState, MarketplaceInstalledMetadata, Command } from "@roo/ExtensionMessage"
 import { findLastIndex } from "@roo/array"
-import { McpServer } from "@roo/mcp"
+
 import { checkExistKey } from "@roo/checkExistApiConfig"
 import { Mode, defaultModeSlug, defaultPrompts } from "@roo/modes"
 import { CustomSupportPrompts } from "@roo/support-prompt"
 import { experimentDefault } from "@roo/experiments"
-import { RouterModels } from "@roo/api"
 
 import { vscode } from "@src/utils/vscode"
 import { convertTextMateToHljs } from "@src/utils/textMateToHljs"

+ 6 - 3
webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx

@@ -1,8 +1,11 @@
 import { render, screen, act } from "@/utils/test-utils"
 
-import { ProviderSettings, ExperimentId, DEFAULT_CHECKPOINT_TIMEOUT_SECONDS } from "@roo-code/types"
-
-import { ExtensionState } from "@roo/ExtensionMessage"
+import {
+	type ProviderSettings,
+	type ExperimentId,
+	type ExtensionState,
+	DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
+} from "@roo-code/types"
 
 import { ExtensionStateContextProvider, useExtensionState, mergeExtensionState } from "../ExtensionStateContext"
 

+ 1 - 3
webview-ui/src/utils/__tests__/validate.spec.ts

@@ -1,6 +1,4 @@
-import type { ProviderSettings, OrganizationAllowList } from "@roo-code/types"
-
-import { RouterModels } from "@roo/api"
+import type { ProviderSettings, OrganizationAllowList, RouterModels } from "@roo-code/types"
 
 // Mock i18next to return translation keys with interpolated values
 vi.mock("i18next", () => ({

+ 1 - 2
webview-ui/src/utils/context-mentions.ts

@@ -1,7 +1,6 @@
 import { Fzf } from "fzf"
 
-import type { ModeConfig } from "@roo-code/types"
-import type { Command } from "@roo/ExtensionMessage"
+import type { ModeConfig, Command } from "@roo-code/types"
 
 import { mentionRegex } from "@roo/context-mentions"
 

+ 1 - 1
webview-ui/src/utils/mcp.ts

@@ -1,4 +1,4 @@
-import { McpResource, McpResourceTemplate } from "@roo/mcp"
+import type { McpResource, McpResourceTemplate } from "@roo-code/types"
 
 /**
  * Matches a URI against an array of URI templates and returns the matching template

+ 1 - 2
webview-ui/src/utils/validate.ts

@@ -4,6 +4,7 @@ import {
 	type ProviderSettings,
 	type OrganizationAllowList,
 	type ProviderName,
+	type RouterModels,
 	modelIdKeysByProvider,
 	isProviderName,
 	isDynamicProvider,
@@ -11,8 +12,6 @@ import {
 	isCustomProvider,
 } from "@roo-code/types"
 
-import type { RouterModels } from "@roo/api"
-
 export function validateApiConfiguration(
 	apiConfiguration: ProviderSettings,
 	routerModels?: RouterModels,