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

Add a new @roo-code/types package and use it everywhere (#3912)

Chris Estreich 7 месяцев назад
Родитель
Сommit
e66136f1aa
100 измененных файлов с 904 добавлено и 1092 удалено
  1. 0 82
      .github/scripts/overwrite_changeset_changelog.py
  2. 14 38
      .github/workflows/code-qa.yml
  3. 0 8
      .husky/pre-commit
  4. 3 3
      apps/vscode-e2e/package.json
  5. 2 6
      apps/vscode-e2e/src/suite/extension.test.ts
  6. 4 9
      apps/vscode-e2e/src/suite/index.ts
  7. 2 8
      apps/vscode-e2e/src/suite/modes.test.ts
  8. 4 5
      apps/vscode-e2e/src/suite/subtasks.test.ts
  9. 2 3
      apps/vscode-e2e/src/suite/task.test.ts
  10. 8 0
      apps/vscode-e2e/src/types/global.d.ts
  11. 8 0
      apps/vscode-e2e/tsconfig.esm.json
  12. 1 1
      apps/vscode-e2e/tsconfig.json
  13. 21 10
      apps/vscode-nightly/esbuild.mjs
  14. 2 3
      apps/vscode-nightly/package.json
  15. 0 243
      e2e/src/suite/condensing.test.ts
  16. 1 1
      knip.json
  17. 5 6
      package.json
  18. 44 20
      packages/build/src/esbuild.ts
  19. 1 1
      packages/build/src/index.ts
  20. 7 6
      packages/types/README.md
  21. 4 0
      packages/types/eslint.config.mjs
  22. 37 0
      packages/types/package.json
  23. 17 0
      packages/types/src/__tests__/index.test.ts
  24. 24 73
      packages/types/src/api.ts
  25. 2 0
      packages/types/src/index.ts
  26. 10 49
      packages/types/src/types.ts
  27. 9 0
      packages/types/tsconfig.json
  28. 11 0
      packages/types/tsup.config.ts
  29. 342 314
      pnpm-lock.yaml
  30. 2 1
      src/activate/CodeActionProvider.ts
  31. 1 1
      src/activate/handleTask.ts
  32. 2 1
      src/activate/registerCodeActions.ts
  33. 3 1
      src/activate/registerCommands.ts
  34. 2 1
      src/activate/registerTerminalActions.ts
  35. 30 28
      src/api/index.ts
  36. 3 1
      src/api/providers/__tests__/gemini.test.ts
  37. 3 1
      src/api/providers/anthropic-vertex.ts
  38. 3 7
      src/api/providers/anthropic.ts
  39. 3 1
      src/api/providers/base-openai-compatible-provider.ts
  40. 1 1
      src/api/providers/base-provider.ts
  41. 8 11
      src/api/providers/bedrock.ts
  42. 5 2
      src/api/providers/fake-ai.ts
  43. 3 2
      src/api/providers/fetchers/glama.ts
  44. 1 0
      src/api/providers/fetchers/litellm.ts
  45. 3 3
      src/api/providers/fetchers/openrouter.ts
  46. 3 2
      src/api/providers/fetchers/requesty.ts
  47. 1 1
      src/api/providers/fetchers/unbound.ts
  48. 5 2
      src/api/providers/gemini.ts
  49. 1 1
      src/api/providers/glama.ts
  50. 4 1
      src/api/providers/human-relay.ts
  51. 22 0
      src/api/providers/index.ts
  52. 6 2
      src/api/providers/lmstudio.ts
  53. 5 1
      src/api/providers/mistral.ts
  54. 7 3
      src/api/providers/ollama.ts
  55. 4 3
      src/api/providers/openai-native.ts
  56. 4 7
      src/api/providers/openai.ts
  57. 10 11
      src/api/providers/requesty.ts
  58. 4 1
      src/api/providers/router-provider.ts
  59. 4 2
      src/api/providers/vertex.ts
  60. 7 3
      src/api/providers/vscode-lm.ts
  61. 3 2
      src/api/transform/__tests__/image-cleaning.test.ts
  62. 2 1
      src/api/transform/__tests__/model-params.test.ts
  63. 2 1
      src/api/transform/__tests__/reasoning.test.ts
  64. 2 1
      src/api/transform/image-cleaning.ts
  65. 3 6
      src/api/transform/model-params.ts
  66. 2 1
      src/api/transform/reasoning.ts
  67. 2 1
      src/core/assistant-message/parseAssistantMessage.ts
  68. 2 1
      src/core/assistant-message/parseAssistantMessageV2.ts
  69. 1 2
      src/core/assistant-message/presentAssistantMessage.ts
  70. 7 6
      src/core/config/ContextProxy.ts
  71. 5 3
      src/core/config/CustomModesManager.ts
  72. 6 1
      src/core/config/ProviderSettingsManager.ts
  73. 3 2
      src/core/config/__tests__/ContextProxy.test.ts
  74. 7 3
      src/core/config/__tests__/CustomModesManager.test.ts
  75. 2 2
      src/core/config/__tests__/CustomModesSettings.test.ts
  76. 1 2
      src/core/config/__tests__/ModeConfig.test.ts
  77. 2 1
      src/core/config/__tests__/ProviderSettingsManager.test.ts
  78. 2 1
      src/core/config/__tests__/importExport.test.ts
  79. 3 2
      src/core/config/importExport.ts
  80. 2 1
      src/core/diff/strategies/multi-search-replace.ts
  81. 3 1
      src/core/environment/getEnvironmentDetails.ts
  82. 6 2
      src/core/prompts/__tests__/system.test.ts
  83. 4 2
      src/core/prompts/sections/custom-instructions.ts
  84. 3 1
      src/core/prompts/sections/modes.ts
  85. 12 15
      src/core/prompts/system.ts
  86. 3 2
      src/core/prompts/tools/index.ts
  87. 5 3
      src/core/sliding-window/__tests__/sliding-window.test.ts
  88. 2 1
      src/core/task-persistence/taskMessages.ts
  89. 2 2
      src/core/task-persistence/taskMetadata.ts
  90. 14 13
      src/core/task/Task.ts
  91. 2 2
      src/core/task/__tests__/Task.test.ts
  92. 2 1
      src/core/tools/__tests__/ToolRepetitionDetector.test.ts
  93. 2 1
      src/core/tools/__tests__/executeCommandTool.test.ts
  94. 4 1
      src/core/tools/__tests__/validateToolUse.test.ts
  95. 3 1
      src/core/tools/executeCommandTool.ts
  96. 3 2
      src/core/tools/validateToolUse.ts
  97. 5 4
      src/core/webview/ClineProvider.ts
  98. 6 3
      src/core/webview/__tests__/ClineProvider.test.ts
  99. 3 1
      src/core/webview/webviewMessageHandler.ts
  100. 16 3
      src/esbuild.mjs

+ 0 - 82
.github/scripts/overwrite_changeset_changelog.py

@@ -1,82 +0,0 @@
-"""
-This script updates a specific version's release notes section in CHANGELOG.md with new content
-or reformats existing content.
-
-The script:
-1. Takes a version number, changelog path, and optionally new content as input from environment variables
-2. Finds the section in the changelog for the specified version
-3. Either:
-   a) Replaces the content with new content if provided, or
-   b) Reformats existing content by:
-      - Removing the first two lines of the changeset format
-      - Ensuring version numbers are wrapped in square brackets
-4. Writes the updated changelog back to the file
-
-Environment Variables:
-    CHANGELOG_PATH: Path to the changelog file (defaults to 'CHANGELOG.md')
-    VERSION: The version number to update/format
-    PREV_VERSION: The previous version number (used to locate section boundaries)
-    NEW_CONTENT: Optional new content to insert for this version
-"""
-
-#!/usr/bin/env python3
-
-import os
-
-CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md")
-VERSION = os.environ["VERSION"]
-PREV_VERSION = os.environ.get("PREV_VERSION", "")
-NEW_CONTENT = os.environ.get("NEW_CONTENT", "")
-
-
-def overwrite_changelog_section(changelog_text: str, new_content: str):
-    # Find the section for the specified version
-    version_pattern = f"## {VERSION}\n"
-    prev_version_pattern = f"## [{PREV_VERSION}]\n"
-    print(f"latest version: {VERSION}")
-    print(f"prev_version: {PREV_VERSION}")
-
-    notes_start_index = changelog_text.find(version_pattern) + len(version_pattern)
-    notes_end_index = (
-        changelog_text.find(prev_version_pattern, notes_start_index)
-        if PREV_VERSION and prev_version_pattern in changelog_text
-        else len(changelog_text)
-    )
-
-    if new_content:
-        return (
-            changelog_text[:notes_start_index]
-            + f"{new_content}\n"
-            + changelog_text[notes_end_index:]
-        )
-    else:
-        changeset_lines = changelog_text[notes_start_index:notes_end_index].split("\n")
-        # Remove the first two lines from the regular changeset format, ex: \n### Patch Changes
-        parsed_lines = "\n".join(changeset_lines[2:])
-        updated_changelog = (
-            changelog_text[:notes_start_index]
-            + parsed_lines
-            + changelog_text[notes_end_index:]
-        )
-        updated_changelog = updated_changelog.replace(
-            f"## {VERSION}", f"## [{VERSION}]"
-        )
-        return updated_changelog
-
-
-with open(CHANGELOG_PATH, "r") as f:
-    changelog_content = f.read()
-
-new_changelog = overwrite_changelog_section(changelog_content, NEW_CONTENT)
-print(
-    "----------------------------------------------------------------------------------"
-)
-print(new_changelog)
-print(
-    "----------------------------------------------------------------------------------"
-)
-# Write back to CHANGELOG.md
-with open(CHANGELOG_PATH, "w") as f:
-    f.write(new_changelog)
-
-print(f"{CHANGELOG_PATH} updated successfully!")

+ 14 - 38
.github/workflows/code-qa.yml

@@ -13,27 +13,6 @@ env:
   PNPM_VERSION: 10.8.1
 
 jobs:
-  compile:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@v4
-      - name: Install pnpm
-        uses: pnpm/action-setup@v4
-        with:
-          version: ${{ env.PNPM_VERSION }}
-      - name: Setup Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: ${{ env.NODE_VERSION }}
-          cache: 'pnpm'
-      - name: Install dependencies
-        run: pnpm install
-      - name: Check types
-        run: pnpm check-types
-      - name: Lint
-        run: pnpm lint
-
   check-translations:
     runs-on: ubuntu-latest
     steps:
@@ -72,11 +51,8 @@ jobs:
       - name: Run knip checks
         run: pnpm knip
 
-  test-extension:
-    runs-on: ${{ matrix.os }}
-    strategy:
-      matrix:
-        os: [ubuntu-latest, windows-latest]
+  compile:
+    runs-on: ubuntu-latest
     steps:
       - name: Checkout code
         uses: actions/checkout@v4
@@ -91,11 +67,12 @@ jobs:
           cache: 'pnpm'
       - name: Install dependencies
         run: pnpm install
-      - name: Run unit tests
-        working-directory: src
-        run: pnpm test
+      - name: Lint
+        run: pnpm lint
+      - name: Check types
+        run: pnpm check-types
 
-  test-webview:
+  platform-unit-test:
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
@@ -115,16 +92,8 @@ jobs:
       - name: Install dependencies
         run: pnpm install
       - name: Run unit tests
-        working-directory: webview-ui
         run: pnpm test
 
-  unit-test:
-    needs: [test-extension, test-webview]
-    runs-on: ubuntu-latest
-    steps:
-      - name: NO-OP
-        run: echo "All unit tests passed."
-
   check-openrouter-api-key:
     runs-on: ubuntu-latest
     outputs:
@@ -164,3 +133,10 @@ jobs:
       - name: Run integration tests
         working-directory: apps/vscode-e2e
         run: xvfb-run -a pnpm test:ci
+
+  unit-test:
+    needs: [platform-unit-test] # [platform-unit-test, integration-test]
+    runs-on: ubuntu-latest
+    steps:
+      - name: NO-OP
+        run: echo "All tests passed."

+ 0 - 8
.husky/pre-commit

@@ -16,14 +16,6 @@ else
   fi
 fi
 
-$pnpm_cmd --filter roo-cline generate-types
-
-if [ -n "$(git diff --name-only src/exports/roo-code.d.ts)" ]; then
-  echo "Error: There are unstaged changes to roo-code.d.ts after running 'pnpm --filter roo-cline generate-types'."
-  echo "Please review and stage the changes before committing."
-  exit 1
-fi
-
 # Detect if running on Windows and use npx.cmd, otherwise use npx.
 if [ "$OS" = "Windows_NT" ]; then
   npx_cmd="npx.cmd"

+ 3 - 3
apps/vscode-e2e/package.json

@@ -3,16 +3,16 @@
 	"private": true,
 	"scripts": {
 		"lint": "eslint src --ext=ts --max-warnings=0",
-		"check-types": "tsc --noEmit",
+		"check-types": "tsc -p tsconfig.esm.json --noEmit",
 		"format": "prettier --write src",
-		"test:ci": "pnpm --filter roo-cline build:development && pnpm test:run",
+		"test:ci": "pnpm -w bundle && pnpm --filter @roo-code/vscode-webview build && pnpm test:run",
 		"test:run": "rimraf out && tsc -p tsconfig.json && npx dotenvx run -f .env.local -- node ./out/runTest.js",
 		"clean": "rimraf out .turbo"
 	},
 	"devDependencies": {
 		"@roo-code/config-eslint": "workspace:^",
 		"@roo-code/config-typescript": "workspace:^",
-		"@roo-code/types": "^1.12.0",
+		"@roo-code/types": "workspace:^",
 		"@types/mocha": "^10.0.10",
 		"@types/node": "^22.14.1",
 		"@types/vscode": "^1.95.0",

+ 2 - 6
apps/vscode-e2e/src/suite/extension.test.ts

@@ -1,8 +1,6 @@
 import * as assert from "assert"
 import * as vscode from "vscode"
 
-import { Package } from "@roo-code/types"
-
 suite("Roo Code Extension", () => {
 	test("Commands should be registered", async () => {
 		const expectedCommands = [
@@ -36,12 +34,10 @@ suite("Roo Code Extension", () => {
 			"terminalExplainCommand",
 		]
 
-		const commands = new Set(
-			(await vscode.commands.getCommands(true)).filter((cmd) => cmd.startsWith(Package.name)),
-		)
+		const commands = new Set((await vscode.commands.getCommands(true)).filter((cmd) => cmd.startsWith("roo-cline")))
 
 		for (const command of expectedCommands) {
-			assert.ok(commands.has(`${Package.name}.${command}`), `Command ${command} should be registered`)
+			assert.ok(commands.has(`roo-cline.${command}`), `Command ${command} should be registered`)
 		}
 	})
 })

+ 4 - 9
apps/vscode-e2e/src/suite/index.ts

@@ -3,16 +3,12 @@ import Mocha from "mocha"
 import { glob } from "glob"
 import * as vscode from "vscode"
 
-import { type RooCodeAPI, Package } from "@roo-code/types"
+import type { RooCodeAPI } from "@roo-code/types"
 
 import { waitFor } from "./utils"
 
-declare global {
-	let api: RooCodeAPI
-}
-
 export async function run() {
-	const extension = vscode.extensions.getExtension<RooCodeAPI>(`${Package.publisher}.${Package.name}`)
+	const extension = vscode.extensions.getExtension<RooCodeAPI>("RooVeterinaryInc.roo-cline")
 
 	if (!extension) {
 		throw new Error("Extension not found")
@@ -23,13 +19,12 @@ export async function run() {
 	await api.setConfiguration({
 		apiProvider: "openrouter" as const,
 		openRouterApiKey: process.env.OPENROUTER_API_KEY!,
-		openRouterModelId: "google/gemini-2.0-flash-001",
+		openRouterModelId: "openai/gpt-4.1",
 	})
 
-	await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
+	await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
 	await waitFor(() => api.isReady())
 
-	// @ts-expect-error - Expose the API to the tests.
 	globalThis.api = api
 
 	// Add all the tests to the runner.

+ 2 - 8
apps/vscode-e2e/src/suite/modes.test.ts

@@ -1,23 +1,17 @@
 import * as assert from "assert"
 
-import type { RooCodeAPI, ClineMessage } from "@roo-code/types"
+import type { ClineMessage } from "@roo-code/types"
 
 import { waitUntilCompleted } from "./utils"
 
 suite("Roo Code Modes", () => {
 	test("Should handle switching modes correctly", async () => {
-		// @ts-expect-error - Expose the API to the tests.
-		const api = globalThis.api as RooCodeAPI
-
-		/**
-		 * Switch modes.
-		 */
+		const api = globalThis.api
 
 		const switchModesPrompt =
 			"For each mode (Architect, Ask, Debug) respond with the mode name and what it specializes in after switching to that mode."
 
 		const messages: ClineMessage[] = []
-
 		const modeSwitches: string[] = []
 
 		api.on("taskModeSwitched", (_taskId, mode) => {

+ 4 - 5
apps/vscode-e2e/src/suite/subtasks.test.ts

@@ -1,13 +1,12 @@
 import * as assert from "assert"
 
-import type { RooCodeAPI, ClineMessage } from "@roo-code/types"
+import type { ClineMessage } from "@roo-code/types"
 
 import { sleep, waitFor, waitUntilCompleted } from "./utils"
 
 suite.skip("Roo Code Subtasks", () => {
 	test("Should handle subtask cancellation and resumption correctly", async () => {
-		// @ts-expect-error - Expose the API to the tests.
-		const api = globalThis.api as RooCodeAPI
+		const api = globalThis.api
 
 		const messages: Record<string, ClineMessage[]> = {}
 
@@ -49,7 +48,7 @@ suite.skip("Roo Code Subtasks", () => {
 		// The parent task should not have resumed yet, so we shouldn't see
 		// "Parent task resumed".
 		assert.ok(
-			messages[parentTaskId].find(({ type, text }) => type === "say" && text === "Parent task resumed") ===
+			messages[parentTaskId]?.find(({ type, text }) => type === "say" && text === "Parent task resumed") ===
 				undefined,
 			"Parent task should not have resumed after subtask cancellation",
 		)
@@ -63,7 +62,7 @@ suite.skip("Roo Code Subtasks", () => {
 
 		// The parent task should still not have resumed.
 		assert.ok(
-			messages[parentTaskId].find(({ type, text }) => type === "say" && text === "Parent task resumed") ===
+			messages[parentTaskId]?.find(({ type, text }) => type === "say" && text === "Parent task resumed") ===
 				undefined,
 			"Parent task should not have resumed after subtask cancellation",
 		)

+ 2 - 3
apps/vscode-e2e/src/suite/task.test.ts

@@ -1,13 +1,12 @@
 import * as assert from "assert"
 
-import type { RooCodeAPI, ClineMessage } from "@roo-code/types"
+import type { ClineMessage } from "@roo-code/types"
 
 import { waitUntilCompleted } from "./utils"
 
 suite("Roo Code Task", () => {
 	test("Should handle prompt and response correctly", async () => {
-		// @ts-expect-error - Expose the API to the tests.
-		const api = globalThis.api as RooCodeAPI
+		const api = globalThis.api
 
 		const messages: ClineMessage[] = []
 

+ 8 - 0
apps/vscode-e2e/src/types/global.d.ts

@@ -0,0 +1,8 @@
+import type { RooCodeAPI } from "@roo-code/types"
+
+declare global {
+	// eslint-disable-next-line no-var
+	var api: RooCodeAPI
+}
+
+export {}

+ 8 - 0
apps/vscode-e2e/tsconfig.esm.json

@@ -0,0 +1,8 @@
+{
+	"extends": "@roo-code/config-typescript/base.json",
+	"compilerOptions": {
+		"outDir": "out"
+	},
+	"include": ["src"],
+	"exclude": ["node_modules"]
+}

+ 1 - 1
apps/vscode-e2e/tsconfig.json

@@ -11,6 +11,6 @@
 		"useUnknownInCatchVariables": false,
 		"outDir": "out"
 	},
-	"include": ["src", "../src/exports/roo-code.d.ts"],
+	"include": ["src"],
 	"exclude": [".vscode-test", "**/node_modules/**", "out"]
 }

+ 21 - 10
apps/vscode-nightly/esbuild.mjs

@@ -9,16 +9,17 @@ const __filename = fileURLToPath(import.meta.url)
 const __dirname = path.dirname(__filename)
 
 async function main() {
+	const name = "extension-nightly"
 	const production = process.argv.includes("--production")
 	const minify = production
 	const sourcemap = !production
 
 	const overrideJson = JSON.parse(fs.readFileSync(path.join(__dirname, "package.nightly.json"), "utf8"))
-	console.log(`[main] name: ${overrideJson.name}`)
-	console.log(`[main] version: ${overrideJson.version}`)
+	console.log(`[${name}] name: ${overrideJson.name}`)
+	console.log(`[${name}] version: ${overrideJson.version}`)
 
 	const gitSha = getGitSha()
-	console.log(`[main] gitSha: ${gitSha}`)
+	console.log(`[${name}] gitSha: ${gitSha}`)
 
 	/**
 	 * @type {import('esbuild').BuildOptions}
@@ -43,12 +44,22 @@ async function main() {
 	const buildDir = path.join(__dirname, "build")
 	const distDir = path.join(buildDir, "dist")
 
+	console.log(`[${name}] srcDir: ${srcDir}`)
+	console.log(`[${name}] buildDir: ${buildDir}`)
+	console.log(`[${name}] distDir: ${distDir}`)
+
+	// Clean build directory before starting new build
+	if (fs.existsSync(buildDir)) {
+		console.log(`[${name}] Cleaning build directory: ${buildDir}`)
+		fs.rmSync(buildDir, { recursive: true, force: true })
+	}
+
 	/**
 	 * @type {import('esbuild').Plugin[]}
 	 */
 	const plugins = [
 		{
-			name: "copy-files",
+			name: "copyPaths",
 			setup(build) {
 				build.onEnd(() => {
 					copyPaths(
@@ -69,7 +80,7 @@ async function main() {
 			},
 		},
 		{
-			name: "generate-package-json",
+			name: "generatePackageJson",
 			setup(build) {
 				build.onEnd(() => {
 					const packageJson = JSON.parse(fs.readFileSync(path.join(srcDir, "package.json"), "utf8"))
@@ -81,7 +92,7 @@ async function main() {
 					})
 
 					fs.writeFileSync(path.join(buildDir, "package.json"), JSON.stringify(generatedPackageJson, null, 2))
-					console.log(`[generate-package-json] Generated package.json`)
+					console.log(`[generatePackageJson] Generated package.json`)
 
 					let count = 0
 
@@ -92,7 +103,7 @@ async function main() {
 						}
 					})
 
-					console.log(`[copy-src] Copied ${count} package.nls*.json files to ${buildDir}`)
+					console.log(`[generatePackageJson] Copied ${count} package.nls*.json files to ${buildDir}`)
 
 					const nlsPkg = JSON.parse(fs.readFileSync(path.join(srcDir, "package.nls.json"), "utf8"))
 
@@ -105,18 +116,18 @@ async function main() {
 						JSON.stringify({ ...nlsPkg, ...nlsNightlyPkg }, null, 2),
 					)
 
-					console.log(`[copy-src] Generated package.nls.json`)
+					console.log(`[generatePackageJson] Generated package.nls.json`)
 				})
 			},
 		},
 		{
-			name: "copy-wasms",
+			name: "copyWasms",
 			setup(build) {
 				build.onEnd(() => copyWasms(srcDir, distDir))
 			},
 		},
 		{
-			name: "copy-locales",
+			name: "copyLocales",
 			setup(build) {
 				build.onEnd(() => copyLocales(srcDir, distDir))
 			},

+ 2 - 3
apps/vscode-nightly/package.json

@@ -4,9 +4,8 @@
 	"private": true,
 	"packageManager": "[email protected]",
 	"scripts": {
-		"bundle": "pnpm clean && pnpm --filter @roo-code/build build && node esbuild.mjs",
-		"build": "pnpm bundle --production && pnpm --filter @roo-code/vscode-webview build --mode nightly",
-		"vsix": "pnpm build && cd build && mkdirp ../../../bin && npx vsce package --no-dependencies --out ../../../bin",
+		"bundle:nightly": "node esbuild.mjs",
+		"vsix:nightly": "cd build && mkdirp ../../../bin && npx vsce package --no-dependencies --out ../../../bin",
 		"clean": "rimraf build .turbo"
 	},
 	"devDependencies": {

+ 0 - 243
e2e/src/suite/condensing.test.ts

@@ -1,243 +0,0 @@
-import { suite, test, before, after } from "mocha"
-import * as assert from "assert"
-import { type RooCodeAPI } from "@roo-code/types"
-import { waitFor, sleep } from "./utils" // Assuming utils.ts is in the same directory or path is adjusted
-
-// Define an interface for globalThis that includes the 'api' property
-interface GlobalWithApi extends NodeJS.Global {
-	api: RooCodeAPI
-}
-
-// Cast globalThis to our new interface
-const g = globalThis as unknown as GlobalWithApi
-
-// Define a minimal interface for task messages for type safety in callbacks
-interface TestTaskMessage {
-	role: string
-	content: string | unknown // Content can be complex
-	isSummary?: boolean
-	// Allow other properties
-	[key: string]: unknown
-}
-
-suite("Context Condensing Integration Tests", () => {
-	let initialConfig: ReturnType<RooCodeAPI["getConfiguration"]>
-
-	before(async () => {
-		// Ensure API is ready before starting tests
-		await waitFor(() => g.api && g.api.isReady())
-		initialConfig = g.api.getConfiguration()
-	})
-
-	after(async () => {
-		// Restore initial configuration after tests
-		if (initialConfig) {
-			// Type issue: RooCodeSettings might not include new props.
-			// This will cause a type error if initialConfig contains new props not in RooCodeSettings.
-			// For now, we assume initialConfig is a valid RooCodeSettings or types need update.
-			await g.api.setConfiguration(initialConfig)
-		}
-	})
-
-	suite("Settings Persistence", () => {
-		test("should persist condensingApiConfigId when set", async () => {
-			const testConfigId = "test-condensing-api-config"
-			// @ts-expect-error - Argument of type '{ condensingApiConfigId: string; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ condensingApiConfigId: testConfigId })
-			await sleep(100)
-			const updatedConfig = g.api.getConfiguration()
-			assert.strictEqual(
-				// @ts-expect-error - Property 'condensingApiConfigId' does not exist on type 'RooCodeSettings'.
-				updatedConfig.condensingApiConfigId,
-				testConfigId,
-				"condensingApiConfigId did not persist",
-			)
-		})
-
-		test("should persist customCondensingPrompt when set", async () => {
-			const testPrompt = "This is a custom condensing prompt for testing."
-			// @ts-expect-error - Argument of type '{ customCondensingPrompt: string; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ customCondensingPrompt: testPrompt })
-			await sleep(100)
-			const updatedConfig = g.api.getConfiguration()
-			assert.strictEqual(
-				// @ts-expect-error - Property 'customCondensingPrompt' does not exist on type 'RooCodeSettings'.
-				updatedConfig.customCondensingPrompt,
-				testPrompt,
-				"customCondensingPrompt did not persist",
-			)
-		})
-
-		test("should clear customCondensingPrompt when set to empty string", async () => {
-			const initialPrompt = "A prompt to be cleared."
-			// @ts-expect-error - Argument of type '{ customCondensingPrompt: string; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ customCondensingPrompt: initialPrompt })
-			await sleep(100)
-			let updatedConfig = g.api.getConfiguration()
-			// @ts-expect-error - Property 'customCondensingPrompt' does not exist on type 'RooCodeSettings'.
-			assert.strictEqual(updatedConfig.customCondensingPrompt, initialPrompt, "Initial prompt was not set")
-
-			// @ts-expect-error - Argument of type '{ customCondensingPrompt: string; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ customCondensingPrompt: "" })
-			await sleep(100)
-			updatedConfig = g.api.getConfiguration()
-			// @ts-expect-error - Property 'customCondensingPrompt' does not exist on type 'RooCodeSettings'.
-			assert.strictEqual(updatedConfig.customCondensingPrompt, "", "customCondensingPrompt was not cleared")
-		})
-
-		test("should clear customCondensingPrompt when set to undefined", async () => {
-			const initialPrompt = "Another prompt to be cleared."
-			// @ts-expect-error - Argument of type '{ customCondensingPrompt: string; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ customCondensingPrompt: initialPrompt })
-			await sleep(100)
-			let updatedConfig = g.api.getConfiguration()
-			assert.strictEqual(
-				// @ts-expect-error - Property 'customCondensingPrompt' does not exist on type 'RooCodeSettings'.
-				updatedConfig.customCondensingPrompt,
-				initialPrompt,
-				"Initial prompt for undefined test was not set",
-			)
-
-			// @ts-expect-error - Argument of type '{ customCondensingPrompt: undefined; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ customCondensingPrompt: undefined })
-			await sleep(100)
-			updatedConfig = g.api.getConfiguration()
-			// @ts-expect-error - Property 'customCondensingPrompt' does not exist on type 'RooCodeSettings'.
-			const currentPrompt = updatedConfig.customCondensingPrompt
-			assert.ok(
-				currentPrompt === "" || currentPrompt === undefined || currentPrompt === null,
-				"customCondensingPrompt was not cleared by undefined",
-			)
-		})
-	})
-
-	suite("Message Handling (Conceptual - Covered by Settings Persistence)", () => {
-		test.skip("should correctly update backend state from webview messages", () => {
-			assert.ok(true, "Skipping direct webview message test, covered by settings persistence.")
-		})
-	})
-
-	suite("API Configuration Resolution and Prompt Customization", () => {
-		let taskId: string | undefined
-
-		beforeEach(async () => {
-			// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-			const taskResponse = await g.api.tasks.createTask({
-				initialMessage: "This is the first message for a new task.",
-			})
-			taskId = taskResponse.taskId
-			assert.ok(taskId, "Task ID should be created")
-			await sleep(500)
-		})
-
-		afterEach(async () => {
-			if (taskId) {
-				taskId = undefined
-			}
-			// This directive was unused, meaning setConfiguration(initialConfig) is fine.
-			await g.api.setConfiguration(initialConfig)
-			await sleep(100)
-		})
-
-		test("should trigger condensation with default settings", async function () {
-			this.timeout(60000)
-			assert.ok(taskId, "Task ID must be defined for this test")
-
-			for (let i = 0; i < 5; i++) {
-				// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-				await g.api.tasks.sendMessage({
-					taskId: taskId!,
-					message: `This is message number ${i + 2} in the conversation.`,
-					messageType: "user",
-				})
-				await sleep(2000)
-			}
-
-			// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-			const task = await g.api.tasks.getTask(taskId!)
-			assert.ok(task, "Task should be retrievable")
-			const hasSummary = task.messages.some((msg: TestTaskMessage) => msg.isSummary === true)
-			console.log(
-				`Task messages for default settings test (taskId: ${taskId}):`,
-				JSON.stringify(task.messages, null, 2),
-			)
-			console.log(`Has summary (default settings): ${hasSummary}`)
-			assert.ok(
-				true,
-				"Condensation process completed with default settings (actual summary check is complex for e2e).",
-			)
-		})
-
-		test("should trigger condensation with custom condensing API config", async function () {
-			this.timeout(60000)
-			assert.ok(taskId, "Task ID must be defined for this test")
-
-			const customCondensingConfigId = "condensing-test-provider"
-			// This directive was unused. The error is on the property itself.
-			await g.api.setConfiguration({
-				// @ts-expect-error - condensingApiConfigId is not a known property in RooCodeSettings.
-				condensingApiConfigId: customCondensingConfigId,
-			})
-			await sleep(100)
-
-			for (let i = 0; i < 5; i++) {
-				// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-				await g.api.tasks.sendMessage({
-					taskId: taskId!,
-					message: `Message ${i + 2} with custom API config.`,
-					messageType: "user",
-				})
-				await sleep(2000)
-			}
-			// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-			const task = await g.api.tasks.getTask(taskId!)
-			assert.ok(task, "Task should be retrievable with custom API config")
-			const hasSummary = task.messages.some((msg: TestTaskMessage) => msg.isSummary === true)
-			console.log(
-				`Task messages for custom API config test (taskId: ${taskId}):`,
-				JSON.stringify(task.messages, null, 2),
-			)
-			console.log(`Has summary (custom API config): ${hasSummary}`)
-			assert.ok(
-				true,
-				"Condensation process completed with custom API config (specific handler verification is complex for e2e).",
-			)
-		})
-
-		test("should trigger condensation with custom condensing prompt", async function () {
-			this.timeout(60000)
-			assert.ok(taskId, "Task ID must be defined for this test")
-
-			const customPrompt = "E2E Test: Summarize this conversation very briefly."
-			// @ts-expect-error - Argument of type '{ customCondensingPrompt: string; }' is not assignable to parameter of type 'RooCodeSettings'.
-			await g.api.setConfiguration({ customCondensingPrompt: customPrompt })
-			await sleep(100)
-
-			for (let i = 0; i < 5; i++) {
-				// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-				await g.api.tasks.sendMessage({
-					taskId: taskId!,
-					message: `Message ${i + 2} with custom prompt.`,
-					messageType: "user",
-				})
-				await sleep(2000)
-			}
-
-			// @ts-expect-error - Property 'tasks' does not exist on type 'RooCodeAPI'.
-			const task = await g.api.tasks.getTask(taskId!)
-			assert.ok(task, "Task should be retrievable with custom prompt")
-			const summaryMessage = task.messages.find((msg: TestTaskMessage) => msg.isSummary === true)
-			console.log(
-				`Task messages for custom prompt test (taskId: ${taskId}):`,
-				JSON.stringify(task.messages, null, 2),
-			)
-			if (summaryMessage) {
-				console.log("Summary content with custom prompt:", summaryMessage.content)
-			}
-			assert.ok(
-				true,
-				"Condensation process completed with custom prompt (prompt content verification is complex for e2e).",
-			)
-		})
-	})
-})

+ 1 - 1
knip.json

@@ -12,8 +12,8 @@
 		"bin/**",
 		"apps/vscode-e2e/**",
 		"evals/**",
+		"src/extension/**",
 		"src/activate/**",
-		"src/exports/**",
 		"src/workers/**",
 		"src/schemas/ipc.ts",
 		"src/extension.ts",

+ 5 - 6
package.json

@@ -13,14 +13,13 @@
 		"check-types": "turbo check-types --log-order grouped --output-logs new-only",
 		"test": "turbo test --log-order grouped --output-logs new-only",
 		"format": "turbo format --log-order grouped --output-logs new-only",
+		"bundle": "turbo bundle --log-order grouped --output-logs new-only",
+		"bundle:nightly": "turbo bundle:nightly --log-order grouped --output-logs new-only",
+		"build": "turbo vsix --log-order grouped --output-logs new-only",
+		"build:nightly": "turbo vsix:nightly --log-order grouped --output-logs new-only",
 		"clean": "turbo clean --log-order grouped --output-logs new-only && rimraf dist out bin .vite-port .turbo",
-		"build": "pnpm --filter roo-cline vsix",
-		"compile": "pnpm --filter roo-cline bundle",
-		"vsix": "pnpm --filter roo-cline vsix",
-		"build:nightly": "pnpm --filter @roo-code/vscode-nightly vsix",
-		"generate-types": "pnpm --filter roo-cline generate-types",
 		"changeset:version": "cp CHANGELOG.md src/CHANGELOG.md && changeset version && cp -vf src/CHANGELOG.md .",
-		"knip": "pnpm --filter @roo-code/build build && knip --include files",
+		"knip": "knip --include files",
 		"update-contributors": "node scripts/update-contributors.js"
 	},
 	"devDependencies": {

+ 44 - 20
packages/build/src/esbuild.ts

@@ -3,13 +3,56 @@ import * as path from "path"
 
 import { ViewsContainer, Views, Menus, Configuration, contributesSchema } from "./types.js"
 
+function copyDir(srcDir: string, dstDir: string, count: number): number {
+	const entries = fs.readdirSync(srcDir, { withFileTypes: true })
+
+	for (const entry of entries) {
+		const srcPath = path.join(srcDir, entry.name)
+		const dstPath = path.join(dstDir, entry.name)
+
+		if (entry.isDirectory()) {
+			fs.mkdirSync(dstPath, { recursive: true })
+			count = copyDir(srcPath, dstPath, count)
+		} else {
+			count = count + 1
+			fs.copyFileSync(srcPath, dstPath)
+		}
+	}
+
+	return count
+}
+
+function rmDir(dirPath: string, maxRetries: number = 3): void {
+	for (let attempt = 1; attempt <= maxRetries; attempt++) {
+		try {
+			fs.rmSync(dirPath, { recursive: true, force: true })
+			return
+		} catch (error) {
+			const isLastAttempt = attempt === maxRetries
+			const isEnotemptyError = error instanceof Error && "code" in error && (error.code === 'ENOTEMPTY' || error.code === 'EBUSY')
+
+			if (isLastAttempt || !isEnotemptyError) {
+				throw error // Re-throw if it's the last attempt or not a locking error.
+			}
+
+			// Wait with exponential backoff before retrying.
+			const delay = Math.min(100 * Math.pow(2, attempt - 1), 1000) // Cap at 1s.
+			console.warn(`[rmDir] Attempt ${attempt} failed for ${dirPath}, retrying in ${delay}ms...`)
+
+			// Synchronous sleep for simplicity in build scripts.
+			const start = Date.now()
+			while (Date.now() - start < delay) { /* Busy wait */ }
+		}
+	}
+}
+
 export function copyPaths(copyPaths: [string, string][], srcDir: string, dstDir: string) {
 	copyPaths.forEach(([srcRelPath, dstRelPath]) => {
 		const stats = fs.lstatSync(path.join(srcDir, srcRelPath))
 
 		if (stats.isDirectory()) {
 			if (fs.existsSync(path.join(dstDir, dstRelPath))) {
-				fs.rmSync(path.join(dstDir, dstRelPath), { recursive: true })
+				rmDir(path.join(dstDir, dstRelPath))
 			}
 
 			fs.mkdirSync(path.join(dstDir, dstRelPath), { recursive: true })
@@ -23,25 +66,6 @@ export function copyPaths(copyPaths: [string, string][], srcDir: string, dstDir:
 	})
 }
 
-export function copyDir(srcDir: string, dstDir: string, count: number): number {
-	const entries = fs.readdirSync(srcDir, { withFileTypes: true })
-
-	for (const entry of entries) {
-		const srcPath = path.join(srcDir, entry.name)
-		const dstPath = path.join(dstDir, entry.name)
-
-		if (entry.isDirectory()) {
-			fs.mkdirSync(dstPath, { recursive: true })
-			count = copyDir(srcPath, dstPath, count)
-		} else {
-			count = count + 1
-			fs.copyFileSync(srcPath, dstPath)
-		}
-	}
-
-	return count
-}
-
 export function copyWasms(srcDir: string, distDir: string): void {
 	const nodeModulesDir = path.join(srcDir, "node_modules")
 

+ 1 - 1
packages/build/src/index.ts

@@ -1,2 +1,2 @@
 export { getGitSha } from "./git.js"
-export { copyPaths, copyDir, copyWasms, copyLocales, setupLocaleWatcher, generatePackageJson } from "./esbuild.js"
+export { copyPaths, copyWasms, copyLocales, setupLocaleWatcher, generatePackageJson } from "./esbuild.js"

+ 7 - 6
src/exports/README.md → packages/types/README.md

@@ -1,15 +1,16 @@
 # Roo Code API
 
-The Roo Code extension exposes an API that can be used by other extensions. To use this API in your extension:
+The Roo Code extension exposes an API that can be used by other extensions.
+To use this API in your extension:
 
-1. Copy `src/extension-api/roo-code.d.ts` to your extension's source directory.
-2. Include `roo-code.d.ts` in your extension's compilation.
-3. Get access to the API with the following code:
+1. Install `@roo-code/types` with npm, pnpm, or yarn.
+2. Import the `RooCodeAPI` type.
+3. Load the extension API.
 
 ```typescript
-import { RooCodeAPI, Package } from "path/to/roo-code"
+import { RooCodeAPI } from "@roo-code/types"
 
-const extension = vscode.extensions.getExtension<RooCodeAPI>(`${Package.publisher}.${Package.name}`)
+const extension = vscode.extensions.getExtension<RooCodeAPI>("RooVeterinaryInc.roo-cline")
 
 if (!extension?.isActive) {
 	throw new Error("Extension is not activated")

+ 4 - 0
packages/types/eslint.config.mjs

@@ -0,0 +1,4 @@
+import { config } from "@roo-code/config-eslint/base"
+
+/** @type {import("eslint").Linter.Config} */
+export default [...config]

+ 37 - 0
packages/types/package.json

@@ -0,0 +1,37 @@
+{
+	"name": "@roo-code/types",
+	"description": "Roo Code foundational types and schemas.",
+	"private": true,
+	"type": "module",
+	"main": "./dist/index.cjs",
+	"exports": {
+		".": {
+			"types": "./src/index.ts",
+			"import": "./src/index.ts",
+			"require": {
+				"types": "./dist/index.d.cts",
+				"default": "./dist/index.cjs"
+			}
+		}
+	},
+	"files": [
+		"dist"
+	],
+	"scripts": {
+		"lint": "eslint src --ext=ts --max-warnings=0",
+		"check-types": "tsc --noEmit",
+		"test": "vitest --globals --run",
+		"build": "tsup",
+		"clean": "rimraf dist .turbo"
+	},
+	"dependencies": {
+		"zod": "^3.24.2"
+	},
+	"devDependencies": {
+		"@roo-code/config-eslint": "workspace:^",
+		"@roo-code/config-typescript": "workspace:^",
+		"@types/node": "^22.15.20",
+		"tsup": "^8.3.5",
+		"vitest": "^3.1.3"
+	}
+}

+ 17 - 0
packages/types/src/__tests__/index.test.ts

@@ -0,0 +1,17 @@
+// npx vitest run src/__tests__/index.test.ts
+
+import { GLOBAL_STATE_KEYS } from "../index.js"
+
+describe("GLOBAL_STATE_KEYS", () => {
+	it("should contain provider settings keys", () => {
+		expect(GLOBAL_STATE_KEYS).toContain("autoApprovalEnabled")
+	})
+
+	it("should contain provider settings keys", () => {
+		expect(GLOBAL_STATE_KEYS).toContain("anthropicBaseUrl")
+	})
+
+	it("should not contain secret state keys", () => {
+		expect(GLOBAL_STATE_KEYS).not.toContain("openRouterApiKey")
+	})
+})

+ 24 - 73
src/exports/interface.ts → packages/types/src/api.ts

@@ -1,59 +1,37 @@
-import { EventEmitter } from "events"
-import { Socket } from "node:net"
-
-/**
- * Types
- */
+import type { EventEmitter } from "events"
+import type { Socket } from "net"
 
 import type {
-	GlobalSettings,
-	ProviderName,
-	ProviderSettings,
+	RooCodeSettings,
 	ProviderSettingsEntry,
-	ClineMessage,
-	TokenUsage,
-	RooCodeEvents,
-	IpcMessage,
-	TaskCommand,
-	TaskEvent,
-} from "./types"
-
-export type {
-	GlobalSettings,
-	ProviderName,
 	ProviderSettings,
-	ProviderSettingsEntry,
 	ClineMessage,
 	TokenUsage,
-	RooCodeEvents,
-	IpcMessage,
+	ToolUsage,
+	ToolName,
 	TaskCommand,
 	TaskEvent,
+	IpcMessage,
+} from "./index.js"
+import { IpcMessageType } from "./index.js"
+
+// TODO: Make sure this matches `RooCodeEvents` from `@roo-code/types`.
+export interface RooCodeAPIEvents {
+	message: [data: { taskId: string; action: "created" | "updated"; message: ClineMessage }]
+	taskCreated: [taskId: string]
+	taskStarted: [taskId: string]
+	taskModeSwitched: [taskId: string, mode: string]
+	taskPaused: [taskId: string]
+	taskUnpaused: [taskId: string]
+	taskAskResponded: [taskId: string]
+	taskAborted: [taskId: string]
+	taskSpawned: [parentTaskId: string, childTaskId: string]
+	taskCompleted: [taskId: string, tokenUsage: TokenUsage, toolUsage: ToolUsage]
+	taskTokenUsageUpdated: [taskId: string, tokenUsage: TokenUsage]
+	taskToolFailed: [taskId: string, toolName: ToolName, error: string]
 }
 
-/**
- * Enums
- */
-
-import { RooCodeEventName, IpcOrigin, IpcMessageType } from "../schemas"
-
-export { RooCodeEventName, IpcOrigin, IpcMessageType }
-
-/**
- * Constants
- */
-
-import { providerNames, Package } from "../schemas"
-
-export { providerNames, Package }
-
-/**
- * RooCodeAPI
- */
-
-export type RooCodeSettings = GlobalSettings & ProviderSettings
-
-export interface RooCodeAPI extends EventEmitter<RooCodeEvents> {
+export interface RooCodeAPI extends EventEmitter<RooCodeAPIEvents> {
 	/**
 	 * Starts a new task with an optional initial message and images.
 	 * @param task Optional initial task message.
@@ -71,84 +49,70 @@ export interface RooCodeAPI extends EventEmitter<RooCodeEvents> {
 		images?: string[]
 		newTab?: boolean
 	}): Promise<string>
-
 	/**
 	 * Resumes a task with the given ID.
 	 * @param taskId The ID of the task to resume.
 	 * @throws Error if the task is not found in the task history.
 	 */
 	resumeTask(taskId: string): Promise<void>
-
 	/**
 	 * Checks if a task with the given ID is in the task history.
 	 * @param taskId The ID of the task to check.
 	 * @returns True if the task is in the task history, false otherwise.
 	 */
 	isTaskInHistory(taskId: string): Promise<boolean>
-
 	/**
 	 * Returns the current task stack.
 	 * @returns An array of task IDs.
 	 */
 	getCurrentTaskStack(): string[]
-
 	/**
 	 * Clears the current task.
 	 */
 	clearCurrentTask(lastMessage?: string): Promise<void>
-
 	/**
 	 * Cancels the current task.
 	 */
 	cancelCurrentTask(): Promise<void>
-
 	/**
 	 * Sends a message to the current task.
 	 * @param message Optional message to send.
 	 * @param images Optional array of image data URIs (e.g., "data:image/webp;base64,...").
 	 */
 	sendMessage(message?: string, images?: string[]): Promise<void>
-
 	/**
 	 * Simulates pressing the primary button in the chat interface.
 	 */
 	pressPrimaryButton(): Promise<void>
-
 	/**
 	 * Simulates pressing the secondary button in the chat interface.
 	 */
 	pressSecondaryButton(): Promise<void>
-
 	/**
 	 * Returns true if the API is ready to use.
 	 */
 	isReady(): boolean
-
 	/**
 	 * Returns the current configuration.
 	 * @returns The current configuration.
 	 */
 	getConfiguration(): RooCodeSettings
-
 	/**
 	 * Sets the configuration for the current task.
 	 * @param values An object containing key-value pairs to set.
 	 */
 	setConfiguration(values: RooCodeSettings): Promise<void>
-
 	/**
 	 * Returns a list of all configured profile names
 	 * @returns Array of profile names
 	 */
 	getProfiles(): string[]
-
 	/**
 	 * Returns the profile entry for a given name
 	 * @param name The name of the profile
 	 * @returns The profile entry, or undefined if the profile does not exist
 	 */
 	getProfileEntry(name: string): ProviderSettingsEntry | undefined
-
 	/**
 	 * Creates a new API configuration profile
 	 * @param name The name of the profile
@@ -158,7 +122,6 @@ export interface RooCodeAPI extends EventEmitter<RooCodeEvents> {
 	 * @throws Error if the profile already exists
 	 */
 	createProfile(name: string, profile?: ProviderSettings, activate?: boolean): Promise<string>
-
 	/**
 	 * Updates an existing API configuration profile
 	 * @param name The name of the profile
@@ -168,7 +131,6 @@ export interface RooCodeAPI extends EventEmitter<RooCodeEvents> {
 	 * @throws Error if the profile does not exist
 	 */
 	updateProfile(name: string, profile: ProviderSettings, activate?: boolean): Promise<string | undefined>
-
 	/**
 	 * Creates a new API configuration profile or updates an existing one
 	 * @param name The name of the profile
@@ -177,20 +139,17 @@ export interface RooCodeAPI extends EventEmitter<RooCodeEvents> {
 	 * @returns The ID of the upserted profile
 	 */
 	upsertProfile(name: string, profile: ProviderSettings, activate?: boolean): Promise<string | undefined>
-
 	/**
 	 * Deletes a profile by name
 	 * @param name The name of the profile to delete
 	 * @throws Error if the profile does not exist
 	 */
 	deleteProfile(name: string): Promise<void>
-
 	/**
 	 * Returns the name of the currently active profile
 	 * @returns The profile name, or undefined if no profile is active
 	 */
 	getActiveProfile(): string | undefined
-
 	/**
 	 * Changes the active API configuration profile
 	 * @param name The name of the profile to activate
@@ -199,10 +158,6 @@ export interface RooCodeAPI extends EventEmitter<RooCodeEvents> {
 	setActiveProfile(name: string): Promise<string | undefined>
 }
 
-/**
- * RooCodeIpcServer
- */
-
 export type IpcServerEvents = {
 	[IpcMessageType.Connect]: [clientId: string]
 	[IpcMessageType.Disconnect]: [clientId: string]
@@ -212,12 +167,8 @@ export type IpcServerEvents = {
 
 export interface RooCodeIpcServer extends EventEmitter<IpcServerEvents> {
 	listen(): void
-
 	broadcast(message: IpcMessage): void
-
 	send(client: string | Socket, message: IpcMessage): void
-
 	get socketPath(): string
-
 	get isListening(): boolean
 }

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

@@ -0,0 +1,2 @@
+export * from "./types.js"
+export * from "./api.js"

+ 10 - 49
src/schemas/index.ts → packages/types/src/types.ts

@@ -1,30 +1,16 @@
-// Updates to this file will automatically propgate to src/exports/types.ts
-// via a pre-commit hook. If you want to update the types before committing you
-// can run `pnpm generate-types`.
-
 import { z } from "zod"
 
-import { Equals, Keys, AssertEqual } from "../utils/type-fu"
-
 /**
- * Extension
+ * TS
  */
 
-import { publisher, name, version } from "../package.json"
-
-// These ENV variables can be defined by ESBuild when building the extension
-// in order to override the values in package.json. This allows us to build
-// different extension variants with the same package.json file.
-// The build process still needs to emit a modified package.json for consumption
-// by VSCode, but that build artifact is not used during the transpile step of
-// the build, so we still need this override mechanism.
-export const Package = {
-	publisher,
-	name: process.env.PKG_NAME || name,
-	version: process.env.PKG_VERSION || version,
-	outputChannel: process.env.PKG_OUTPUT_CHANNEL || "Roo-Code",
-	sha: process.env.PKG_SHA,
-} as const
+export type Keys<T> = keyof T
+
+export type Values<T> = T[keyof T]
+
+export type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false
+
+export type AssertEqual<T extends true> = T
 
 /**
  * CodeAction
@@ -244,7 +230,7 @@ export const codebaseIndexModelsSchema = z.object({
 export type CodebaseIndexModels = z.infer<typeof codebaseIndexModelsSchema>
 
 export const codebaseIndexProviderSchema = z.object({
-  codeIndexOpenAiKey: z.string().optional(),
+	codeIndexOpenAiKey: z.string().optional(),
 	codeIndexQdrantApiKey: z.string().optional(),
 })
 
@@ -661,7 +647,7 @@ export const providerSettingsSchema = z.object({
 	...groqSchema.shape,
 	...chutesSchema.shape,
 	...litellmSchema.shape,
-  ...codebaseIndexProviderSchema.shape
+	...codebaseIndexProviderSchema.shape,
 })
 
 export type ProviderSettings = z.infer<typeof providerSettingsSchema>
@@ -1356,28 +1342,3 @@ export const ipcMessageSchema = z.discriminatedUnion("type", [
 ])
 
 export type IpcMessage = z.infer<typeof ipcMessageSchema>
-
-/**
- * TypeDefinition
- */
-
-export type TypeDefinition = {
-	schema: z.ZodTypeAny
-	identifier: string
-}
-
-export const typeDefinitions: TypeDefinition[] = [
-	{ schema: globalSettingsSchema, identifier: "GlobalSettings" },
-	{ schema: providerNamesSchema, identifier: "ProviderName" },
-	{ schema: providerSettingsSchema, identifier: "ProviderSettings" },
-	{ schema: providerSettingsEntrySchema, identifier: "ProviderSettingsEntry" },
-	{ schema: clineMessageSchema, identifier: "ClineMessage" },
-	{ schema: tokenUsageSchema, identifier: "TokenUsage" },
-	{ schema: rooCodeEventsSchema, identifier: "RooCodeEvents" },
-	{ schema: ipcMessageSchema, identifier: "IpcMessage" },
-	{ schema: taskCommandSchema, identifier: "TaskCommand" },
-	{ schema: taskEventSchema, identifier: "TaskEvent" },
-]
-
-// Also export as default for ESM compatibility.
-export default { typeDefinitions }

+ 9 - 0
packages/types/tsconfig.json

@@ -0,0 +1,9 @@
+{
+	"extends": "@roo-code/config-typescript/base.json",
+	"compilerOptions": {
+		"types": ["vitest/globals"],
+		"outDir": "dist"
+	},
+	"include": ["src"],
+	"exclude": ["node_modules"]
+}

+ 11 - 0
packages/types/tsup.config.ts

@@ -0,0 +1,11 @@
+import { defineConfig } from "tsup"
+
+export default defineConfig({
+	entry: ["src/index.ts"],
+	format: ["cjs", "esm"],
+	dts: true,
+	clean: false,
+	splitting: false,
+	sourcemap: true,
+	outDir: "dist",
+})

Разница между файлами не показана из-за своего большого размера
+ 342 - 314
pnpm-lock.yaml


+ 2 - 1
src/activate/CodeActionProvider.ts

@@ -1,6 +1,7 @@
 import * as vscode from "vscode"
 
-import { CodeActionName, CodeActionId } from "../schemas"
+import { CodeActionName, CodeActionId } from "@roo-code/types"
+
 import { getCodeActionCommand } from "../utils/commands"
 import { EditorUtils } from "../integrations/editor/EditorUtils"
 

+ 1 - 1
src/activate/handleTask.ts

@@ -1,6 +1,6 @@
 import * as vscode from "vscode"
 
-import { Package } from "../schemas"
+import { Package } from "../shared/package"
 import { ClineProvider } from "../core/webview/ClineProvider"
 import { t } from "../i18n"
 

+ 2 - 1
src/activate/registerCodeActions.ts

@@ -1,6 +1,7 @@
 import * as vscode from "vscode"
 
-import { CodeActionId, CodeActionName } from "../schemas"
+import { CodeActionId, CodeActionName } from "@roo-code/types"
+
 import { getCodeActionCommand } from "../utils/commands"
 import { EditorUtils } from "../integrations/editor/EditorUtils"
 import { ClineProvider } from "../core/webview/ClineProvider"

+ 3 - 1
src/activate/registerCommands.ts

@@ -1,7 +1,9 @@
 import * as vscode from "vscode"
 import delay from "delay"
 
-import { CommandId, Package } from "../schemas"
+import type { CommandId } from "@roo-code/types"
+
+import { Package } from "../shared/package"
 import { getCommand } from "../utils/commands"
 import { ClineProvider } from "../core/webview/ClineProvider"
 import { ContextProxy } from "../core/config/ContextProxy"

+ 2 - 1
src/activate/registerTerminalActions.ts

@@ -1,6 +1,7 @@
 import * as vscode from "vscode"
 
-import { TerminalActionId, TerminalActionPromptType } from "../schemas"
+import { TerminalActionId, TerminalActionPromptType } from "@roo-code/types"
+
 import { getTerminalCommand } from "../utils/commands"
 import { ClineProvider } from "../core/webview/ClineProvider"
 import { Terminal } from "../integrations/terminal/Terminal"

+ 30 - 28
src/api/index.ts

@@ -1,29 +1,33 @@
 import { Anthropic } from "@anthropic-ai/sdk"
 
-import { ProviderSettings, ModelInfo } from "../shared/api"
-import { GlamaHandler } from "./providers/glama"
-import { AnthropicHandler } from "./providers/anthropic"
-import { AwsBedrockHandler } from "./providers/bedrock"
-import { OpenRouterHandler } from "./providers/openrouter"
-import { VertexHandler } from "./providers/vertex"
-import { AnthropicVertexHandler } from "./providers/anthropic-vertex"
-import { OpenAiHandler } from "./providers/openai"
-import { OllamaHandler } from "./providers/ollama"
-import { LmStudioHandler } from "./providers/lmstudio"
-import { GeminiHandler } from "./providers/gemini"
-import { OpenAiNativeHandler } from "./providers/openai-native"
-import { DeepSeekHandler } from "./providers/deepseek"
-import { MistralHandler } from "./providers/mistral"
-import { VsCodeLmHandler } from "./providers/vscode-lm"
+import type { ProviderSettings, ModelInfo } from "@roo-code/types"
+
 import { ApiStream } from "./transform/stream"
-import { UnboundHandler } from "./providers/unbound"
-import { RequestyHandler } from "./providers/requesty"
-import { HumanRelayHandler } from "./providers/human-relay"
-import { FakeAIHandler } from "./providers/fake-ai"
-import { XAIHandler } from "./providers/xai"
-import { GroqHandler } from "./providers/groq"
-import { ChutesHandler } from "./providers/chutes"
-import { LiteLLMHandler } from "./providers/litellm"
+
+import {
+	GlamaHandler,
+	AnthropicHandler,
+	AwsBedrockHandler,
+	OpenRouterHandler,
+	VertexHandler,
+	AnthropicVertexHandler,
+	OpenAiHandler,
+	OllamaHandler,
+	LmStudioHandler,
+	GeminiHandler,
+	OpenAiNativeHandler,
+	DeepSeekHandler,
+	MistralHandler,
+	VsCodeLmHandler,
+	UnboundHandler,
+	RequestyHandler,
+	HumanRelayHandler,
+	FakeAIHandler,
+	XAIHandler,
+	GroqHandler,
+	ChutesHandler,
+	LiteLLMHandler,
+} from "./providers"
 
 export interface SingleCompletionHandler {
 	completePrompt(prompt: string): Promise<string>
@@ -67,11 +71,9 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
 		case "bedrock":
 			return new AwsBedrockHandler(options)
 		case "vertex":
-			if (options.apiModelId?.startsWith("claude")) {
-				return new AnthropicVertexHandler(options)
-			} else {
-				return new VertexHandler(options)
-			}
+			return options.apiModelId?.startsWith("claude")
+				? new AnthropicVertexHandler(options)
+				: new VertexHandler(options)
 		case "openai":
 			return new OpenAiHandler(options)
 		case "ollama":

+ 3 - 1
src/api/providers/__tests__/gemini.test.ts

@@ -2,8 +2,10 @@
 
 import { Anthropic } from "@anthropic-ai/sdk"
 
+import type { ModelInfo } from "@roo-code/types"
+
+import { geminiDefaultModelId } from "../../../shared/api"
 import { GeminiHandler } from "../gemini"
-import { geminiDefaultModelId, type ModelInfo } from "../../../shared/api"
 
 const GEMINI_20_FLASH_THINKING_NAME = "gemini-2.0-flash-thinking-exp-1219"
 

+ 3 - 1
src/api/providers/anthropic-vertex.ts

@@ -2,7 +2,9 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import { AnthropicVertex } from "@anthropic-ai/vertex-sdk"
 import { GoogleAuth, JWTInput } from "google-auth-library"
 
-import { ApiHandlerOptions, ModelInfo, vertexDefaultModelId, VertexModelId, vertexModels } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, vertexDefaultModelId, VertexModelId, vertexModels } from "../../shared/api"
 import { safeJsonParse } from "../../shared/safeJsonParse"
 
 import { ApiStream } from "../transform/stream"

+ 3 - 7
src/api/providers/anthropic.ts

@@ -2,13 +2,9 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming"
 import { CacheControlEphemeral } from "@anthropic-ai/sdk/resources"
 
-import {
-	anthropicDefaultModelId,
-	AnthropicModelId,
-	anthropicModels,
-	ApiHandlerOptions,
-	ModelInfo,
-} from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { anthropicDefaultModelId, AnthropicModelId, anthropicModels, ApiHandlerOptions } from "../../shared/api"
 
 import { ApiStream } from "../transform/stream"
 import { getModelParams } from "../transform/model-params"

+ 3 - 1
src/api/providers/base-openai-compatible-provider.ts

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

+ 1 - 1
src/api/providers/base-provider.ts

@@ -1,6 +1,6 @@
 import { Anthropic } from "@anthropic-ai/sdk"
 
-import { ModelInfo } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
 
 import type { ApiHandler, ApiHandlerCreateMessageMetadata } from "../index"
 import { ApiStream } from "../transform/stream"

+ 8 - 11
src/api/providers/bedrock.ts

@@ -9,18 +9,18 @@ import {
 } from "@aws-sdk/client-bedrock-runtime"
 import { fromIni } from "@aws-sdk/credential-providers"
 import { Anthropic } from "@anthropic-ai/sdk"
+
+import type { ModelInfo, ProviderSettings } from "@roo-code/types"
+
 import {
 	BedrockModelId,
-	ModelInfo as SharedModelInfo,
 	bedrockDefaultModelId,
 	bedrockModels,
 	bedrockDefaultPromptRouterModelId,
 } from "../../shared/api"
-import { ProviderSettings } from "../../schemas"
 import { ApiStream } from "../transform/stream"
 import { BaseProvider } from "./base-provider"
 import { logger } from "../../utils/logging"
-// New cache-related imports
 import { MultiPointStrategy } from "../transform/cache-strategy/multi-point-strategy"
 import { ModelInfo as CacheModelInfo } from "../transform/cache-strategy/types"
 import { AMAZON_BEDROCK_REGION_INFO } from "../../shared/aws_regions"
@@ -514,7 +514,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
 	 *
 	 *************************************************************************************/
 
-	private costModelConfig: { id: BedrockModelId | string; info: SharedModelInfo } = {
+	private costModelConfig: { id: BedrockModelId | string; info: ModelInfo } = {
 		id: "",
 		info: { maxTokens: 0, contextWindow: 0, supportsPromptCache: false, supportsImages: false },
 	}
@@ -621,7 +621,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
 	}
 
 	//Prompt Router responses come back in a different sequence and the model used is in the response and must be fetched by name
-	getModelById(modelId: string, modelType?: string): { id: BedrockModelId | string; info: SharedModelInfo } {
+	getModelById(modelId: string, modelType?: string): { id: BedrockModelId | string; info: ModelInfo } {
 		// Try to find the model in bedrockModels
 		const baseModelId = this.parseBaseModelId(modelId) as BedrockModelId
 
@@ -651,7 +651,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
 		return model
 	}
 
-	override getModel(): { id: BedrockModelId | string; info: SharedModelInfo } {
+	override getModel(): { id: BedrockModelId | string; info: ModelInfo } {
 		if (this.costModelConfig?.id?.trim().length > 0) {
 			return this.costModelConfig
 		}
@@ -683,7 +683,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
 
 		modelConfig.info.maxTokens = modelConfig.info.maxTokens || BEDROCK_MAX_TOKENS
 
-		return modelConfig as { id: BedrockModelId | string; info: SharedModelInfo }
+		return modelConfig as { id: BedrockModelId | string; info: ModelInfo }
 	}
 
 	/************************************************************************************
@@ -695,10 +695,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
 	// Store previous cache point placements for maintaining consistency across consecutive messages
 	private previousCachePointPlacements: { [conversationId: string]: any[] } = {}
 
-	private supportsAwsPromptCache(modelConfig: {
-		id: BedrockModelId | string
-		info: SharedModelInfo
-	}): boolean | undefined {
+	private supportsAwsPromptCache(modelConfig: { id: BedrockModelId | string; info: ModelInfo }): boolean | undefined {
 		// Check if the model supports prompt cache
 		// The cachableFields property is not part of the ModelInfo type in schemas
 		// but it's used in the bedrockModels object in shared/api.ts

+ 5 - 2
src/api/providers/fake-ai.ts

@@ -1,7 +1,10 @@
 import { Anthropic } from "@anthropic-ai/sdk"
-import { ApiHandlerOptions, ModelInfo } from "../../shared/api"
-import { ApiStream } from "../transform/stream"
+
+import type { ModelInfo } from "@roo-code/types"
+
 import type { ApiHandler, SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
+import type { ApiHandlerOptions } from "../../shared/api"
+import { ApiStream } from "../transform/stream"
 
 interface FakeAI {
 	/**

+ 3 - 2
src/api/providers/fetchers/glama.ts

@@ -1,7 +1,8 @@
 import axios from "axios"
 
-import { ModelInfo } from "../../../shared/api"
-import { parseApiPrice } from "../../../utils/cost"
+import type { ModelInfo } from "@roo-code/types"
+
+import { parseApiPrice } from "../../../shared/cost"
 
 export async function getGlamaModels(): Promise<Record<string, ModelInfo>> {
 	const models: Record<string, ModelInfo> = {}

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

@@ -1,4 +1,5 @@
 import axios from "axios"
+
 import { OPEN_ROUTER_COMPUTER_USE_MODELS, ModelRecord } from "../../../shared/api"
 
 /**

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

@@ -1,16 +1,16 @@
 import axios from "axios"
 import { z } from "zod"
 
-import { isModelParameter } from "../../../schemas"
+import { type ModelInfo, isModelParameter } from "@roo-code/types"
+
 import {
 	ApiHandlerOptions,
-	ModelInfo,
 	OPEN_ROUTER_COMPUTER_USE_MODELS,
 	OPEN_ROUTER_REASONING_BUDGET_MODELS,
 	OPEN_ROUTER_REQUIRED_REASONING_BUDGET_MODELS,
 	anthropicModels,
 } from "../../../shared/api"
-import { parseApiPrice } from "../../../utils/cost"
+import { parseApiPrice } from "../../../shared/cost"
 
 /**
  * OpenRouterBaseModel

+ 3 - 2
src/api/providers/fetchers/requesty.ts

@@ -1,7 +1,8 @@
 import axios from "axios"
 
-import { ModelInfo } from "../../../shared/api"
-import { parseApiPrice } from "../../../utils/cost"
+import type { ModelInfo } from "@roo-code/types"
+
+import { parseApiPrice } from "../../../shared/cost"
 
 export async function getRequestyModels(apiKey?: string): Promise<Record<string, ModelInfo>> {
 	const models: Record<string, ModelInfo> = {}

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

@@ -1,6 +1,6 @@
 import axios from "axios"
 
-import { ModelInfo } from "../../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
 
 export async function getUnboundModels(apiKey?: string | null): Promise<Record<string, ModelInfo>> {
 	const models: Record<string, ModelInfo> = {}

+ 5 - 2
src/api/providers/gemini.ts

@@ -7,12 +7,15 @@ import {
 } from "@google/genai"
 import type { JWTInput } from "google-auth-library"
 
-import { ApiHandlerOptions, ModelInfo, GeminiModelId, geminiDefaultModelId, geminiModels } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, GeminiModelId, geminiDefaultModelId, geminiModels } from "../../shared/api"
 import { safeJsonParse } from "../../shared/safeJsonParse"
 
-import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 import { convertAnthropicContentToGemini, convertAnthropicMessageToGemini } from "../transform/gemini-format"
 import type { ApiStream } from "../transform/stream"
+
+import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 import { BaseProvider } from "./base-provider"
 
 type GeminiHandlerOptions = ApiHandlerOptions & {

+ 1 - 1
src/api/providers/glama.ts

@@ -2,7 +2,7 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import axios from "axios"
 import OpenAI from "openai"
 
-import { Package } from "../../schemas"
+import { Package } from "../../shared/package"
 import { ApiHandlerOptions, glamaDefaultModelId, glamaDefaultModelInfo } from "../../shared/api"
 
 import { ApiStream } from "../transform/stream"

+ 4 - 1
src/api/providers/human-relay.ts

@@ -1,10 +1,13 @@
 import { Anthropic } from "@anthropic-ai/sdk"
 import * as vscode from "vscode"
 
-import { ModelInfo } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
 import { getCommand } from "../../utils/commands"
 import { ApiStream } from "../transform/stream"
+
 import type { ApiHandler, SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
+
 /**
  * Human Relay API processor
  * This processor does not directly call the API, but interacts with the model through human operations copy and paste.

+ 22 - 0
src/api/providers/index.ts

@@ -0,0 +1,22 @@
+export { GlamaHandler } from "./glama"
+export { AnthropicHandler } from "./anthropic"
+export { AwsBedrockHandler } from "./bedrock"
+export { OpenRouterHandler } from "./openrouter"
+export { VertexHandler } from "./vertex"
+export { AnthropicVertexHandler } from "./anthropic-vertex"
+export { OpenAiHandler } from "./openai"
+export { OllamaHandler } from "./ollama"
+export { LmStudioHandler } from "./lmstudio"
+export { GeminiHandler } from "./gemini"
+export { OpenAiNativeHandler } from "./openai-native"
+export { DeepSeekHandler } from "./deepseek"
+export { MistralHandler } from "./mistral"
+export { VsCodeLmHandler } from "./vscode-lm"
+export { UnboundHandler } from "./unbound"
+export { RequestyHandler } from "./requesty"
+export { HumanRelayHandler } from "./human-relay"
+export { FakeAIHandler } from "./fake-ai"
+export { XAIHandler } from "./xai"
+export { GroqHandler } from "./groq"
+export { ChutesHandler } from "./chutes"
+export { LiteLLMHandler } from "./litellm"

+ 6 - 2
src/api/providers/lmstudio.ts

@@ -2,11 +2,15 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import OpenAI from "openai"
 import axios from "axios"
 
-import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, openAiModelInfoSaneDefaults } from "../../shared/api"
+import { XmlMatcher } from "../../utils/xml-matcher"
+
 import { convertToOpenAiMessages } from "../transform/openai-format"
 import { ApiStream } from "../transform/stream"
+
 import { BaseProvider } from "./base-provider"
-import { XmlMatcher } from "../../utils/xml-matcher"
 import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 
 const LMSTUDIO_DEFAULT_TEMPERATURE = 0

+ 5 - 1
src/api/providers/mistral.ts

@@ -1,8 +1,12 @@
 import { Anthropic } from "@anthropic-ai/sdk"
 import { Mistral } from "@mistralai/mistralai"
-import { ApiHandlerOptions, mistralDefaultModelId, MistralModelId, mistralModels, ModelInfo } from "../../shared/api"
+
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, mistralDefaultModelId, MistralModelId, mistralModels } from "../../shared/api"
 import { convertToMistralMessages } from "../transform/mistral-format"
 import { ApiStream } from "../transform/stream"
+
 import { BaseProvider } from "./base-provider"
 import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 

+ 7 - 3
src/api/providers/ollama.ts

@@ -2,14 +2,18 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import OpenAI from "openai"
 import axios from "axios"
 
-import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
-import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, openAiModelInfoSaneDefaults } from "../../shared/api"
+import { XmlMatcher } from "../../utils/xml-matcher"
+
 import { convertToOpenAiMessages } from "../transform/openai-format"
 import { convertToR1Format } from "../transform/r1-format"
 import { ApiStream } from "../transform/stream"
+
 import { DEEP_SEEK_DEFAULT_TEMPERATURE } from "./constants"
-import { XmlMatcher } from "../../utils/xml-matcher"
 import { BaseProvider } from "./base-provider"
+import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 
 // Alias for the usage object returned in streaming chunks
 type CompletionUsage = OpenAI.Chat.Completions.ChatCompletionChunk["usage"]

+ 4 - 3
src/api/providers/openai-native.ts

@@ -1,22 +1,23 @@
 import { Anthropic } from "@anthropic-ai/sdk"
 import OpenAI from "openai"
 
+import type { ModelInfo } from "@roo-code/types"
+
 import {
 	ApiHandlerOptions,
-	ModelInfo,
 	openAiNativeDefaultModelId,
 	OpenAiNativeModelId,
 	openAiNativeModels,
 } from "../../shared/api"
 
-import { calculateApiCostOpenAI } from "../../utils/cost"
+import { calculateApiCostOpenAI } from "../../shared/cost"
 
 import { convertToOpenAiMessages } from "../transform/openai-format"
 import { ApiStream } from "../transform/stream"
 import { getModelParams } from "../transform/model-params"
 
-import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 import { BaseProvider } from "./base-provider"
+import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 
 const OPENAI_NATIVE_DEFAULT_TEMPERATURE = 0
 

+ 4 - 7
src/api/providers/openai.ts

@@ -2,12 +2,9 @@ import { Anthropic } from "@anthropic-ai/sdk"
 import OpenAI, { AzureOpenAI } from "openai"
 import axios from "axios"
 
-import {
-	ApiHandlerOptions,
-	azureOpenAiDefaultApiVersion,
-	ModelInfo,
-	openAiModelInfoSaneDefaults,
-} from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, azureOpenAiDefaultApiVersion, openAiModelInfoSaneDefaults } from "../../shared/api"
 
 import { XmlMatcher } from "../../utils/xml-matcher"
 
@@ -18,8 +15,8 @@ import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
 import { getModelParams } from "../transform/model-params"
 
 import { DEFAULT_HEADERS, DEEP_SEEK_DEFAULT_TEMPERATURE } from "./constants"
-import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 import { BaseProvider } from "./base-provider"
+import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 
 export const AZURE_AI_INFERENCE_PATH = "/models/chat/completions"
 

+ 10 - 11
src/api/providers/requesty.ts

@@ -1,19 +1,18 @@
 import { Anthropic } from "@anthropic-ai/sdk"
-import {
-	ApiHandlerOptions,
-	ModelInfo,
-	ModelRecord,
-	requestyDefaultModelId,
-	requestyDefaultModelInfo,
-} from "../../shared/api"
+import OpenAI from "openai"
+
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, ModelRecord, requestyDefaultModelId, requestyDefaultModelInfo } from "../../shared/api"
+import { calculateApiCostOpenAI } from "../../shared/cost"
+
 import { convertToOpenAiMessages } from "../transform/openai-format"
-import { calculateApiCostOpenAI } from "../../utils/cost"
 import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
-import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../"
-import { BaseProvider } from "./base-provider"
+
 import { DEFAULT_HEADERS } from "./constants"
 import { getModels } from "./fetchers/modelCache"
-import OpenAI from "openai"
+import { BaseProvider } from "./base-provider"
+import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../"
 
 // Requesty usage includes an extra field for Anthropic use cases.
 // Safely cast the prompt token details section to the appropriate structure.

+ 4 - 1
src/api/providers/router-provider.ts

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

+ 4 - 2
src/api/providers/vertex.ts

@@ -1,7 +1,9 @@
-import { ApiHandlerOptions, ModelInfo, VertexModelId, vertexDefaultModelId, vertexModels } from "../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandlerOptions, VertexModelId, vertexDefaultModelId, vertexModels } from "../../shared/api"
 
-import { SingleCompletionHandler } from "../index"
 import { GeminiHandler } from "./gemini"
+import { SingleCompletionHandler } from "../index"
 
 export class VertexHandler extends GeminiHandler implements SingleCompletionHandler {
 	constructor(options: ApiHandlerOptions) {

+ 7 - 3
src/api/providers/vscode-lm.ts

@@ -1,12 +1,16 @@
 import { Anthropic } from "@anthropic-ai/sdk"
 import * as vscode from "vscode"
 
+import type { ModelInfo } from "@roo-code/types"
+
+import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "../../shared/vsCodeSelectorUtils"
+import { ApiHandlerOptions, openAiModelInfoSaneDefaults } from "../../shared/api"
+
 import { ApiStream } from "../transform/stream"
 import { convertToVsCodeLmMessages } from "../transform/vscode-lm-format"
-import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "../../shared/vsCodeSelectorUtils"
-import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api"
+
 import { BaseProvider } from "./base-provider"
-import type { SingleCompletionHandler, ApiHandler, ApiHandlerCreateMessageMetadata } from "../index"
+import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
 
 /**
  * Handles interaction with VS Code's Language Model API for chat-based operations.

+ 3 - 2
src/api/transform/__tests__/image-cleaning.test.ts

@@ -1,7 +1,8 @@
-import { ApiHandler } from "../.."
+import type { ModelInfo } from "@roo-code/types"
+
+import { ApiHandler } from "../../index"
 import { ApiMessage } from "../../../core/task-persistence/apiMessages"
 import { maybeRemoveImageBlocks } from "../image-cleaning"
-import { ModelInfo } from "../../../shared/api"
 
 describe("maybeRemoveImageBlocks", () => {
 	// Mock ApiHandler factory function

+ 2 - 1
src/api/transform/__tests__/model-params.test.ts

@@ -1,6 +1,7 @@
 // npx jest src/api/transform/__tests__/model-params.test.ts
 
-import { ModelInfo } from "../../../schemas"
+import type { ModelInfo } from "@roo-code/types"
+
 import { ANTHROPIC_DEFAULT_MAX_TOKENS } from "../../providers/constants"
 
 import { getModelParams } from "../model-params"

+ 2 - 1
src/api/transform/__tests__/reasoning.test.ts

@@ -1,6 +1,7 @@
 // npx jest src/api/transform/__tests__/reasoning.test.ts
 
-import { ModelInfo, ProviderSettings } from "../../../schemas"
+import type { ModelInfo, ProviderSettings } from "@roo-code/types"
+
 import {
 	getOpenRouterReasoning,
 	getAnthropicReasoning,

+ 2 - 1
src/api/transform/image-cleaning.ts

@@ -1,6 +1,7 @@
-import { ApiHandler } from ".."
 import { ApiMessage } from "../../core/task-persistence/apiMessages"
 
+import { ApiHandler } from "../index"
+
 /* Removes image blocks from messages if they are not supported by the Api Handler */
 export function maybeRemoveImageBlocks(messages: ApiMessage[], apiHandler: ApiHandler): ApiMessage[] {
 	return messages.map((message) => {

+ 3 - 6
src/api/transform/model-params.ts

@@ -1,10 +1,7 @@
+import type { ModelInfo, ProviderSettings } from "@roo-code/types"
+
 import { ANTHROPIC_DEFAULT_MAX_TOKENS } from "../providers/constants"
-import {
-	shouldUseReasoningBudget,
-	shouldUseReasoningEffort,
-	type ModelInfo,
-	type ProviderSettings,
-} from "../../shared/api"
+import { shouldUseReasoningBudget, shouldUseReasoningEffort } from "../../shared/api"
 
 import {
 	type AnthropicReasoningParams,

+ 2 - 1
src/api/transform/reasoning.ts

@@ -1,7 +1,8 @@
 import { BetaThinkingConfigParam } from "@anthropic-ai/sdk/resources/beta"
 import OpenAI from "openai"
 
-import { ModelInfo, ProviderSettings } from "../../schemas"
+import type { ModelInfo, ProviderSettings } from "@roo-code/types"
+
 import { shouldUseReasoningBudget, shouldUseReasoningEffort } from "../../shared/api"
 
 type ReasoningEffort = "low" | "medium" | "high"

+ 2 - 1
src/core/assistant-message/parseAssistantMessage.ts

@@ -1,5 +1,6 @@
+import { type ToolName, toolNames } from "@roo-code/types"
+
 import { TextContent, ToolUse, ToolParamName, toolParamNames } from "../../shared/tools"
-import { toolNames, ToolName } from "../../schemas"
 
 export type AssistantMessageContent = TextContent | ToolUse
 

+ 2 - 1
src/core/assistant-message/parseAssistantMessageV2.ts

@@ -1,5 +1,6 @@
+import { type ToolName, toolNames } from "@roo-code/types"
+
 import { TextContent, ToolUse, ToolParamName, toolParamNames } from "../../shared/tools"
-import { toolNames, ToolName } from "../../schemas"
 
 export type AssistantMessageContent = TextContent | ToolUse
 

+ 1 - 2
src/core/assistant-message/presentAssistantMessage.ts

@@ -1,11 +1,10 @@
 import cloneDeep from "clone-deep"
 import { serializeError } from "serialize-error"
 
-import type { ToolName } from "../../schemas"
+import type { ToolName, ClineAsk, ToolProgressStatus } from "@roo-code/types"
 
 import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
 import type { ToolParamName, ToolResponse } from "../../shared/tools"
-import type { ClineAsk, ToolProgressStatus } from "../../shared/ExtensionMessage"
 
 import { telemetryService } from "../../services/telemetry/TelemetryService"
 

+ 7 - 6
src/core/config/ContextProxy.ts

@@ -6,15 +6,16 @@ import {
 	GLOBAL_SETTINGS_KEYS,
 	SECRET_STATE_KEYS,
 	GLOBAL_STATE_KEYS,
-	ProviderSettings,
-	GlobalSettings,
-	SecretState,
-	GlobalState,
-	RooCodeSettings,
+	type ProviderSettings,
+	type GlobalSettings,
+	type SecretState,
+	type GlobalState,
+	type RooCodeSettings,
 	providerSettingsSchema,
 	globalSettingsSchema,
 	isSecretStateKey,
-} from "../../schemas"
+} from "@roo-code/types"
+
 import { logger } from "../../utils/logging"
 import { telemetryService } from "../../services/telemetry/TelemetryService"
 

+ 5 - 3
src/core/config/CustomModesManager.ts

@@ -1,13 +1,15 @@
 import * as vscode from "vscode"
 import * as path from "path"
 import * as fs from "fs/promises"
-import { customModesSettingsSchema } from "../../schemas"
-import { ModeConfig } from "../../shared/modes"
+
+import * as yaml from "yaml"
+
+import { type ModeConfig, customModesSettingsSchema } from "@roo-code/types"
+
 import { fileExistsAtPath } from "../../utils/fs"
 import { arePathsEqual, getWorkspacePath } from "../../utils/path"
 import { logger } from "../../utils/logging"
 import { GlobalFileNames } from "../../shared/globalFileNames"
-import * as yaml from "yaml"
 
 const ROOMODES_FILENAME = ".roomodes"
 

+ 6 - 1
src/core/config/ProviderSettingsManager.ts

@@ -1,7 +1,12 @@
 import { ExtensionContext } from "vscode"
 import { z, ZodError } from "zod"
 
-import { providerSettingsSchema, ProviderSettingsEntry, providerSettingsSchemaDiscriminated } from "../../schemas"
+import {
+	type ProviderSettingsEntry,
+	providerSettingsSchema,
+	providerSettingsSchemaDiscriminated,
+} from "@roo-code/types"
+
 import { Mode, modes } from "../../shared/modes"
 import { telemetryService } from "../../services/telemetry/TelemetryService"
 

+ 3 - 2
src/core/config/__tests__/ContextProxy.test.ts

@@ -1,9 +1,10 @@
 // npx jest src/core/config/__tests__/ContextProxy.test.ts
 
 import * as vscode from "vscode"
-import { ContextProxy } from "../ContextProxy"
 
-import { GLOBAL_STATE_KEYS, SECRET_STATE_KEYS } from "../../../schemas"
+import { GLOBAL_STATE_KEYS, SECRET_STATE_KEYS } from "@roo-code/types"
+
+import { ContextProxy } from "../ContextProxy"
 
 jest.mock("vscode", () => ({
 	Uri: {

+ 7 - 3
src/core/config/__tests__/CustomModesManager.test.ts

@@ -3,12 +3,16 @@
 import * as vscode from "vscode"
 import * as path from "path"
 import * as fs from "fs/promises"
-import { CustomModesManager } from "../CustomModesManager"
-import { ModeConfig } from "../../../shared/modes"
+
+import * as yaml from "yaml"
+
+import type { ModeConfig } from "@roo-code/types"
+
 import { fileExistsAtPath } from "../../../utils/fs"
 import { getWorkspacePath, arePathsEqual } from "../../../utils/path"
 import { GlobalFileNames } from "../../../shared/globalFileNames"
-import * as yaml from "yaml"
+
+import { CustomModesManager } from "../CustomModesManager"
 
 jest.mock("vscode")
 jest.mock("fs/promises")

+ 2 - 2
src/core/config/__tests__/CustomModesSettings.test.ts

@@ -1,9 +1,9 @@
 // npx jest src/core/config/__tests__/CustomModesSettings.test.ts
 
-import { customModesSettingsSchema } from "../../../schemas"
-import { ModeConfig } from "../../../shared/modes"
 import { ZodError } from "zod"
 
+import { type ModeConfig, customModesSettingsSchema } from "@roo-code/types"
+
 describe("CustomModesSettings", () => {
 	const validMode = {
 		slug: "123e4567-e89b-12d3-a456-426614174000",

+ 1 - 2
src/core/config/__tests__/ModeConfig.test.ts

@@ -2,8 +2,7 @@
 
 import { ZodError } from "zod"
 
-import { modeConfigSchema } from "../../../schemas"
-import { ModeConfig } from "../../../shared/modes"
+import { type ModeConfig, modeConfigSchema } from "@roo-code/types"
 
 function validateCustomMode(mode: unknown): asserts mode is ModeConfig {
 	modeConfigSchema.parse(mode)

+ 2 - 1
src/core/config/__tests__/ProviderSettingsManager.test.ts

@@ -2,7 +2,8 @@
 
 import { ExtensionContext } from "vscode"
 
-import { ProviderSettings } from "../../../schemas"
+import type { ProviderSettings } from "@roo-code/types"
+
 import { ProviderSettingsManager, ProviderProfiles } from "../ProviderSettingsManager"
 
 // Mock VSCode ExtensionContext

+ 2 - 1
src/core/config/__tests__/importExport.test.ts

@@ -5,7 +5,8 @@ import * as path from "path"
 
 import * as vscode from "vscode"
 
-import { ProviderName } from "../../../schemas"
+import type { ProviderName } from "@roo-code/types"
+
 import { importSettings, exportSettings } from "../importExport"
 import { ProviderSettingsManager } from "../ProviderSettingsManager"
 import { ContextProxy } from "../ContextProxy"

+ 3 - 2
src/core/config/importExport.ts

@@ -5,12 +5,13 @@ import fs from "fs/promises"
 import * as vscode from "vscode"
 import { z, ZodError } from "zod"
 
-import { globalSettingsSchema } from "../../schemas"
+import { globalSettingsSchema } from "@roo-code/types"
+
+import { telemetryService } from "../../services/telemetry/TelemetryService"
 
 import { ProviderSettingsManager, providerProfilesSchema } from "./ProviderSettingsManager"
 import { ContextProxy } from "./ContextProxy"
 import { CustomModesManager } from "./CustomModesManager"
-import { telemetryService } from "../../services/telemetry/TelemetryService"
 
 type ImportOptions = {
 	providerSettingsManager: ProviderSettingsManager

+ 2 - 1
src/core/diff/strategies/multi-search-replace.ts

@@ -2,8 +2,9 @@
 
 import { distance } from "fastest-levenshtein"
 
+import { ToolProgressStatus } from "@roo-code/types"
+
 import { addLineNumbers, everyLineHasLineNumbers, stripLineNumbers } from "../../../integrations/misc/extract-text"
-import { ToolProgressStatus } from "../../../shared/ExtensionMessage"
 import { ToolUse, DiffStrategy, DiffResult } from "../../../shared/tools"
 import { normalizeString } from "../../../utils/text-normalization"
 

+ 3 - 1
src/core/environment/getEnvironmentDetails.ts

@@ -5,7 +5,9 @@ import * as vscode from "vscode"
 import pWaitFor from "p-wait-for"
 import delay from "delay"
 
-import { EXPERIMENT_IDS, experiments as Experiments, ExperimentId } from "../../shared/experiments"
+import type { ExperimentId } from "@roo-code/types"
+
+import { EXPERIMENT_IDS, experiments as Experiments } from "../../shared/experiments"
 import { formatLanguage } from "../../shared/language"
 import { defaultModeSlug, getFullModeDetails, getModeBySlug, isToolAllowedForMode } from "../../shared/modes"
 import { getApiMetrics } from "../../shared/getApiMetrics"

+ 6 - 2
src/core/prompts/__tests__/system.test.ts

@@ -1,9 +1,13 @@
+// npx jest src/core/prompts/__tests__/system.test.ts
+
 import * as vscode from "vscode"
 
+import { ModeConfig } from "@roo-code/types"
+
 import { SYSTEM_PROMPT } from "../system"
 import { McpHub } from "../../../services/mcp/McpHub"
-import { defaultModeSlug, modes, Mode, ModeConfig } from "../../../shared/modes"
-import "../../../utils/path" // Import path utils to get access to toPosix string extension.
+import { defaultModeSlug, modes, Mode } from "../../../shared/modes"
+import "../../../utils/path"
 import { addCustomInstructions } from "../sections/custom-instructions"
 import { MultiSearchReplaceDiffStrategy } from "../../diff/strategies/multi-search-replace"
 

+ 4 - 2
src/core/prompts/sections/custom-instructions.ts

@@ -1,9 +1,11 @@
 import fs from "fs/promises"
 import path from "path"
-
-import { LANGUAGES, isLanguage } from "../../../shared/language"
 import { Dirent } from "fs"
 
+import { isLanguage } from "@roo-code/types"
+
+import { LANGUAGES } from "../../../shared/language"
+
 /**
  * Safely read a file and return its trimmed content
  */

+ 3 - 1
src/core/prompts/sections/modes.ts

@@ -2,7 +2,9 @@ import * as path from "path"
 import * as vscode from "vscode"
 import { promises as fs } from "fs"
 
-import { ModeConfig, getAllModesWithPrompts } from "../../../shared/modes"
+import type { ModeConfig } from "@roo-code/types"
+
+import { getAllModesWithPrompts } from "../../../shared/modes"
 
 export async function getModesSection(context: vscode.ExtensionContext): Promise<string> {
 	const settingsDir = path.join(context.globalStorageUri.fsPath, "settings")

+ 12 - 15
src/core/prompts/system.ts

@@ -1,19 +1,18 @@
-import {
-	Mode,
-	modes,
-	CustomModePrompts,
-	PromptComponent,
-	defaultModeSlug,
-	ModeConfig,
-	getModeBySlug,
-	getGroupName,
-} from "../../shared/modes"
-import { PromptVariables, loadSystemPromptFile } from "./sections/custom-system-prompt"
+import * as vscode from "vscode"
+import * as os from "os"
+
+import type { ModeConfig, PromptComponent, CustomModePrompts } from "@roo-code/types"
+
+import { Mode, modes, defaultModeSlug, getModeBySlug, getGroupName } from "../../shared/modes"
 import { DiffStrategy } from "../../shared/tools"
+import { formatLanguage } from "../../shared/language"
+
 import { McpHub } from "../../services/mcp/McpHub"
+import { CodeIndexManager } from "../../services/code-index/manager"
+
+import { PromptVariables, loadSystemPromptFile } from "./sections/custom-system-prompt"
+
 import { getToolDescriptionsForMode } from "./tools"
-import * as vscode from "vscode"
-import * as os from "os"
 import {
 	getRulesSection,
 	getSystemInfoSection,
@@ -26,8 +25,6 @@ import {
 	addCustomInstructions,
 	markdownFormattingSection,
 } from "./sections"
-import { formatLanguage } from "../../shared/language"
-import { CodeIndexManager } from "../../services/code-index/manager"
 
 async function generatePrompt(
 	context: vscode.ExtensionContext,

+ 3 - 2
src/core/prompts/tools/index.ts

@@ -1,7 +1,8 @@
-import { ToolName } from "../../../schemas"
+import type { ToolName, ModeConfig } from "@roo-code/types"
+
 import { TOOL_GROUPS, ALWAYS_AVAILABLE_TOOLS, DiffStrategy } from "../../../shared/tools"
 import { McpHub } from "../../../services/mcp/McpHub"
-import { Mode, ModeConfig, getModeConfig, isToolAllowedForMode, getGroupName } from "../../../shared/modes"
+import { Mode, getModeConfig, isToolAllowedForMode, getGroupName } from "../../../shared/modes"
 
 import { ToolArgs } from "./types"
 import { getExecuteCommandDescription } from "./execute-command"

+ 5 - 3
src/core/sliding-window/__tests__/sliding-window.test.ts

@@ -2,16 +2,18 @@
 
 import { Anthropic } from "@anthropic-ai/sdk"
 
-import { ModelInfo } from "../../../shared/api"
+import type { ModelInfo } from "@roo-code/types"
+
 import { BaseProvider } from "../../../api/providers/base-provider"
+import { ApiMessage } from "../../task-persistence/apiMessages"
+import * as condenseModule from "../../condense"
+
 import {
 	TOKEN_BUFFER_PERCENTAGE,
 	estimateTokenCount,
 	truncateConversation,
 	truncateConversationIfNeeded,
 } from "../index"
-import { ApiMessage } from "../../task-persistence/apiMessages"
-import * as condenseModule from "../../condense"
 
 // Create a mock ApiHandler for testing
 class MockApiHandler extends BaseProvider {

+ 2 - 1
src/core/task-persistence/taskMessages.ts

@@ -1,10 +1,11 @@
 import * as path from "path"
 import * as fs from "fs/promises"
 
+import type { ClineMessage } from "@roo-code/types"
+
 import { fileExistsAtPath } from "../../utils/fs"
 
 import { GlobalFileNames } from "../../shared/globalFileNames"
-import { ClineMessage } from "../../shared/ExtensionMessage"
 import { getTaskDirectoryPath } from "../../utils/storage"
 
 export type ReadTaskMessagesOptions = {

+ 2 - 2
src/core/task-persistence/taskMetadata.ts

@@ -1,12 +1,12 @@
 import NodeCache from "node-cache"
 import getFolderSize from "get-folder-size"
 
-import { ClineMessage } from "../../shared/ExtensionMessage"
+import type { ClineMessage, HistoryItem } from "@roo-code/types"
+
 import { combineApiRequests } from "../../shared/combineApiRequests"
 import { combineCommandSequences } from "../../shared/combineCommandSequences"
 import { getApiMetrics } from "../../shared/getApiMetrics"
 import { findLastIndex } from "../../shared/array"
-import { HistoryItem } from "../../shared/HistoryItem"
 import { getTaskDirectoryPath } from "../../utils/storage"
 
 const taskSizeCache = new NodeCache({ stdTTL: 30, checkperiod: 5 * 60 })

+ 14 - 13
src/core/task/Task.ts

@@ -8,29 +8,30 @@ import delay from "delay"
 import pWaitFor from "p-wait-for"
 import { serializeError } from "serialize-error"
 
-// schemas
-import { TokenUsage, ToolUsage, ToolName, ContextCondense } from "../../schemas"
+import type {
+	ProviderSettings,
+	TokenUsage,
+	ToolUsage,
+	ToolName,
+	ContextCondense,
+	ClineAsk,
+	ClineMessage,
+	ClineSay,
+	ToolProgressStatus,
+	HistoryItem,
+} from "@roo-code/types"
 
 // api
 import { ApiHandler, ApiHandlerCreateMessageMetadata, buildApiHandler } from "../../api"
 import { ApiStream } from "../../api/transform/stream"
 
 // shared
-import { ProviderSettings } from "../../shared/api"
 import { findLastIndex } from "../../shared/array"
 import { combineApiRequests } from "../../shared/combineApiRequests"
 import { combineCommandSequences } from "../../shared/combineCommandSequences"
 import { t } from "../../i18n"
-import {
-	ClineApiReqCancelReason,
-	ClineApiReqInfo,
-	ClineAsk,
-	ClineMessage,
-	ClineSay,
-	ToolProgressStatus,
-} from "../../shared/ExtensionMessage"
+import { ClineApiReqCancelReason, ClineApiReqInfo } from "../../shared/ExtensionMessage"
 import { getApiMetrics } from "../../shared/getApiMetrics"
-import { HistoryItem } from "../../shared/HistoryItem"
 import { ClineAskResponse } from "../../shared/WebviewMessage"
 import { defaultModeSlug } from "../../shared/modes"
 import { DiffStrategy } from "../../shared/tools"
@@ -50,7 +51,7 @@ import { RooTerminalProcess } from "../../integrations/terminal/types"
 import { TerminalRegistry } from "../../integrations/terminal/TerminalRegistry"
 
 // utils
-import { calculateApiCostAnthropic } from "../../utils/cost"
+import { calculateApiCostAnthropic } from "../../shared/cost"
 import { getWorkspacePath } from "../../utils/path"
 
 // prompts

+ 2 - 2
src/core/task/__tests__/Task.test.ts

@@ -6,10 +6,10 @@ import * as path from "path"
 import * as vscode from "vscode"
 import { Anthropic } from "@anthropic-ai/sdk"
 
-import { GlobalState } from "../../../schemas"
+import type { GlobalState, ProviderSettings, ModelInfo } from "@roo-code/types"
+
 import { Task } from "../Task"
 import { ClineProvider } from "../../webview/ClineProvider"
-import { ProviderSettings, ModelInfo } from "../../../shared/api"
 import { ApiStreamChunk } from "../../../api/transform/stream"
 import { ContextProxy } from "../../config/ContextProxy"
 import { processUserContentMentions } from "../../mentions/processUserContentMentions"

+ 2 - 1
src/core/tools/__tests__/ToolRepetitionDetector.test.ts

@@ -1,6 +1,7 @@
 // npx jest src/core/tools/__tests__/ToolRepetitionDetector.test.ts
 
-import type { ToolName } from "../../../schemas"
+import type { ToolName } from "@roo-code/types"
+
 import type { ToolUse } from "../../../shared/tools"
 
 import { ToolRepetitionDetector } from "../ToolRepetitionDetector"

+ 2 - 1
src/core/tools/__tests__/executeCommandTool.test.ts

@@ -2,10 +2,11 @@
 
 import { describe, expect, it, jest, beforeEach } from "@jest/globals"
 
+import type { ToolUsage } from "@roo-code/types"
+
 import { Task } from "../../task/Task"
 import { formatResponse } from "../../prompts/responses"
 import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../../shared/tools"
-import { ToolUsage } from "../../../schemas"
 import { unescapeHtmlEntities } from "../../../utils/text-normalization"
 
 // Mock dependencies

+ 4 - 1
src/core/tools/__tests__/validateToolUse.test.ts

@@ -1,7 +1,10 @@
 // npx jest src/core/tools/__tests__/validateToolUse.test.ts
 
-import { isToolAllowedForMode, modes, ModeConfig } from "../../../shared/modes"
+import type { ModeConfig } from "@roo-code/types"
+
+import { isToolAllowedForMode, modes } from "../../../shared/modes"
 import { TOOL_GROUPS } from "../../../shared/tools"
+
 import { validateToolUse } from "../validateToolUse"
 
 const [codeMode, architectMode, askMode] = modes.map((mode) => mode.slug)

+ 3 - 1
src/core/tools/executeCommandTool.ts

@@ -3,8 +3,10 @@ import * as path from "path"
 
 import delay from "delay"
 
+import { CommandExecutionStatus } from "@roo-code/types"
+
 import { Task } from "../task/Task"
-import { CommandExecutionStatus } from "../../schemas"
+
 import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag, ToolResponse } from "../../shared/tools"
 import { formatResponse } from "../prompts/responses"
 import { unescapeHtmlEntities } from "../../utils/text-normalization"

+ 3 - 2
src/core/tools/validateToolUse.ts

@@ -1,5 +1,6 @@
-import { ToolName } from "../../schemas"
-import { Mode, isToolAllowedForMode, ModeConfig } from "../../shared/modes"
+import type { ToolName, ModeConfig } from "@roo-code/types"
+
+import { Mode, isToolAllowedForMode } from "../../shared/modes"
 
 export function validateToolUse(
 	toolName: ToolName,

+ 5 - 4
src/core/webview/ClineProvider.ts

@@ -9,25 +9,26 @@ import axios from "axios"
 import pWaitFor from "p-wait-for"
 import * as vscode from "vscode"
 
-import {
+import type {
 	GlobalState,
 	ProviderName,
 	ProviderSettings,
 	RooCodeSettings,
 	ProviderSettingsEntry,
-	Package,
 	CodeActionId,
 	CodeActionName,
 	TerminalActionId,
 	TerminalActionPromptType,
-} from "../../schemas"
+	HistoryItem,
+} from "@roo-code/types"
+
 import { t } from "../../i18n"
 import { setPanel } from "../../activate/registerCommands"
+import { Package } from "../../shared/package"
 import { requestyDefaultModelId, openRouterDefaultModelId, glamaDefaultModelId } from "../../shared/api"
 import { findLast } from "../../shared/array"
 import { supportPrompt } from "../../shared/support-prompt"
 import { GlobalFileNames } from "../../shared/globalFileNames"
-import { HistoryItem } from "../../shared/HistoryItem"
 import { ExtensionMessage } from "../../shared/ExtensionMessage"
 import { Mode, defaultModeSlug } from "../../shared/modes"
 import { experimentDefault } from "../../shared/experiments"

+ 6 - 3
src/core/webview/__tests__/ClineProvider.test.ts

@@ -4,14 +4,17 @@ import Anthropic from "@anthropic-ai/sdk"
 import * as vscode from "vscode"
 import axios from "axios"
 
-import { ClineProvider } from "../ClineProvider"
-import { ProviderSettingsEntry, ClineMessage, ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage"
-import { setTtsEnabled } from "../../../utils/tts"
+import type { ProviderSettingsEntry, ClineMessage } from "@roo-code/types"
+
+import { ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage"
 import { defaultModeSlug } from "../../../shared/modes"
 import { experimentDefault } from "../../../shared/experiments"
+import { setTtsEnabled } from "../../../utils/tts"
 import { ContextProxy } from "../../config/ContextProxy"
 import { Task, TaskOptions } from "../../task/Task"
 
+import { ClineProvider } from "../ClineProvider"
+
 // Mock setup must come before imports
 jest.mock("../../prompts/sections/custom-instructions")
 

+ 3 - 1
src/core/webview/webviewMessageHandler.ts

@@ -3,9 +3,11 @@ import fs from "fs/promises"
 import pWaitFor from "p-wait-for"
 import * as vscode from "vscode"
 
+import type { Language, ProviderSettings, GlobalState } from "@roo-code/types"
+
 import { ClineProvider } from "./ClineProvider"
-import { Language, ProviderSettings, GlobalState, Package } from "../../schemas"
 import { changeLanguage, t } from "../../i18n"
+import { Package } from "../../shared/package"
 import { RouterName, toRouterName, ModelRecord } from "../../shared/api"
 import { supportPrompt } from "../../shared/support-prompt"
 import { checkoutDiffPayloadSchema, checkoutRestorePayloadSchema, WebviewMessage } from "../../shared/WebviewMessage"

+ 16 - 3
src/esbuild.mjs

@@ -1,4 +1,5 @@
 import * as esbuild from "esbuild"
+import * as fs from "fs"
 import * as path from "path"
 import { fileURLToPath } from "url"
 import process from "node:process"
@@ -10,6 +11,7 @@ const __filename = fileURLToPath(import.meta.url)
 const __dirname = path.dirname(__filename)
 
 async function main() {
+	const name = "extension"
 	const production = process.argv.includes("--production")
 	const watch = process.argv.includes("--watch")
 	const minify = production
@@ -32,12 +34,17 @@ async function main() {
 	const buildDir = __dirname
 	const distDir = path.join(buildDir, "dist")
 
+	if (fs.existsSync(distDir)) {
+		console.log(`[${name}] Cleaning dist directory: ${distDir}`)
+		fs.rmSync(distDir, { recursive: true, force: true })
+	}
+
 	/**
 	 * @type {import('esbuild').Plugin[]}
 	 */
 	const plugins = [
 		{
-			name: "copy-files",
+			name: "copyFiles",
 			setup(build) {
 				build.onEnd(() => {
 					copyPaths(
@@ -55,13 +62,13 @@ async function main() {
 			},
 		},
 		{
-			name: "copy-wasms",
+			name: "copyWasms",
 			setup(build) {
 				build.onEnd(() => copyWasms(srcDir, distDir))
 			},
 		},
 		{
-			name: "copy-locales",
+			name: "copyLocales",
 			setup(build) {
 				build.onEnd(() => copyLocales(srcDir, distDir))
 			},
@@ -91,6 +98,9 @@ async function main() {
 		entryPoints: ["extension.ts"],
 		outfile: "dist/extension.js",
 		external: ["vscode"],
+		alias: {
+			"@roo-code/types": path.resolve(__dirname, "../packages/types/dist/index.js"),
+		},
 	}
 
 	/**
@@ -100,6 +110,9 @@ async function main() {
 		...buildOptions,
 		entryPoints: ["workers/countTokens.ts"],
 		outdir: "dist/workers",
+		alias: {
+			"@roo-code/types": path.resolve(__dirname, "../packages/types/dist/index.js"),
+		},
 	}
 
 	const [extensionCtx, workerCtx] = await Promise.all([

Некоторые файлы не были показаны из-за большого количества измененных файлов