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

Merge branch 'RooVetGit:main' into improvement/task_delete_confirmation_854

mosleyit 10 месяцев назад
Родитель
Сommit
fc660a52e5
50 измененных файлов с 1591 добавлено и 1633 удалено
  1. 1 1
      .github/CODEOWNERS
  2. 40 2
      .github/workflows/code-qa.yml
  3. 15 1
      CHANGELOG.md
  4. 1 1
      jest.config.js
  5. 27 0
      knip.json
  6. 321 10
      package-lock.json
  7. 5 4
      package.json
  8. 17 0
      src/__mocks__/jest.setup.ts
  9. 0 429
      src/api/transform/o1-format.ts
  10. 98 41
      src/core/Cline.ts
  11. 139 84
      src/core/__tests__/Cline.test.ts
  12. 20 20
      src/core/__tests__/mode-validator.test.ts
  13. 3 3
      src/core/assistant-message/index.ts
  14. 2 2
      src/core/assistant-message/parse-assistant-message.ts
  15. 1 1
      src/core/diff/strategies/__tests__/new-unified.test.ts
  16. 2 2
      src/core/diff/strategies/__tests__/search-replace.test.ts
  17. 1 1
      src/core/diff/strategies/__tests__/unified.test.ts
  18. 3 3
      src/core/diff/strategies/new-unified/index.ts
  19. 3 3
      src/core/diff/strategies/search-replace.ts
  20. 3 3
      src/core/diff/strategies/unified.ts
  21. 142 142
      src/core/prompts/__tests__/__snapshots__/system.test.ts.snap
  22. 8 8
      src/core/prompts/__tests__/sections.test.ts
  23. 6 6
      src/core/prompts/__tests__/system.test.ts
  24. 1 1
      src/core/prompts/sections/capabilities.ts
  25. 1 1
      src/core/prompts/sections/mcp-servers.ts
  26. 1 1
      src/core/prompts/sections/modes.ts
  27. 14 9
      src/core/prompts/sections/rules.ts
  28. 2 2
      src/core/prompts/tools/index.ts
  29. 5 5
      src/core/prompts/tools/write-to-file.ts
  30. 12 15
      src/core/webview/ClineProvider.ts
  31. 45 17
      src/core/webview/__tests__/ClineProvider.test.ts
  32. 0 123
      src/integrations/diagnostics/DiagnosticsMonitor.ts
  33. 0 0
      src/integrations/terminal/TerminalActions.ts
  34. 0 42
      src/integrations/workspace/get-python-env.ts
  35. 10 5
      src/services/checkpoints/__tests__/LocalCheckpointService.test.ts
  36. 11 9
      src/services/checkpoints/__tests__/ShadowCheckpointService.test.ts
  37. 1 1
      src/shared/ExtensionMessage.ts
  38. 47 0
      src/shared/__tests__/experiments.test.ts
  39. 135 34
      src/shared/__tests__/modes.test.ts
  40. 2 2
      src/shared/api.ts
  41. 7 0
      src/shared/experiments.ts
  42. 50 0
      src/shared/modes.ts
  43. 3 3
      src/shared/tool-groups.ts
  44. 2 1
      webview-ui/.eslintrc.json
  45. 380 246
      webview-ui/package-lock.json
  46. 3 3
      webview-ui/package.json
  47. 0 130
      webview-ui/src/components/common/Demo.tsx
  48. 1 3
      webview-ui/src/components/settings/ApiOptions.tsx
  49. 0 167
      webview-ui/src/components/settings/TabNavbar.tsx
  50. 0 46
      webview-ui/src/services/GitService.ts

+ 1 - 1
.github/CODEOWNERS

@@ -1,2 +1,2 @@
 # These owners will be the default owners for everything in the repo
-* @stea9499 @ColemanRoo @mrubens @cte
+* @mrubens @cte

+ 40 - 2
.github/workflows/code-qa.yml

@@ -28,7 +28,37 @@ jobs:
       - name: Lint
         run: npm run lint
 
-  unit-test:
+  knip:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v4
+      - name: Setup Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: '18'
+          cache: 'npm'
+      - name: Install dependencies
+        run: npm run install:all
+      - name: Run knip checks
+        run: npm run knip
+
+  test-extension:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v4
+      - name: Setup Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: '18'
+          cache: 'npm'
+      - name: Install dependencies
+        run: npm run install:all
+      - name: Run unit tests
+        run: npx jest --silent
+
+  test-webview:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout code
@@ -41,7 +71,15 @@ jobs:
       - name: Install dependencies
         run: npm run install:all
       - name: Run unit tests
-        run: npm test
+        working-directory: webview-ui
+        run: npx jest --silent
+
+  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

+ 15 - 1
CHANGELOG.md

@@ -1,5 +1,19 @@
 # Roo Code Changelog
 
+## [3.3.26]
+
+- Adjust the default prompt for Debug mode to focus more on diagnosis and to require user confirmation before moving on to implementation
+
+## [3.3.25]
+
+- Add a "Debug" mode that specializes in debugging tricky problems (thanks [Ted Werbel](https://x.com/tedx_ai/status/1891514191179309457) and [Carlos E. Perez](https://x.com/IntuitMachine/status/1891516362486337739)!)
+- Add an experimental "Power Steering" option to significantly improve adherence to role definitions and custom instructions
+
+## [3.3.24]
+
+- Fixed a bug with region selection preventing AWS Bedrock profiles from being saved (thanks @oprstchn!)
+- Updated the price of gpt-4o (thanks @marvijo-code!)
+
 ## [3.3.23]
 
 - Handle errors more gracefully when reading custom instructions from files (thanks @joemanley201!)
@@ -465,7 +479,7 @@ Join us at https://www.reddit.com/r/RooCode to share your custom modes and be pa
 ## [2.1.14]
 
 - Fix bug where diffs were not being applied correctly and try Aider's [unified diff prompt](https://github.com/Aider-AI/aider/blob/3995accd0ca71cea90ef76d516837f8c2731b9fe/aider/coders/udiff_prompts.py#L75-L105)
-- If diffs are enabled, automatically reject write_to_file commands that lead to truncated output
+- If diffs are enabled, automatically reject create_file commands that lead to truncated output
 
 ## [2.1.13]
 

+ 1 - 1
jest.config.js

@@ -37,5 +37,5 @@ module.exports = {
 	roots: ["<rootDir>/src", "<rootDir>/webview-ui/src"],
 	modulePathIgnorePatterns: [".vscode-test"],
 	reporters: [["jest-simple-dot-reporter", {}]],
-	setupFiles: [],
+	setupFiles: ["<rootDir>/src/__mocks__/jest.setup.ts"],
 }

+ 27 - 0
knip.json

@@ -0,0 +1,27 @@
+{
+	"$schema": "https://unpkg.com/knip@latest/schema.json",
+	"entry": ["src/extension.ts", "src/activate/index.ts", "webview-ui/src/index.tsx"],
+	"project": ["src/**/*.ts", "webview-ui/src/**/*.{ts,tsx}"],
+	"ignore": [
+		"**/__mocks__/**",
+		"**/__tests__/**",
+		"**/test/**",
+		"**/*.test.ts",
+		"**/*.test.tsx",
+		"**/stories/**",
+		"coverage/**",
+		"dist/**",
+		"out/**",
+		"bin/**",
+		"src/activate/**",
+		"src/exports/**",
+		"src/extension.ts",
+		".vscode-test.mjs"
+	],
+	"workspaces": {
+		"webview-ui": {
+			"entry": ["src/index.tsx"],
+			"project": ["src/**/*.{ts,tsx}"]
+		}
+	}
+}

+ 321 - 10
package-lock.json

@@ -1,12 +1,12 @@
 {
 	"name": "roo-cline",
-	"version": "3.3.23",
+	"version": "3.3.26",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "roo-cline",
-			"version": "3.3.23",
+			"version": "3.3.26",
 			"dependencies": {
 				"@anthropic-ai/bedrock-sdk": "^0.10.2",
 				"@anthropic-ai/sdk": "^0.26.0",
@@ -76,6 +76,7 @@
 				"husky": "^9.1.7",
 				"jest": "^29.7.0",
 				"jest-simple-dot-reporter": "^1.0.5",
+				"knip": "^5.44.4",
 				"lint-staged": "^15.2.11",
 				"mkdirp": "^3.0.1",
 				"mocha": "^11.1.0",
@@ -5854,6 +5855,47 @@
 			"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
 			"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
 		},
+		"node_modules/@snyk/github-codeowners": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz",
+			"integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==",
+			"dev": true,
+			"dependencies": {
+				"commander": "^4.1.1",
+				"ignore": "^5.1.8",
+				"p-map": "^4.0.0"
+			},
+			"bin": {
+				"github-codeowners": "dist/cli.js"
+			},
+			"engines": {
+				"node": ">=8.10"
+			}
+		},
+		"node_modules/@snyk/github-codeowners/node_modules/commander": {
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+			"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+			"dev": true,
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/@snyk/github-codeowners/node_modules/p-map": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+			"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+			"dev": true,
+			"dependencies": {
+				"aggregate-error": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/@tootallnate/quickjs-emscripten": {
 			"version": "0.23.0",
 			"resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
@@ -6696,6 +6738,19 @@
 				"node": ">= 8.0.0"
 			}
 		},
+		"node_modules/aggregate-error": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+			"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+			"dev": true,
+			"dependencies": {
+				"clean-stack": "^2.0.0",
+				"indent-string": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/ajv": {
 			"version": "6.12.6",
 			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -7530,6 +7585,15 @@
 			"integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
 			"dev": true
 		},
+		"node_modules/clean-stack": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+			"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+			"dev": true,
+			"engines": {
+				"node": ">=6"
+			}
+		},
 		"node_modules/cli-cursor": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
@@ -7662,6 +7726,16 @@
 				"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
 			}
 		},
+		"node_modules/clone": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+			"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+			"dev": true,
+			"optional": true,
+			"engines": {
+				"node": ">=0.8"
+			}
+		},
 		"node_modules/clone-deep": {
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -7957,6 +8031,19 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/defaults": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+			"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+			"dev": true,
+			"optional": true,
+			"dependencies": {
+				"clone": "^1.0.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/define-data-property": {
 			"version": "1.1.4",
 			"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -8207,6 +8294,27 @@
 			"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
 			"dev": true
 		},
+		"node_modules/easy-table": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+			"integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
+			"dev": true,
+			"dependencies": {
+				"ansi-regex": "^5.0.1"
+			},
+			"optionalDependencies": {
+				"wcwidth": "^1.0.1"
+			}
+		},
+		"node_modules/easy-table/node_modules/ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/ecdsa-sig-formatter": {
 			"version": "1.0.11",
 			"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
@@ -8299,9 +8407,9 @@
 			}
 		},
 		"node_modules/enhanced-resolve": {
-			"version": "5.17.1",
-			"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
-			"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
+			"version": "5.18.1",
+			"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+			"integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
 			"dev": true,
 			"dependencies": {
 				"graceful-fs": "^4.2.4",
@@ -8947,15 +9055,15 @@
 			"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
 		},
 		"node_modules/fast-glob": {
-			"version": "3.3.2",
-			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-			"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+			"version": "3.3.3",
+			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+			"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
 			"dependencies": {
 				"@nodelib/fs.stat": "^2.0.2",
 				"@nodelib/fs.walk": "^1.2.3",
 				"glob-parent": "^5.1.2",
 				"merge2": "^1.3.0",
-				"micromatch": "^4.0.4"
+				"micromatch": "^4.0.8"
 			},
 			"engines": {
 				"node": ">=8.6.0"
@@ -9957,6 +10065,15 @@
 				"node": ">=0.8.19"
 			}
 		},
+		"node_modules/indent-string": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+			"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/inflight": {
 			"version": "1.0.6",
 			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -11195,7 +11312,8 @@
 			"version": "1.0.5",
 			"resolved": "https://registry.npmjs.org/jest-simple-dot-reporter/-/jest-simple-dot-reporter-1.0.5.tgz",
 			"integrity": "sha512-cZLFG/C7k0+WYoIGGuGXKm0vmJiXlWG/m3uCZ4RaMPYxt8lxjdXMLHYkxXaQ7gVWaSPe7uAPCEUcRxthC5xskg==",
-			"dev": true
+			"dev": true,
+			"license": "MIT"
 		},
 		"node_modules/jest-snapshot": {
 			"version": "29.7.0",
@@ -11323,6 +11441,15 @@
 				"url": "https://github.com/chalk/supports-color?sponsor=1"
 			}
 		},
+		"node_modules/jiti": {
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+			"integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
+			"dev": true,
+			"bin": {
+				"jiti": "lib/jiti-cli.mjs"
+			}
+		},
 		"node_modules/js-tokens": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -11472,6 +11599,114 @@
 				"node": ">=6"
 			}
 		},
+		"node_modules/knip": {
+			"version": "5.44.4",
+			"resolved": "https://registry.npmjs.org/knip/-/knip-5.44.4.tgz",
+			"integrity": "sha512-Ryn8LwWHLId8jSK1DgtT0hmg5DbzkqAtH+Gg3vZJpmSMgGHMspej9Ag+qKTm8wsPLDjVetuEz/lIsobo0XCMvQ==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/webpro"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/knip"
+				},
+				{
+					"type": "polar",
+					"url": "https://polar.sh/webpro-nl"
+				}
+			],
+			"dependencies": {
+				"@nodelib/fs.walk": "3.0.1",
+				"@snyk/github-codeowners": "1.1.0",
+				"easy-table": "1.2.0",
+				"enhanced-resolve": "^5.18.0",
+				"fast-glob": "^3.3.3",
+				"jiti": "^2.4.2",
+				"js-yaml": "^4.1.0",
+				"minimist": "^1.2.8",
+				"picocolors": "^1.1.0",
+				"picomatch": "^4.0.1",
+				"pretty-ms": "^9.0.0",
+				"smol-toml": "^1.3.1",
+				"strip-json-comments": "5.0.1",
+				"summary": "2.1.0",
+				"zod": "^3.22.4",
+				"zod-validation-error": "^3.0.3"
+			},
+			"bin": {
+				"knip": "bin/knip.js",
+				"knip-bun": "bin/knip-bun.js"
+			},
+			"engines": {
+				"node": ">=18.18.0"
+			},
+			"peerDependencies": {
+				"@types/node": ">=18",
+				"typescript": ">=5.0.4"
+			}
+		},
+		"node_modules/knip/node_modules/@nodelib/fs.scandir": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-4.0.1.tgz",
+			"integrity": "sha512-vAkI715yhnmiPupY+dq+xenu5Tdf2TBQ66jLvBIcCddtz+5Q8LbMKaf9CIJJreez8fQ8fgaY+RaywQx8RJIWpw==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.stat": "4.0.0",
+				"run-parallel": "^1.2.0"
+			},
+			"engines": {
+				"node": ">=18.18.0"
+			}
+		},
+		"node_modules/knip/node_modules/@nodelib/fs.stat": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-4.0.0.tgz",
+			"integrity": "sha512-ctr6bByzksKRCV0bavi8WoQevU6plSp2IkllIsEqaiKe2mwNNnaluhnRhcsgGZHrrHk57B3lf95MkLMO3STYcg==",
+			"dev": true,
+			"engines": {
+				"node": ">=18.18.0"
+			}
+		},
+		"node_modules/knip/node_modules/@nodelib/fs.walk": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-3.0.1.tgz",
+			"integrity": "sha512-nIh/M6Kh3ZtOmlY00DaUYB4xeeV6F3/ts1l29iwl3/cfyY/OuCfUx+v08zgx8TKPTifXRcjjqVQ4KB2zOYSbyw==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.scandir": "4.0.1",
+				"fastq": "^1.15.0"
+			},
+			"engines": {
+				"node": ">=18.18.0"
+			}
+		},
+		"node_modules/knip/node_modules/picomatch": {
+			"version": "4.0.2",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+			"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+			"dev": true,
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
+		"node_modules/knip/node_modules/strip-json-comments": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
+			"integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
+			"dev": true,
+			"engines": {
+				"node": ">=14.16"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/leven": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -12205,6 +12440,15 @@
 				"url": "https://github.com/sponsors/isaacs"
 			}
 		},
+		"node_modules/minimist": {
+			"version": "1.2.8",
+			"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+			"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/minipass": {
 			"version": "7.1.2",
 			"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
@@ -13170,6 +13414,18 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/parse-ms": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+			"integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+			"dev": true,
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/parse5": {
 			"version": "7.2.1",
 			"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
@@ -13480,6 +13736,21 @@
 				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
 			}
 		},
+		"node_modules/pretty-ms": {
+			"version": "9.2.0",
+			"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz",
+			"integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==",
+			"dev": true,
+			"dependencies": {
+				"parse-ms": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/process-nextick-args": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -14340,6 +14611,18 @@
 				"npm": ">= 3.0.0"
 			}
 		},
+		"node_modules/smol-toml": {
+			"version": "1.3.1",
+			"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.1.tgz",
+			"integrity": "sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==",
+			"dev": true,
+			"engines": {
+				"node": ">= 18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/cyyynthia"
+			}
+		},
 		"node_modules/socks": {
 			"version": "2.8.3",
 			"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
@@ -14761,6 +15044,12 @@
 			"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
 			"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
 		},
+		"node_modules/summary": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/summary/-/summary-2.1.0.tgz",
+			"integrity": "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==",
+			"dev": true
+		},
 		"node_modules/supports-color": {
 			"version": "9.4.0",
 			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz",
@@ -15336,6 +15625,16 @@
 				"makeerror": "1.0.12"
 			}
 		},
+		"node_modules/wcwidth": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+			"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+			"dev": true,
+			"optional": true,
+			"dependencies": {
+				"defaults": "^1.0.3"
+			}
+		},
 		"node_modules/web-streams-polyfill": {
 			"version": "4.0.0-beta.3",
 			"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
@@ -15962,6 +16261,18 @@
 			"funding": {
 				"url": "https://github.com/sponsors/colinhacks"
 			}
+		},
+		"node_modules/zod-validation-error": {
+			"version": "3.4.0",
+			"resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.4.0.tgz",
+			"integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=18.0.0"
+			},
+			"peerDependencies": {
+				"zod": "^3.18.0"
+			}
 		}
 	}
 }

+ 5 - 4
package.json

@@ -3,7 +3,7 @@
 	"displayName": "Roo Code (prev. Roo Cline)",
 	"description": "An AI-powered autonomous coding agent that lives in your editor.",
 	"publisher": "RooVeterinaryInc",
-	"version": "3.3.23",
+	"version": "3.3.26",
 	"icon": "assets/icons/rocket.png",
 	"galleryBanner": {
 		"color": "#617A91",
@@ -277,10 +277,11 @@
 		"build": "npm run build:webview && npm run vsix",
 		"build:webview": "cd webview-ui && npm run build",
 		"changeset": "changeset",
-		"check-types": "tsc --noEmit",
+		"check-types": "tsc --noEmit && cd webview-ui && npm run check-types",
 		"compile": "tsc -p . --outDir out && node esbuild.js",
 		"compile:integration": "tsc -p tsconfig.integration.json",
 		"install:all": "npm install && cd webview-ui && npm install",
+		"knip": "knip --include files",
 		"lint": "eslint src --ext ts && npm run lint --prefix webview-ui",
 		"lint-local": "eslint -c .eslintrc.local.json src --ext ts && npm run lint --prefix webview-ui",
 		"lint-fix": "eslint src --ext ts --fix && npm run lint-fix --prefix webview-ui",
@@ -288,8 +289,7 @@
 		"package": "npm run build:webview && npm run check-types && npm run lint && node esbuild.js --production",
 		"pretest": "npm run compile && npm run compile:integration",
 		"dev": "cd webview-ui && npm run dev",
-		"test": "jest && npm run test:webview",
-		"test:webview": "cd webview-ui && npm run test",
+		"test": "jest && cd webview-ui && npm run test",
 		"test:integration": "npm run build && npm run compile:integration && npx dotenvx run -f .env.integration -- node ./out-integration/test/runTest.js",
 		"prepare": "husky",
 		"publish:marketplace": "vsce publish && ovsx publish",
@@ -371,6 +371,7 @@
 		"husky": "^9.1.7",
 		"jest": "^29.7.0",
 		"jest-simple-dot-reporter": "^1.0.5",
+		"knip": "^5.44.4",
 		"lint-staged": "^15.2.11",
 		"mkdirp": "^3.0.1",
 		"mocha": "^11.1.0",

+ 17 - 0
src/__mocks__/jest.setup.ts

@@ -0,0 +1,17 @@
+// Mock the logger globally for all tests
+jest.mock("../utils/logging", () => ({
+	logger: {
+		debug: jest.fn(),
+		info: jest.fn(),
+		warn: jest.fn(),
+		error: jest.fn(),
+		fatal: jest.fn(),
+		child: jest.fn().mockReturnValue({
+			debug: jest.fn(),
+			info: jest.fn(),
+			warn: jest.fn(),
+			error: jest.fn(),
+			fatal: jest.fn(),
+		}),
+	},
+}))

+ 0 - 429
src/api/transform/o1-format.ts

@@ -1,429 +0,0 @@
-import { Anthropic } from "@anthropic-ai/sdk"
-import OpenAI from "openai"
-
-const o1SystemPrompt = (systemPrompt: string) => `
-# System Prompt
-
-${systemPrompt}
-
-# Instructions for Formulating Your Response
-
-You must respond to the user's request by using at least one tool call. When formulating your response, follow these guidelines:
-
-1. Begin your response with normal text, explaining your thoughts, analysis, or plan of action.
-2. If you need to use any tools, place ALL tool calls at the END of your message, after your normal text explanation.
-3. You can use multiple tool calls if needed, but they should all be grouped together at the end of your message.
-4. After placing the tool calls, do not add any additional normal text. The tool calls should be the final content in your message.
-
-Here's the general structure your responses should follow:
-
-\`\`\`
-[Your normal text response explaining your thoughts and actions]
-
-[Tool Call 1]
-[Tool Call 2 if needed]
-[Tool Call 3 if needed]
-...
-\`\`\`
-
-Remember:
-- Choose the most appropriate tool(s) based on the task and the tool descriptions provided.
-- Formulate your tool calls using the XML format specified for each tool.
-- Provide clear explanations in your normal text about what actions you're taking and why you're using particular tools.
-- Act as if the tool calls will be executed immediately after your message, and your next response will have access to their results.
-
-# Tool Descriptions and XML Formats
-
-1. execute_command:
-<execute_command>
-<command>Your command here</command>
-</execute_command>
-Description: Execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory.
-
-2. list_files:
-<list_files>
-<path>Directory path here</path>
-<recursive>true or false (optional)</recursive>
-</list_files>
-Description: List files and directories within the specified directory. If recursive is true, it will list all files and directories recursively. If recursive is false or not provided, it will only list the top-level contents.
-
-3. list_code_definition_names:
-<list_code_definition_names>
-<path>Directory path here</path>
-</list_code_definition_names>
-Description: Lists definition names (classes, functions, methods, etc.) used in source code files at the top level of the specified directory. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture.
-
-4. search_files:
-<search_files>
-<path>Directory path here</path>
-<regex>Your regex pattern here</regex>
-<filePattern>Optional file pattern here</filePattern>
-</search_files>
-Description: Perform a regex search across files in a specified directory, providing context-rich results. This tool searches for patterns or specific content across multiple files, displaying each match with encapsulating context.
-
-5. read_file:
-<read_file>
-<path>File path here</path>
-</read_file>
-Description: Read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
-
-6. write_to_file:
-<write_to_file>
-<path>File path here</path>
-<content>
-Your file content here
-</content>
-</write_to_file>
-Description: Write content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. Always provide the full intended content of the file, without any truncation. This tool will automatically create any directories needed to write the file.
-
-7. ask_followup_question:
-<ask_followup_question>
-<question>Your question here</question>
-</ask_followup_question>
-Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth.
-
-8. attempt_completion:
-<attempt_completion>
-<command>Optional command to demonstrate result</command>
-<result>
-Your final result description here
-</result>
-</attempt_completion>
-Description: Once you've completed the task, use this tool to present the result to the user. They may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again.
-
-# Examples
-
-Here are some examples of how to structure your responses with tool calls:
-
-Example 1: Using a single tool
-
-Let's run the test suite for our project. This will help us ensure that all our components are functioning correctly.
-
-<execute_command>
-<command>npm test</command>
-</execute_command>
-
-Example 2: Using multiple tools
-
-Let's create two new configuration files for the web application: one for the frontend and one for the backend.
-
-<write_to_file>
-<path>./frontend-config.json</path>
-<content>
-{
-  "apiEndpoint": "https://api.example.com",
-  "theme": {
-    "primaryColor": "#007bff",
-    "secondaryColor": "#6c757d",
-    "fontFamily": "Arial, sans-serif"
-  },
-  "features": {
-    "darkMode": true,
-    "notifications": true,
-    "analytics": false
-  },
-  "version": "1.0.0"
-}
-</content>
-</write_to_file>
-
-<write_to_file>
-<path>./backend-config.yaml</path>
-<content>
-database:
-  host: localhost
-  port: 5432
-  name: myapp_db
-  user: admin
-
-server:
-  port: 3000
-  environment: development
-  logLevel: debug
-
-security:
-  jwtSecret: your-secret-key-here
-  passwordSaltRounds: 10
-
-caching:
-  enabled: true
-  provider: redis
-  ttl: 3600
-
-externalServices:
-  emailProvider: sendgrid
-  storageProvider: aws-s3
-</content>
-</write_to_file>
-
-Example 3: Asking a follow-up question
-
-I've analyzed the project structure, but I need more information to proceed. Let me ask the user for clarification.
-
-<ask_followup_question>
-<question>Which specific feature would you like me to implement in the example.py file?</question>
-</ask_followup_question>
-`
-
-export function convertToO1Messages(
-	openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[],
-	systemPrompt: string,
-): OpenAI.Chat.ChatCompletionMessageParam[] {
-	const toolsReplaced = openAiMessages.reduce((acc, message) => {
-		if (message.role === "tool") {
-			// Convert tool messages to user messages
-			acc.push({
-				role: "user",
-				content: message.content || "",
-			})
-		} else if (message.role === "assistant" && message.tool_calls) {
-			// Convert tool calls to content and remove tool_calls
-			let content = message.content || ""
-			message.tool_calls.forEach((toolCall) => {
-				if (toolCall.type === "function") {
-					content += `\nTool Call: ${toolCall.function.name}\nArguments: ${toolCall.function.arguments}`
-				}
-			})
-			acc.push({
-				role: "assistant",
-				content: content,
-				tool_calls: undefined,
-			})
-		} else {
-			// Keep other messages as they are
-			acc.push(message)
-		}
-		return acc
-	}, [] as OpenAI.Chat.ChatCompletionMessageParam[])
-
-	// Find the index of the last assistant message
-	// const lastAssistantIndex = findLastIndex(toolsReplaced, (message) => message.role === "assistant")
-
-	// Create a new array to hold the modified messages
-	const messagesWithSystemPrompt = [
-		{
-			role: "user",
-			content: o1SystemPrompt(systemPrompt),
-		} as OpenAI.Chat.ChatCompletionUserMessageParam,
-		...toolsReplaced,
-	]
-
-	// If there's an assistant message, insert the system prompt after it
-	// if (lastAssistantIndex !== -1) {
-	// 	const insertIndex = lastAssistantIndex + 1
-	// 	if (insertIndex < messagesWithSystemPrompt.length && messagesWithSystemPrompt[insertIndex].role === "user") {
-	// 		messagesWithSystemPrompt.splice(insertIndex, 0, {
-	// 			role: "user",
-	// 			content: o1SystemPrompt(systemPrompt),
-	// 		})
-	// 	}
-	// } else {
-	// 	// If there were no assistant messages, prepend the system prompt
-	// 	messagesWithSystemPrompt.unshift({
-	// 		role: "user",
-	// 		content: o1SystemPrompt(systemPrompt),
-	// 	})
-	// }
-
-	return messagesWithSystemPrompt
-}
-
-interface ToolCall {
-	tool: string
-	tool_input: Record<string, string>
-}
-
-const toolNames = [
-	"execute_command",
-	"list_files",
-	"list_code_definition_names",
-	"search_files",
-	"read_file",
-	"write_to_file",
-	"ask_followup_question",
-	"attempt_completion",
-]
-
-function parseAIResponse(response: string): { normalText: string; toolCalls: ToolCall[] } {
-	// Create a regex pattern to match any tool call opening tag
-	const toolCallPattern = new RegExp(`<(${toolNames.join("|")})`, "i")
-	const match = response.match(toolCallPattern)
-
-	if (!match) {
-		// No tool calls found
-		return { normalText: response.trim(), toolCalls: [] }
-	}
-
-	const toolCallStart = match.index!
-	const normalText = response.slice(0, toolCallStart).trim()
-	const toolCallsText = response.slice(toolCallStart)
-
-	const toolCalls = parseToolCalls(toolCallsText)
-
-	return { normalText, toolCalls }
-}
-
-function parseToolCalls(toolCallsText: string): ToolCall[] {
-	const toolCalls: ToolCall[] = []
-
-	let remainingText = toolCallsText
-
-	while (remainingText.length > 0) {
-		const toolMatch = toolNames.find((tool) => new RegExp(`<${tool}`, "i").test(remainingText))
-
-		if (!toolMatch) {
-			break // No more tool calls found
-		}
-
-		const startTag = `<${toolMatch}`
-		const endTag = `</${toolMatch}>`
-		const startIndex = remainingText.indexOf(startTag)
-		const endIndex = remainingText.indexOf(endTag, startIndex)
-
-		if (endIndex === -1) {
-			break // Malformed XML, no closing tag found
-		}
-
-		const toolCallContent = remainingText.slice(startIndex, endIndex + endTag.length)
-		remainingText = remainingText.slice(endIndex + endTag.length).trim()
-
-		const toolCall = parseToolCall(toolMatch, toolCallContent)
-		if (toolCall) {
-			toolCalls.push(toolCall)
-		}
-	}
-
-	return toolCalls
-}
-
-function parseToolCall(toolName: string, content: string): ToolCall | null {
-	const tool_input: Record<string, string> = {}
-
-	// Remove the outer tool tags
-	const innerContent = content.replace(new RegExp(`^<${toolName}>|</${toolName}>$`, "g"), "").trim()
-
-	// Parse nested XML elements
-	const paramRegex = /<(\w+)>([\s\S]*?)<\/\1>/gs
-	let match
-
-	while ((match = paramRegex.exec(innerContent)) !== null) {
-		const [, paramName, paramValue] = match
-		// Preserve newlines and trim only leading/trailing whitespace
-		tool_input[paramName] = paramValue.replace(/^\s+|\s+$/g, "")
-	}
-
-	// Validate required parameters
-	if (!validateToolInput(toolName, tool_input)) {
-		console.error(`Invalid tool call for ${toolName}:`, content)
-		return null
-	}
-
-	return { tool: toolName, tool_input }
-}
-
-function validateToolInput(toolName: string, tool_input: Record<string, string>): boolean {
-	switch (toolName) {
-		case "execute_command":
-			return "command" in tool_input
-		case "read_file":
-		case "list_code_definition_names":
-		case "list_files":
-			return "path" in tool_input
-		case "search_files":
-			return "path" in tool_input && "regex" in tool_input
-		case "write_to_file":
-			return "path" in tool_input && "content" in tool_input
-		case "ask_followup_question":
-			return "question" in tool_input
-		case "attempt_completion":
-			return "result" in tool_input
-		default:
-			return false
-	}
-}
-
-// Example usage:
-// const aiResponse = `Here's my analysis of the situation...
-
-// <execute_command>
-//   <command>ls -la</command>
-// </execute_command>
-
-// <write_to_file>
-//   <path>./example.txt</path>
-//   <content>Hello, World!</content>
-// </write_to_file>`;
-//
-// const { normalText, toolCalls } = parseAIResponse(aiResponse);
-// console.log(normalText);
-// console.log(toolCalls);
-
-// Convert OpenAI response to Anthropic format
-export function convertO1ResponseToAnthropicMessage(
-	completion: OpenAI.Chat.Completions.ChatCompletion,
-): Anthropic.Messages.Message {
-	const openAiMessage = completion.choices[0].message
-	const { normalText, toolCalls } = parseAIResponse(openAiMessage.content || "")
-
-	const anthropicMessage: Anthropic.Messages.Message = {
-		id: completion.id,
-		type: "message",
-		role: openAiMessage.role, // always "assistant"
-		content: [
-			{
-				type: "text",
-				text: normalText,
-			},
-		],
-		model: completion.model,
-		stop_reason: (() => {
-			switch (completion.choices[0].finish_reason) {
-				case "stop":
-					return "end_turn"
-				case "length":
-					return "max_tokens"
-				case "tool_calls":
-					return "tool_use"
-				case "content_filter": // Anthropic doesn't have an exact equivalent
-				default:
-					return null
-			}
-		})(),
-		stop_sequence: null, // which custom stop_sequence was generated, if any (not applicable if you don't use stop_sequence)
-		usage: {
-			input_tokens: completion.usage?.prompt_tokens || 0,
-			output_tokens: completion.usage?.completion_tokens || 0,
-		},
-	}
-
-	if (toolCalls.length > 0) {
-		anthropicMessage.content.push(
-			...toolCalls.map((toolCall: ToolCall, index: number): Anthropic.ToolUseBlock => {
-				return {
-					type: "tool_use",
-					id: `call_${index}_${Date.now()}`, // Generate a unique ID for each tool call
-					name: toolCall.tool,
-					input: toolCall.tool_input,
-				}
-			}),
-		)
-	}
-
-	return anthropicMessage
-}
-
-// Example usage:
-// const openAICompletion = {
-//     id: "cmpl-123",
-//     choices: [{
-//         message: {
-//             role: "assistant",
-//             content: "Here's my analysis...\n\n<execute_command>\n  <command>ls -la</command>\n</execute_command>"
-//         },
-//         finish_reason: "stop"
-//     }],
-//     model: "gpt-3.5-turbo",
-//     usage: { prompt_tokens: 50, completion_tokens: 100 }
-// };
-// const anthropicMessage = convertO1ResponseToAnthropicMessage(openAICompletion);
-// console.log(anthropicMessage);

+ 98 - 41
src/core/Cline.ts

@@ -54,7 +54,7 @@ import { parseMentions } from "./mentions"
 import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message"
 import { formatResponse } from "./prompts/responses"
 import { SYSTEM_PROMPT } from "./prompts/system"
-import { modes, defaultModeSlug, getModeBySlug } from "../shared/modes"
+import { modes, defaultModeSlug, getModeBySlug, getFullModeDetails } from "../shared/modes"
 import { truncateConversationIfNeeded } from "./sliding-window"
 import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider"
 import { detectCodeOmission } from "../integrations/editor/detect-omission"
@@ -63,7 +63,7 @@ import { OpenRouterHandler } from "../api/providers/openrouter"
 import { McpHub } from "../services/mcp/McpHub"
 import crypto from "crypto"
 import { insertGroups } from "./diff/insert-groups"
-import { EXPERIMENT_IDS, experiments as Experiments } from "../shared/experiments"
+import { EXPERIMENT_IDS, experiments as Experiments, ExperimentId } from "../shared/experiments"
 
 const cwd =
 	vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution
@@ -73,6 +73,20 @@ type UserContent = Array<
 	Anthropic.TextBlockParam | Anthropic.ImageBlockParam | Anthropic.ToolUseBlockParam | Anthropic.ToolResultBlockParam
 >
 
+export type ClineOptions = {
+	provider: ClineProvider
+	apiConfiguration: ApiConfiguration
+	customInstructions?: string
+	enableDiff?: boolean
+	enableCheckpoints?: boolean
+	fuzzyMatchThreshold?: number
+	task?: string
+	images?: string[]
+	historyItem?: HistoryItem
+	experiments?: Record<string, boolean>
+	startTask?: boolean
+}
+
 export class Cline {
 	readonly taskId: string
 	api: ApiHandler
@@ -118,19 +132,20 @@ export class Cline {
 	private didAlreadyUseTool = false
 	private didCompleteReadingStream = false
 
-	constructor(
-		provider: ClineProvider,
-		apiConfiguration: ApiConfiguration,
-		customInstructions?: string,
-		enableDiff?: boolean,
-		enableCheckpoints?: boolean,
-		fuzzyMatchThreshold?: number,
-		task?: string | undefined,
-		images?: string[] | undefined,
-		historyItem?: HistoryItem | undefined,
-		experiments?: Record<string, boolean>,
-	) {
-		if (!task && !images && !historyItem) {
+	constructor({
+		provider,
+		apiConfiguration,
+		customInstructions,
+		enableDiff,
+		enableCheckpoints,
+		fuzzyMatchThreshold,
+		task,
+		images,
+		historyItem,
+		experiments,
+		startTask = true,
+	}: ClineOptions) {
+		if (startTask && !task && !images && !historyItem) {
 			throw new Error("Either historyItem or task/images must be provided")
 		}
 
@@ -153,11 +168,31 @@ export class Cline {
 		// Initialize diffStrategy based on current state
 		this.updateDiffStrategy(Experiments.isEnabled(experiments ?? {}, EXPERIMENT_IDS.DIFF_STRATEGY))
 
-		if (task || images) {
-			this.startTask(task, images)
+		if (startTask) {
+			if (task || images) {
+				this.startTask(task, images)
+			} else if (historyItem) {
+				this.resumeTaskFromHistory()
+			} else {
+				throw new Error("Either historyItem or task/images must be provided")
+			}
+		}
+	}
+
+	static create(options: ClineOptions): [Cline, Promise<void>] {
+		const instance = new Cline({ ...options, startTask: false })
+		const { images, task, historyItem } = options
+		let promise
+
+		if (images || task) {
+			promise = instance.startTask(task, images)
 		} else if (historyItem) {
-			this.resumeTaskFromHistory()
+			promise = instance.resumeTaskFromHistory()
+		} else {
+			throw new Error("Either historyItem or task/images must be provided")
 		}
+
+		return [instance, promise]
 	}
 
 	// Add method to update diffStrategy
@@ -698,7 +733,7 @@ export class Cline {
 			text:
 				`[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.${
 					wasRecent
-						? "\n\nIMPORTANT: If the last tool use was a write_to_file that was interrupted, the file was reverted back to its original state before the interrupted edit, and you do NOT need to re-read the file as you already have its up-to-date contents."
+						? "\n\nIMPORTANT: If the last tool use was a create_file that was interrupted, the file was reverted back to its original state before the interrupted edit, and you do NOT need to re-read the file as you already have its up-to-date contents."
 						: ""
 				}` +
 				(responseText
@@ -745,8 +780,12 @@ export class Cline {
 		}
 	}
 
-	async abortTask() {
+	async abortTask(isAbandoned = false) {
 		// Will stop any autonomously running promises.
+		if (isAbandoned) {
+			this.abandoned = true
+		}
+
 		this.abort = true
 
 		this.terminalManager.disposeAll()
@@ -1102,9 +1141,9 @@ export class Cline {
 							return `[${block.name} for '${block.params.command}']`
 						case "read_file":
 							return `[${block.name} for '${block.params.path}']`
-						case "write_to_file":
+						case "create_file":
 							return `[${block.name} for '${block.params.path}']`
-						case "apply_diff":
+						case "edit_file":
 							return `[${block.name} for '${block.params.path}']`
 						case "search_files":
 							return `[${block.name} for '${block.params.regex}'${
@@ -1256,7 +1295,7 @@ export class Cline {
 						mode ?? defaultModeSlug,
 						customModes ?? [],
 						{
-							apply_diff: this.diffEnabled,
+							edit_file: this.diffEnabled,
 						},
 						block.params,
 					)
@@ -1267,7 +1306,7 @@ export class Cline {
 				}
 
 				switch (block.name) {
-					case "write_to_file": {
+					case "create_file": {
 						const relPath: string | undefined = block.params.path
 						let newContent: string | undefined = block.params.content
 						let predictedLineCount: number | undefined = parseInt(block.params.line_count ?? "0")
@@ -1332,20 +1371,20 @@ export class Cline {
 							} else {
 								if (!relPath) {
 									this.consecutiveMistakeCount++
-									pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "path"))
+									pushToolResult(await this.sayAndCreateMissingParamError("create_file", "path"))
 									await this.diffViewProvider.reset()
 									break
 								}
 								if (!newContent) {
 									this.consecutiveMistakeCount++
-									pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "content"))
+									pushToolResult(await this.sayAndCreateMissingParamError("create_file", "content"))
 									await this.diffViewProvider.reset()
 									break
 								}
 								if (!predictedLineCount) {
 									this.consecutiveMistakeCount++
 									pushToolResult(
-										await this.sayAndCreateMissingParamError("write_to_file", "line_count"),
+										await this.sayAndCreateMissingParamError("create_file", "line_count"),
 									)
 									await this.diffViewProvider.reset()
 									break
@@ -1382,7 +1421,7 @@ export class Cline {
 											formatResponse.toolError(
 												`Content appears to be truncated (file has ${
 													newContent.split("\n").length
-												} lines but was predicted to have ${predictedLineCount} lines), and found comments indicating omitted code (e.g., '// rest of code unchanged', '/* previous code */'). Please provide the complete file content without any omissions if possible, or otherwise use the 'apply_diff' tool to apply the diff to the original file.`,
+												} lines but was predicted to have ${predictedLineCount} lines), and found comments indicating omitted code (e.g., '// rest of code unchanged', '/* previous code */'). Please provide the complete file content without any omissions if possible, or otherwise use the 'edit_file' tool to apply the diff to the original file.`,
 											),
 										)
 										break
@@ -1458,7 +1497,7 @@ export class Cline {
 							break
 						}
 					}
-					case "apply_diff": {
+					case "edit_file": {
 						const relPath: string | undefined = block.params.path
 						const diffContent: string | undefined = block.params.diff
 
@@ -1476,12 +1515,12 @@ export class Cline {
 							} else {
 								if (!relPath) {
 									this.consecutiveMistakeCount++
-									pushToolResult(await this.sayAndCreateMissingParamError("apply_diff", "path"))
+									pushToolResult(await this.sayAndCreateMissingParamError("edit_file", "path"))
 									break
 								}
 								if (!diffContent) {
 									this.consecutiveMistakeCount++
-									pushToolResult(await this.sayAndCreateMissingParamError("apply_diff", "diff"))
+									pushToolResult(await this.sayAndCreateMissingParamError("edit_file", "diff"))
 									break
 								}
 
@@ -2194,7 +2233,7 @@ export class Cline {
 											formatResponse.toolResult(
 												`The browser action has been executed. The console logs and screenshot have been captured for your analysis.\n\nConsole logs:\n${
 													browserActionResult.logs || "(No new logs)"
-												}\n\n(REMEMBER: if you need to proceed to using non-\`browser_action\` tools or launch a new browser, you MUST first close this browser. For example, if after analyzing the logs and screenshot you need to edit a file, you must first close the browser before you can use the write_to_file tool.)`,
+												}\n\n(REMEMBER: if you need to proceed to using non-\`browser_action\` tools or launch a new browser, you MUST first close this browser. For example, if after analyzing the logs and screenshot you need to edit a file, you must first close the browser before you can use the create_file tool.)`,
 												browserActionResult.screenshot ? [browserActionResult.screenshot] : [],
 											),
 										)
@@ -2711,7 +2750,7 @@ export class Cline {
 
 		/*
 		Seeing out of bounds is fine, it means that the next too call is being built up and ready to add to assistantMessageContent to present.
-		When you see the UI inactive during this, it means that a tool is breaking without presenting any UI. For example the write_to_file tool was breaking when relpath was undefined, and for invalid relpath it never presented UI.
+		When you see the UI inactive during this, it means that a tool is breaking without presenting any UI. For example the create_file tool was breaking when relpath was undefined, and for invalid relpath it never presented UI.
 		*/
 		this.presentAssistantMessageLocked = false // this needs to be placed here, if not then calling this.presentAssistantMessage below would fail (sometimes) since it's locked
 		// NOTE: when tool is rejected, iterator stream is interrupted and it waits for userMessageContentReady to be true. Future calls to present will skip execution since didRejectTool and iterate until contentIndex is set to message length and it sets userMessageContentReady to true itself (instead of preemptively doing it in iterator)
@@ -2836,8 +2875,6 @@ export class Cline {
 			}
 
 			const abortStream = async (cancelReason: ClineApiReqCancelReason, streamingFailedMessage?: string) => {
-				console.log(`[Cline#abortStream] cancelReason = ${cancelReason}`)
-
 				if (this.diffViewProvider.isEditing) {
 					await this.diffViewProvider.revertChanges() // closes diff view
 				}
@@ -2969,7 +3006,7 @@ export class Cline {
 			}
 
 			// need to call here in case the stream was aborted
-			if (this.abort) {
+			if (this.abort || this.abandoned) {
 				throw new Error("Roo Code instance aborted")
 			}
 
@@ -3237,16 +3274,36 @@ export class Cline {
 		details += `\n\n# Current Context Size (Tokens)\n${contextTokens ? `${contextTokens.toLocaleString()} (${contextPercentage}%)` : "(Not available)"}`
 
 		// Add current mode and any mode-specific warnings
-		const { mode, customModes } = (await this.providerRef.deref()?.getState()) ?? {}
+		const {
+			mode,
+			customModes,
+			customModePrompts,
+			experiments = {} as Record<ExperimentId, boolean>,
+			customInstructions: globalCustomInstructions,
+			preferredLanguage,
+		} = (await this.providerRef.deref()?.getState()) ?? {}
 		const currentMode = mode ?? defaultModeSlug
-		details += `\n\n# Current Mode\n${currentMode}`
+		const modeDetails = await getFullModeDetails(currentMode, customModes, customModePrompts, {
+			cwd,
+			globalCustomInstructions,
+			preferredLanguage,
+		})
+		details += `\n\n# Current Mode\n`
+		details += `<slug>${currentMode}</slug>\n`
+		details += `<name>${modeDetails.name}</name>\n`
+		if (Experiments.isEnabled(experiments ?? {}, EXPERIMENT_IDS.POWER_STEERING)) {
+			details += `<role>${modeDetails.roleDefinition}</role>\n`
+			if (modeDetails.customInstructions) {
+				details += `<custom_instructions>${modeDetails.customInstructions}</custom_instructions>\n`
+			}
+		}
 
 		// Add warning if not in code mode
 		if (
-			!isToolAllowedForMode("write_to_file", currentMode, customModes ?? [], {
-				apply_diff: this.diffEnabled,
+			!isToolAllowedForMode("create_file", currentMode, customModes ?? [], {
+				edit_file: this.diffEnabled,
 			}) &&
-			!isToolAllowedForMode("apply_diff", currentMode, customModes ?? [], { apply_diff: this.diffEnabled })
+			!isToolAllowedForMode("edit_file", currentMode, customModes ?? [], { edit_file: this.diffEnabled })
 		) {
 			const currentModeName = getModeBySlug(currentMode, customModes)?.name ?? currentMode
 			const defaultModeName = getModeBySlug(defaultModeSlug, customModes)?.name ?? defaultModeSlug

+ 139 - 84
src/core/__tests__/Cline.test.ts

@@ -1,3 +1,5 @@
+// npx jest src/core/__tests__/Cline.test.ts
+
 import { Cline } from "../Cline"
 import { ClineProvider } from "../webview/ClineProvider"
 import { ApiConfiguration, ModelInfo } from "../../shared/api"
@@ -82,7 +84,20 @@ jest.mock("fs/promises", () => ({
 			return Promise.resolve(JSON.stringify(mockMessages))
 		}
 		if (filePath.includes("api_conversation_history.json")) {
-			return Promise.resolve("[]")
+			return Promise.resolve(
+				JSON.stringify([
+					{
+						role: "user",
+						content: [{ type: "text", text: "historical task" }],
+						ts: Date.now(),
+					},
+					{
+						role: "assistant",
+						content: [{ type: "text", text: "I'll help you with that task." }],
+						ts: Date.now(),
+					},
+				]),
+			)
 		}
 		return Promise.resolve("[]")
 	}),
@@ -295,93 +310,102 @@ describe("Cline", () => {
 			taskDirPath: "/mock/storage/path/tasks/123",
 			apiConversationHistoryFilePath: "/mock/storage/path/tasks/123/api_conversation_history.json",
 			uiMessagesFilePath: "/mock/storage/path/tasks/123/ui_messages.json",
-			apiConversationHistory: [],
+			apiConversationHistory: [
+				{
+					role: "user",
+					content: [{ type: "text", text: "historical task" }],
+					ts: Date.now(),
+				},
+				{
+					role: "assistant",
+					content: [{ type: "text", text: "I'll help you with that task." }],
+					ts: Date.now(),
+				},
+			],
 		}))
 	})
 
 	describe("constructor", () => {
-		it("should respect provided settings", () => {
-			const cline = new Cline(
-				mockProvider,
-				mockApiConfig,
-				"custom instructions",
-				false,
-				false,
-				0.95, // 95% threshold
-				"test task",
-			)
+		it("should respect provided settings", async () => {
+			const [cline, task] = Cline.create({
+				provider: mockProvider,
+				apiConfiguration: mockApiConfig,
+				customInstructions: "custom instructions",
+				fuzzyMatchThreshold: 0.95,
+				task: "test task",
+			})
 
 			expect(cline.customInstructions).toBe("custom instructions")
 			expect(cline.diffEnabled).toBe(false)
+
+			await cline.abortTask(true)
+			await task.catch(() => {})
 		})
 
-		it("should use default fuzzy match threshold when not provided", () => {
-			const cline = new Cline(
-				mockProvider,
-				mockApiConfig,
-				"custom instructions",
-				true,
-				false,
-				undefined,
-				"test task",
-			)
+		it("should use default fuzzy match threshold when not provided", async () => {
+			const [cline, task] = await Cline.create({
+				provider: mockProvider,
+				apiConfiguration: mockApiConfig,
+				customInstructions: "custom instructions",
+				enableDiff: true,
+				fuzzyMatchThreshold: 0.95,
+				task: "test task",
+			})
 
 			expect(cline.diffEnabled).toBe(true)
 			// The diff strategy should be created with default threshold (1.0)
 			expect(cline.diffStrategy).toBeDefined()
+
+			await cline.abortTask(true)
+			await task.catch(() => {})
 		})
 
-		it("should use provided fuzzy match threshold", () => {
+		it("should use provided fuzzy match threshold", async () => {
 			const getDiffStrategySpy = jest.spyOn(require("../diff/DiffStrategy"), "getDiffStrategy")
 
-			const cline = new Cline(
-				mockProvider,
-				mockApiConfig,
-				"custom instructions",
-				true,
-				false,
-				0.9, // 90% threshold
-				"test task",
-			)
+			const [cline, task] = await Cline.create({
+				provider: mockProvider,
+				apiConfiguration: mockApiConfig,
+				customInstructions: "custom instructions",
+				enableDiff: true,
+				fuzzyMatchThreshold: 0.9,
+				task: "test task",
+			})
 
 			expect(cline.diffEnabled).toBe(true)
 			expect(cline.diffStrategy).toBeDefined()
 			expect(getDiffStrategySpy).toHaveBeenCalledWith("claude-3-5-sonnet-20241022", 0.9, false)
 
 			getDiffStrategySpy.mockRestore()
+
+			await cline.abortTask(true)
+			await task.catch(() => {})
 		})
 
-		it("should pass default threshold to diff strategy when not provided", () => {
+		it("should pass default threshold to diff strategy when not provided", async () => {
 			const getDiffStrategySpy = jest.spyOn(require("../diff/DiffStrategy"), "getDiffStrategy")
 
-			const cline = new Cline(
-				mockProvider,
-				mockApiConfig,
-				"custom instructions",
-				true,
-				false,
-				undefined,
-				"test task",
-			)
+			const [cline, task] = Cline.create({
+				provider: mockProvider,
+				apiConfiguration: mockApiConfig,
+				customInstructions: "custom instructions",
+				enableDiff: true,
+				task: "test task",
+			})
 
 			expect(cline.diffEnabled).toBe(true)
 			expect(cline.diffStrategy).toBeDefined()
 			expect(getDiffStrategySpy).toHaveBeenCalledWith("claude-3-5-sonnet-20241022", 1.0, false)
 
 			getDiffStrategySpy.mockRestore()
+
+			await cline.abortTask(true)
+			await task.catch(() => {})
 		})
 
 		it("should require either task or historyItem", () => {
 			expect(() => {
-				new Cline(
-					mockProvider,
-					mockApiConfig,
-					undefined, // customInstructions
-					false, // diffEnabled
-					false, // checkpointsEnabled
-					undefined, // fuzzyMatchThreshold
-					undefined, // task
-				)
+				new Cline({ provider: mockProvider, apiConfiguration: mockApiConfig })
 			}).toThrow("Either historyItem or task/images must be provided")
 		})
 	})
@@ -431,7 +455,11 @@ describe("Cline", () => {
 		})
 
 		it("should include timezone information in environment details", async () => {
-			const cline = new Cline(mockProvider, mockApiConfig, undefined, false, false, undefined, "test task")
+			const [cline, task] = Cline.create({
+				provider: mockProvider,
+				apiConfiguration: mockApiConfig,
+				task: "test task",
+			})
 
 			const details = await cline["getEnvironmentDetails"](false)
 
@@ -440,11 +468,21 @@ describe("Cline", () => {
 			expect(details).toMatch(/UTC-7:00/) // Fixed offset for America/Los_Angeles
 			expect(details).toContain("# Current Time")
 			expect(details).toMatch(/1\/1\/2024.*5:00:00 AM.*\(America\/Los_Angeles, UTC-7:00\)/) // Full time string format
+
+			await cline.abortTask(true)
+			await task.catch(() => {})
 		})
 
 		describe("API conversation handling", () => {
 			it("should clean conversation history before sending to API", async () => {
-				const cline = new Cline(mockProvider, mockApiConfig, undefined, false, false, undefined, "test task")
+				const [cline, task] = Cline.create({
+					provider: mockProvider,
+					apiConfiguration: mockApiConfig,
+					task: "test task",
+				})
+
+				cline.abandoned = true
+				await task
 
 				// Mock the API's createMessage method to capture the conversation history
 				const createMessageSpy = jest.fn()
@@ -552,15 +590,12 @@ describe("Cline", () => {
 				]
 
 				// Test with model that supports images
-				const clineWithImages = new Cline(
-					mockProvider,
-					configWithImages,
-					undefined,
-					false,
-					false,
-					undefined,
-					"test task",
-				)
+				const [clineWithImages, taskWithImages] = Cline.create({
+					provider: mockProvider,
+					apiConfiguration: configWithImages,
+					task: "test task",
+				})
+
 				// Mock the model info to indicate image support
 				jest.spyOn(clineWithImages.api, "getModel").mockReturnValue({
 					id: "claude-3-sonnet",
@@ -574,18 +609,16 @@ describe("Cline", () => {
 						outputPrice: 0.75,
 					} as ModelInfo,
 				})
+
 				clineWithImages.apiConversationHistory = conversationHistory
 
 				// Test with model that doesn't support images
-				const clineWithoutImages = new Cline(
-					mockProvider,
-					configWithoutImages,
-					undefined,
-					false,
-					false,
-					undefined,
-					"test task",
-				)
+				const [clineWithoutImages, taskWithoutImages] = Cline.create({
+					provider: mockProvider,
+					apiConfiguration: configWithoutImages,
+					task: "test task",
+				})
+
 				// Mock the model info to indicate no image support
 				jest.spyOn(clineWithoutImages.api, "getModel").mockReturnValue({
 					id: "gpt-3.5-turbo",
@@ -599,6 +632,7 @@ describe("Cline", () => {
 						outputPrice: 0.2,
 					} as ModelInfo,
 				})
+
 				clineWithoutImages.apiConversationHistory = conversationHistory
 
 				// Mock abort state for both instances
@@ -607,6 +641,7 @@ describe("Cline", () => {
 					set: () => {},
 					configurable: true,
 				})
+
 				Object.defineProperty(clineWithoutImages, "abort", {
 					get: () => false,
 					set: () => {},
@@ -621,6 +656,7 @@ describe("Cline", () => {
 					content,
 					"",
 				])
+
 				// Set up mock streams
 				const mockStreamWithImages = (async function* () {
 					yield { type: "text", text: "test response" }
@@ -648,6 +684,12 @@ describe("Cline", () => {
 					},
 				]
 
+				clineWithImages.abandoned = true
+				await taskWithImages.catch(() => {})
+
+				clineWithoutImages.abandoned = true
+				await taskWithoutImages.catch(() => {})
+
 				// Trigger API requests
 				await clineWithImages.recursivelyMakeClineRequests([{ type: "text", text: "test request" }])
 				await clineWithoutImages.recursivelyMakeClineRequests([{ type: "text", text: "test request" }])
@@ -670,8 +712,12 @@ describe("Cline", () => {
 				})
 			})
 
-			it("should handle API retry with countdown", async () => {
-				const cline = new Cline(mockProvider, mockApiConfig, undefined, false, false, undefined, "test task")
+			it.skip("should handle API retry with countdown", async () => {
+				const [cline, task] = Cline.create({
+					provider: mockProvider,
+					apiConfiguration: mockApiConfig,
+					task: "test task",
+				})
 
 				// Mock delay to track countdown timing
 				const mockDelay = jest.fn().mockResolvedValue(undefined)
@@ -785,10 +831,17 @@ describe("Cline", () => {
 				expect(errorMessage).toBe(
 					`${mockError.message}\n\nRetry attempt 1\nRetrying in ${baseDelay} seconds...`,
 				)
+
+				await cline.abortTask(true)
+				await task.catch(() => {})
 			})
 
-			it("should not apply retry delay twice", async () => {
-				const cline = new Cline(mockProvider, mockApiConfig, undefined, false, false, undefined, "test task")
+			it.skip("should not apply retry delay twice", async () => {
+				const [cline, task] = Cline.create({
+					provider: mockProvider,
+					apiConfiguration: mockApiConfig,
+					task: "test task",
+				})
 
 				// Mock delay to track countdown timing
 				const mockDelay = jest.fn().mockResolvedValue(undefined)
@@ -901,19 +954,18 @@ describe("Cline", () => {
 					undefined,
 					false,
 				)
+
+				await cline.abortTask(true)
+				await task.catch(() => {})
 			})
 
 			describe("loadContext", () => {
 				it("should process mentions in task and feedback tags", async () => {
-					const cline = new Cline(
-						mockProvider,
-						mockApiConfig,
-						undefined,
-						false,
-						false,
-						undefined,
-						"test task",
-					)
+					const [cline, task] = Cline.create({
+						provider: mockProvider,
+						apiConfiguration: mockApiConfig,
+						task: "test task",
+					})
 
 					// Mock parseMentions to track calls
 					const mockParseMentions = jest.fn().mockImplementation((text) => `processed: ${text}`)
@@ -978,6 +1030,9 @@ describe("Cline", () => {
 					const toolResult2 = processedContent[3] as Anthropic.ToolResultBlockParam
 					const content2 = Array.isArray(toolResult2.content) ? toolResult2.content[0] : toolResult2.content
 					expect((content2 as Anthropic.TextBlockParam).text).toBe("Regular tool result with @/path")
+
+					await cline.abortTask(true)
+					await task.catch(() => {})
 				})
 			})
 		})

+ 20 - 20
src/core/__tests__/mode-validator.test.ts

@@ -59,7 +59,7 @@ describe("mode-validator", () => {
 				]
 				// Should allow tools from read and edit groups
 				expect(isToolAllowedForMode("read_file", "custom-mode", customModes)).toBe(true)
-				expect(isToolAllowedForMode("write_to_file", "custom-mode", customModes)).toBe(true)
+				expect(isToolAllowedForMode("create_file", "custom-mode", customModes)).toBe(true)
 				// Should not allow tools from other groups
 				expect(isToolAllowedForMode("execute_command", "custom-mode", customModes)).toBe(false)
 			})
@@ -76,7 +76,7 @@ describe("mode-validator", () => {
 				// Should allow tools from read group
 				expect(isToolAllowedForMode("read_file", codeMode, customModes)).toBe(true)
 				// Should not allow tools from other groups
-				expect(isToolAllowedForMode("write_to_file", codeMode, customModes)).toBe(false)
+				expect(isToolAllowedForMode("create_file", codeMode, customModes)).toBe(false)
 			})
 
 			it("respects tool requirements in custom modes", () => {
@@ -88,39 +88,39 @@ describe("mode-validator", () => {
 						groups: ["edit"] as const,
 					},
 				]
-				const requirements = { apply_diff: false }
+				const requirements = { edit_file: false }
 
 				// Should respect disabled requirement even if tool group is allowed
-				expect(isToolAllowedForMode("apply_diff", "custom-mode", customModes, requirements)).toBe(false)
+				expect(isToolAllowedForMode("edit_file", "custom-mode", customModes, requirements)).toBe(false)
 
 				// Should allow other edit tools
-				expect(isToolAllowedForMode("write_to_file", "custom-mode", customModes, requirements)).toBe(true)
+				expect(isToolAllowedForMode("create_file", "custom-mode", customModes, requirements)).toBe(true)
 			})
 		})
 
 		describe("tool requirements", () => {
 			it("respects tool requirements when provided", () => {
-				const requirements = { apply_diff: false }
-				expect(isToolAllowedForMode("apply_diff", codeMode, [], requirements)).toBe(false)
+				const requirements = { edit_file: false }
+				expect(isToolAllowedForMode("edit_file", codeMode, [], requirements)).toBe(false)
 
-				const enabledRequirements = { apply_diff: true }
-				expect(isToolAllowedForMode("apply_diff", codeMode, [], enabledRequirements)).toBe(true)
+				const enabledRequirements = { edit_file: true }
+				expect(isToolAllowedForMode("edit_file", codeMode, [], enabledRequirements)).toBe(true)
 			})
 
 			it("allows tools when their requirements are not specified", () => {
 				const requirements = { some_other_tool: true }
-				expect(isToolAllowedForMode("apply_diff", codeMode, [], requirements)).toBe(true)
+				expect(isToolAllowedForMode("edit_file", codeMode, [], requirements)).toBe(true)
 			})
 
 			it("handles undefined and empty requirements", () => {
-				expect(isToolAllowedForMode("apply_diff", codeMode, [], undefined)).toBe(true)
-				expect(isToolAllowedForMode("apply_diff", codeMode, [], {})).toBe(true)
+				expect(isToolAllowedForMode("edit_file", codeMode, [], undefined)).toBe(true)
+				expect(isToolAllowedForMode("edit_file", codeMode, [], {})).toBe(true)
 			})
 
 			it("prioritizes requirements over mode configuration", () => {
-				const requirements = { apply_diff: false }
+				const requirements = { edit_file: false }
 				// Even in code mode which allows all tools, disabled requirement should take precedence
-				expect(isToolAllowedForMode("apply_diff", codeMode, [], requirements)).toBe(false)
+				expect(isToolAllowedForMode("edit_file", codeMode, [], requirements)).toBe(false)
 			})
 		})
 	})
@@ -137,19 +137,19 @@ describe("mode-validator", () => {
 		})
 
 		it("throws error when tool requirement is not met", () => {
-			const requirements = { apply_diff: false }
-			expect(() => validateToolUse("apply_diff", codeMode, [], requirements)).toThrow(
-				'Tool "apply_diff" is not allowed in code mode.',
+			const requirements = { edit_file: false }
+			expect(() => validateToolUse("edit_file", codeMode, [], requirements)).toThrow(
+				'Tool "edit_file" is not allowed in code mode.',
 			)
 		})
 
 		it("does not throw when tool requirement is met", () => {
-			const requirements = { apply_diff: true }
-			expect(() => validateToolUse("apply_diff", codeMode, [], requirements)).not.toThrow()
+			const requirements = { edit_file: true }
+			expect(() => validateToolUse("edit_file", codeMode, [], requirements)).not.toThrow()
 		})
 
 		it("handles undefined requirements gracefully", () => {
-			expect(() => validateToolUse("apply_diff", codeMode, [], undefined)).not.toThrow()
+			expect(() => validateToolUse("edit_file", codeMode, [], undefined)).not.toThrow()
 		})
 	})
 })

+ 3 - 3
src/core/assistant-message/index.ts

@@ -11,8 +11,8 @@ export interface TextContent {
 export const toolUseNames = [
 	"execute_command",
 	"read_file",
-	"write_to_file",
-	"apply_diff",
+	"create_file",
+	"edit_file",
 	"insert_content",
 	"search_and_replace",
 	"search_files",
@@ -80,7 +80,7 @@ export interface ReadFileToolUse extends ToolUse {
 }
 
 export interface WriteToFileToolUse extends ToolUse {
-	name: "write_to_file"
+	name: "create_file"
 	params: Partial<Pick<Record<ToolParamName, string>, "path" | "content" | "line_count">>
 }
 

+ 2 - 2
src/core/assistant-message/parse-assistant-message.ts

@@ -61,9 +61,9 @@ export function parseAssistantMessage(assistantMessage: string) {
 
 				// there's no current param, and not starting a new param
 
-				// special case for write_to_file where file contents could contain the closing tag, in which case the param would have closed and we end up with the rest of the file contents here. To work around this, we get the string between the starting content tag and the LAST content tag.
+				// special case for create_file where file contents could contain the closing tag, in which case the param would have closed and we end up with the rest of the file contents here. To work around this, we get the string between the starting content tag and the LAST content tag.
 				const contentParamName: ToolParamName = "content"
-				if (currentToolUse.name === "write_to_file" && accumulator.endsWith(`</${contentParamName}>`)) {
+				if (currentToolUse.name === "create_file" && accumulator.endsWith(`</${contentParamName}>`)) {
 					const toolContent = accumulator.slice(currentToolUseStartIndex)
 					const contentStartTag = `<${contentParamName}>`
 					const contentEndTag = `</${contentParamName}>`

+ 1 - 1
src/core/diff/strategies/__tests__/new-unified.test.ts

@@ -29,7 +29,7 @@ describe("main", () => {
 			const cwd = "/test/path"
 			const description = strategy.getToolDescription({ cwd })
 
-			expect(description).toContain("apply_diff Tool - Generate Precise Code Changes")
+			expect(description).toContain("edit_file Tool - Generate Precise Code Changes")
 			expect(description).toContain(cwd)
 			expect(description).toContain("Step-by-Step Instructions")
 			expect(description).toContain("Requirements")

+ 2 - 2
src/core/diff/strategies/__tests__/search-replace.test.ts

@@ -1544,8 +1544,8 @@ function two() {
 			expect(description).toContain("<<<<<<< SEARCH")
 			expect(description).toContain("=======")
 			expect(description).toContain(">>>>>>> REPLACE")
-			expect(description).toContain("<apply_diff>")
-			expect(description).toContain("</apply_diff>")
+			expect(description).toContain("<edit_file>")
+			expect(description).toContain("</edit_file>")
 		})
 
 		it("should document start_line and end_line parameters", async () => {

+ 1 - 1
src/core/diff/strategies/__tests__/unified.test.ts

@@ -12,7 +12,7 @@ describe("UnifiedDiffStrategy", () => {
 			const cwd = "/test/path"
 			const description = strategy.getToolDescription({ cwd })
 
-			expect(description).toContain("apply_diff")
+			expect(description).toContain("edit_file")
 			expect(description).toContain(cwd)
 			expect(description).toContain("Parameters:")
 			expect(description).toContain("Format Requirements:")

+ 3 - 3
src/core/diff/strategies/new-unified/index.ts

@@ -108,7 +108,7 @@ export class NewUnifiedDiffStrategy implements DiffStrategy {
 	}
 
 	getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
-		return `# apply_diff Tool - Generate Precise Code Changes
+		return `# edit_file Tool - Generate Precise Code Changes
 
 Generate a unified diff that can be cleanly applied to modify code files.
 
@@ -168,12 +168,12 @@ Parameters:
 - diff: (required) Unified diff content in unified format to apply to the file.
 
 Usage:
-<apply_diff>
+<edit_file>
 <path>path/to/file.ext</path>
 <diff>
 Your diff here
 </diff>
-</apply_diff>`
+</edit_file>`
 	}
 
 	// Helper function to split a hunk into smaller hunks based on contiguous changes

+ 3 - 3
src/core/diff/strategies/search-replace.ts

@@ -40,7 +40,7 @@ export class SearchReplaceDiffStrategy implements DiffStrategy {
 	}
 
 	getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
-		return `## apply_diff
+		return `## edit_file
 Description: Request to replace existing code using a search and replace block.
 This tool allows for precise, surgical replaces to files by specifying exactly what content to search for and what to replace it with.
 The tool will maintain proper indentation and formatting while making changes.
@@ -91,14 +91,14 @@ def calculate_total(items):
 \`\`\`
 
 Usage:
-<apply_diff>
+<edit_file>
 <path>File path here</path>
 <diff>
 Your search/replace content here
 </diff>
 <start_line>1</start_line>
 <end_line>5</end_line>
-</apply_diff>`
+</edit_file>`
 	}
 
 	async applyDiff(

+ 3 - 3
src/core/diff/strategies/unified.ts

@@ -3,7 +3,7 @@ import { DiffStrategy, DiffResult } from "../types"
 
 export class UnifiedDiffStrategy implements DiffStrategy {
 	getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
-		return `## apply_diff
+		return `## edit_file
 Description: Apply a unified diff to a file at the specified path. This tool is useful when you need to make specific modifications to a file based on a set of changes provided in unified diff format (diff -U3).
 
 Parameters:
@@ -100,12 +100,12 @@ Best Practices:
 4. Verify line numbers match the line numbers you have in the file
 
 Usage:
-<apply_diff>
+<edit_file>
 <path>File path here</path>
 <diff>
 Your diff here
 </diff>
-</apply_diff>`
+</edit_file>`
 	}
 
 	async applyDiff(originalContent: string, diffContent: string): Promise<DiffResult> {

+ 142 - 142
src/core/prompts/__tests__/__snapshots__/system.test.ts.snap

@@ -94,23 +94,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -129,7 +129,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -249,7 +249,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -266,9 +266,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -417,23 +417,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -452,7 +452,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -572,7 +572,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -589,9 +589,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -740,23 +740,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -775,7 +775,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -895,7 +895,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -912,9 +912,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -1063,23 +1063,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -1098,7 +1098,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## browser_action
 Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
@@ -1264,7 +1264,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 - You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.
   - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser.
@@ -1283,9 +1283,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -1435,23 +1435,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -1470,7 +1470,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -1983,7 +1983,7 @@ IMPORTANT: Regardless of what else you see in the MCP settings file, you must de
 
 ## Editing MCP Servers
 
-The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: (None running currently), e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use write_to_file to make changes to the files.
+The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: (None running currently), e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use create_file to make changes to the files.
 
 However some MCP servers may be running from installed packages rather than a local repository, in which case it may make more sense to create a new MCP server.
 
@@ -2001,7 +2001,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.
 
@@ -2020,9 +2020,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -2171,23 +2171,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -2206,7 +2206,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## browser_action
 Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
@@ -2372,7 +2372,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 - You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.
   - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser.
@@ -2391,9 +2391,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -2543,44 +2543,7 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
-Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
-Parameters:
-- path: (required) The path of the file to write to (relative to the current working directory /test/path)
-- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
-- line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
-Usage:
-<write_to_file>
-<path>File path here</path>
-<content>
-Your file content here
-</content>
-<line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
-
-Example: Requesting to write to frontend-config.json
-<write_to_file>
-<path>frontend-config.json</path>
-<content>
-{
-  "apiEndpoint": "https://api.example.com",
-  "theme": {
-    "primaryColor": "#007bff",
-    "secondaryColor": "#6c757d",
-    "fontFamily": "Arial, sans-serif"
-  },
-  "features": {
-    "darkMode": true,
-    "notifications": true,
-    "analytics": false
-  },
-  "version": "1.0.0"
-}
-</content>
-<line_count>14</line_count>
-</write_to_file>
-
-## apply_diff
+## edit_file
 Description: Request to replace existing code using a search and replace block.
 This tool allows for precise, surgical replaces to files by specifying exactly what content to search for and what to replace it with.
 The tool will maintain proper indentation and formatting while making changes.
@@ -2631,14 +2594,51 @@ def calculate_total(items):
 \`\`\`
 
 Usage:
-<apply_diff>
+<edit_file>
 <path>File path here</path>
 <diff>
 Your search/replace content here
 </diff>
 <start_line>1</start_line>
 <end_line>5</end_line>
-</apply_diff>
+</edit_file>
+
+## create_file
+Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
+Parameters:
+- path: (required) The path of the file to write to (relative to the current working directory /test/path)
+- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
+- line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
+Usage:
+<create_file>
+<path>File path here</path>
+<content>
+Your file content here
+</content>
+<line_count>total number of lines in the file, including empty lines</line_count>
+</create_file>
+
+Example: Requesting to write to frontend-config.json
+<create_file>
+<path>frontend-config.json</path>
+<content>
+{
+  "apiEndpoint": "https://api.example.com",
+  "theme": {
+    "primaryColor": "#007bff",
+    "secondaryColor": "#6c757d",
+    "fontFamily": "Arial, sans-serif"
+  },
+  "features": {
+    "darkMode": true,
+    "notifications": true,
+    "analytics": false
+  },
+  "version": "1.0.0"
+}
+</content>
+<line_count>14</line_count>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -2758,7 +2758,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file or apply_diff tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the edit_file or create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -2775,11 +2775,11 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), apply_diff (for replacing lines in existing files).
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
-- You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using edit_file or create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- For editing files, you have access to these tools: edit_file (for replacing lines in existing files), create_file (for creating new files or complete file rewrites).
+- You should always prefer using other editing tools over create_file when making changes to existing files since create_file is much slower and cannot handle large files.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -2928,23 +2928,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -2963,7 +2963,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -3083,7 +3083,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -3100,9 +3100,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -3293,23 +3293,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -3328,7 +3328,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -3505,7 +3505,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.
 
@@ -3524,9 +3524,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -3690,23 +3690,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -3725,7 +3725,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## ask_followup_question
 Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth.
@@ -3831,7 +3831,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -3848,9 +3848,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -4108,7 +4108,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 
 ====
@@ -4125,9 +4125,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
@@ -4309,23 +4309,23 @@ Example: Requesting to list all top level source code definitions in the current
 <path>.</path>
 </list_code_definition_names>
 
-## write_to_file
+## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory /test/path)
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -4344,7 +4344,7 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>
+</create_file>
 
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: /test/path
@@ -4857,7 +4857,7 @@ IMPORTANT: Regardless of what else you see in the MCP settings file, you must de
 
 ## Editing MCP Servers
 
-The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: (None running currently), e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use write_to_file to make changes to the files.
+The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: (None running currently), e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use create_file to make changes to the files.
 
 However some MCP servers may be running from installed packages rather than a local repository, in which case it may make more sense to create a new MCP server.
 
@@ -4875,7 +4875,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the create_file tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.
 - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.
 
@@ -4894,9 +4894,9 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '/test/path', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using create_file to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
   * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"

+ 8 - 8
src/core/prompts/__tests__/sections.test.ts

@@ -33,24 +33,24 @@ describe("getCapabilitiesSection", () => {
 	const cwd = "/test/path"
 	const mcpHub = undefined
 	const mockDiffStrategy: DiffStrategy = {
-		getToolDescription: () => "apply_diff tool description",
+		getToolDescription: () => "edit_file tool description",
 		applyDiff: async (originalContent: string, diffContent: string): Promise<DiffResult> => {
 			return { success: true, content: "mock result" }
 		},
 	}
 
-	test("includes apply_diff in capabilities when diffStrategy is provided", () => {
+	test("includes edit_file in capabilities when diffStrategy is provided", () => {
 		const result = getCapabilitiesSection(cwd, false, mcpHub, mockDiffStrategy)
 
-		expect(result).toContain("or apply_diff")
-		expect(result).toContain("then use the write_to_file or apply_diff tool")
+		expect(result).toContain("or create_file")
+		expect(result).toContain("then use the edit_file or create_file tool")
 	})
 
-	test("excludes apply_diff from capabilities when diffStrategy is undefined", () => {
+	test("excludes edit_file from capabilities when diffStrategy is undefined", () => {
 		const result = getCapabilitiesSection(cwd, false, mcpHub, undefined)
 
-		expect(result).not.toContain("or apply_diff")
-		expect(result).toContain("then use the write_to_file tool")
-		expect(result).not.toContain("write_to_file or apply_diff")
+		expect(result).not.toContain("or edit_file")
+		expect(result).toContain("then use the create_file tool")
+		expect(result).not.toContain("create_file or edit_file")
 	})
 })

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

@@ -288,7 +288,7 @@ describe("SYSTEM_PROMPT", () => {
 			true, // enableMcpServerCreation
 		)
 
-		expect(prompt).toContain("apply_diff")
+		expect(prompt).toContain("edit_file")
 		expect(prompt).toMatchSnapshot()
 	})
 
@@ -310,7 +310,7 @@ describe("SYSTEM_PROMPT", () => {
 			true, // enableMcpServerCreation
 		)
 
-		expect(prompt).not.toContain("apply_diff")
+		expect(prompt).not.toContain("edit_file")
 		expect(prompt).toMatchSnapshot()
 	})
 
@@ -332,7 +332,7 @@ describe("SYSTEM_PROMPT", () => {
 			true, // enableMcpServerCreation
 		)
 
-		expect(prompt).not.toContain("apply_diff")
+		expect(prompt).not.toContain("edit_file")
 		expect(prompt).toMatchSnapshot()
 	})
 
@@ -562,8 +562,8 @@ describe("SYSTEM_PROMPT", () => {
 			)
 
 			// Verify base instruction lists all available tools
-			expect(prompt).toContain("apply_diff (for replacing lines in existing files)")
-			expect(prompt).toContain("write_to_file (for creating new files or complete file rewrites)")
+			expect(prompt).toContain("edit_file (for replacing lines in existing files)")
+			expect(prompt).toContain("create_file (for creating new files or complete file rewrites)")
 			expect(prompt).toContain("insert_content (for adding lines to existing files)")
 			expect(prompt).toContain("search_and_replace (for finding and replacing individual pieces of text)")
 		})
@@ -593,7 +593,7 @@ describe("SYSTEM_PROMPT", () => {
 
 			// Verify detailed instructions for each tool
 			expect(prompt).toContain(
-				"You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.",
+				"You should always prefer using other editing tools over create_file when making changes to existing files since create_file is much slower and cannot handle large files.",
 			)
 			expect(prompt).toContain("The insert_content tool adds lines of text to files")
 			expect(prompt).toContain("The search_and_replace tool finds and replaces text or regex in files")

+ 1 - 1
src/core/prompts/sections/capabilities.ts

@@ -17,7 +17,7 @@ CAPABILITIES
 - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('${cwd}') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
 - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
 - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
-    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the write_to_file${diffStrategy ? " or apply_diff" : ""} tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
+    - For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use ${diffStrategy ? "the edit_file or create_file" : "the create_file"} tool to apply the changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
 - You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.${
 		supportsComputerUse
 			? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n  - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser."

+ 1 - 1
src/core/prompts/sections/mcp-servers.ts

@@ -414,7 +414,7 @@ The user may ask to add tools or resources that may make sense to add to an exis
 				.getServers()
 				.map((server) => server.name)
 				.join(", ") || "(None running currently)"
-		}, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use write_to_file${diffStrategy ? " or apply_diff" : ""} to make changes to the files.
+		}, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use create_file${diffStrategy ? " or edit_file" : ""} to make changes to the files.
 
 However some MCP servers may be running from installed packages rather than a local repository, in which case it may make more sense to create a new MCP server.
 

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

@@ -45,7 +45,7 @@ Both files should follow this structure:
      "roleDefinition": "You are Roo, a UI/UX expert specializing in design systems and frontend development. Your expertise includes:\\n- Creating and maintaining design systems\\n- Implementing responsive and accessible web interfaces\\n- Working with CSS, HTML, and modern frontend frameworks\\n- Ensuring consistent user experiences across platforms", // Required: non-empty
      "groups": [ // Required: array of tool groups (can be empty)
        "read",    // Read files group (read_file, search_files, list_files, list_code_definition_names)
-       "edit",    // Edit files group (write_to_file, apply_diff) - allows editing any file
+       "edit",    // Edit files group (edit_file, create_file) - allows editing any file
        // Or with file restrictions:
        // ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }],  // Edit group that only allows editing markdown files
        "browser", // Browser group (browser_action)

+ 14 - 9
src/core/prompts/sections/rules.ts

@@ -5,11 +5,16 @@ import * as path from "path"
 
 function getEditingInstructions(diffStrategy?: DiffStrategy, experiments?: Record<string, boolean>): string {
 	const instructions: string[] = []
-	const availableTools: string[] = ["write_to_file (for creating new files or complete file rewrites)"]
+	const availableTools: string[] = []
 
 	// Collect available editing tools
 	if (diffStrategy) {
-		availableTools.push("apply_diff (for replacing lines in existing files)")
+		availableTools.push(
+			"edit_file (for replacing lines in existing files)",
+			"create_file (for creating new files or complete file rewrites)",
+		)
+	} else {
+		availableTools.push("create_file (for creating new files or complete file rewrites)")
 	}
 	if (experiments?.["insert_content"]) {
 		availableTools.push("insert_content (for adding lines to existing files)")
@@ -36,16 +41,16 @@ function getEditingInstructions(diffStrategy?: DiffStrategy, experiments?: Recor
 		)
 	}
 
-	instructions.push(
-		"- When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.",
-	)
-
 	if (availableTools.length > 1) {
 		instructions.push(
-			"- You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.",
+			"- You should always prefer using other editing tools over create_file when making changes to existing files since create_file is much slower and cannot handle large files.",
 		)
 	}
 
+	instructions.push(
+		"- When using the create_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.",
+	)
+
 	return instructions.join("\n")
 }
 
@@ -63,8 +68,8 @@ RULES
 - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '${cwd.toPosix()}', so be sure to pass in the correct 'path' parameter when using tools that require a path.
 - Do not use the ~ character or $HOME to refer to the home directory.
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '${cwd.toPosix()}', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '${cwd.toPosix()}'). For example, if you needed to run \`npm install\` in a project outside of '${cwd.toPosix()}', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
-- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
-- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
+- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using ${diffStrategy ? "edit_file or create_file" : "create_file"} to make informed changes.
+- When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the create_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
 ${getEditingInstructions(diffStrategy, experiments)}
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
 - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.

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

@@ -23,7 +23,7 @@ import { ToolArgs } from "./types"
 const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined> = {
 	execute_command: (args) => getExecuteCommandDescription(args),
 	read_file: (args) => getReadFileDescription(args),
-	write_to_file: (args) => getWriteToFileDescription(args),
+	create_file: (args) => getWriteToFileDescription(args),
 	search_files: (args) => getSearchFilesDescription(args),
 	list_files: (args) => getListFilesDescription(args),
 	list_code_definition_names: (args) => getListCodeDefinitionNamesDescription(args),
@@ -36,7 +36,7 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
 	new_task: (args) => getNewTaskDescription(args),
 	insert_content: (args) => getInsertContentDescription(args),
 	search_and_replace: (args) => getSearchAndReplaceDescription(args),
-	apply_diff: (args) =>
+	edit_file: (args) =>
 		args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "",
 }
 

+ 5 - 5
src/core/prompts/tools/write-to-file.ts

@@ -1,23 +1,23 @@
 import { ToolArgs } from "./types"
 
 export function getWriteToFileDescription(args: ToolArgs): string {
-	return `## write_to_file
+	return `## create_file
 Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
 Parameters:
 - path: (required) The path of the file to write to (relative to the current working directory ${args.cwd})
 - content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
 - line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing.
 Usage:
-<write_to_file>
+<create_file>
 <path>File path here</path>
 <content>
 Your file content here
 </content>
 <line_count>total number of lines in the file, including empty lines</line_count>
-</write_to_file>
+</create_file>
 
 Example: Requesting to write to frontend-config.json
-<write_to_file>
+<create_file>
 <path>frontend-config.json</path>
 <content>
 {
@@ -36,5 +36,5 @@ Example: Requesting to write to frontend-config.json
 }
 </content>
 <line_count>14</line_count>
-</write_to_file>`
+</create_file>`
 }

+ 12 - 15
src/core/webview/ClineProvider.ts

@@ -413,18 +413,17 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 		const modePrompt = customModePrompts?.[mode] as PromptComponent
 		const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
 
-		this.cline = new Cline(
-			this,
+		this.cline = new Cline({
+			provider: this,
 			apiConfiguration,
-			effectiveInstructions,
-			diffEnabled,
-			checkpointsEnabled,
+			customInstructions: effectiveInstructions,
+			enableDiff: diffEnabled,
+			enableCheckpoints: checkpointsEnabled,
 			fuzzyMatchThreshold,
 			task,
 			images,
-			undefined,
 			experiments,
-		)
+		})
 	}
 
 	public async initClineWithHistoryItem(historyItem: HistoryItem) {
@@ -444,18 +443,16 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 		const modePrompt = customModePrompts?.[mode] as PromptComponent
 		const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
 
-		this.cline = new Cline(
-			this,
+		this.cline = new Cline({
+			provider: this,
 			apiConfiguration,
-			effectiveInstructions,
-			diffEnabled,
-			checkpointsEnabled,
+			customInstructions: effectiveInstructions,
+			enableDiff: diffEnabled,
+			enableCheckpoints: checkpointsEnabled,
 			fuzzyMatchThreshold,
-			undefined,
-			undefined,
 			historyItem,
 			experiments,
-		)
+		})
 	}
 
 	public async postMessageToWebview(message: ExtensionMessage) {

+ 45 - 17
src/core/webview/__tests__/ClineProvider.test.ts

@@ -9,12 +9,41 @@ import { setSoundEnabled } from "../../../utils/sound"
 import { defaultModeSlug } from "../../../shared/modes"
 import { experimentDefault } from "../../../shared/experiments"
 
-// Mock custom-instructions module
-const mockAddCustomInstructions = jest.fn()
+// Mock setup must come before imports
+jest.mock("../../prompts/sections/custom-instructions")
 
-jest.mock("../../prompts/sections/custom-instructions", () => ({
-	addCustomInstructions: mockAddCustomInstructions,
-}))
+// Mock dependencies
+jest.mock("vscode")
+jest.mock("delay")
+jest.mock(
+	"@modelcontextprotocol/sdk/types.js",
+	() => ({
+		CallToolResultSchema: {},
+		ListResourcesResultSchema: {},
+		ListResourceTemplatesResultSchema: {},
+		ListToolsResultSchema: {},
+		ReadResourceResultSchema: {},
+		ErrorCode: {
+			InvalidRequest: "InvalidRequest",
+			MethodNotFound: "MethodNotFound",
+			InternalError: "InternalError",
+		},
+		McpError: class McpError extends Error {
+			code: string
+			constructor(code: string, message: string) {
+				super(message)
+				this.code = code
+				this.name = "McpError"
+			}
+		},
+	}),
+	{ virtual: true },
+)
+
+// Initialize mocks
+const mockAddCustomInstructions = jest.fn().mockResolvedValue("Combined instructions")
+;(jest.requireMock("../../prompts/sections/custom-instructions") as any).addCustomInstructions =
+	mockAddCustomInstructions
 
 // Mock delay module
 jest.mock("delay", () => {
@@ -78,7 +107,7 @@ jest.mock(
 // Mock DiffStrategy
 jest.mock("../../diff/DiffStrategy", () => ({
 	getDiffStrategy: jest.fn().mockImplementation(() => ({
-		getToolDescription: jest.fn().mockReturnValue("apply_diff tool description"),
+		getToolDescription: jest.fn().mockReturnValue("edit_file tool description"),
 	})),
 }))
 
@@ -661,19 +690,18 @@ describe("ClineProvider", () => {
 		await provider.initClineWithTask("Test task")
 
 		// Verify Cline was initialized with mode-specific instructions
-		expect(Cline).toHaveBeenCalledWith(
+		expect(Cline).toHaveBeenCalledWith({
 			provider,
-			mockApiConfig,
-			modeCustomInstructions,
-			true,
-			false,
-			1.0,
-			"Test task",
-			undefined,
-			undefined,
-			experimentDefault,
-		)
+			apiConfiguration: mockApiConfig,
+			customInstructions: modeCustomInstructions,
+			enableDiff: true,
+			enableCheckpoints: false,
+			fuzzyMatchThreshold: 1.0,
+			task: "Test task",
+			experiments: experimentDefault,
+		})
 	})
+
 	test("handles mode-specific custom instructions updates", async () => {
 		await provider.resolveWebviewView(mockWebviewView)
 		const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as jest.Mock).mock.calls[0][0]

+ 0 - 123
src/integrations/diagnostics/DiagnosticsMonitor.ts

@@ -1,123 +0,0 @@
-/*
-import * as vscode from "vscode"
-import deepEqual from "fast-deep-equal"
-
-type FileDiagnostics = [vscode.Uri, vscode.Diagnostic[]][]
-
-
-About Diagnostics:
-The Problems tab shows diagnostics that have been reported for your project. These diagnostics are categorized into:
-Errors: Critical issues that usually prevent your code from compiling or running correctly.
-Warnings: Potential problems in the code that may not prevent it from running but could cause issues (e.g., bad practices, unused variables).
-Information: Non-critical suggestions or tips (e.g., formatting issues or notes from linters).
-The Problems tab displays diagnostics from various sources:
-1. Language Servers:
-   - TypeScript: Type errors, missing imports, syntax issues
-   - Python: Syntax errors, invalid type hints, undefined variables
-   - JavaScript/Node.js: Parsing and execution errors
-2. Linters:
-   - ESLint: Code style, best practices, potential bugs
-   - Pylint: Unused imports, naming conventions
-   - TSLint: Style and correctness issues in TypeScript
-3. Build Tools:
-   - Webpack: Module resolution failures, build errors
-   - Gulp: Build errors during task execution
-4. Custom Validators:
-   - Extensions can generate custom diagnostics for specific languages or tools
-Each problem typically indicates its source (e.g., language server, linter, build tool).
-Diagnostics update in real-time as you edit code, helping identify issues quickly. For example, if you introduce a syntax error in a TypeScript file, the Problems tab will immediately display the new error.
-
-Notes on diagnostics:
-- linter diagnostics are only captured for open editors
-- this works great for us since when cline edits/creates files its through vscode's textedit api's and we get those diagnostics for free
-- some tools might require you to save the file or manually refresh to clear the problem from the list.
-
-System Prompt
-- You will automatically receive workspace error diagnostics in environment_details. Be mindful that this may include issues beyond the scope of your task or the user's request. Only address errors relevant to your work, and avoid fixing pre-existing or unrelated issues unless the user specifically instructs you to do so.
-- If you are unable to resolve errors provided in environment_details after two attempts, consider using ask_followup_question to ask the user for additional information, such as the latest documentation related to a problematic framework, to help you make progress on the task. If the error remains unresolved after this step, proceed with your task while disregarding the error.
-
-class DiagnosticsMonitor {
-	private diagnosticsChangeEmitter: vscode.EventEmitter<void> = new vscode.EventEmitter<void>()
-	private disposables: vscode.Disposable[] = []
-	private lastDiagnostics: FileDiagnostics = []
-
-	constructor() {
-		this.disposables.push(
-			vscode.languages.onDidChangeDiagnostics(() => {
-				this.diagnosticsChangeEmitter.fire()
-			})
-		)
-	}
-
-	public async getCurrentDiagnostics(shouldWaitForChanges: boolean): Promise<FileDiagnostics> {
-		const currentDiagnostics = this.getDiagnostics()
-		if (!shouldWaitForChanges) {
-			this.lastDiagnostics = currentDiagnostics
-			return currentDiagnostics
-		}
-
-		if (!deepEqual(this.lastDiagnostics, currentDiagnostics)) {
-			this.lastDiagnostics = currentDiagnostics
-			return currentDiagnostics
-		}
-
-		let timeout = 300 // only way this happens is if theres no errors
-
-		// if diagnostics contain existing errors (since the check above didn't trigger) then it's likely cline just did something that should have fixed the error, so we'll give a longer grace period for diagnostics to catch up
-		const hasErrors = currentDiagnostics.some(([_, diagnostics]) =>
-			diagnostics.some((d) => d.severity === vscode.DiagnosticSeverity.Error)
-		)
-		if (hasErrors) {
-			console.log("Existing errors detected, extending timeout", currentDiagnostics)
-			timeout = 10_000
-		}
-
-		return this.waitForUpdatedDiagnostics(timeout)
-	}
-
-	private async waitForUpdatedDiagnostics(timeout: number): Promise<FileDiagnostics> {
-		return new Promise((resolve, reject) => {
-			const timer = setTimeout(() => {
-				cleanup()
-				const finalDiagnostics = this.getDiagnostics()
-				this.lastDiagnostics = finalDiagnostics
-				resolve(finalDiagnostics)
-			}, timeout)
-
-			const disposable = this.diagnosticsChangeEmitter.event(() => {
-				const updatedDiagnostics = this.getDiagnostics() // I thought this would only trigger when diagnostics changed, but that's not the case.
-				if (deepEqual(this.lastDiagnostics, updatedDiagnostics)) {
-					// diagnostics have not changed, ignoring...
-					return
-				}
-				cleanup()
-				this.lastDiagnostics = updatedDiagnostics
-				resolve(updatedDiagnostics)
-			})
-
-			const cleanup = () => {
-				clearTimeout(timer)
-				disposable.dispose()
-			}
-		})
-	}
-
-	private getDiagnostics(): FileDiagnostics {
-		const allDiagnostics = vscode.languages.getDiagnostics()
-		return allDiagnostics
-			.filter(([_, diagnostics]) => diagnostics.some((d) => d.severity === vscode.DiagnosticSeverity.Error))
-			.map(([uri, diagnostics]) => [
-				uri,
-				diagnostics.filter((d) => d.severity === vscode.DiagnosticSeverity.Error),
-			])
-	}
-
-	public dispose() {
-		this.disposables.forEach((d) => d.dispose())
-		this.disposables = []
-		this.diagnosticsChangeEmitter.dispose()
-	}
-}
-
-export default DiagnosticsMonitor
-*/

+ 0 - 0
src/integrations/terminal/TerminalActions.ts


+ 0 - 42
src/integrations/workspace/get-python-env.ts

@@ -1,42 +0,0 @@
-import * as vscode from "vscode"
-
-/*
-Used to get user's current python environment (unnecessary now that we use the IDE's terminal)
-${await (async () => {
-		try {
-			const pythonEnvPath = await getPythonEnvPath()
-			if (pythonEnvPath) {
-				return `\nPython Environment: ${pythonEnvPath}`
-			}
-		} catch {}
-		return ""
-	})()}
-*/
-export async function getPythonEnvPath(): Promise<string | undefined> {
-	const pythonExtension = vscode.extensions.getExtension("ms-python.python")
-
-	if (!pythonExtension) {
-		return undefined
-	}
-
-	// Ensure the Python extension is activated
-	if (!pythonExtension.isActive) {
-		// if the python extension is not active, we can assume the project is not a python project
-		return undefined
-	}
-
-	// Access the Python extension API
-	const pythonApi = pythonExtension.exports
-	// Get the active environment path for the current workspace
-	const workspaceFolder = vscode.workspace.workspaceFolders?.[0]
-	if (!workspaceFolder) {
-		return undefined
-	}
-	// Get the active python environment path for the current workspace
-	const pythonEnv = await pythonApi?.environments?.getActiveEnvironmentPath(workspaceFolder.uri)
-	if (pythonEnv && pythonEnv.path) {
-		return pythonEnv.path
-	} else {
-		return undefined
-	}
-}

+ 10 - 5
src/services/checkpoints/__tests__/LocalCheckpointService.test.ts

@@ -9,6 +9,8 @@ import { simpleGit, SimpleGit } from "simple-git"
 import { CheckpointServiceFactory } from "../CheckpointServiceFactory"
 import { LocalCheckpointService } from "../LocalCheckpointService"
 
+const tmpDir = path.join(os.tmpdir(), "test-LocalCheckpointService")
+
 describe("LocalCheckpointService", () => {
 	const taskId = "test-task"
 
@@ -29,7 +31,7 @@ describe("LocalCheckpointService", () => {
 		textFileContent?: string
 	}) => {
 		// Create a temporary directory for testing.
-		await fs.mkdir(workspaceDir)
+		await fs.mkdir(workspaceDir, { recursive: true })
 
 		// Initialize git repo.
 		const git = simpleGit(workspaceDir)
@@ -49,7 +51,7 @@ describe("LocalCheckpointService", () => {
 	}
 
 	beforeEach(async () => {
-		const workspaceDir = path.join(os.tmpdir(), `checkpoint-service-test-${Date.now()}`)
+		const workspaceDir = path.join(tmpDir, `checkpoint-service-test-${Date.now()}`)
 		const repo = await initRepo({ workspaceDir })
 
 		testFile = repo.testFile
@@ -60,10 +62,13 @@ describe("LocalCheckpointService", () => {
 	})
 
 	afterEach(async () => {
-		await fs.rm(service.workspaceDir, { recursive: true, force: true })
 		jest.restoreAllMocks()
 	})
 
+	afterAll(async () => {
+		await fs.rm(tmpDir, { recursive: true, force: true })
+	})
+
 	describe("getDiff", () => {
 		it("returns the correct diff between commits", async () => {
 			await fs.writeFile(testFile, "Ahoy, world!")
@@ -316,7 +321,7 @@ describe("LocalCheckpointService", () => {
 
 	describe("create", () => {
 		it("initializes a git repository if one does not already exist", async () => {
-			const workspaceDir = path.join(os.tmpdir(), `checkpoint-service-test2-${Date.now()}`)
+			const workspaceDir = path.join(tmpDir, `checkpoint-service-test2-${Date.now()}`)
 			await fs.mkdir(workspaceDir)
 			const newTestFile = path.join(workspaceDir, "test.txt")
 			await fs.writeFile(newTestFile, "Hello, world!")
@@ -364,7 +369,7 @@ describe("LocalCheckpointService", () => {
 		})
 
 		it("respects existing git user configuration", async () => {
-			const workspaceDir = path.join(os.tmpdir(), `checkpoint-service-test-config2-${Date.now()}`)
+			const workspaceDir = path.join(tmpDir, `checkpoint-service-test-config2-${Date.now()}`)
 			const userName = "Custom User"
 			const userEmail = "[email protected]"
 			await initRepo({ workspaceDir, userName, userEmail })

+ 11 - 9
src/services/checkpoints/__tests__/ShadowCheckpointService.test.ts

@@ -13,11 +13,12 @@ jest.mock("globby", () => ({
 	globby: jest.fn().mockResolvedValue([]),
 }))
 
+const tmpDir = path.join(os.tmpdir(), "test-ShadowCheckpointService")
+
 describe("ShadowCheckpointService", () => {
 	const taskId = "test-task"
 
 	let workspaceGit: SimpleGit
-	let shadowGit: SimpleGit
 	let testFile: string
 	let service: ShadowCheckpointService
 
@@ -35,7 +36,7 @@ describe("ShadowCheckpointService", () => {
 		textFileContent?: string
 	}) => {
 		// Create a temporary directory for testing.
-		await fs.mkdir(workspaceDir)
+		await fs.mkdir(workspaceDir, { recursive: true })
 
 		// Initialize git repo.
 		const git = simpleGit(workspaceDir)
@@ -57,8 +58,8 @@ describe("ShadowCheckpointService", () => {
 	beforeEach(async () => {
 		jest.mocked(require("globby").globby).mockClear().mockResolvedValue([])
 
-		const shadowDir = path.join(os.tmpdir(), `shadow-${Date.now()}`)
-		const workspaceDir = path.join(os.tmpdir(), `workspace-${Date.now()}`)
+		const shadowDir = path.join(tmpDir, `shadow-${Date.now()}`)
+		const workspaceDir = path.join(tmpDir, `workspace-${Date.now()}`)
 		const repo = await initRepo({ workspaceDir })
 
 		testFile = repo.testFile
@@ -69,15 +70,16 @@ describe("ShadowCheckpointService", () => {
 		})
 
 		workspaceGit = repo.git
-		shadowGit = service.git
 	})
 
 	afterEach(async () => {
-		await fs.rm(service.shadowDir, { recursive: true, force: true })
-		await fs.rm(service.workspaceDir, { recursive: true, force: true })
 		jest.restoreAllMocks()
 	})
 
+	afterAll(async () => {
+		await fs.rm(tmpDir, { recursive: true, force: true })
+	})
+
 	describe("getDiff", () => {
 		it("returns the correct diff between commits", async () => {
 			await fs.writeFile(testFile, "Ahoy, world!")
@@ -299,8 +301,8 @@ describe("ShadowCheckpointService", () => {
 
 	describe("create", () => {
 		it("initializes a git repository if one does not already exist", async () => {
-			const shadowDir = path.join(os.tmpdir(), `shadow2-${Date.now()}`)
-			const workspaceDir = path.join(os.tmpdir(), `workspace2-${Date.now()}`)
+			const shadowDir = path.join(tmpDir, `shadow2-${Date.now()}`)
+			const workspaceDir = path.join(tmpDir, `workspace2-${Date.now()}`)
 			await fs.mkdir(workspaceDir)
 
 			const newTestFile = path.join(workspaceDir, "test.txt")

+ 1 - 1
src/shared/ExtensionMessage.ts

@@ -127,7 +127,7 @@ export interface ExtensionState {
 	experiments: Record<ExperimentId, boolean> // Map of experiment IDs to their enabled state
 	autoApprovalEnabled?: boolean
 	customModes: ModeConfig[]
-	toolRequirements?: Record<string, boolean> // Map of tool names to their requirements (e.g. {"apply_diff": true} if diffEnabled)
+	toolRequirements?: Record<string, boolean> // Map of tool names to their requirements (e.g. {"edit_file": true} if diffEnabled)
 	maxOpenTabsContext: number // Maximum number of VSCode open tabs to include in context (0-500)
 }
 

+ 47 - 0
src/shared/__tests__/experiments.test.ts

@@ -0,0 +1,47 @@
+import { EXPERIMENT_IDS, experimentConfigsMap, experiments as Experiments, ExperimentId } from "../experiments"
+
+describe("experiments", () => {
+	describe("POWER_STEERING", () => {
+		it("is configured correctly", () => {
+			expect(EXPERIMENT_IDS.POWER_STEERING).toBe("powerSteering")
+			expect(experimentConfigsMap.POWER_STEERING).toMatchObject({
+				name: 'Use experimental "power steering" mode',
+				description:
+					"When enabled, Roo will remind the model about the details of its current mode definition more frequently. This will lead to stronger adherence to role definitions and custom instructions, but will use more tokens per message.",
+				enabled: false,
+			})
+		})
+	})
+
+	describe("isEnabled", () => {
+		it("returns false when experiment is not enabled", () => {
+			const experiments: Record<ExperimentId, boolean> = {
+				powerSteering: false,
+				experimentalDiffStrategy: false,
+				search_and_replace: false,
+				insert_content: false,
+			}
+			expect(Experiments.isEnabled(experiments, EXPERIMENT_IDS.POWER_STEERING)).toBe(false)
+		})
+
+		it("returns true when experiment is enabled", () => {
+			const experiments: Record<ExperimentId, boolean> = {
+				powerSteering: true,
+				experimentalDiffStrategy: false,
+				search_and_replace: false,
+				insert_content: false,
+			}
+			expect(Experiments.isEnabled(experiments, EXPERIMENT_IDS.POWER_STEERING)).toBe(true)
+		})
+
+		it("returns false when experiment is not present", () => {
+			const experiments: Record<ExperimentId, boolean> = {
+				experimentalDiffStrategy: false,
+				search_and_replace: false,
+				insert_content: false,
+				powerSteering: false,
+			}
+			expect(Experiments.isEnabled(experiments, EXPERIMENT_IDS.POWER_STEERING)).toBe(false)
+		})
+	})
+})

+ 135 - 34
src/shared/__tests__/modes.test.ts

@@ -1,4 +1,13 @@
-import { isToolAllowedForMode, FileRestrictionError, ModeConfig } from "../modes"
+// Mock setup must come before imports
+jest.mock("vscode")
+const mockAddCustomInstructions = jest.fn().mockResolvedValue("Combined instructions")
+jest.mock("../../core/prompts/sections/custom-instructions", () => ({
+	addCustomInstructions: mockAddCustomInstructions,
+}))
+
+import { isToolAllowedForMode, FileRestrictionError, ModeConfig, getFullModeDetails, modes } from "../modes"
+import * as vscode from "vscode"
+import { addCustomInstructions } from "../../core/prompts/sections/custom-instructions"
 
 describe("isToolAllowedForMode", () => {
 	const customModes: ModeConfig[] = [
@@ -35,14 +44,14 @@ describe("isToolAllowedForMode", () => {
 	describe("file restrictions", () => {
 		it("allows editing matching files", () => {
 			// Test markdown editor mode
-			const mdResult = isToolAllowedForMode("write_to_file", "markdown-editor", customModes, undefined, {
+			const mdResult = isToolAllowedForMode("create_file", "markdown-editor", customModes, undefined, {
 				path: "test.md",
 				content: "# Test",
 			})
 			expect(mdResult).toBe(true)
 
 			// Test CSS editor mode
-			const cssResult = isToolAllowedForMode("write_to_file", "css-editor", customModes, undefined, {
+			const cssResult = isToolAllowedForMode("create_file", "css-editor", customModes, undefined, {
 				path: "styles.css",
 				content: ".test { color: red; }",
 			})
@@ -52,13 +61,13 @@ describe("isToolAllowedForMode", () => {
 		it("rejects editing non-matching files", () => {
 			// Test markdown editor mode with non-markdown file
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "markdown-editor", customModes, undefined, {
+				isToolAllowedForMode("create_file", "markdown-editor", customModes, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
 			).toThrow(FileRestrictionError)
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "markdown-editor", customModes, undefined, {
+				isToolAllowedForMode("create_file", "markdown-editor", customModes, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
@@ -66,13 +75,13 @@ describe("isToolAllowedForMode", () => {
 
 			// Test CSS editor mode with non-CSS file
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "css-editor", customModes, undefined, {
+				isToolAllowedForMode("create_file", "css-editor", customModes, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
 			).toThrow(FileRestrictionError)
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "css-editor", customModes, undefined, {
+				isToolAllowedForMode("create_file", "css-editor", customModes, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
@@ -82,35 +91,35 @@ describe("isToolAllowedForMode", () => {
 		it("handles partial streaming cases (path only, no content/diff)", () => {
 			// Should allow path-only for matching files (no validation yet since content/diff not provided)
 			expect(
-				isToolAllowedForMode("write_to_file", "markdown-editor", customModes, undefined, {
+				isToolAllowedForMode("create_file", "markdown-editor", customModes, undefined, {
 					path: "test.js",
 				}),
 			).toBe(true)
 
 			expect(
-				isToolAllowedForMode("apply_diff", "markdown-editor", customModes, undefined, {
+				isToolAllowedForMode("edit_file", "markdown-editor", customModes, undefined, {
 					path: "test.js",
 				}),
 			).toBe(true)
 
 			// Should allow path-only for architect mode too
 			expect(
-				isToolAllowedForMode("write_to_file", "architect", [], undefined, {
+				isToolAllowedForMode("create_file", "architect", [], undefined, {
 					path: "test.js",
 				}),
 			).toBe(true)
 		})
 
-		it("applies restrictions to both write_to_file and apply_diff", () => {
-			// Test write_to_file
-			const writeResult = isToolAllowedForMode("write_to_file", "markdown-editor", customModes, undefined, {
+		it("applies restrictions to both create_file and edit_file", () => {
+			// Test create_file
+			const writeResult = isToolAllowedForMode("create_file", "markdown-editor", customModes, undefined, {
 				path: "test.md",
 				content: "# Test",
 			})
 			expect(writeResult).toBe(true)
 
-			// Test apply_diff
-			const diffResult = isToolAllowedForMode("apply_diff", "markdown-editor", customModes, undefined, {
+			// Test edit_file
+			const diffResult = isToolAllowedForMode("edit_file", "markdown-editor", customModes, undefined, {
 				path: "test.md",
 				diff: "- old\n+ new",
 			})
@@ -118,14 +127,14 @@ describe("isToolAllowedForMode", () => {
 
 			// Test both with non-matching file
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "markdown-editor", customModes, undefined, {
+				isToolAllowedForMode("create_file", "markdown-editor", customModes, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
 			).toThrow(FileRestrictionError)
 
 			expect(() =>
-				isToolAllowedForMode("apply_diff", "markdown-editor", customModes, undefined, {
+				isToolAllowedForMode("edit_file", "markdown-editor", customModes, undefined, {
 					path: "test.js",
 					diff: "- old\n+ new",
 				}),
@@ -146,29 +155,29 @@ describe("isToolAllowedForMode", () => {
 				},
 			]
 
-			// Test write_to_file with non-matching file
+			// Test create_file with non-matching file
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("create_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
 			).toThrow(FileRestrictionError)
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("create_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
 			).toThrow(/Documentation files only/)
 
-			// Test apply_diff with non-matching file
+			// Test edit_file with non-matching file
 			expect(() =>
-				isToolAllowedForMode("apply_diff", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("edit_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.js",
 					diff: "- old\n+ new",
 				}),
 			).toThrow(FileRestrictionError)
 			expect(() =>
-				isToolAllowedForMode("apply_diff", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("edit_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.js",
 					diff: "- old\n+ new",
 				}),
@@ -176,14 +185,14 @@ describe("isToolAllowedForMode", () => {
 
 			// Test that matching files are allowed
 			expect(
-				isToolAllowedForMode("write_to_file", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("create_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.md",
 					content: "# Test",
 				}),
 			).toBe(true)
 
 			expect(
-				isToolAllowedForMode("write_to_file", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("create_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.txt",
 					content: "Test content",
 				}),
@@ -191,7 +200,7 @@ describe("isToolAllowedForMode", () => {
 
 			// Test partial streaming cases
 			expect(
-				isToolAllowedForMode("write_to_file", "docs-editor", customModesWithDescription, undefined, {
+				isToolAllowedForMode("create_file", "docs-editor", customModesWithDescription, undefined, {
 					path: "test.js",
 				}),
 			).toBe(true)
@@ -200,7 +209,7 @@ describe("isToolAllowedForMode", () => {
 		it("allows architect mode to edit markdown files only", () => {
 			// Should allow editing markdown files
 			expect(
-				isToolAllowedForMode("write_to_file", "architect", [], undefined, {
+				isToolAllowedForMode("create_file", "architect", [], undefined, {
 					path: "test.md",
 					content: "# Test",
 				}),
@@ -208,7 +217,7 @@ describe("isToolAllowedForMode", () => {
 
 			// Should allow applying diffs to markdown files
 			expect(
-				isToolAllowedForMode("apply_diff", "architect", [], undefined, {
+				isToolAllowedForMode("edit_file", "architect", [], undefined, {
 					path: "readme.md",
 					diff: "- old\n+ new",
 				}),
@@ -216,13 +225,13 @@ describe("isToolAllowedForMode", () => {
 
 			// Should reject non-markdown files
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "architect", [], undefined, {
+				isToolAllowedForMode("create_file", "architect", [], undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
 			).toThrow(FileRestrictionError)
 			expect(() =>
-				isToolAllowedForMode("write_to_file", "architect", [], undefined, {
+				isToolAllowedForMode("create_file", "architect", [], undefined, {
 					path: "test.js",
 					content: "console.log('test')",
 				}),
@@ -236,15 +245,15 @@ describe("isToolAllowedForMode", () => {
 	})
 
 	it("handles non-existent modes", () => {
-		expect(isToolAllowedForMode("write_to_file", "non-existent", customModes)).toBe(false)
+		expect(isToolAllowedForMode("create_file", "non-existent", customModes)).toBe(false)
 	})
 
 	it("respects tool requirements", () => {
 		const toolRequirements = {
-			write_to_file: false,
+			create_file: false,
 		}
 
-		expect(isToolAllowedForMode("write_to_file", "markdown-editor", customModes, toolRequirements)).toBe(false)
+		expect(isToolAllowedForMode("create_file", "markdown-editor", customModes, toolRequirements)).toBe(false)
 	})
 
 	describe("experimental tools", () => {
@@ -303,7 +312,7 @@ describe("isToolAllowedForMode", () => {
 			).toBe(true)
 			expect(
 				isToolAllowedForMode(
-					"write_to_file",
+					"create_file",
 					"markdown-editor",
 					customModes,
 					undefined,
@@ -324,6 +333,98 @@ describe("FileRestrictionError", () => {
 		expect(error.name).toBe("FileRestrictionError")
 	})
 
+	describe("debug mode", () => {
+		it("is configured correctly", () => {
+			const debugMode = modes.find((mode) => mode.slug === "debug")
+			expect(debugMode).toBeDefined()
+			expect(debugMode).toMatchObject({
+				slug: "debug",
+				name: "Debug",
+				roleDefinition:
+					"You are Roo, an expert software debugger specializing in systematic problem diagnosis and resolution.",
+				groups: ["read", "edit", "browser", "command", "mcp"],
+			})
+			expect(debugMode?.customInstructions).toContain(
+				"Reflect on 5-7 different possible sources of the problem, distill those down to 1-2 most likely sources, and then add logs to validate your assumptions. Explicitly ask the user to confirm the diagnosis before fixing the problem.",
+			)
+		})
+	})
+
+	describe("getFullModeDetails", () => {
+		beforeEach(() => {
+			jest.clearAllMocks()
+			;(addCustomInstructions as jest.Mock).mockResolvedValue("Combined instructions")
+		})
+
+		it("returns base mode when no overrides exist", async () => {
+			const result = await getFullModeDetails("debug")
+			expect(result).toMatchObject({
+				slug: "debug",
+				name: "Debug",
+				roleDefinition:
+					"You are Roo, an expert software debugger specializing in systematic problem diagnosis and resolution.",
+			})
+		})
+
+		it("applies custom mode overrides", async () => {
+			const customModes = [
+				{
+					slug: "debug",
+					name: "Custom Debug",
+					roleDefinition: "Custom debug role",
+					groups: ["read"],
+				},
+			]
+
+			const result = await getFullModeDetails("debug", customModes)
+			expect(result).toMatchObject({
+				slug: "debug",
+				name: "Custom Debug",
+				roleDefinition: "Custom debug role",
+				groups: ["read"],
+			})
+		})
+
+		it("applies prompt component overrides", async () => {
+			const customModePrompts = {
+				debug: {
+					roleDefinition: "Overridden role",
+					customInstructions: "Overridden instructions",
+				},
+			}
+
+			const result = await getFullModeDetails("debug", undefined, customModePrompts)
+			expect(result.roleDefinition).toBe("Overridden role")
+			expect(result.customInstructions).toBe("Overridden instructions")
+		})
+
+		it("combines custom instructions when cwd provided", async () => {
+			const options = {
+				cwd: "/test/path",
+				globalCustomInstructions: "Global instructions",
+				preferredLanguage: "en",
+			}
+
+			await getFullModeDetails("debug", undefined, undefined, options)
+
+			expect(addCustomInstructions).toHaveBeenCalledWith(
+				expect.any(String),
+				"Global instructions",
+				"/test/path",
+				"debug",
+				{ preferredLanguage: "en" },
+			)
+		})
+
+		it("falls back to first mode for non-existent mode", async () => {
+			const result = await getFullModeDetails("non-existent")
+			expect(result).toMatchObject({
+				...modes[0],
+				customInstructions: "",
+			})
+		})
+	})
+
 	it("formats error message with description when provided", () => {
 		const error = new FileRestrictionError("Markdown Editor", "\\.md$", "Markdown files only", "test.js")
 		expect(error.message).toBe(

+ 2 - 2
src/shared/api.ts

@@ -622,8 +622,8 @@ export const openAiNativeModels = {
 		contextWindow: 128_000,
 		supportsImages: true,
 		supportsPromptCache: false,
-		inputPrice: 5,
-		outputPrice: 15,
+		inputPrice: 2.5,
+		outputPrice: 10,
 	},
 	"gpt-4o-mini": {
 		maxTokens: 16_384,

+ 7 - 0
src/shared/experiments.ts

@@ -2,6 +2,7 @@ export const EXPERIMENT_IDS = {
 	DIFF_STRATEGY: "experimentalDiffStrategy",
 	SEARCH_AND_REPLACE: "search_and_replace",
 	INSERT_BLOCK: "insert_content",
+	POWER_STEERING: "powerSteering",
 } as const
 
 export type ExperimentKey = keyof typeof EXPERIMENT_IDS
@@ -35,6 +36,12 @@ export const experimentConfigsMap: Record<ExperimentKey, ExperimentConfig> = {
 			"Enable the experimental insert content tool, allowing Roo to insert content at specific line numbers without needing to create a diff.",
 		enabled: false,
 	},
+	POWER_STEERING: {
+		name: 'Use experimental "power steering" mode',
+		description:
+			"When enabled, Roo will remind the model about the details of its current mode definition more frequently. This will lead to stronger adherence to role definitions and custom instructions, but will use more tokens per message.",
+		enabled: false,
+	},
 }
 
 export const experimentDefault = Object.fromEntries(

+ 50 - 0
src/shared/modes.ts

@@ -1,5 +1,6 @@
 import * as vscode from "vscode"
 import { TOOL_GROUPS, ToolGroup, ALWAYS_AVAILABLE_TOOLS } from "./tool-groups"
+import { addCustomInstructions } from "../core/prompts/sections/custom-instructions"
 
 // Mode types
 export type Mode = string
@@ -98,6 +99,15 @@ export const modes: readonly ModeConfig[] = [
 		customInstructions:
 			"You can analyze code, explain concepts, and access external resources. Make sure to answer the user's questions and don't rush to switch to implementing code.",
 	},
+	{
+		slug: "debug",
+		name: "Debug",
+		roleDefinition:
+			"You are Roo, an expert software debugger specializing in systematic problem diagnosis and resolution.",
+		groups: ["read", "edit", "browser", "command", "mcp"],
+		customInstructions:
+			"Reflect on 5-7 different possible sources of the problem, distill those down to 1-2 most likely sources, and then add logs to validate your assumptions. Explicitly ask the user to confirm the diagnosis before fixing the problem.",
+	},
 ] as const
 
 // Export the default mode slug
@@ -253,6 +263,46 @@ export async function getAllModesWithPrompts(context: vscode.ExtensionContext):
 	}))
 }
 
+// Helper function to get complete mode details with all overrides
+export async function getFullModeDetails(
+	modeSlug: string,
+	customModes?: ModeConfig[],
+	customModePrompts?: CustomModePrompts,
+	options?: {
+		cwd?: string
+		globalCustomInstructions?: string
+		preferredLanguage?: string
+	},
+): Promise<ModeConfig> {
+	// First get the base mode config from custom modes or built-in modes
+	const baseMode = getModeBySlug(modeSlug, customModes) || modes.find((m) => m.slug === modeSlug) || modes[0]
+
+	// Check for any prompt component overrides
+	const promptComponent = customModePrompts?.[modeSlug]
+
+	// Get the base custom instructions
+	const baseCustomInstructions = promptComponent?.customInstructions || baseMode.customInstructions || ""
+
+	// If we have cwd, load and combine all custom instructions
+	let fullCustomInstructions = baseCustomInstructions
+	if (options?.cwd) {
+		fullCustomInstructions = await addCustomInstructions(
+			baseCustomInstructions,
+			options.globalCustomInstructions || "",
+			options.cwd,
+			modeSlug,
+			{ preferredLanguage: options.preferredLanguage },
+		)
+	}
+
+	// Return mode with any overrides applied
+	return {
+		...baseMode,
+		roleDefinition: promptComponent?.roleDefinition || baseMode.roleDefinition,
+		customInstructions: fullCustomInstructions,
+	}
+}
+
 // Helper function to safely get role definition
 export function getRoleDefinition(modeSlug: string, customModes?: ModeConfig[]): string {
 	const mode = getModeBySlug(modeSlug, customModes)

+ 3 - 3
src/shared/tool-groups.ts

@@ -8,8 +8,8 @@ export type ToolGroupConfig = {
 export const TOOL_DISPLAY_NAMES = {
 	execute_command: "run commands",
 	read_file: "read files",
-	write_to_file: "write files",
-	apply_diff: "apply changes",
+	create_file: "write files",
+	edit_file: "apply changes",
 	search_files: "search files",
 	list_files: "list files",
 	list_code_definition_names: "list definitions",
@@ -28,7 +28,7 @@ export const TOOL_GROUPS: Record<string, ToolGroupConfig> = {
 		tools: ["read_file", "search_files", "list_files", "list_code_definition_names"],
 	},
 	edit: {
-		tools: ["write_to_file", "apply_diff", "insert_content", "search_and_replace"],
+		tools: ["edit_file", "create_file", "insert_content", "search_and_replace"],
 	},
 	browser: {
 		tools: ["browser_action"],

+ 2 - 1
webview-ui/.eslintrc.json

@@ -1,3 +1,4 @@
 {
-	"extends": "react-app"
+	"extends": "react-app",
+	"ignorePatterns": ["!.storybook"]
 }

Разница между файлами не показана из-за своего большого размера
+ 380 - 246
webview-ui/package-lock.json


+ 3 - 3
webview-ui/package.json

@@ -75,13 +75,13 @@
 		"eslint-plugin-react-hooks": "^4.6.0",
 		"eslint-plugin-storybook": "^0.11.2",
 		"identity-obj-proxy": "^3.0.0",
-		"jest": "^27.5.1",
-		"jest-environment-jsdom": "^27.5.1",
+		"jest": "^29.7.0",
+		"jest-environment-jsdom": "^29.7.0",
 		"jest-simple-dot-reporter": "^1.0.5",
 		"shiki": "^2.3.2",
 		"storybook": "^8.5.6",
 		"storybook-dark-mode": "^4.0.2",
-		"ts-jest": "^27.1.5",
+		"ts-jest": "^29.2.5",
 		"typescript": "^4.9.5",
 		"vite": "6.0.11"
 	}

+ 0 - 130
webview-ui/src/components/common/Demo.tsx

@@ -1,130 +0,0 @@
-import {
-	VSCodeBadge,
-	VSCodeButton,
-	VSCodeCheckbox,
-	VSCodeDataGrid,
-	VSCodeDataGridCell,
-	VSCodeDataGridRow,
-	VSCodeDivider,
-	VSCodeDropdown,
-	VSCodeLink,
-	VSCodeOption,
-	VSCodePanels,
-	VSCodePanelTab,
-	VSCodePanelView,
-	VSCodeProgressRing,
-	VSCodeRadio,
-	VSCodeRadioGroup,
-	VSCodeTag,
-	VSCodeTextArea,
-	VSCodeTextField,
-} from "@vscode/webview-ui-toolkit/react"
-
-function Demo() {
-	// function handleHowdyClick() {
-	// 	vscode.postMessage({
-	// 		command: "hello",
-	// 		text: "Hey there partner! 🤠",
-	// 	})
-	// }
-
-	const rowData = [
-		{
-			cell1: "Cell Data",
-			cell2: "Cell Data",
-			cell3: "Cell Data",
-			cell4: "Cell Data",
-		},
-		{
-			cell1: "Cell Data",
-			cell2: "Cell Data",
-			cell3: "Cell Data",
-			cell4: "Cell Data",
-		},
-		{
-			cell1: "Cell Data",
-			cell2: "Cell Data",
-			cell3: "Cell Data",
-			cell4: "Cell Data",
-		},
-	]
-
-	return (
-		<main>
-			<h1>Hello World!</h1>
-			<VSCodeButton>Howdy!</VSCodeButton>
-
-			<div className="grid gap-3 p-2 place-items-start">
-				<VSCodeDataGrid>
-					<VSCodeDataGridRow row-type="header">
-						<VSCodeDataGridCell cell-type="columnheader" grid-column="1">
-							A Custom Header Title
-						</VSCodeDataGridCell>
-						<VSCodeDataGridCell cell-type="columnheader" grid-column="2">
-							Another Custom Title
-						</VSCodeDataGridCell>
-						<VSCodeDataGridCell cell-type="columnheader" grid-column="3">
-							Title Is Custom
-						</VSCodeDataGridCell>
-						<VSCodeDataGridCell cell-type="columnheader" grid-column="4">
-							Custom Title
-						</VSCodeDataGridCell>
-					</VSCodeDataGridRow>
-					{rowData.map((row, index) => (
-						<VSCodeDataGridRow key={index}>
-							<VSCodeDataGridCell grid-column="1">{row.cell1}</VSCodeDataGridCell>
-							<VSCodeDataGridCell grid-column="2">{row.cell2}</VSCodeDataGridCell>
-							<VSCodeDataGridCell grid-column="3">{row.cell3}</VSCodeDataGridCell>
-							<VSCodeDataGridCell grid-column="4">{row.cell4}</VSCodeDataGridCell>
-						</VSCodeDataGridRow>
-					))}
-				</VSCodeDataGrid>
-
-				<VSCodeTextField>
-					<section slot="end" style={{ display: "flex", alignItems: "center" }}>
-						<VSCodeButton appearance="icon" aria-label="Match Case">
-							<span className="codicon codicon-case-sensitive"></span>
-						</VSCodeButton>
-						<VSCodeButton appearance="icon" aria-label="Match Whole Word">
-							<span className="codicon codicon-whole-word"></span>
-						</VSCodeButton>
-						<VSCodeButton appearance="icon" aria-label="Use Regular Expression">
-							<span className="codicon codicon-regex"></span>
-						</VSCodeButton>
-					</section>
-				</VSCodeTextField>
-				<span slot="end" className="codicon codicon-chevron-right"></span>
-
-				<span className="flex gap-3">
-					<VSCodeProgressRing />
-					<VSCodeTextField />
-					<VSCodeButton>Add</VSCodeButton>
-					<VSCodeButton appearance="secondary">Remove</VSCodeButton>
-				</span>
-
-				<VSCodeBadge>Badge</VSCodeBadge>
-				<VSCodeCheckbox>Checkbox</VSCodeCheckbox>
-				<VSCodeDivider />
-				<VSCodeDropdown>
-					<VSCodeOption>Option 1</VSCodeOption>
-					<VSCodeOption>Option 2</VSCodeOption>
-				</VSCodeDropdown>
-				<VSCodeLink href="#">Link</VSCodeLink>
-				<VSCodePanels>
-					<VSCodePanelTab id="tab-1">Tab 1</VSCodePanelTab>
-					<VSCodePanelTab id="tab-2">Tab 2</VSCodePanelTab>
-					<VSCodePanelView id="view-1">Panel View 1</VSCodePanelView>
-					<VSCodePanelView id="view-2">Panel View 2</VSCodePanelView>
-				</VSCodePanels>
-				<VSCodeRadioGroup>
-					<VSCodeRadio>Radio 1</VSCodeRadio>
-					<VSCodeRadio>Radio 2</VSCodeRadio>
-				</VSCodeRadioGroup>
-				<VSCodeTag>Tag</VSCodeTag>
-				<VSCodeTextArea placeholder="Text Area" />
-			</div>
-		</main>
-	)
-}
-
-export default Demo

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

@@ -468,9 +468,7 @@ const ApiOptions = ({
 							id="aws-region-dropdown"
 							value={apiConfiguration?.awsRegion || ""}
 							style={{ width: "100%" }}
-							onChange={(value: unknown) => {
-								handleInputChange("awsRegion", dropdownEventTransform)
-							}}
+							onChange={handleInputChange("awsRegion", dropdownEventTransform)}
 							options={[
 								{ value: "", label: "Select a region..." },
 								{ value: "us-east-1", label: "us-east-1" },

+ 0 - 167
webview-ui/src/components/settings/TabNavbar.tsx

@@ -1,167 +0,0 @@
-import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
-import React, { useState } from "react"
-
-export const TAB_NAVBAR_HEIGHT = 24
-const BUTTON_MARGIN_RIGHT = "3px"
-const LAST_BUTTON_MARGIN_RIGHT = "13px"
-
-type TabNavbarProps = {
-	onPlusClick: () => void
-	onHistoryClick: () => void
-	onSettingsClick: () => void
-}
-
-type TooltipProps = {
-	text: string
-	isVisible: boolean
-	position: { x: number; y: number }
-	align?: "left" | "center" | "right"
-}
-
-const Tooltip: React.FC<TooltipProps> = ({ text, isVisible, position, align = "center" }) => {
-	let leftPosition = position.x
-	let triangleStyle: React.CSSProperties = {
-		left: "50%",
-		marginLeft: "-5px",
-	}
-
-	if (align === "right") {
-		leftPosition = position.x - 10 // Adjust this value as needed
-		triangleStyle = {
-			right: "10px", // Adjust this value to match the tooltip's right padding
-			marginLeft: "0",
-		}
-	} else if (align === "left") {
-		leftPosition = position.x + 10 // Adjust this value as needed
-		triangleStyle = {
-			left: "10px", // Adjust this value to match the tooltip's left padding
-			marginLeft: "0",
-		}
-	}
-
-	return (
-		<div
-			style={{
-				position: "fixed",
-				top: `${position.y}px`,
-				left: align === "center" ? leftPosition + "px" : "auto",
-				right: align === "right" ? "10px" : "auto", // Ensure 10px from screen edge
-				transform: align === "center" ? "translateX(-50%)" : "none",
-				opacity: isVisible ? 1 : 0,
-				visibility: isVisible ? "visible" : "hidden",
-				transition: "opacity 0.1s ease-out 0.1s, visibility 0.1s ease-out 0.1s",
-				backgroundColor: "var(--vscode-editorHoverWidget-background)",
-				color: "var(--vscode-editorHoverWidget-foreground)",
-				padding: "4px 8px",
-				borderRadius: "3px",
-				fontSize: "12px",
-				pointerEvents: "none",
-				zIndex: 1000,
-				boxShadow: "0 2px 8px var(--vscode-widget-shadow)",
-				border: "1px solid var(--vscode-editorHoverWidget-border)",
-				textAlign: "center",
-				whiteSpace: "nowrap",
-			}}>
-			<div
-				style={{
-					position: "absolute",
-					top: "-5px",
-					...triangleStyle,
-					borderLeft: "5px solid transparent",
-					borderRight: "5px solid transparent",
-					borderBottom: "5px solid var(--vscode-editorHoverWidget-border)",
-				}}
-			/>
-			<div
-				style={{
-					position: "absolute",
-					top: "-4px",
-					...triangleStyle,
-					borderLeft: "5px solid transparent",
-					borderRight: "5px solid transparent",
-					borderBottom: "5px solid var(--vscode-editorHoverWidget-background)",
-				}}
-			/>
-			{text}
-		</div>
-	)
-}
-
-const TabNavbar = ({ onPlusClick, onHistoryClick, onSettingsClick }: TabNavbarProps) => {
-	const [tooltip, setTooltip] = useState<TooltipProps>({
-		text: "",
-		isVisible: false,
-		position: { x: 0, y: 0 },
-		align: "center",
-	})
-
-	const showTooltip = (text: string, event: React.MouseEvent, align: "left" | "center" | "right" = "center") => {
-		const rect = event.currentTarget.getBoundingClientRect()
-		setTooltip({
-			text,
-			isVisible: true,
-			position: { x: rect.left + rect.width / 2, y: rect.bottom + 7 },
-			align,
-		})
-	}
-
-	const hideTooltip = () => {
-		setTooltip((prev) => ({ ...prev, isVisible: false }))
-	}
-
-	const buttonStyle = {
-		marginRight: BUTTON_MARGIN_RIGHT,
-	}
-
-	const lastButtonStyle = {
-		...buttonStyle,
-		marginRight: LAST_BUTTON_MARGIN_RIGHT,
-	}
-
-	return (
-		<>
-			<div
-				style={{
-					position: "absolute",
-					top: 4,
-					right: 0,
-					left: 0,
-					height: TAB_NAVBAR_HEIGHT,
-					display: "flex",
-					justifyContent: "flex-end",
-					alignItems: "center",
-				}}>
-				<VSCodeButton
-					appearance="icon"
-					onClick={onPlusClick}
-					style={buttonStyle}
-					onMouseEnter={(e) => showTooltip("New Chat", e, "center")}
-					onMouseLeave={hideTooltip}
-					onMouseMove={(e) => showTooltip("New Chat", e, "center")}>
-					<span className="codicon codicon-add"></span>
-				</VSCodeButton>
-				<VSCodeButton
-					appearance="icon"
-					onClick={onHistoryClick}
-					style={buttonStyle}
-					onMouseEnter={(e) => showTooltip("History", e, "center")}
-					onMouseLeave={hideTooltip}
-					onMouseMove={(e) => showTooltip("History", e, "center")}>
-					<span className="codicon codicon-history"></span>
-				</VSCodeButton>
-				<VSCodeButton
-					appearance="icon"
-					onClick={onSettingsClick}
-					style={lastButtonStyle}
-					onMouseEnter={(e) => showTooltip("Settings", e, "right")}
-					onMouseLeave={hideTooltip}
-					onMouseMove={(e) => showTooltip("Settings", e, "right")}>
-					<span className="codicon codicon-settings-gear"></span>
-				</VSCodeButton>
-			</div>
-			<Tooltip {...tooltip} />
-		</>
-	)
-}
-
-export default TabNavbar

+ 0 - 46
webview-ui/src/services/GitService.ts

@@ -1,46 +0,0 @@
-import { vscode } from "../utils/vscode"
-
-export interface GitCommit {
-	hash: string
-	shortHash: string
-	subject: string
-	author: string
-	date: string
-}
-
-class GitService {
-	private commits: GitCommit[] | null = null
-	private lastQuery: string = ""
-
-	async searchCommits(query: string = ""): Promise<GitCommit[]> {
-		if (query === this.lastQuery && this.commits) {
-			return this.commits
-		}
-
-		// Request search from extension
-		vscode.postMessage({ type: "searchCommits", query })
-
-		// Wait for response
-		const response = await new Promise<GitCommit[]>((resolve) => {
-			const handler = (event: MessageEvent) => {
-				const message = event.data
-				if (message.type === "commitSearchResults") {
-					window.removeEventListener("message", handler)
-					resolve(message.commits)
-				}
-			}
-			window.addEventListener("message", handler)
-		})
-
-		this.commits = response
-		this.lastQuery = query
-		return response
-	}
-
-	clearCache() {
-		this.commits = null
-		this.lastQuery = ""
-	}
-}
-
-export const gitService = new GitService()

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