diff --git a/CHANGELOG.md b/CHANGELOG.md
index abf82c348c..1c97f6fcb2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,42 @@
# Roo Code Changelog
+## [3.25.15] - 2025-08-14
+
+- Fix: Remove 500-message limit to prevent scrollbar jumping in long conversations (#7052, #7063 by @daniel-lxs, PR by @app/roomote)
+- Fix: Reset condensing state when switching tasks (#6919 by @f14XuanLv, PR by @f14XuanLv)
+- Fix: Implement sitemap generation in TypeScript and remove XML file (#5231 by @abumalick, PR by @abumalick)
+- Fix: allowedMaxRequests and allowedMaxCost values not showing in the settings UI (thanks @chrarnoldus!)
+
+## [3.25.14] - 2025-08-13
+
+- Fix: Only include verbosity parameter for models that support it (#7054 by @eastonmeth, PR by @app/roomote)
+- Fix: AWS Bedrock 1M context - Move anthropic_beta to additionalModelRequestFields (thanks @daniel-lxs!)
+- Fix: Make cancelling requests more responsive by reverting recent changes
+
+## [3.25.13] - 2025-08-12
+
+- Add Sonnet 1M context checkbox to Bedrock
+- Fix: add --no-messages flag to ripgrep to suppress file access errors (#6756 by @R-omk, PR by @app/roomote)
+- Add support for AGENT.md alongside AGENTS.md (#6912 by @Brendan-Z, PR by @app/roomote)
+- Remove deprecated GPT-4.5 Preview model (thanks @PeterDaveHello!)
+
+## [3.25.12] - 2025-08-12
+
+- Update: Claude Sonnet 4 context window configurable to 1 million tokens in Anthropic provider (thanks @daniel-lxs!)
+- Add: Minimal reasoning support to OpenRouter (thanks @daniel-lxs!)
+- Fix: Add configurable API request timeout for local providers (#6521 by @dabockster, PR by @app/roomote)
+- Fix: Add --no-sandbox flag to browser launch options (#6632 by @QuinsZouls, PR by @QuinsZouls)
+- Fix: Ensure JSON files respect .rooignore during indexing (#6690 by @evermoving, PR by @app/roomote)
+- Add: New Chutes provider models (#6698 by @fstandhartinger, PR by @app/roomote)
+- Add: OpenAI gpt-oss models to Amazon Bedrock dropdown (#6752 by @josh-clanton-powerschool, PR by @app/roomote)
+- Fix: Correct tool repetition detector to not block first tool call when limit is 1 (#6834 by @NaccOll, PR by @app/roomote)
+- Fix: Improve checkpoint service initialization handling (thanks @NaccOll!)
+- Update: Improve zh-TW Traditional Chinese locale (thanks @PeterDaveHello!)
+- Add: Task expand and collapse translations (thanks @app/roomote!)
+- Update: Exclude GPT-5 models from 20% context window output token cap (thanks @app/roomote!)
+- Fix: Truncate long model names in model selector to prevent overflow (thanks @app/roomote!)
+- Add: Requesty base url support (thanks @requesty-JohnCosta27!)
+
## [3.25.11] - 2025-08-11
- Add: Native OpenAI provider support for Codex Mini model (#5386 by @KJ7LNW, PR by @daniel-lxs)
diff --git a/README.md b/README.md
index 1b5e8fe2ec..2f3a6069d9 100644
--- a/README.md
+++ b/README.md
@@ -208,46 +208,47 @@ Thanks to all our contributors who have helped make Roo Code better!
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/apps/web-roo-code/.env.example b/apps/web-roo-code/.env.example
index 734a9a2a08..01258bc500 100644
--- a/apps/web-roo-code/.env.example
+++ b/apps/web-roo-code/.env.example
@@ -6,3 +6,7 @@ NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
# Basin Form Endpoint for Static Form Submissions
# Replace this with your actual Basin form endpoint (e.g., https://usebasin.com/f/your-form-id)
NEXT_PUBLIC_BASIN_ENDPOINT=https://usebasin.com/f/your-form-id-here
+
+# Site URL Configuration
+# Used for generating absolute URLs in sitemap and other contexts
+NEXT_PUBLIC_SITE_URL=https://roocode.com
diff --git a/apps/web-roo-code/.gitignore b/apps/web-roo-code/.gitignore
index 7b8da95f5e..6f31e99c00 100644
--- a/apps/web-roo-code/.gitignore
+++ b/apps/web-roo-code/.gitignore
@@ -40,3 +40,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+
+# generated files
+/public/sitemap*.xml
+/public/robots.txt
diff --git a/apps/web-roo-code/.npmrc b/apps/web-roo-code/.npmrc
new file mode 100644
index 0000000000..b7425b9ee8
--- /dev/null
+++ b/apps/web-roo-code/.npmrc
@@ -0,0 +1 @@
+enable-pre-post-scripts=true
\ No newline at end of file
diff --git a/apps/web-roo-code/next-sitemap.config.cjs b/apps/web-roo-code/next-sitemap.config.cjs
new file mode 100644
index 0000000000..e9b0ca3c47
--- /dev/null
+++ b/apps/web-roo-code/next-sitemap.config.cjs
@@ -0,0 +1,73 @@
+/** @type {import('next-sitemap').IConfig} */
+module.exports = {
+ siteUrl: process.env.NEXT_PUBLIC_SITE_URL || 'https://roocode.com',
+ generateRobotsTxt: true,
+ generateIndexSitemap: false, // We don't need index sitemap for a small site
+ changefreq: 'monthly',
+ priority: 0.7,
+ sitemapSize: 5000,
+ exclude: [
+ '/api/*',
+ '/server-sitemap-index.xml',
+ '/404',
+ '/500',
+ '/_not-found',
+ ],
+ robotsTxtOptions: {
+ policies: [
+ {
+ userAgent: '*',
+ allow: '/',
+ },
+ ],
+ additionalSitemaps: [
+ // Add any additional sitemaps here if needed in the future
+ ],
+ },
+ // Custom transform function to set specific priorities and change frequencies
+ transform: async (config, path) => {
+ // Set custom priority for specific pages
+ let priority = config.priority;
+ let changefreq = config.changefreq;
+
+ if (path === '/') {
+ priority = 1.0;
+ changefreq = 'yearly';
+ } else if (path === '/enterprise' || path === '/evals') {
+ priority = 0.8;
+ changefreq = 'monthly';
+ } else if (path === '/privacy' || path === '/terms') {
+ priority = 0.5;
+ changefreq = 'yearly';
+ }
+
+ return {
+ loc: path,
+ changefreq,
+ priority,
+ lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
+ alternateRefs: config.alternateRefs ?? [],
+ };
+ },
+ additionalPaths: async (config) => {
+ // Add any additional paths that might not be automatically discovered
+ // This is useful for dynamic routes or API-generated pages
+ // Add the /evals page since it's a dynamic route
+ return [{
+ loc: '/evals',
+ changefreq: 'monthly',
+ priority: 0.8,
+ lastmod: new Date().toISOString(),
+ }];
+
+ // Add the /evals page since it's a dynamic route
+ result.push({
+ loc: '/evals',
+ changefreq: 'monthly',
+ priority: 0.8,
+ lastmod: new Date().toISOString(),
+ });
+
+ return result;
+ },
+};
\ No newline at end of file
diff --git a/apps/web-roo-code/package.json b/apps/web-roo-code/package.json
index 8495dd961a..fa59cacccb 100644
--- a/apps/web-roo-code/package.json
+++ b/apps/web-roo-code/package.json
@@ -7,6 +7,7 @@
"check-types": "tsc --noEmit",
"dev": "next dev",
"build": "next build",
+ "postbuild": "next-sitemap --config next-sitemap.config.cjs",
"start": "next start",
"clean": "rimraf .next .turbo"
},
@@ -42,6 +43,7 @@
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.7",
"autoprefixer": "^10.4.21",
+ "next-sitemap": "^4.2.3",
"postcss": "^8.5.4",
"tailwindcss": "^3.4.17"
}
diff --git a/apps/web-roo-code/src/app/enterprise/page.tsx b/apps/web-roo-code/src/app/enterprise/page.tsx
index ca15857ffd..7a1d36f068 100644
--- a/apps/web-roo-code/src/app/enterprise/page.tsx
+++ b/apps/web-roo-code/src/app/enterprise/page.tsx
@@ -5,6 +5,54 @@ import { AnimatedText } from "@/components/animated-text"
import { AnimatedBackground } from "@/components/homepage"
import { ContactForm } from "@/components/enterprise/contact-form"
import { EXTERNAL_LINKS } from "@/lib/constants"
+import type { Metadata } from "next"
+import { SEO } from "@/lib/seo"
+
+const TITLE = "Enterprise Solution"
+const DESCRIPTION =
+ "The control-plane for AI-powered software development. Gain visibility, governance, and control over your AI coding initiatives."
+const PATH = "/enterprise"
+const OG_IMAGE = SEO.ogImage
+
+export const metadata: Metadata = {
+ title: TITLE,
+ description: DESCRIPTION,
+ alternates: {
+ canonical: `${SEO.url}${PATH}`,
+ },
+ openGraph: {
+ title: TITLE,
+ description: DESCRIPTION,
+ url: `${SEO.url}${PATH}`,
+ siteName: SEO.name,
+ images: [
+ {
+ url: OG_IMAGE.url,
+ width: OG_IMAGE.width,
+ height: OG_IMAGE.height,
+ alt: OG_IMAGE.alt,
+ },
+ ],
+ locale: SEO.locale,
+ type: "website",
+ },
+ twitter: {
+ card: SEO.twitterCard,
+ title: TITLE,
+ description: DESCRIPTION,
+ images: [OG_IMAGE.url],
+ },
+ keywords: [
+ ...SEO.keywords,
+ "Enterprise AI",
+ "AI governance",
+ "AI control-plane",
+ "developer productivity",
+ "SAML",
+ "SCIM",
+ "cost management",
+ ],
+}
export default async function Enterprise() {
return (
diff --git a/apps/web-roo-code/src/app/evals/page.tsx b/apps/web-roo-code/src/app/evals/page.tsx
index b97b025348..a6af30d70e 100644
--- a/apps/web-roo-code/src/app/evals/page.tsx
+++ b/apps/web-roo-code/src/app/evals/page.tsx
@@ -1,25 +1,45 @@
import type { Metadata } from "next"
import { getEvalRuns } from "@/actions/evals"
+import { SEO } from "@/lib/seo"
import { Evals } from "./evals"
export const revalidate = 300
export const dynamic = "force-dynamic"
+const TITLE = "Evals"
+const DESCRIPTION = "Explore quantitative evals of LLM coding skills across tasks and providers."
+const PATH = "/evals"
+const IMAGE = {
+ url: "https://i.imgur.com/ijP7aZm.png",
+ width: 1954,
+ height: 1088,
+ alt: "Roo Code Evals – LLM coding benchmarks",
+}
+
export const metadata: Metadata = {
- title: "Roo Code Evals",
- openGraph: {
- title: "Roo Code Evals",
- description: "Quantitative evals of LLM coding skills.",
- url: "https://roocode.com/evals",
- siteName: "Roo Code",
- images: {
- url: "https://i.imgur.com/ijP7aZm.png",
- width: 1954,
- height: 1088,
- },
+ title: TITLE,
+ description: DESCRIPTION,
+ alternates: {
+ canonical: `${SEO.url}${PATH}`,
},
+ openGraph: {
+ title: TITLE,
+ description: DESCRIPTION,
+ url: `${SEO.url}${PATH}`,
+ siteName: SEO.name,
+ images: [IMAGE],
+ locale: SEO.locale,
+ type: "website",
+ },
+ twitter: {
+ card: SEO.twitterCard,
+ title: TITLE,
+ description: DESCRIPTION,
+ images: [IMAGE.url],
+ },
+ keywords: [...SEO.keywords, "benchmarks", "LLM evals", "coding evaluations", "model comparison"],
}
export default async function Page() {
diff --git a/apps/web-roo-code/src/app/layout.tsx b/apps/web-roo-code/src/app/layout.tsx
index 132a8b31d7..ac33c8920f 100644
--- a/apps/web-roo-code/src/app/layout.tsx
+++ b/apps/web-roo-code/src/app/layout.tsx
@@ -2,6 +2,7 @@ import React from "react"
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import Script from "next/script"
+import { SEO } from "@/lib/seo"
import { Providers } from "@/components/providers"
@@ -12,11 +13,14 @@ import "./globals.css"
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
- title: "Roo Code – Your AI-Powered Dev Team in VS Code",
- description:
- "Roo Code puts an entire AI dev team right in your editor, outpacing closed tools with deep project-wide context, multi-step agentic coding, and unmatched developer-centric flexibility.",
+ metadataBase: new URL(SEO.url),
+ title: {
+ template: "%s | Roo Code",
+ default: SEO.title,
+ },
+ description: SEO.description,
alternates: {
- canonical: "https://roocode.com",
+ canonical: SEO.url,
},
icons: {
icon: [
@@ -40,6 +44,42 @@ export const metadata: Metadata = {
},
],
},
+ openGraph: {
+ title: SEO.title,
+ description: SEO.description,
+ url: SEO.url,
+ siteName: SEO.name,
+ images: [
+ {
+ url: SEO.ogImage.url,
+ width: SEO.ogImage.width,
+ height: SEO.ogImage.height,
+ alt: SEO.ogImage.alt,
+ },
+ ],
+ locale: SEO.locale,
+ type: "website",
+ },
+ twitter: {
+ card: SEO.twitterCard,
+ title: SEO.title,
+ description: SEO.description,
+ images: [SEO.ogImage.url],
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: {
+ index: true,
+ follow: true,
+ "max-snippet": -1,
+ "max-image-preview": "large",
+ "max-video-preview": -1,
+ },
+ },
+ keywords: [...SEO.keywords],
+ applicationName: SEO.name,
+ category: SEO.category,
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
@@ -64,8 +104,8 @@ export default function RootLayout({ children }: { children: React.ReactNode })
`}
-
-
+
+
{children}
diff --git a/apps/web-roo-code/src/app/privacy/page.tsx b/apps/web-roo-code/src/app/privacy/page.tsx
index ea12094ebb..1812d18eff 100644
--- a/apps/web-roo-code/src/app/privacy/page.tsx
+++ b/apps/web-roo-code/src/app/privacy/page.tsx
@@ -1,9 +1,41 @@
-import { Metadata } from "next"
+import type { Metadata } from "next"
+import { SEO } from "@/lib/seo"
+
+const TITLE = "Privacy Policy"
+const DESCRIPTION =
+ "Privacy policy for Roo Code Cloud and marketing website. Learn how we handle your data and protect your privacy."
+const PATH = "/privacy"
+const OG_IMAGE = SEO.ogImage
export const metadata: Metadata = {
- title: "Privacy Policy - Roo Code",
- description:
- "Privacy policy for Roo Code Cloud and marketing website. Learn how we handle your data and protect your privacy.",
+ title: TITLE,
+ description: DESCRIPTION,
+ alternates: {
+ canonical: `${SEO.url}${PATH}`,
+ },
+ openGraph: {
+ title: TITLE,
+ description: DESCRIPTION,
+ url: `${SEO.url}${PATH}`,
+ siteName: SEO.name,
+ images: [
+ {
+ url: OG_IMAGE.url,
+ width: OG_IMAGE.width,
+ height: OG_IMAGE.height,
+ alt: OG_IMAGE.alt,
+ },
+ ],
+ locale: SEO.locale,
+ type: "article",
+ },
+ twitter: {
+ card: SEO.twitterCard,
+ title: TITLE,
+ description: DESCRIPTION,
+ images: [OG_IMAGE.url],
+ },
+ keywords: [...SEO.keywords, "privacy", "data protection", "GDPR", "security"],
}
export default function Privacy() {
diff --git a/apps/web-roo-code/src/app/robots.ts b/apps/web-roo-code/src/app/robots.ts
new file mode 100644
index 0000000000..fcdda5031e
--- /dev/null
+++ b/apps/web-roo-code/src/app/robots.ts
@@ -0,0 +1,13 @@
+import type { MetadataRoute } from "next"
+import { SEO } from "@/lib/seo"
+
+export default function robots(): MetadataRoute.Robots {
+ return {
+ rules: {
+ userAgent: "*",
+ allow: "/",
+ },
+ sitemap: `${SEO.url}/sitemap.xml`,
+ host: SEO.url,
+ }
+}
diff --git a/apps/web-roo-code/src/app/sitemap.xml b/apps/web-roo-code/src/app/sitemap.xml
deleted file mode 100644
index 43ac973306..0000000000
--- a/apps/web-roo-code/src/app/sitemap.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- https://roocode.com/
- 2025-03-13T22:26:09Z
- yearly
- 1.0
-
-
diff --git a/apps/web-roo-code/src/app/terms/page.tsx b/apps/web-roo-code/src/app/terms/page.tsx
index 545e577457..f5aea3d663 100644
--- a/apps/web-roo-code/src/app/terms/page.tsx
+++ b/apps/web-roo-code/src/app/terms/page.tsx
@@ -1,9 +1,41 @@
-import { Metadata } from "next"
+import type { Metadata } from "next"
+import { SEO } from "@/lib/seo"
+
+const TITLE = "Terms of Service"
+const DESCRIPTION =
+ "Terms of Service for Roo Code Cloud. Learn about our service terms, commercial conditions, and legal framework."
+const PATH = "/terms"
+const OG_IMAGE = SEO.ogImage
export const metadata: Metadata = {
- title: "Terms of Service - Roo Code",
- description:
- "Terms of Service for Roo Code Cloud. Learn about our service terms, commercial conditions, and legal framework.",
+ title: TITLE,
+ description: DESCRIPTION,
+ alternates: {
+ canonical: `${SEO.url}${PATH}`,
+ },
+ openGraph: {
+ title: TITLE,
+ description: DESCRIPTION,
+ url: `${SEO.url}${PATH}`,
+ siteName: SEO.name,
+ images: [
+ {
+ url: OG_IMAGE.url,
+ width: OG_IMAGE.width,
+ height: OG_IMAGE.height,
+ alt: OG_IMAGE.alt,
+ },
+ ],
+ locale: SEO.locale,
+ type: "article",
+ },
+ twitter: {
+ card: SEO.twitterCard,
+ title: TITLE,
+ description: DESCRIPTION,
+ images: [OG_IMAGE.url],
+ },
+ keywords: [...SEO.keywords, "terms of service", "legal", "agreement", "subscription"],
}
export default function Terms() {
diff --git a/apps/web-roo-code/src/lib/seo.ts b/apps/web-roo-code/src/lib/seo.ts
new file mode 100644
index 0000000000..962662bb22
--- /dev/null
+++ b/apps/web-roo-code/src/lib/seo.ts
@@ -0,0 +1,30 @@
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://roocode.com"
+
+export const SEO = {
+ url: SITE_URL,
+ name: "Roo Code",
+ title: "Roo Code – Your AI-Powered Dev Team in VS Code",
+ description:
+ "Roo Code puts an entire AI dev team right in your editor, outpacing closed tools with deep project-wide context, multi-step agentic coding, and unmatched developer-centric flexibility.",
+ locale: "en_US",
+ ogImage: {
+ url: "/android-chrome-512x512.png",
+ width: 512,
+ height: 512,
+ alt: "Roo Code Logo",
+ },
+ keywords: [
+ "Roo Code",
+ "AI coding agent",
+ "VS Code extension",
+ "AI pair programmer",
+ "software development",
+ "agentic coding",
+ "code refactoring",
+ "debugging",
+ ],
+ category: "technology",
+ twitterCard: "summary_large_image" as const,
+} as const
+
+export type SeoConfig = typeof SEO
diff --git a/knip.json b/knip.json
index 7ca8cfad7b..a847111981 100644
--- a/knip.json
+++ b/knip.json
@@ -7,7 +7,8 @@
"src/activate/**",
"src/workers/countTokens.ts",
"src/extension.ts",
- "scripts/**"
+ "scripts/**",
+ "apps/web-roo-code/next-sitemap.config.cjs"
],
"workspaces": {
"src": {
@@ -16,7 +17,7 @@
},
"webview-ui": {
"entry": ["src/index.tsx"],
- "project": ["src/**/*.{ts,tsx}"]
+ "project": ["src/**/*.{ts,tsx}", "../src/shared/*.ts"]
},
"packages/{build,cloud,evals,ipc,telemetry,types}": {
"project": ["src/**/*.ts"]
diff --git a/locales/ca/README.md b/locales/ca/README.md
index a2ba29f1f0..3a156e83a6 100644
--- a/locales/ca/README.md
+++ b/locales/ca/README.md
@@ -182,46 +182,47 @@ Gràcies a tots els nostres col·laboradors que han ajudat a millorar Roo Code!
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/de/README.md b/locales/de/README.md
index 296f5d45da..4856e9255b 100644
--- a/locales/de/README.md
+++ b/locales/de/README.md
@@ -182,46 +182,47 @@ Danke an alle unsere Mitwirkenden, die geholfen haben, Roo Code zu verbessern!
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/es/README.md b/locales/es/README.md
index 55e337ce2b..4a2298009f 100644
--- a/locales/es/README.md
+++ b/locales/es/README.md
@@ -182,46 +182,47 @@ Usamos [changesets](https://github.com/changesets/changesets) para versionar y p
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/fr/README.md b/locales/fr/README.md
index a21af64235..7ea8ed8bfa 100644
--- a/locales/fr/README.md
+++ b/locales/fr/README.md
@@ -182,46 +182,47 @@ Merci à tous nos contributeurs qui ont aidé à améliorer Roo Code !
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/hi/README.md b/locales/hi/README.md
index dcbb8dfff5..8e174bce24 100644
--- a/locales/hi/README.md
+++ b/locales/hi/README.md
@@ -182,46 +182,47 @@ Roo Code को बेहतर बनाने में मदद करने
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/id/README.md b/locales/id/README.md
index fae6572e7b..ebdc117626 100644
--- a/locales/id/README.md
+++ b/locales/id/README.md
@@ -176,46 +176,47 @@ Terima kasih kepada semua kontributor kami yang telah membantu membuat Roo Code
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/it/README.md b/locales/it/README.md
index a9237c46dc..70c034677b 100644
--- a/locales/it/README.md
+++ b/locales/it/README.md
@@ -182,46 +182,47 @@ Grazie a tutti i nostri contributori che hanno aiutato a migliorare Roo Code!
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/ja/README.md b/locales/ja/README.md
index 3650f18571..15cbde889e 100644
--- a/locales/ja/README.md
+++ b/locales/ja/README.md
@@ -182,46 +182,47 @@ Roo Codeの改善に貢献してくれたすべての貢献者に感謝します
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/ko/README.md b/locales/ko/README.md
index d5f26d1f4e..9453cdd389 100644
--- a/locales/ko/README.md
+++ b/locales/ko/README.md
@@ -182,46 +182,47 @@ Roo Code를 더 좋게 만드는 데 도움을 준 모든 기여자에게 감사
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/nl/README.md b/locales/nl/README.md
index a167b102fb..ec4e34f69e 100644
--- a/locales/nl/README.md
+++ b/locales/nl/README.md
@@ -182,46 +182,47 @@ Dank aan alle bijdragers die Roo Code beter hebben gemaakt!
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/pl/README.md b/locales/pl/README.md
index f4e67900d6..4424ef18ad 100644
--- a/locales/pl/README.md
+++ b/locales/pl/README.md
@@ -182,46 +182,47 @@ Dziękujemy wszystkim naszym współtwórcom, którzy pomogli ulepszyć Roo Code
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/pt-BR/README.md b/locales/pt-BR/README.md
index 3b2042fcc1..a8ab2c3890 100644
--- a/locales/pt-BR/README.md
+++ b/locales/pt-BR/README.md
@@ -182,46 +182,47 @@ Obrigado a todos os nossos contribuidores que ajudaram a tornar o Roo Code melho
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/ru/README.md b/locales/ru/README.md
index cfa3a843ef..84f6830e52 100644
--- a/locales/ru/README.md
+++ b/locales/ru/README.md
@@ -182,46 +182,47 @@ code --install-extension bin/roo-cline-.vsix
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/tr/README.md b/locales/tr/README.md
index ed099e92c7..579b7da4fc 100644
--- a/locales/tr/README.md
+++ b/locales/tr/README.md
@@ -182,46 +182,47 @@ Roo Code'u daha iyi hale getirmeye yardımcı olan tüm katkıda bulunanlara te
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/vi/README.md b/locales/vi/README.md
index 0c37d84ce8..b6a133b5c7 100644
--- a/locales/vi/README.md
+++ b/locales/vi/README.md
@@ -182,46 +182,47 @@ Cảm ơn tất cả những người đóng góp đã giúp cải thiện Roo C
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/zh-CN/README.md b/locales/zh-CN/README.md
index d308eb0304..dd2e654dbe 100644
--- a/locales/zh-CN/README.md
+++ b/locales/zh-CN/README.md
@@ -182,46 +182,47 @@ code --install-extension bin/roo-cline-.vsix
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/locales/zh-TW/README.md b/locales/zh-TW/README.md
index 9767d316ed..85bcf647bb 100644
--- a/locales/zh-TW/README.md
+++ b/locales/zh-TW/README.md
@@ -183,46 +183,47 @@ code --install-extension bin/roo-cline-.vsix
-| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
-| 
joemanley201 | 
jr | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
-| 
NyxJae | 
d-oit | 
elianiva | 
qdaxb | 
xyOz-dev | 
punkpeye |
-| 
wkordalski | 
chrarnoldus | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
-| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
-| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
Szpadel | 
lupuletic |
-| 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie | 
ChuKhaLi |
-| 
PeterDaveHello | 
aheizi | 
NaccOll | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
-| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
-| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
-| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
-| 
p12tic | 
gtaylor | 
aitoroses | 
ross | 
mr-ryan-james | 
heyseth |
-| 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite | 
ronyblum |
-| 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo | 
ashktn |
-| 
franekp | 
yt3trees | 
seedlord | 
bramburn | 
anton-otee | 
benzntech |
-| 
axkirillov | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk | 
GitlyHallows |
-| 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras | 
SplittyDev |
-| 
mdp | 
napter | 
philfung | 
axmo | 
bannzai | 
bbenshalom |
-| 
chris-garrett | 
dairui1 | 
dqroid | 
ershang-fireworks | 
janaki-sasidhar | 
forestyoo |
-| 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
asychin | 
amittell |
-| 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 | 
vladstudio | 
vivekfyi |
-| 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 | 
tgfjt | 
maekawataiki |
-| 
AlexandruSmirnov | 
nevermorec | 
PretzelVector | 
zetaloop | 
cdlliuy | 
user202729 |
-| 
takakoutso | 
student20880 | 
shubhamgupta731 | 
shohei-ihaya | 
shivamd1810 | 
shaybc |
-| 
sensei-woo | 
samir-nimbly | 
robertheadley | 
refactorthis | 
qingyuan1109 | 
pokutuna |
-| 
philipnext | 
village-way | 
oprstchn | 
nobu007 | 
mosleyit | 
moqimoqidea |
-| 
mlopezr | 
mecab | 
olup | 
lightrabbit | 
lhish | 
kohii |
-| 
kinandan | 
jwcraig | 
jues | 
DeXtroTip | 
pfitz | 
ExactDoug |
-| 
celestial-vault | 
linegel | 
edwin-truthsearch-io | 
EamonNerbonne | 
dbasclpy | 
dflatline |
-| 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth | 
thecolorblue | 
bogdan0083 |
-| 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron | 
andrewshu2000 | 
andreastempsch |
-| 
alasano | 
QuinsZouls | 
HadesArchitect | 
alarno | 
nexon33 | 
adilhafeez |
-| 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
samsilveira | 
01Rian |
-| 
RSO | 
RandalSchwartz | 
SECKainersdorfer | 
R-omk | 
pwilkin | 
Sarke |
-| 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 | 
Naam | 
kvokka | 
ecmasx |
-| 
mollux | 
marvijo-code | 
markijbema | 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth |
-| 
shtse8 | 
Rexarrior | 
kevinvandijk | 
KevinZhao | 
ksze | 
AyazKaan |
-| 
Juice10 | 
snova-jorgep | 
Fovty | 
Jdo300 | 
hesara | |
+| 
mrubens | 
saoudrizwan | 
cte | 
daniel-lxs | 
samhvw8 | 
hannesrudolph |
+| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| 
KJ7LNW | 
a8trejo | 
MuriloFP | 
ColemanRoo | 
canrobins13 | 
stea9499 |
+| 
jr | 
joemanley201 | 
System233 | 
nissa-seru | 
jquanton | 
roomote-agent |
+| 
NyxJae | 
d-oit | 
elianiva | 
chrarnoldus | 
qdaxb | 
xyOz-dev |
+| 
punkpeye | 
wkordalski | 
SannidhyaSah | 
sachasayan | 
Smartsheet-JB-Brown | 
monotykamary |
+| 
cannuri | 
feifei325 | 
zhangtony239 | 
shariqriazz | 
vigneshsubbiah16 | 
pugazhendhi-m |
+| 
lloydchang | 
liwilliam2021 | 
dtrugman | 
hassoncs | 
PeterDaveHello | 
Szpadel |
+| 
lupuletic | 
kiwina | 
Premshay | 
psv2522 | 
olweraltuve | 
diarmidmackenzie |
+| 
ChuKhaLi | 
NaccOll | 
aheizi | 
nbihan-mediware | 
noritaka1166 | 
RaySinner |
+| 
afshawnlotfi | 
dleffel | 
StevenTCramer | 
Ruakij | 
pdecat | 
kyle-apex |
+| 
emshvac | 
brunobergher | 
Lunchb0ne | 
SmartManoj | 
vagadiya | 
slytechnical |
+| 
dlab-anton | 
arthurauffray | 
upamune | 
NamesMT | 
taylorwilsdon | 
sammcj |
+| 
p12tic | 
gtaylor | 
aitoroses | 
benzntech | 
ross | 
mr-ryan-james |
+| 
heyseth | 
taisukeoe | 
avtc | 
eonghk | 
GOODBOY008 | 
kcwhite |
+| 
ronyblum | 
teddyOOXX | 
thill2323 | 
vincentsong | 
yongjer | 
zeozeozeo |
+| 
ashktn | 
franekp | 
yt3trees | 
seedlord | 
QuinsZouls | 
anton-otee |
+| 
axkirillov | 
bramburn | 
olearycrew | 
catrielmuller | 
devxpain | 
snoyiatk |
+| 
GitlyHallows | 
jcbdev | 
Chenjiayuan195 | 
julionav | 
KanTakahiro | 
kevint-cerebras |
+| 
SplittyDev | 
mdp | 
napter | 
philfung | 
dqroid | 
dairui1 |
+| 
chris-garrett | 
bbenshalom | 
bannzai | 
ershang-fireworks | 
f14XuanLv | 
janaki-sasidhar |
+| 
forestyoo | 
hatsu38 | 
hongzio | 
im47cn | 
shoopapa | 
axmo |
+| 
asychin | 
amittell | 
Yoshino-Yukitaro | 
Yikai-Liao | 
zxdvd | 
s97712 |
+| 
vladstudio | 
vivekfyi | 
HahaBill | 
tmsjngx0 | 
TGlide | 
Githubguy132010 |
+| 
tgfjt | 
maekawataiki | 
DeXtroTip | 
qingyuan1109 | 
refactorthis | 
robertheadley |
+| 
samir-nimbly | 
sensei-woo | 
shaybc | 
shivamd1810 | 
shohei-ihaya | 
shubhamgupta731 |
+| 
student20880 | 
takakoutso | 
user202729 | 
cdlliuy | 
zetaloop | 
PretzelVector |
+| 
nevermorec | 
jues | 
jwcraig | 
kinandan | 
kohii | 
lhish |
+| 
lightrabbit | 
olup | 
mecab | 
mlopezr | 
moqimoqidea | 
mosleyit |
+| 
nobu007 | 
oprstchn | 
village-way | 
philipnext | 
pokutuna | 
pfitz |
+| 
ExactDoug | 
celestial-vault | 
linegel | 
ertan2002 | 
edwin-truthsearch-io | 
EamonNerbonne |
+| 
dbasclpy | 
dflatline | 
Deon588 | 
dleen | 
CW-B-W | 
chadgauth |
+| 
thecolorblue | 
bogdan0083 | 
benashby | 
Atlogit | 
atlasgong | 
AntiMoron |
+| 
andrewshu2000 | 
andreastempsch | 
alasano | 
HadesArchitect | 
alarno | 
nexon33 |
+| 
adilhafeez | 
adamwlarson | 
adamhill | 
AMHesch | 
adambrand | 
abumalick |
+| 
AlexandruSmirnov | 
samsilveira | 
01Rian | 
RSO | 
RandalSchwartz | 
SECKainersdorfer |
+| 
R-omk | 
pwilkin | 
Sarke | 
PaperBoardOfficial | 
OlegOAndreev | 
niteshbalusu11 |
+| 
Naam | 
kvokka | 
ecmasx | 
mollux | 
marvijo-code | 
markijbema |
+| 
mamertofabian | 
monkeyDluffy6017 | 
libertyteeth | 
shtse8 | 
Rexarrior | 
kevinvandijk |
+| 
KevinZhao | 
ksze | 
AyazKaan | 
Juice10 | 
snova-jorgep | 
Fovty |
+| 
Jdo300 | 
hesara | | | | |
diff --git a/package.json b/package.json
index c1ddc68223..cdc8a1abca 100644
--- a/package.json
+++ b/package.json
@@ -24,15 +24,20 @@
"knip": "knip --include files",
"update-contributors": "node scripts/update-contributors.js",
"evals": "dotenvx run -f packages/evals/.env.development packages/evals/.env.local -- docker compose -f packages/evals/docker-compose.yml --profile server --profile runner up --build --scale runner=0",
- "link-workspace-packages": "node scripts/link-packages.js",
- "unlink-workspace-packages": "node scripts/link-packages.js --unlink"
+ "npm:publish:types": "pnpm --filter @roo-code/types npm:publish",
+ "link-workspace-packages": "tsx scripts/link-packages.ts",
+ "unlink-workspace-packages": "tsx scripts/link-packages.ts --unlink"
},
"devDependencies": {
"@changesets/cli": "^2.27.10",
"@dotenvx/dotenvx": "^1.34.0",
+ "@roo-code/config-typescript": "workspace:^",
+ "@types/glob": "^9.0.0",
+ "@types/node": "^24.1.0",
"@vscode/vsce": "3.3.2",
"esbuild": "^0.25.0",
"eslint": "^9.27.0",
+ "glob": "^11.0.3",
"husky": "^9.1.7",
"knip": "^5.44.4",
"lint-staged": "^16.0.0",
@@ -41,6 +46,7 @@
"ovsx": "0.10.4",
"prettier": "^3.4.2",
"rimraf": "^6.0.1",
+ "tsx": "^4.19.3",
"turbo": "^2.5.3",
"typescript": "^5.4.5"
},
diff --git a/packages/types/.gitignore b/packages/types/.gitignore
new file mode 100644
index 0000000000..ddf5f39ede
--- /dev/null
+++ b/packages/types/.gitignore
@@ -0,0 +1,2 @@
+dist
+npm/package.json
diff --git a/packages/types/eslint.config.mjs b/packages/types/eslint.config.mjs
index 694bf73664..c603a68f12 100644
--- a/packages/types/eslint.config.mjs
+++ b/packages/types/eslint.config.mjs
@@ -1,4 +1,20 @@
import { config } from "@roo-code/config-eslint/base"
+import globals from "globals"
/** @type {import("eslint").Linter.Config} */
-export default [...config]
+export default [
+ ...config,
+ {
+ files: ["**/*.cjs"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.commonjs,
+ },
+ sourceType: "commonjs",
+ },
+ rules: {
+ "@typescript-eslint/no-require-imports": "off",
+ },
+ },
+]
diff --git a/packages/types/npm/package.json b/packages/types/npm/package.metadata.json
similarity index 52%
rename from packages/types/npm/package.json
rename to packages/types/npm/package.metadata.json
index 35e01d4ef7..391d2acbaa 100644
--- a/packages/types/npm/package.json
+++ b/packages/types/npm/package.metadata.json
@@ -1,6 +1,6 @@
{
"name": "@roo-code/types",
- "version": "1.45.0",
+ "version": "1.48.0",
"description": "TypeScript type definitions for Roo Code.",
"publishConfig": {
"access": "public",
@@ -17,28 +17,6 @@
"url": "https://github.com/RooCodeInc/Roo-Code/issues"
},
"homepage": "https://roocode.com",
- "keywords": [
- "roo",
- "roo-code",
- "ai"
- ],
- "main": "./dist/index.cjs",
- "module": "./dist/index.js",
- "types": "./dist/index.d.ts",
- "exports": {
- ".": {
- "types": "./dist/index.d.ts",
- "import": "./dist/index.js",
- "require": {
- "types": "./dist/index.d.cts",
- "default": "./dist/index.cjs"
- }
- }
- },
- "files": [
- "dist"
- ],
- "dependencies": {
- "zod": "^3.25.61"
- }
+ "keywords": ["roo", "roo-code", "ai"],
+ "files": ["dist"]
}
diff --git a/packages/types/package.json b/packages/types/package.json
index feda97f289..44fde30b59 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -18,8 +18,9 @@
"check-types": "tsc --noEmit",
"test": "vitest run",
"build": "tsup",
- "npm:publish": "cd npm && npm version minor && cd - && tsup --outDir npm/dist && cd npm && npm publish",
- "clean": "rimraf dist npm/dist .turbo"
+ "build:watch": "tsup --watch --outDir npm/dist --onSuccess 'echo ✅ Types rebuilt to npm/dist'",
+ "npm:publish": "node scripts/publish-npm.cjs",
+ "clean": "rimraf dist .turbo"
},
"dependencies": {
"zod": "^3.25.61"
@@ -27,7 +28,8 @@
"devDependencies": {
"@roo-code/config-eslint": "workspace:^",
"@roo-code/config-typescript": "workspace:^",
- "@types/node": "20.x",
+ "@types/node": "^24.1.0",
+ "globals": "^16.3.0",
"tsup": "^8.3.5",
"vitest": "^3.2.3"
}
diff --git a/packages/types/scripts/publish-npm.cjs b/packages/types/scripts/publish-npm.cjs
new file mode 100644
index 0000000000..467ae3d506
--- /dev/null
+++ b/packages/types/scripts/publish-npm.cjs
@@ -0,0 +1,351 @@
+/* eslint-env node */
+
+const fs = require("fs")
+const path = require("path")
+const { execSync } = require("child_process")
+const readline = require("readline")
+
+const PACKAGE_NAME = "@roo-code/types"
+const BRANCH_NAME = "roo-code-types-v"
+
+const rootDir = path.join(__dirname, "..")
+const npmDir = path.join(rootDir, "npm")
+const monorepoPackagePath = path.join(rootDir, "package.json")
+const npmMetadataPath = path.join(npmDir, "package.metadata.json")
+const npmPackagePath = path.join(npmDir, "package.json")
+
+const args = process.argv.slice(2)
+const publishOnly = args.includes("--publish-only")
+
+async function confirmPublish() {
+ const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+ })
+
+ return new Promise((resolve) => {
+ rl.question("\n⚠️ Are you sure you want to publish to npm? (y/n): ", (answer) => {
+ rl.close()
+ resolve(answer.toLowerCase() === "y")
+ })
+ })
+}
+
+function updatePackageVersion(filePath, version) {
+ try {
+ const packageContent = JSON.parse(fs.readFileSync(filePath, "utf8"))
+ const oldVersion = packageContent.version
+ packageContent.version = version
+ fs.writeFileSync(filePath, JSON.stringify(packageContent, null, 2) + "\n")
+
+ try {
+ execSync(`npx prettier --write "${filePath}"`, { stdio: "pipe" })
+ console.log(`✨ Formatted ${path.basename(filePath)} with prettier`)
+ } catch (prettierError) {
+ console.warn(`⚠️ Could not format with prettier:`, prettierError.message)
+ }
+
+ const fileName = path.basename(filePath)
+ console.log(`✅ Updated ${fileName} version: ${oldVersion} → ${version}`)
+ return oldVersion
+ } catch (error) {
+ throw new Error(`Failed to update version in ${path.basename(filePath)}: ${error.message}`)
+ }
+}
+
+function syncVersionToMetadata(version) {
+ console.log(" 📝 Syncing version to package.metadata.json...")
+ updatePackageVersion(npmMetadataPath, version)
+}
+
+function commitVersionChanges(version) {
+ try {
+ console.log(" 📝 Committing version changes to git...")
+
+ try {
+ const status = execSync("git status --porcelain", { encoding: "utf8" })
+ const relevantChanges = status.split("\n").filter((line) => line.includes("packages/types/npm/package"))
+
+ if (relevantChanges.length === 0) {
+ console.log(" ⚠️ No version changes to commit")
+ return
+ }
+ } catch (error) {
+ console.warn(" ⚠️ Could not check git status:", error.message)
+ }
+
+ execSync("git add .", { stdio: "pipe" })
+ const commitMessage = `chore: bump version to v${version}`
+ execSync(`git commit -m "${commitMessage}"`, { stdio: "pipe" })
+ console.log(` ✅ Committed: ${commitMessage}`)
+ } catch (error) {
+ console.warn(" ⚠️ Could not commit version changes:", error.message)
+ console.log(" You may need to commit these changes manually.")
+ }
+}
+
+function checkGitHubCLI() {
+ try {
+ execSync("gh --version", { stdio: "pipe" })
+ execSync("gh auth status", { stdio: "pipe" })
+ return true
+ } catch (_error) {
+ return false
+ }
+}
+
+function createPullRequest(branchName, baseBranch, version) {
+ try {
+ console.log(` 🔄 Creating pull request...`)
+
+ if (!checkGitHubCLI()) {
+ console.warn(" ⚠️ GitHub CLI not found or not authenticated")
+ console.log(" Install gh CLI and run: gh auth login")
+ console.log(" Then manually create PR with: gh pr create")
+ return
+ }
+
+ const title = `Release: v${version}`
+ const body = `## 🚀 Release v${version}
+
+This PR contains the version bump for the SDK release v${version}.
+
+### Changes
+- Bumped version from previous to v${version}
+- Published to npm as ${PACKAGE_NAME}@${version}
+
+### Checklist
+- [x] Version bumped
+- [x] Package published to npm
+- [ ] Changelog updated (if applicable)
+- [ ] Documentation updated (if applicable)
+
+---
+*This PR was automatically created by the npm publish script.*`
+
+ try {
+ // Create the pull request
+ const prUrl = execSync(
+ `gh pr create --base "${baseBranch}" --head "${branchName}" --title "${title}" --body "${body}"`,
+ { encoding: "utf8", stdio: "pipe" },
+ ).trim()
+
+ console.log(` ✅ Pull request created: ${prUrl}`)
+ } catch (error) {
+ if (error.message.includes("already exists")) {
+ console.log(" ℹ️ Pull request already exists for this branch")
+ } else {
+ throw error
+ }
+ }
+ } catch (error) {
+ console.error(" ❌ Failed to create pull request:", error.message)
+ console.log(" You can manually create a PR with:")
+ console.log(` gh pr create --base "${baseBranch}" --head "${branchName}"`)
+ }
+}
+
+function createVersionBranchAndCommit(version) {
+ try {
+ const branchName = `${BRANCH_NAME}${version}`
+ console.log(` 🌿 Creating version branch: ${branchName}...`)
+
+ let currentBranch
+
+ try {
+ currentBranch = execSync("git rev-parse --abbrev-ref HEAD", {
+ encoding: "utf8",
+ }).trim()
+ } catch (_error) {
+ console.warn(" ⚠️ Could not determine current branch")
+ currentBranch = "main"
+ }
+
+ execSync(`git checkout -b ${branchName}`, { stdio: "pipe" })
+ console.log(` ✅ Created branch: ${branchName}`)
+ commitVersionChanges(version)
+ execSync(`git push --set-upstream origin ${branchName}`, { stdio: "pipe" })
+ console.log(` ✅ Pushed branch to origin with upstream tracking`)
+ createPullRequest(branchName, currentBranch, version)
+
+ if (currentBranch) {
+ execSync(`git checkout ${currentBranch}`, { stdio: "pipe" })
+ console.log(` ✅ Returned to branch: ${currentBranch}`)
+ }
+
+ console.log(` 🎯 Version branch created with commits: ${branchName}`)
+ } catch (error) {
+ console.error(" ❌ Failed to create version branch:", error.message)
+ console.log(" You may need to create the branch manually.")
+ }
+}
+
+function generateNpmPackage() {
+ try {
+ console.log(" 📖 Reading monorepo package.json...")
+
+ const monorepoPackageContent = fs.readFileSync(monorepoPackagePath, "utf8")
+ const monorepoPackage = JSON.parse(monorepoPackageContent)
+
+ console.log(" 📖 Reading npm package metadata...")
+
+ const npmMetadataContent = fs.readFileSync(npmMetadataPath, "utf8")
+ const npmMetadata = JSON.parse(npmMetadataContent)
+
+ console.log(" 🔨 Generating npm package.json...")
+
+ const npmPackage = {
+ ...npmMetadata,
+ dependencies: monorepoPackage.dependencies || {},
+ main: "./dist/index.cjs",
+ module: "./dist/index.js",
+ types: "./dist/index.d.ts",
+ exports: {
+ ".": {
+ types: "./dist/index.d.ts",
+ import: "./dist/index.js",
+ require: {
+ types: "./dist/index.d.cts",
+ default: "./dist/index.cjs",
+ },
+ },
+ },
+ files: ["dist"],
+ }
+
+ const outputContent = JSON.stringify(npmPackage, null, 2) + "\n"
+ fs.writeFileSync(npmPackagePath, outputContent)
+
+ console.log(" ✅ npm/package.json generated successfully")
+ console.log(` 📦 Package name: ${npmPackage.name}`)
+ console.log(` 📌 Version: ${npmPackage.version}`)
+ console.log(` 📚 Dependencies: ${Object.keys(npmPackage.dependencies).length}`)
+ } catch (error) {
+ throw new Error(`Failed to generate npm package.json: ${error.message}`)
+ }
+}
+
+async function publish() {
+ try {
+ console.log("\n🚀 NPM PUBLISH WORKFLOW")
+ if (publishOnly) {
+ console.log("📌 Mode: Publish only (no git operations)")
+ }
+ console.log("=".repeat(60))
+
+ console.log("\n📦 Step 1: Generating npm package.json...")
+ generateNpmPackage()
+
+ const npmPackage = JSON.parse(fs.readFileSync(npmPackagePath, "utf8"))
+ const originalVersion = npmPackage.version // Save original version
+ console.log(`\n📌 Current version: ${npmPackage.version}`)
+ console.log(`📦 Package name: ${npmPackage.name}`)
+
+ console.log("\n📈 Step 2: Bumping version (minor)...")
+
+ try {
+ execSync("npm version minor --no-git-tag-version", {
+ cwd: npmDir,
+ stdio: "inherit",
+ })
+ } catch (error) {
+ console.error("❌ Failed to bump version:", error.message)
+ throw error
+ }
+
+ const updatedPackage = JSON.parse(fs.readFileSync(npmPackagePath, "utf8"))
+ console.log(`✅ New version: ${updatedPackage.version}`)
+
+ console.log("\n🔨 Step 3: Building production bundle...")
+ console.log(" This may take a moment...")
+
+ try {
+ execSync("NODE_ENV=production pnpm tsup --outDir npm/dist", {
+ cwd: rootDir,
+ stdio: "inherit",
+ })
+
+ console.log("✅ Production build complete")
+ } catch (error) {
+ console.error("❌ Build failed:", error.message)
+ throw error
+ }
+
+ console.log("\n" + "=".repeat(60))
+ console.log("📋 PUBLISH SUMMARY:")
+ console.log(` Package: ${updatedPackage.name}`)
+ console.log(` Version: ${updatedPackage.version}`)
+ console.log(` Registry: ${updatedPackage.publishConfig?.registry || "https://registry.npmjs.org/"}`)
+ console.log(` Access: ${updatedPackage.publishConfig?.access || "public"}`)
+ console.log("=".repeat(60))
+
+ const confirmed = await confirmPublish()
+
+ if (!confirmed) {
+ console.log("\n❌ Publishing cancelled by user")
+ console.log("🔙 Reverting version change...")
+
+ try {
+ updatePackageVersion(npmPackagePath, originalVersion)
+ } catch (revertError) {
+ console.error("⚠️ Could not revert version:", revertError.message)
+ console.log(` You may need to manually change version back to ${originalVersion}`)
+ }
+
+ process.exit(0)
+ }
+
+ console.log("\n💾 Step 4: Syncing version to metadata...")
+ syncVersionToMetadata(updatedPackage.version)
+
+ console.log("\n🚀 Step 5: Publishing to npm...")
+
+ try {
+ execSync("npm publish", {
+ cwd: npmDir,
+ stdio: "inherit",
+ })
+ } catch (error) {
+ console.error("❌ Publish failed:", error.message)
+ console.error("💡 The package was built but not published.")
+ console.error(" You can try publishing manually from the npm directory.")
+
+ throw error
+ }
+
+ if (!publishOnly) {
+ console.log("\n🌿 Step 6: Creating version branch, committing, and opening PR...")
+ createVersionBranchAndCommit(updatedPackage.version)
+ } else {
+ console.log("\n📝 Step 6: Skipping version branch creation (--publish-only mode)")
+ }
+
+ console.log("\n" + "=".repeat(60))
+ console.log("✅ Successfully published to npm!")
+ console.log(`🎉 ${updatedPackage.name}@${updatedPackage.version} is now live`)
+ console.log(`📦 View at: https://www.npmjs.com/package/${updatedPackage.name}`)
+
+ if (!publishOnly) {
+ console.log(`🌿 Version branch: ${BRANCH_NAME}${updatedPackage.version}`)
+ }
+
+ console.log("=".repeat(60) + "\n")
+ } catch (error) {
+ console.error("\n❌ Error during publish process:", error.message)
+ console.error("\n💡 Troubleshooting tips:")
+ console.error(" 1. Ensure you are logged in to npm: npm whoami")
+ console.error(" 2. Check your npm permissions for this package")
+ console.error(" 3. Verify the package name is not already taken")
+ console.error(" 4. Make sure all dependencies are installed: pnpm install")
+ process.exit(1)
+ }
+}
+
+async function main() {
+ await publish()
+}
+
+main().catch((error) => {
+ console.error("Unexpected error:", error)
+ process.exit(1)
+})
diff --git a/packages/types/src/cloud.ts b/packages/types/src/cloud.ts
deleted file mode 100644
index be9a039d43..0000000000
--- a/packages/types/src/cloud.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-import { z } from "zod"
-
-import { globalSettingsSchema } from "./global-settings.js"
-import { mcpMarketplaceItemSchema } from "./marketplace.js"
-import { discriminatedProviderSettingsWithIdSchema } from "./provider-settings.js"
-
-/**
- * CloudUserInfo
- */
-
-export interface CloudUserInfo {
- id?: string
- name?: string
- email?: string
- picture?: string
- organizationId?: string
- organizationName?: string
- organizationRole?: string
- organizationImageUrl?: string
- extensionBridgeEnabled?: boolean
-}
-
-/**
- * CloudOrganization Types
- */
-
-export interface CloudOrganization {
- id: string
- name: string
- slug?: string
- image_url?: string
- has_image?: boolean
- created_at?: number
- updated_at?: number
-}
-
-export interface CloudOrganizationMembership {
- id: string
- organization: CloudOrganization
- role: string
- permissions?: string[]
- created_at?: number
- updated_at?: number
-}
-
-/**
- * OrganizationAllowList
- */
-
-export const organizationAllowListSchema = z.object({
- allowAll: z.boolean(),
- providers: z.record(
- z.object({
- allowAll: z.boolean(),
- models: z.array(z.string()).optional(),
- }),
- ),
-})
-
-export type OrganizationAllowList = z.infer
-
-/**
- * OrganizationDefaultSettings
- */
-
-export const organizationDefaultSettingsSchema = globalSettingsSchema
- .pick({
- enableCheckpoints: true,
- fuzzyMatchThreshold: true,
- maxOpenTabsContext: true,
- maxReadFileLine: true,
- maxWorkspaceFiles: true,
- showRooIgnoredFiles: true,
- terminalCommandDelay: true,
- terminalCompressProgressBar: true,
- terminalOutputLineLimit: true,
- terminalShellIntegrationDisabled: true,
- terminalShellIntegrationTimeout: true,
- terminalZshClearEolMark: true,
- })
- // Add stronger validations for some fields.
- .merge(
- z.object({
- maxOpenTabsContext: z.number().int().nonnegative().optional(),
- maxReadFileLine: z.number().int().gte(-1).optional(),
- maxWorkspaceFiles: z.number().int().nonnegative().optional(),
- terminalCommandDelay: z.number().int().nonnegative().optional(),
- terminalOutputLineLimit: z.number().int().nonnegative().optional(),
- terminalShellIntegrationTimeout: z.number().int().nonnegative().optional(),
- }),
- )
-
-export type OrganizationDefaultSettings = z.infer
-
-/**
- * OrganizationCloudSettings
- */
-
-export const organizationCloudSettingsSchema = z.object({
- recordTaskMessages: z.boolean().optional(),
- enableTaskSharing: z.boolean().optional(),
- taskShareExpirationDays: z.number().int().positive().optional(),
- allowMembersViewAllTasks: z.boolean().optional(),
-})
-
-export type OrganizationCloudSettings = z.infer
-
-/**
- * Organization Settings
- */
-
-export const organizationSettingsSchema = z.object({
- version: z.number(),
- cloudSettings: organizationCloudSettingsSchema.optional(),
- defaultSettings: organizationDefaultSettingsSchema,
- allowList: organizationAllowListSchema,
- hiddenMcps: z.array(z.string()).optional(),
- hideMarketplaceMcps: z.boolean().optional(),
- mcps: z.array(mcpMarketplaceItemSchema).optional(),
- providerProfiles: z.record(z.string(), discriminatedProviderSettingsWithIdSchema).optional(),
-})
-
-export type OrganizationSettings = z.infer
-
-/**
- * Constants
- */
-
-export const ORGANIZATION_ALLOW_ALL: OrganizationAllowList = {
- allowAll: true,
- providers: {},
-} as const
-
-export const ORGANIZATION_DEFAULT: OrganizationSettings = {
- version: 0,
- cloudSettings: {
- recordTaskMessages: true,
- enableTaskSharing: true,
- taskShareExpirationDays: 30,
- allowMembersViewAllTasks: true,
- },
- defaultSettings: {},
- allowList: ORGANIZATION_ALLOW_ALL,
-} as const
-
-/**
- * Share Types
- */
-
-export const shareResponseSchema = z.object({
- success: z.boolean(),
- shareUrl: z.string().optional(),
- error: z.string().optional(),
- isNewShare: z.boolean().optional(),
- manageUrl: z.string().optional(),
-})
-
-export type ShareResponse = z.infer
diff --git a/packages/types/src/global-settings.ts b/packages/types/src/global-settings.ts
index 39480e5a3d..c071726d8a 100644
--- a/packages/types/src/global-settings.ts
+++ b/packages/types/src/global-settings.ts
@@ -29,13 +29,6 @@ export const DEFAULT_WRITE_DELAY_MS = 1000
*/
export const DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT = 50_000
-/**
- * Default timeout for background usage collection in milliseconds.
- * This timeout prevents the background task from running indefinitely
- * when collecting usage data from streaming API responses.
- */
-export const DEFAULT_USAGE_COLLECTION_TIMEOUT_MS = 30_000
-
/**
* GlobalSettings
*/
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index dcbb1c4f54..c65d070086 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -1,5 +1,4 @@
export * from "./api.js"
-export * from "./cloud.js"
export * from "./codebase-index.js"
export * from "./events.js"
export * from "./experiment.js"
@@ -13,7 +12,6 @@ export * from "./message.js"
export * from "./mode.js"
export * from "./model.js"
export * from "./provider-settings.js"
-export * from "./sharing.js"
export * from "./task.js"
export * from "./todo.js"
export * from "./telemetry.js"
diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts
index fe04ad9185..fef7d811a4 100644
--- a/packages/types/src/provider-settings.ts
+++ b/packages/types/src/provider-settings.ts
@@ -3,6 +3,9 @@ import { z } from "zod"
import { reasoningEffortsSchema, verbosityLevelsSchema, modelInfoSchema } from "./model.js"
import { codebaseIndexProviderSchema } from "./codebase-index.js"
+// Bedrock Claude Sonnet 4 model ID that supports 1M context
+export const BEDROCK_CLAUDE_SONNET_4_MODEL_ID = "anthropic.claude-sonnet-4-20250514-v1:0"
+
// Extended schema that includes "minimal" for GPT-5 models
export const extendedReasoningEffortsSchema = z.union([reasoningEffortsSchema, z.literal("minimal")])
@@ -99,6 +102,7 @@ const anthropicSchema = apiModelIdProviderModelSchema.extend({
apiKey: z.string().optional(),
anthropicBaseUrl: z.string().optional(),
anthropicUseAuthToken: z.boolean().optional(),
+ anthropicBeta1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window
})
const claudeCodeSchema = apiModelIdProviderModelSchema.extend({
@@ -134,6 +138,7 @@ const bedrockSchema = apiModelIdProviderModelSchema.extend({
awsModelContextWindow: z.number().optional(),
awsBedrockEndpointEnabled: z.boolean().optional(),
awsBedrockEndpoint: z.string().optional(),
+ awsBedrock1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window
})
const vertexSchema = apiModelIdProviderModelSchema.extend({
diff --git a/packages/types/src/providers/anthropic.ts b/packages/types/src/providers/anthropic.ts
index 0c3323cffe..2cb38537a4 100644
--- a/packages/types/src/providers/anthropic.ts
+++ b/packages/types/src/providers/anthropic.ts
@@ -8,15 +8,25 @@ export const anthropicDefaultModelId: AnthropicModelId = "claude-sonnet-4-202505
export const anthropicModels = {
"claude-sonnet-4-20250514": {
maxTokens: 64_000, // Overridden to 8k if `enableReasoningEffort` is false.
- contextWindow: 200_000,
+ contextWindow: 200_000, // Default 200K, extendable to 1M with beta flag 'context-1m-2025-08-07'
supportsImages: true,
supportsComputerUse: true,
supportsPromptCache: true,
- inputPrice: 3.0, // $3 per million input tokens
- outputPrice: 15.0, // $15 per million output tokens
+ inputPrice: 3.0, // $3 per million input tokens (≤200K context)
+ outputPrice: 15.0, // $15 per million output tokens (≤200K context)
cacheWritesPrice: 3.75, // $3.75 per million tokens
cacheReadsPrice: 0.3, // $0.30 per million tokens
supportsReasoningBudget: true,
+ // Tiered pricing for extended context (requires beta flag 'context-1m-2025-08-07')
+ tiers: [
+ {
+ contextWindow: 1_000_000, // 1M tokens with beta flag
+ inputPrice: 6.0, // $6 per million input tokens (>200K context)
+ outputPrice: 22.5, // $22.50 per million output tokens (>200K context)
+ cacheWritesPrice: 7.5, // $7.50 per million tokens (>200K context)
+ cacheReadsPrice: 0.6, // $0.60 per million tokens (>200K context)
+ },
+ ],
},
"claude-opus-4-1-20250805": {
maxTokens: 8192,
diff --git a/packages/types/src/providers/bedrock.ts b/packages/types/src/providers/bedrock.ts
index 3d3aa8b984..d7319c132e 100644
--- a/packages/types/src/providers/bedrock.ts
+++ b/packages/types/src/providers/bedrock.ts
@@ -221,6 +221,26 @@ export const bedrockModels = {
inputPrice: 1.35,
outputPrice: 5.4,
},
+ "openai.gpt-oss-20b-1:0": {
+ maxTokens: 8192,
+ contextWindow: 128_000,
+ supportsImages: false,
+ supportsComputerUse: false,
+ supportsPromptCache: false,
+ inputPrice: 0.5,
+ outputPrice: 1.5,
+ description: "GPT-OSS 20B - Optimized for low latency and local/specialized use cases",
+ },
+ "openai.gpt-oss-120b-1:0": {
+ maxTokens: 8192,
+ contextWindow: 128_000,
+ supportsImages: false,
+ supportsComputerUse: false,
+ supportsPromptCache: false,
+ inputPrice: 2.0,
+ outputPrice: 6.0,
+ description: "GPT-OSS 120B - Production-ready, general-purpose, high-reasoning model",
+ },
"meta.llama3-3-70b-instruct-v1:0": {
maxTokens: 8192,
contextWindow: 128_000,
diff --git a/packages/types/src/providers/openai.ts b/packages/types/src/providers/openai.ts
index 78d3cb6334..ff79824984 100644
--- a/packages/types/src/providers/openai.ts
+++ b/packages/types/src/providers/openai.ts
@@ -193,15 +193,6 @@ export const openAiNativeModels = {
outputPrice: 4.4,
cacheReadsPrice: 0.55,
},
- "gpt-4.5-preview": {
- maxTokens: 16_384,
- contextWindow: 128_000,
- supportsImages: true,
- supportsPromptCache: true,
- inputPrice: 75,
- outputPrice: 150,
- cacheReadsPrice: 37.5,
- },
"gpt-4o": {
maxTokens: 16_384,
contextWindow: 128_000,
diff --git a/packages/types/src/sharing.ts b/packages/types/src/sharing.ts
deleted file mode 100644
index f295798032..0000000000
--- a/packages/types/src/sharing.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Types related to task sharing functionality
- */
-
-/**
- * Visibility options for sharing tasks
- */
-export type ShareVisibility = "organization" | "public"
diff --git a/packages/types/src/task.ts b/packages/types/src/task.ts
index 20e41acd1f..bf6fc23c96 100644
--- a/packages/types/src/task.ts
+++ b/packages/types/src/task.ts
@@ -1,6 +1,9 @@
+import { z } from "zod"
+
import { RooCodeEventName } from "./events.js"
import { type ClineMessage, type BlockingAsk, type TokenUsage } from "./message.js"
import { type ToolUsage, type ToolName } from "./tool.js"
+import { type Experiments } from "./experiment.js"
/**
* TaskProviderLike
@@ -16,7 +19,7 @@ export interface InitTaskOptions {
enableCheckpoints?: boolean
fuzzyMatchThreshold?: number
consecutiveMistakeLimit?: number
- experiments?: any
+ experiments?: Experiments
}
export interface TaskProviderLike {
readonly cwd: string
@@ -74,10 +77,19 @@ export type TaskProviderEvents = {
* TaskLike
*/
+export const taskMetadataSchema = z.object({
+ taskId: z.string(),
+ task: z.string().optional(),
+ images: z.array(z.string()).optional(),
+})
+
+export type TaskMetadata = z.infer
+
export interface TaskLike {
readonly taskId: string
readonly rootTask?: TaskLike
readonly blockingAsk?: BlockingAsk
+ readonly metadata: TaskMetadata
on(event: K, listener: (...args: TaskEvents[K]) => void | Promise): this
off(event: K, listener: (...args: TaskEvents[K]) => void | Promise): this
diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json
index a66434e570..2a73ee92bb 100644
--- a/packages/types/tsconfig.json
+++ b/packages/types/tsconfig.json
@@ -4,6 +4,6 @@
"types": ["vitest/globals"],
"outDir": "dist"
},
- "include": ["src"],
+ "include": ["src", "scripts", "*.config.ts"],
"exclude": ["node_modules"]
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0bc3f93bcb..7bcc01f194 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -22,6 +22,15 @@ importers:
'@dotenvx/dotenvx':
specifier: ^1.34.0
version: 1.44.2
+ '@roo-code/config-typescript':
+ specifier: workspace:^
+ version: link:packages/config-typescript
+ '@types/glob':
+ specifier: ^9.0.0
+ version: 9.0.0
+ '@types/node':
+ specifier: ^24.1.0
+ version: 24.2.1
'@vscode/vsce':
specifier: 3.3.2
version: 3.3.2
@@ -31,12 +40,15 @@ importers:
eslint:
specifier: ^9.27.0
version: 9.28.0(jiti@2.4.2)
+ glob:
+ specifier: ^11.0.3
+ version: 11.0.3
husky:
specifier: ^9.1.7
version: 9.1.7
knip:
specifier: ^5.44.4
- version: 5.60.2(@types/node@22.15.29)(typescript@5.8.3)
+ version: 5.60.2(@types/node@24.2.1)(typescript@5.8.3)
lint-staged:
specifier: ^16.0.0
version: 16.1.2
@@ -55,6 +67,9 @@ importers:
rimraf:
specifier: ^6.0.1
version: 6.0.1
+ tsx:
+ specifier: ^4.19.3
+ version: 4.19.4
turbo:
specifier: ^2.5.3
version: 2.5.4
@@ -235,7 +250,7 @@ importers:
version: 4.1.6
vitest:
specifier: ^3.2.3
- version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
apps/web-roo-code:
dependencies:
@@ -327,6 +342,9 @@ importers:
autoprefixer:
specifier: ^10.4.21
version: 10.4.21(postcss@8.5.4)
+ next-sitemap:
+ specifier: ^4.2.3
+ version: 4.2.3(next@15.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
postcss:
specifier: ^8.5.4
version: 8.5.4
@@ -521,14 +539,17 @@ importers:
specifier: workspace:^
version: link:../config-typescript
'@types/node':
- specifier: 20.x
- version: 20.17.57
+ specifier: ^24.1.0
+ version: 24.2.1
+ globals:
+ specifier: ^16.3.0
+ version: 16.3.0
tsup:
specifier: ^8.3.5
version: 8.5.0(jiti@2.4.2)(postcss@8.5.4)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.8.0)
vitest:
specifier: ^3.2.3
- version: 3.2.4(@types/debug@4.1.12)(@types/node@20.17.57)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
src:
dependencies:
@@ -563,8 +584,8 @@ importers:
specifier: ^1.14.0
version: 1.14.0(typescript@5.8.3)
'@roo-code/cloud':
- specifier: ^0.11.0
- version: 0.11.0
+ specifier: ^0.14.0
+ version: 0.14.0
'@roo-code/ipc':
specifier: workspace:^
version: link:../packages/ipc
@@ -703,6 +724,9 @@ importers:
simple-git:
specifier: ^3.27.0
version: 3.27.0
+ socket.io-client:
+ specifier: ^4.8.1
+ version: 4.8.1
sound-play:
specifier: ^1.1.0
version: 1.1.0
@@ -1511,6 +1535,9 @@ packages:
'@chevrotain/utils@11.0.3':
resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==}
+ '@corex/deepmerge@4.0.43':
+ resolution: {integrity: sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==}
+
'@csstools/color-helpers@5.0.2':
resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==}
engines: {node: '>=18'}
@@ -1936,6 +1963,14 @@ packages:
'@ioredis/commands@1.3.0':
resolution: {integrity: sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==}
+ '@isaacs/balanced-match@4.0.1':
+ resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
+ engines: {node: 20 || >=22}
+
+ '@isaacs/brace-expansion@5.0.0':
+ resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
+ engines: {node: 20 || >=22}
+
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@@ -2103,6 +2138,9 @@ packages:
'@neon-rs/load@0.0.4':
resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==}
+ '@next/env@13.5.11':
+ resolution: {integrity: sha512-fbb2C7HChgM7CemdCY+y3N1n8pcTKdqtQLbC7/EQtPdLvlMUT9JX/dBYl8MMZAtYG4uVMyPFHXckb68q/NRwqg==}
+
'@next/env@15.2.5':
resolution: {integrity: sha512-uWkCf9C8wKTyQjqrNk+BA7eL3LOQdhL+xlmJUf2O85RM4lbzwBwot3Sqv2QGe/RGnc3zysIf1oJdtq9S00pkmQ==}
@@ -3065,11 +3103,11 @@ packages:
cpu: [x64]
os: [win32]
- '@roo-code/cloud@0.11.0':
- resolution: {integrity: sha512-ZT3gBRNHI0HGmn5bMxdyhMxJVrp/7l7jcx/lDRl+xjeCP3KmJshzFKlfjdSGDtOoztnNj65hSbs/WiTS2wUodQ==}
+ '@roo-code/cloud@0.14.0':
+ resolution: {integrity: sha512-EKFw7sLSJcOpXQDjCMFL4EnE7OH3RhO00joteaysNYNpNe+js6kMFrBZY61rj1tZAXV/943RWeQptG4sSAfPFQ==}
- '@roo-code/types@1.45.0':
- resolution: {integrity: sha512-+rFJ9HcukDl59X9pI6lgZDtJHtKqHg6BIdS4LG759X+5MV7wvlNb4S+bQ3qKqIlBsQhH17bzIJCfsWZwjwxecw==}
+ '@roo-code/types@1.48.0':
+ resolution: {integrity: sha512-DJkA/310sLcs4vM4YLhJhc5A1JFYmdcOt+hRQMUPq+wF02yW9rc7ZZzHNDOOUZL+kk5naUd2nBRxLiJoh6o0Ng==}
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
@@ -3801,6 +3839,10 @@ packages:
'@types/glob@8.1.0':
resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==}
+ '@types/glob@9.0.0':
+ resolution: {integrity: sha512-00UxlRaIUvYm4R4W9WYkN8/J+kV8fmOQ7okeH6YFtGWFMt3odD45tpG5yA5wnL7HE6lLgjaTW5n14ju2hl2NNA==}
+ deprecated: This is a stub types definition. glob provides its own type definitions, so you do not need this installed.
+
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
@@ -3871,14 +3913,8 @@ packages:
'@types/node@20.17.57':
resolution: {integrity: sha512-f3T4y6VU4fVQDKVqJV4Uppy8c1p/sVvS3peyqxyWnzkqXFJLRU7Y1Bl7rMS1Qe9z0v4M6McY0Fp9yBsgHJUsWQ==}
- '@types/node@20.19.1':
- resolution: {integrity: sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA==}
-
- '@types/node@20.19.9':
- resolution: {integrity: sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==}
-
- '@types/node@22.15.29':
- resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==}
+ '@types/node@24.2.1':
+ resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==}
'@types/prop-types@15.7.14':
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
@@ -6000,6 +6036,11 @@ packages:
engines: {node: 20 || >=22}
hasBin: true
+ glob@11.0.3:
+ resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
@@ -6020,6 +6061,10 @@ packages:
resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==}
engines: {node: '>=18'}
+ globals@16.3.0:
+ resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==}
+ engines: {node: '>=18'}
+
globalthis@1.0.4:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
@@ -6571,6 +6616,10 @@ packages:
resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==}
engines: {node: 20 || >=22}
+ jackspeak@4.1.1:
+ resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
+ engines: {node: 20 || >=22}
+
jest-diff@29.7.0:
resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -7333,6 +7382,10 @@ packages:
resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
engines: {node: 20 || >=22}
+ minimatch@10.0.3:
+ resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==}
+ engines: {node: 20 || >=22}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -7441,6 +7494,13 @@ packages:
resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
engines: {node: '>= 0.4.0'}
+ next-sitemap@4.2.3:
+ resolution: {integrity: sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==}
+ engines: {node: '>=14.18'}
+ hasBin: true
+ peerDependencies:
+ next: '*'
+
next-themes@0.4.6:
resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
peerDependencies:
@@ -8675,6 +8735,7 @@ packages:
source-map@0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
engines: {node: '>= 8'}
+ deprecated: The work that was done in this beta branch won't be included in future versions
space-separated-tokens@1.1.5:
resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==}
@@ -9249,8 +9310,8 @@ packages:
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
- undici-types@6.21.0:
- resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+ undici-types@7.10.0:
+ resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==}
undici@6.21.3:
resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==}
@@ -10776,6 +10837,8 @@ snapshots:
'@chevrotain/utils@11.0.3': {}
+ '@corex/deepmerge@4.0.43': {}
+
'@csstools/color-helpers@5.0.2': {}
'@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
@@ -11133,6 +11196,12 @@ snapshots:
'@ioredis/commands@1.3.0': {}
+ '@isaacs/balanced-match@4.0.1': {}
+
+ '@isaacs/brace-expansion@5.0.0':
+ dependencies:
+ '@isaacs/balanced-match': 4.0.1
+
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@@ -11161,7 +11230,7 @@ snapshots:
'@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4
- '@types/node': 20.17.57
+ '@types/node': 24.2.1
'@types/yargs': 17.0.33
chalk: 4.1.2
@@ -11367,6 +11436,8 @@ snapshots:
'@neon-rs/load@0.0.4':
optional: true
+ '@next/env@13.5.11': {}
+
'@next/env@15.2.5': {}
'@next/eslint-plugin-next@15.3.2':
@@ -12234,9 +12305,9 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.40.2':
optional: true
- '@roo-code/cloud@0.11.0':
+ '@roo-code/cloud@0.14.0':
dependencies:
- '@roo-code/types': 1.45.0
+ '@roo-code/types': 1.48.0
ioredis: 5.6.1
p-wait-for: 5.0.2
socket.io-client: 4.8.1
@@ -12246,7 +12317,7 @@ snapshots:
- supports-color
- utf-8-validate
- '@roo-code/types@1.45.0':
+ '@roo-code/types@1.48.0':
dependencies:
zod: 3.25.76
@@ -13159,7 +13230,11 @@ snapshots:
'@types/glob@8.1.0':
dependencies:
'@types/minimatch': 5.1.2
- '@types/node': 20.17.57
+ '@types/node': 24.2.1
+
+ '@types/glob@9.0.0':
+ dependencies:
+ glob: 11.0.3
'@types/hast@3.0.4':
dependencies:
@@ -13212,12 +13287,12 @@ snapshots:
'@types/node-fetch@2.6.12':
dependencies:
- '@types/node': 20.17.57
+ '@types/node': 24.2.1
form-data: 4.0.4
'@types/node-ipc@9.2.3':
dependencies:
- '@types/node': 20.17.57
+ '@types/node': 24.2.1
'@types/node@12.20.55': {}
@@ -13235,18 +13310,9 @@ snapshots:
dependencies:
undici-types: 6.19.8
- '@types/node@20.19.1':
+ '@types/node@24.2.1':
dependencies:
- undici-types: 6.21.0
-
- '@types/node@20.19.9':
- dependencies:
- undici-types: 6.21.0
- optional: true
-
- '@types/node@22.15.29':
- dependencies:
- undici-types: 6.21.0
+ undici-types: 7.10.0
'@types/prop-types@15.7.14': {}
@@ -13277,11 +13343,11 @@ snapshots:
'@types/stream-chain@2.1.0':
dependencies:
- '@types/node': 20.19.1
+ '@types/node': 24.2.1
'@types/stream-json@1.7.8':
dependencies:
- '@types/node': 20.19.1
+ '@types/node': 24.2.1
'@types/stream-chain': 2.1.0
'@types/string-similarity@4.0.2': {}
@@ -13307,7 +13373,7 @@ snapshots:
'@types/ws@8.18.1':
dependencies:
- '@types/node': 20.19.9
+ '@types/node': 24.2.1
optional: true
'@types/yargs-parser@21.0.3': {}
@@ -13318,7 +13384,7 @@ snapshots:
'@types/yauzl@2.10.3':
dependencies:
- '@types/node': 20.17.50
+ '@types/node': 24.2.1
optional: true
'@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)':
@@ -13443,13 +13509,13 @@ snapshots:
optionalDependencies:
vite: 6.3.5(@types/node@20.17.57)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
- '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0))':
+ '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
- vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ vite: 6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -13480,7 +13546,7 @@ snapshots:
sirv: 3.0.1
tinyglobby: 0.2.14
tinyrainbow: 2.0.0
- vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
'@vitest/utils@3.2.4':
dependencies:
@@ -13561,7 +13627,7 @@ snapshots:
cockatiel: 3.2.1
commander: 12.1.0
form-data: 4.0.4
- glob: 11.0.2
+ glob: 11.0.3
hosted-git-info: 4.1.0
jsonc-parser: 3.3.1
leven: 3.1.0
@@ -15691,6 +15757,15 @@ snapshots:
package-json-from-dist: 1.0.1
path-scurry: 2.0.0
+ glob@11.0.3:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 4.1.1
+ minimatch: 10.0.3
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -15708,6 +15783,8 @@ snapshots:
globals@16.1.0: {}
+ globals@16.3.0: {}
+
globalthis@1.0.4:
dependencies:
define-properties: 1.2.1
@@ -16297,6 +16374,10 @@ snapshots:
dependencies:
'@isaacs/cliui': 8.0.2
+ jackspeak@4.1.1:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
jest-diff@29.7.0:
dependencies:
chalk: 4.1.2
@@ -16328,7 +16409,7 @@ snapshots:
jest-util@29.7.0:
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.17.57
+ '@types/node': 24.2.1
chalk: 4.1.2
ci-info: 3.9.0
graceful-fs: 4.2.11
@@ -16488,10 +16569,10 @@ snapshots:
kind-of@6.0.3: {}
- knip@5.60.2(@types/node@22.15.29)(typescript@5.8.3):
+ knip@5.60.2(@types/node@24.2.1)(typescript@5.8.3):
dependencies:
'@nodelib/fs.walk': 1.2.8
- '@types/node': 22.15.29
+ '@types/node': 24.2.1
fast-glob: 3.3.3
formatly: 0.2.4
jiti: 2.4.2
@@ -17322,6 +17403,10 @@ snapshots:
dependencies:
brace-expansion: 4.0.1
+ minimatch@10.0.3:
+ dependencies:
+ '@isaacs/brace-expansion': 5.0.0
+
minimatch@3.1.2:
dependencies:
brace-expansion: 4.0.1
@@ -17437,6 +17522,14 @@ snapshots:
netmask@2.0.2: {}
+ next-sitemap@4.2.3(next@15.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
+ dependencies:
+ '@corex/deepmerge': 4.0.43
+ '@next/env': 13.5.11
+ fast-glob: 3.3.3
+ minimist: 1.2.8
+ next: 15.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+
next-themes@0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
react: 18.3.1
@@ -18544,7 +18637,7 @@ snapshots:
rimraf@6.0.1:
dependencies:
- glob: 11.0.2
+ glob: 11.0.3
package-json-from-dist: 1.0.1
robust-predicates@3.0.2: {}
@@ -19531,7 +19624,7 @@ snapshots:
undici-types@6.19.8: {}
- undici-types@6.21.0: {}
+ undici-types@7.10.0: {}
undici@6.21.3: {}
@@ -19806,13 +19899,13 @@ snapshots:
- tsx
- yaml
- vite-node@3.2.4(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0):
+ vite-node@3.2.4(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0):
dependencies:
cac: 6.7.14
debug: 4.4.1(supports-color@8.1.1)
es-module-lexer: 1.7.0
pathe: 2.0.3
- vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ vite: 6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -19859,7 +19952,7 @@ snapshots:
tsx: 4.19.4
yaml: 2.8.0
- vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0):
+ vite@6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0):
dependencies:
esbuild: 0.25.5
fdir: 6.4.4(picomatch@4.0.2)
@@ -19868,7 +19961,7 @@ snapshots:
rollup: 4.40.2
tinyglobby: 0.2.13
optionalDependencies:
- '@types/node': 22.15.29
+ '@types/node': 24.2.1
fsevents: 2.3.3
jiti: 2.4.2
lightningcss: 1.30.1
@@ -19963,11 +20056,11 @@ snapshots:
- tsx
- yaml
- vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.29)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0):
+ vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0):
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
- '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0))
+ '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@@ -19985,12 +20078,12 @@ snapshots:
tinyglobby: 0.2.14
tinypool: 1.1.1
tinyrainbow: 2.0.0
- vite: 6.3.5(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
- vite-node: 3.2.4(@types/node@22.15.29)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ vite: 6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
+ vite-node: 3.2.4(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/debug': 4.1.12
- '@types/node': 22.15.29
+ '@types/node': 24.2.1
'@vitest/ui': 3.2.4(vitest@3.2.4)
jsdom: 26.1.0
transitivePeerDependencies:
diff --git a/scripts/link-packages.js b/scripts/link-packages.js
deleted file mode 100755
index 6d8b33f6de..0000000000
--- a/scripts/link-packages.js
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/usr/bin/env node
-
-const { spawn, execSync } = require("child_process")
-const path = require("path")
-const fs = require("fs")
-
-// Package configuration - Add new packages here as needed.
-const config = {
- packages: [
- {
- name: "@roo-code/cloud",
- sourcePath: "../Roo-Code-Cloud/packages/sdk",
- targetPath: "src/node_modules/@roo-code/cloud",
- npmPath: "npm",
- watchCommand: "pnpm build:development:watch",
- },
- ],
-}
-
-const args = process.argv.slice(2)
-const packageName = args.find((arg) => !arg.startsWith("--"))
-const watch = !args.includes("--no-watch")
-const unlink = args.includes("--unlink")
-
-const packages = packageName ? config.packages.filter((p) => p.name === packageName) : config.packages
-
-if (!packages.length) {
- console.error(`Package '${packageName}' not found`)
- process.exit(1)
-}
-
-packages.forEach(unlink ? unlinkPackage : linkPackage)
-
-// After unlinking, restore npm packages with a single pnpm install.
-if (unlink && packages.length > 0) {
- const srcPath = path.resolve(__dirname, "..", "src")
- console.log("\nRestoring npm packages...")
-
- try {
- execSync("pnpm install", { cwd: srcPath, stdio: "inherit" })
- console.log("Successfully restored npm packages")
- } catch (error) {
- console.error(`Failed to restore packages: ${error.message}`)
- console.log("You may need to run 'pnpm install' manually in the src directory")
- }
-}
-
-if (!unlink && watch) {
- const watchers = packages.filter((pkg) => pkg.watchCommand).map(startWatch)
-
- if (watchers.length) {
- process.on("SIGINT", () => {
- console.log("\nStopping...")
- watchers.forEach((w) => w.kill())
- process.exit(0)
- })
- console.log("\nWatching for changes. Press Ctrl+C to stop.\n")
- }
-}
-
-function generateNpmPackageJson(sourcePath, npmPath) {
- const npmDir = path.join(sourcePath, npmPath)
- const npmPackagePath = path.join(npmDir, "package.json")
- const npmMetadataPath = path.join(npmDir, "package.metadata.json")
- const monorepoPackagePath = path.join(sourcePath, "package.json")
-
- if (fs.existsSync(npmPackagePath)) {
- console.log(` ✓ npm/package.json already exists`)
- return
- }
-
- if (!fs.existsSync(npmMetadataPath)) {
- console.log(` ⚠ No package.metadata.json found, skipping npm package.json generation`)
- return
- }
-
- try {
- console.log(` 📦 Generating npm/package.json...`)
- const monorepoPackage = JSON.parse(fs.readFileSync(monorepoPackagePath, "utf8"))
- const npmMetadata = JSON.parse(fs.readFileSync(npmMetadataPath, "utf8"))
-
- const npmPackage = {
- ...npmMetadata,
- type: "module",
- dependencies: monorepoPackage.dependencies || {},
- main: "./dist/index.cjs",
- module: "./dist/index.js",
- types: "./dist/index.d.ts",
- exports: {
- ".": {
- types: "./dist/index.d.ts",
- import: "./dist/index.js",
- require: {
- types: "./dist/index.d.cts",
- default: "./dist/index.cjs",
- },
- },
- },
- files: ["dist"],
- }
-
- fs.writeFileSync(npmPackagePath, JSON.stringify(npmPackage, null, 2) + "\n")
- console.log(` ✓ Generated npm/package.json for ${npmPackage.name}`)
- } catch (error) {
- console.error(` ✗ Failed to generate npm/package.json: ${error.message}`)
- }
-}
-
-function linkPackage(pkg) {
- const sourcePath = path.resolve(__dirname, "..", pkg.sourcePath)
- const targetPath = path.resolve(__dirname, "..", pkg.targetPath)
-
- if (!fs.existsSync(sourcePath)) {
- console.error(`Source not found: ${sourcePath}`)
- process.exit(1)
- }
-
- // Install dependencies if needed.
- if (!fs.existsSync(path.join(sourcePath, "node_modules"))) {
- console.log(`Installing dependencies for ${pkg.name}...`)
-
- try {
- execSync("pnpm install", { cwd: sourcePath, stdio: "inherit" })
- } catch (e) {
- execSync("pnpm install --no-frozen-lockfile", { cwd: sourcePath, stdio: "inherit" })
- }
- }
-
- // If npmPath is specified, check if we need to generate package.json.
- if (pkg.npmPath) {
- generateNpmPackageJson(sourcePath, pkg.npmPath)
- }
-
- // Create symlink.
- fs.rmSync(targetPath, { recursive: true, force: true })
- fs.mkdirSync(path.dirname(targetPath), { recursive: true })
- const linkSource = pkg.npmPath ? path.join(sourcePath, pkg.npmPath) : sourcePath
- fs.symlinkSync(linkSource, targetPath, "dir")
- console.log(`Linked ${pkg.name}`)
-}
-
-function unlinkPackage(pkg) {
- const targetPath = path.resolve(__dirname, "..", pkg.targetPath)
- if (fs.existsSync(targetPath)) {
- fs.rmSync(targetPath, { recursive: true, force: true })
- console.log(`Unlinked ${pkg.name}`)
- }
-}
-
-function startWatch(pkg) {
- console.log(`Watching ${pkg.name}...`)
- const [cmd, ...args] = pkg.watchCommand.split(" ")
- return spawn(cmd, args, {
- cwd: path.resolve(__dirname, "..", pkg.sourcePath),
- stdio: "inherit",
- shell: true,
- })
-}
diff --git a/scripts/link-packages.ts b/scripts/link-packages.ts
new file mode 100644
index 0000000000..4d7e4a7c4c
--- /dev/null
+++ b/scripts/link-packages.ts
@@ -0,0 +1,340 @@
+import { spawn, execSync, type ChildProcess } from "child_process"
+import * as path from "path"
+import * as fs from "fs"
+import { fileURLToPath } from "url"
+import { glob } from "glob"
+
+// @ts-expect-error - TS1470: We only run this script with tsx so it will never
+// compile to CJS and it's safe to ignore this tsc error.
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = path.dirname(__filename)
+
+interface PackageConfig {
+ readonly name: string
+ readonly sourcePath: string
+ readonly targetPaths: readonly string[]
+ readonly replacePath?: string
+ readonly npmPath: string
+ readonly watchCommand?: string
+ readonly watchOutput?: {
+ readonly start: string[]
+ readonly stop: string[]
+ }
+}
+
+interface Config {
+ readonly packages: readonly PackageConfig[]
+}
+
+interface WatcherResult {
+ child: ChildProcess
+}
+
+interface NpmPackage {
+ name?: string
+ version?: string
+ type: "module"
+ dependencies: Record
+ main: string
+ module: string
+ types: string
+ exports: {
+ ".": {
+ types: string
+ import: string
+ require: {
+ types: string
+ default: string
+ }
+ }
+ }
+ files: string[]
+}
+
+const config: Config = {
+ packages: [
+ {
+ name: "@roo-code/cloud",
+ sourcePath: "../Roo-Code-Cloud/packages/sdk",
+ targetPaths: ["src/node_modules/@roo-code/cloud"] as const,
+ replacePath: "node_modules/.pnpm/@roo-code+cloud*",
+ npmPath: "npm",
+ watchCommand: "pnpm build:development:watch",
+ watchOutput: {
+ start: ["CLI Building", "CLI Change detected"],
+ stop: ["DTS ⚡️ Build success"],
+ },
+ },
+ ],
+} as const
+
+const args = process.argv.slice(2)
+const packageName = args.find((arg) => !arg.startsWith("--"))
+const watchMode = !args.includes("--no-watch")
+const unlink = args.includes("--unlink")
+
+const packages: readonly PackageConfig[] = packageName
+ ? config.packages.filter((p) => p.name === packageName)
+ : config.packages
+
+if (!packages.length) {
+ console.error(`Package '${packageName}' not found`)
+ process.exit(1)
+}
+
+function pathExists(filePath: string): boolean {
+ try {
+ fs.accessSync(filePath)
+ return true
+ } catch {
+ return false
+ }
+}
+
+function copyRecursiveSync(src: string, dest: string): void {
+ const exists = pathExists(src)
+
+ if (!exists) {
+ return
+ }
+
+ const stats = fs.statSync(src)
+ const isDirectory = stats.isDirectory()
+
+ if (isDirectory) {
+ if (!pathExists(dest)) {
+ fs.mkdirSync(dest, { recursive: true })
+ }
+
+ const children = fs.readdirSync(src)
+
+ children.forEach((childItemName) => {
+ copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName))
+ })
+ } else {
+ fs.copyFileSync(src, dest)
+ }
+}
+
+function generateNpmPackageJson(sourcePath: string, npmPath: string): string {
+ const npmDir = path.join(sourcePath, npmPath)
+ const npmPackagePath = path.join(npmDir, "package.json")
+ const npmMetadataPath = path.join(npmDir, "package.metadata.json")
+ const monorepoPackagePath = path.join(sourcePath, "package.json")
+
+ if (pathExists(npmPackagePath)) {
+ return npmPackagePath
+ }
+
+ if (!pathExists(npmMetadataPath)) {
+ throw new Error(`No package.metadata.json found in ${npmDir}`)
+ }
+
+ const monorepoPackageContent = fs.readFileSync(monorepoPackagePath, "utf8")
+
+ const monorepoPackage = JSON.parse(monorepoPackageContent) as {
+ dependencies?: Record
+ }
+
+ const npmMetadataContent = fs.readFileSync(npmMetadataPath, "utf8")
+ const npmMetadata = JSON.parse(npmMetadataContent) as Partial
+
+ const npmPackage: NpmPackage = {
+ ...npmMetadata,
+ type: "module",
+ dependencies: monorepoPackage.dependencies || {},
+ main: "./dist/index.cjs",
+ module: "./dist/index.js",
+ types: "./dist/index.d.ts",
+ exports: {
+ ".": {
+ types: "./dist/index.d.ts",
+ import: "./dist/index.js",
+ require: {
+ types: "./dist/index.d.cts",
+ default: "./dist/index.cjs",
+ },
+ },
+ },
+ files: ["dist"],
+ }
+
+ fs.writeFileSync(npmPackagePath, JSON.stringify(npmPackage, null, 2) + "\n")
+
+ return npmPackagePath
+}
+
+function linkPackage(pkg: PackageConfig): void {
+ const sourcePath = path.resolve(__dirname, "..", pkg.sourcePath)
+
+ if (!pathExists(sourcePath)) {
+ console.error(`❌ Source not found: ${sourcePath}`)
+ process.exit(1)
+ }
+
+ generateNpmPackageJson(sourcePath, pkg.npmPath)
+
+ for (const currentTargetPath of pkg.targetPaths) {
+ const targetPath = path.resolve(__dirname, "..", currentTargetPath)
+
+ if (pathExists(targetPath)) {
+ fs.rmSync(targetPath, { recursive: true, force: true })
+ }
+
+ const parentDir = path.dirname(targetPath)
+ fs.mkdirSync(parentDir, { recursive: true })
+
+ const linkSource = pkg.npmPath ? path.join(sourcePath, pkg.npmPath) : sourcePath
+ copyRecursiveSync(linkSource, targetPath)
+ }
+}
+
+function unlinkPackage(pkg: PackageConfig): void {
+ for (const currentTargetPath of pkg.targetPaths) {
+ const targetPath = path.resolve(__dirname, "..", currentTargetPath)
+
+ if (pathExists(targetPath)) {
+ fs.rmSync(targetPath, { recursive: true, force: true })
+ console.log(`🗑️ Removed ${pkg.name} from ${currentTargetPath}`)
+ }
+ }
+}
+
+function startWatch(pkg: PackageConfig): WatcherResult {
+ if (!pkg.watchCommand) {
+ throw new Error(`Package ${pkg.name} has no watch command configured`)
+ }
+
+ const commandParts = pkg.watchCommand.split(" ")
+ const [cmd, ...args] = commandParts
+
+ if (!cmd) {
+ throw new Error(`Invalid watch command for ${pkg.name}`)
+ }
+
+ console.log(`Watching for changes to ${pkg.sourcePath} with ${cmd} ${args.join(" ")}`)
+
+ const child = spawn(cmd, args, {
+ cwd: path.resolve(__dirname, "..", pkg.sourcePath),
+ stdio: "pipe",
+ shell: true,
+ })
+
+ let debounceTimer: NodeJS.Timeout | null = null
+
+ const DEBOUNCE_DELAY = 500
+
+ if (child.stdout) {
+ child.stdout.on("data", (data: Buffer) => {
+ const output = data.toString()
+
+ const isStarting = pkg.watchOutput?.start.some((start) => output.includes(start))
+
+ const isDone = pkg.watchOutput?.stop.some((stop) => output.includes(stop))
+
+ if (isStarting) {
+ console.log(`🔨 Building ${pkg.name}...`)
+
+ if (debounceTimer) {
+ clearTimeout(debounceTimer)
+ debounceTimer = null
+ }
+ }
+
+ if (isDone) {
+ console.log(`✅ Built ${pkg.name}`)
+
+ if (debounceTimer) {
+ clearTimeout(debounceTimer)
+ }
+
+ debounceTimer = setTimeout(() => {
+ linkPackage(pkg)
+
+ console.log(`📋 Copied ${pkg.name} to ${pkg.targetPaths.length} paths\n`)
+
+ debounceTimer = null
+ }, DEBOUNCE_DELAY)
+ }
+ })
+ }
+
+ if (child.stderr) {
+ child.stderr.on("data", (data: Buffer) => {
+ console.log(`❌ "${data.toString()}"`)
+ })
+ }
+
+ return { child }
+}
+
+function main(): void {
+ if (unlink) {
+ packages.forEach(unlinkPackage)
+
+ console.log("\n📦 Restoring npm packages...")
+
+ try {
+ execSync("pnpm install", { cwd: __dirname, stdio: "ignore" })
+ console.log("✅ npm packages restored")
+ } catch (error) {
+ console.error(`❌ Failed to restore packages: ${error instanceof Error ? error.message : String(error)}`)
+
+ console.log(" Run 'pnpm install' manually if needed")
+ }
+ } else {
+ packages.forEach((pkg) => {
+ linkPackage(pkg)
+
+ if (pkg.replacePath) {
+ const replacePattern = path.resolve(__dirname, "..", pkg.replacePath)
+
+ try {
+ const matchedPaths = glob.sync(replacePattern)
+
+ if (matchedPaths.length > 0) {
+ matchedPaths.forEach((matchedPath: string) => {
+ if (pathExists(matchedPath)) {
+ fs.rmSync(matchedPath, { recursive: true, force: true })
+ console.log(`🗑️ Removed ${pkg.name} from ${matchedPath}`)
+ }
+ })
+ } else {
+ if (pathExists(replacePattern)) {
+ fs.rmSync(replacePattern, { recursive: true, force: true })
+ console.log(`🗑️ Removed ${pkg.name} from ${replacePattern}`)
+ }
+ }
+ } catch (error) {
+ console.error(
+ `❌ Error processing replace path: ${error instanceof Error ? error.message : String(error)}`,
+ )
+ }
+ }
+ })
+
+ if (watchMode) {
+ const packagesWithWatch = packages.filter(
+ (pkg): pkg is PackageConfig & { watchCommand: string } => pkg.watchCommand !== undefined,
+ )
+
+ const watchers = packagesWithWatch.map(startWatch)
+
+ if (watchers.length > 0) {
+ process.on("SIGINT", () => {
+ console.log("\n👋 Stopping watchers...")
+
+ watchers.forEach((w) => {
+ if (w.child) {
+ w.child.kill()
+ }
+ })
+
+ process.exit(0)
+ })
+ }
+ }
+ }
+}
+
+main()
diff --git a/src/api/providers/__tests__/bedrock.spec.ts b/src/api/providers/__tests__/bedrock.spec.ts
index ad0ae2bdb5..8df495ca9f 100644
--- a/src/api/providers/__tests__/bedrock.spec.ts
+++ b/src/api/providers/__tests__/bedrock.spec.ts
@@ -25,6 +25,7 @@ vi.mock("@aws-sdk/client-bedrock-runtime", () => {
import { AwsBedrockHandler } from "../bedrock"
import { ConverseStreamCommand, BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime"
+import { BEDROCK_CLAUDE_SONNET_4_MODEL_ID } from "@roo-code/types"
import type { Anthropic } from "@anthropic-ai/sdk"
@@ -564,4 +565,188 @@ describe("AwsBedrockHandler", () => {
expect(typeof model.info.supportsPromptCache).toBe("boolean")
})
})
+
+ describe("1M context beta feature", () => {
+ it("should enable 1M context window when awsBedrock1MContext is true for Claude Sonnet 4", () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsBedrock1MContext: true,
+ })
+
+ const model = handler.getModel()
+
+ // Should have 1M context window when enabled
+ expect(model.info.contextWindow).toBe(1_000_000)
+ })
+
+ it("should use default context window when awsBedrock1MContext is false for Claude Sonnet 4", () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsBedrock1MContext: false,
+ })
+
+ const model = handler.getModel()
+
+ // Should use default context window (200k)
+ expect(model.info.contextWindow).toBe(200_000)
+ })
+
+ it("should not affect context window for non-Claude Sonnet 4 models", () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsBedrock1MContext: true,
+ })
+
+ const model = handler.getModel()
+
+ // Should use default context window for non-Sonnet 4 models
+ expect(model.info.contextWindow).toBe(200_000)
+ })
+
+ it("should include anthropic_beta parameter when 1M context is enabled", async () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsBedrock1MContext: true,
+ })
+
+ const messages: Anthropic.Messages.MessageParam[] = [
+ {
+ role: "user",
+ content: "Test message",
+ },
+ ]
+
+ const generator = handler.createMessage("", messages)
+ await generator.next() // Start the generator
+
+ // Verify the command was created with the right payload
+ expect(mockConverseStreamCommand).toHaveBeenCalled()
+ const commandArg = mockConverseStreamCommand.mock.calls[0][0] as any
+
+ // Should include anthropic_beta in additionalModelRequestFields
+ expect(commandArg.additionalModelRequestFields).toBeDefined()
+ expect(commandArg.additionalModelRequestFields.anthropic_beta).toEqual(["context-1m-2025-08-07"])
+ // Should not include anthropic_version since thinking is not enabled
+ expect(commandArg.additionalModelRequestFields.anthropic_version).toBeUndefined()
+ })
+
+ it("should not include anthropic_beta parameter when 1M context is disabled", async () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsBedrock1MContext: false,
+ })
+
+ const messages: Anthropic.Messages.MessageParam[] = [
+ {
+ role: "user",
+ content: "Test message",
+ },
+ ]
+
+ const generator = handler.createMessage("", messages)
+ await generator.next() // Start the generator
+
+ // Verify the command was created with the right payload
+ expect(mockConverseStreamCommand).toHaveBeenCalled()
+ const commandArg = mockConverseStreamCommand.mock.calls[0][0] as any
+
+ // Should not include anthropic_beta in additionalModelRequestFields
+ expect(commandArg.additionalModelRequestFields).toBeUndefined()
+ })
+
+ it("should not include anthropic_beta parameter for non-Claude Sonnet 4 models", async () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsBedrock1MContext: true,
+ })
+
+ const messages: Anthropic.Messages.MessageParam[] = [
+ {
+ role: "user",
+ content: "Test message",
+ },
+ ]
+
+ const generator = handler.createMessage("", messages)
+ await generator.next() // Start the generator
+
+ // Verify the command was created with the right payload
+ expect(mockConverseStreamCommand).toHaveBeenCalled()
+ const commandArg = mockConverseStreamCommand.mock.calls[0][0] as any
+
+ // Should not include anthropic_beta for non-Sonnet 4 models
+ expect(commandArg.additionalModelRequestFields).toBeUndefined()
+ })
+
+ it("should enable 1M context window with cross-region inference for Claude Sonnet 4", () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsUseCrossRegionInference: true,
+ awsBedrock1MContext: true,
+ })
+
+ const model = handler.getModel()
+
+ // Should have 1M context window even with cross-region prefix
+ expect(model.info.contextWindow).toBe(1_000_000)
+ // Model ID should have cross-region prefix
+ expect(model.id).toBe(`us.${BEDROCK_CLAUDE_SONNET_4_MODEL_ID}`)
+ })
+
+ it("should include anthropic_beta parameter with cross-region inference for Claude Sonnet 4", async () => {
+ const handler = new AwsBedrockHandler({
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsAccessKey: "test",
+ awsSecretKey: "test",
+ awsRegion: "us-east-1",
+ awsUseCrossRegionInference: true,
+ awsBedrock1MContext: true,
+ })
+
+ const messages: Anthropic.Messages.MessageParam[] = [
+ {
+ role: "user",
+ content: "Test message",
+ },
+ ]
+
+ const generator = handler.createMessage("", messages)
+ await generator.next() // Start the generator
+
+ // Verify the command was created with the right payload
+ expect(mockConverseStreamCommand).toHaveBeenCalled()
+ const commandArg = mockConverseStreamCommand.mock.calls[
+ mockConverseStreamCommand.mock.calls.length - 1
+ ][0] as any
+
+ // Should include anthropic_beta in additionalModelRequestFields
+ expect(commandArg.additionalModelRequestFields).toBeDefined()
+ expect(commandArg.additionalModelRequestFields.anthropic_beta).toEqual(["context-1m-2025-08-07"])
+ // Should not include anthropic_version since thinking is not enabled
+ expect(commandArg.additionalModelRequestFields.anthropic_version).toBeUndefined()
+ // Model ID should have cross-region prefix
+ expect(commandArg.modelId).toBe(`us.${BEDROCK_CLAUDE_SONNET_4_MODEL_ID}`)
+ })
+ })
})
diff --git a/src/api/providers/__tests__/openai-native.spec.ts b/src/api/providers/__tests__/openai-native.spec.ts
index 1d76d387a9..0acdb6202e 100644
--- a/src/api/providers/__tests__/openai-native.spec.ts
+++ b/src/api/providers/__tests__/openai-native.spec.ts
@@ -258,6 +258,68 @@ describe("OpenAiNativeHandler", () => {
})
})
+ it("should not include verbosity parameter for models that don't support it", async () => {
+ // Test with gpt-4.1 which does NOT support verbosity
+ handler = new OpenAiNativeHandler({
+ ...mockOptions,
+ apiModelId: "gpt-4.1",
+ verbosity: "high", // Set verbosity but it should be ignored
+ })
+
+ const stream = handler.createMessage(systemPrompt, messages)
+ const chunks: any[] = []
+ for await (const chunk of stream) {
+ chunks.push(chunk)
+ }
+
+ // Verify that verbosity is NOT included in the request
+ const callArgs = mockCreate.mock.calls[0][0]
+ expect(callArgs).not.toHaveProperty("verbosity")
+ expect(callArgs.model).toBe("gpt-4.1")
+ expect(callArgs.temperature).toBe(0)
+ expect(callArgs.stream).toBe(true)
+ })
+
+ it("should not include verbosity for gpt-4o models", async () => {
+ // Test with gpt-4o which does NOT support verbosity
+ handler = new OpenAiNativeHandler({
+ ...mockOptions,
+ apiModelId: "gpt-4o",
+ verbosity: "medium", // Set verbosity but it should be ignored
+ })
+
+ const stream = handler.createMessage(systemPrompt, messages)
+ const chunks: any[] = []
+ for await (const chunk of stream) {
+ chunks.push(chunk)
+ }
+
+ // Verify that verbosity is NOT included in the request
+ const callArgs = mockCreate.mock.calls[0][0]
+ expect(callArgs).not.toHaveProperty("verbosity")
+ expect(callArgs.model).toBe("gpt-4o")
+ })
+
+ it("should not include verbosity for gpt-4.1-mini models", async () => {
+ // Test with gpt-4.1-mini which does NOT support verbosity
+ handler = new OpenAiNativeHandler({
+ ...mockOptions,
+ apiModelId: "gpt-4.1-mini",
+ verbosity: "low", // Set verbosity but it should be ignored
+ })
+
+ const stream = handler.createMessage(systemPrompt, messages)
+ const chunks: any[] = []
+ for await (const chunk of stream) {
+ chunks.push(chunk)
+ }
+
+ // Verify that verbosity is NOT included in the request
+ const callArgs = mockCreate.mock.calls[0][0]
+ expect(callArgs).not.toHaveProperty("verbosity")
+ expect(callArgs.model).toBe("gpt-4.1-mini")
+ })
+
it("should handle empty delta content", async () => {
const mockStream = [
{ choices: [{ delta: {} }], usage: null },
diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts
index f456586762..cb48492b60 100644
--- a/src/api/providers/anthropic.ts
+++ b/src/api/providers/anthropic.ts
@@ -45,6 +45,11 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
const cacheControl: CacheControlEphemeral = { type: "ephemeral" }
let { id: modelId, betas = [], maxTokens, temperature, reasoning: thinking } = this.getModel()
+ // Add 1M context beta flag if enabled for Claude Sonnet 4
+ if (modelId === "claude-sonnet-4-20250514" && this.options.anthropicBeta1MContext) {
+ betas.push("context-1m-2025-08-07")
+ }
+
switch (modelId) {
case "claude-sonnet-4-20250514":
case "claude-opus-4-1-20250805":
@@ -236,7 +241,23 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
getModel() {
const modelId = this.options.apiModelId
let id = modelId && modelId in anthropicModels ? (modelId as AnthropicModelId) : anthropicDefaultModelId
- const info: ModelInfo = anthropicModels[id]
+ let info: ModelInfo = anthropicModels[id]
+
+ // If 1M context beta is enabled for Claude Sonnet 4, update the model info
+ if (id === "claude-sonnet-4-20250514" && this.options.anthropicBeta1MContext) {
+ // Use the tier pricing for 1M context
+ const tier = info.tiers?.[0]
+ if (tier) {
+ info = {
+ ...info,
+ contextWindow: tier.contextWindow,
+ inputPrice: tier.inputPrice,
+ outputPrice: tier.outputPrice,
+ cacheWritesPrice: tier.cacheWritesPrice,
+ cacheReadsPrice: tier.cacheReadsPrice,
+ }
+ }
+ }
const params = getModelParams({
format: "anthropic",
diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts
index 706b801d0c..c6a0b35df4 100644
--- a/src/api/providers/bedrock.ts
+++ b/src/api/providers/bedrock.ts
@@ -21,6 +21,7 @@ import {
BEDROCK_MAX_TOKENS,
BEDROCK_DEFAULT_CONTEXT,
AWS_INFERENCE_PROFILE_MAPPING,
+ BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
} from "@roo-code/types"
import { ApiStream } from "../transform/stream"
@@ -46,12 +47,14 @@ interface BedrockInferenceConfig {
topP?: number
}
-// Define interface for Bedrock thinking configuration
-interface BedrockThinkingConfig {
- thinking: {
+// Define interface for Bedrock additional model request fields
+// This includes thinking configuration, 1M context beta, and other model-specific parameters
+interface BedrockAdditionalModelFields {
+ thinking?: {
type: "enabled"
budget_tokens: number
}
+ anthropic_beta?: string[]
[key: string]: any // Add index signature to be compatible with DocumentType
}
@@ -62,7 +65,7 @@ interface BedrockPayload {
system?: SystemContentBlock[]
inferenceConfig: BedrockInferenceConfig
anthropic_version?: string
- additionalModelRequestFields?: BedrockThinkingConfig
+ additionalModelRequestFields?: BedrockAdditionalModelFields
}
// Define specific types for content block events to avoid 'as any' usage
@@ -339,7 +342,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
conversationId,
)
- let additionalModelRequestFields: BedrockThinkingConfig | undefined
+ let additionalModelRequestFields: BedrockAdditionalModelFields | undefined
let thinkingEnabled = false
// Determine if thinking should be enabled
@@ -375,13 +378,26 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
inferenceConfig.topP = 0.1
}
+ // Check if 1M context is enabled for Claude Sonnet 4
+ // Use parseBaseModelId to handle cross-region inference prefixes
+ const baseModelId = this.parseBaseModelId(modelConfig.id)
+ const is1MContextEnabled = baseModelId === BEDROCK_CLAUDE_SONNET_4_MODEL_ID && this.options.awsBedrock1MContext
+
+ // Add anthropic_beta for 1M context to additionalModelRequestFields
+ if (is1MContextEnabled) {
+ if (!additionalModelRequestFields) {
+ additionalModelRequestFields = {} as BedrockAdditionalModelFields
+ }
+ additionalModelRequestFields.anthropic_beta = ["context-1m-2025-08-07"]
+ }
+
const payload: BedrockPayload = {
modelId: modelConfig.id,
messages: formatted.messages,
system: formatted.system,
inferenceConfig,
...(additionalModelRequestFields && { additionalModelRequestFields }),
- // Add anthropic_version when using thinking features
+ // Add anthropic_version at top level when using thinking features
...(thinkingEnabled && { anthropic_version: "bedrock-2023-05-31" }),
}
@@ -960,6 +976,17 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
}
}
+ // Check if 1M context is enabled for Claude Sonnet 4
+ // Use parseBaseModelId to handle cross-region inference prefixes
+ const baseModelId = this.parseBaseModelId(modelConfig.id)
+ if (baseModelId === BEDROCK_CLAUDE_SONNET_4_MODEL_ID && this.options.awsBedrock1MContext) {
+ // Update context window to 1M tokens when 1M context beta is enabled
+ modelConfig.info = {
+ ...modelConfig.info,
+ contextWindow: 1_000_000,
+ }
+ }
+
// Get model params including reasoning configuration
const params = getModelParams({
format: "anthropic",
diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts
index 053af7f5e5..2ba8566963 100644
--- a/src/api/providers/openai-native.ts
+++ b/src/api/providers/openai-native.ts
@@ -194,8 +194,8 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
...(reasoning && reasoning),
}
- // Add verbosity if supported
- if (verbosity) {
+ // Add verbosity only if the model supports it
+ if (verbosity && model.info.supportsVerbosity) {
params.verbosity = verbosity
}
diff --git a/src/core/checkpoints/index.ts b/src/core/checkpoints/index.ts
index 05549be0f9..83aefe56b5 100644
--- a/src/core/checkpoints/index.ts
+++ b/src/core/checkpoints/index.ts
@@ -42,7 +42,7 @@ export async function getCheckpointService(
console.log("[Task#getCheckpointService] initializing checkpoints service")
try {
- const workspaceDir = getWorkspacePath()
+ const workspaceDir = cline.cwd || getWorkspacePath()
if (!workspaceDir) {
log("[Task#getCheckpointService] workspace folder not found, disabling checkpoints")
diff --git a/src/core/prompts/sections/__tests__/custom-instructions.spec.ts b/src/core/prompts/sections/__tests__/custom-instructions.spec.ts
index d015748315..be9c25bcaa 100644
--- a/src/core/prompts/sections/__tests__/custom-instructions.spec.ts
+++ b/src/core/prompts/sections/__tests__/custom-instructions.spec.ts
@@ -775,6 +775,86 @@ describe("addCustomInstructions", () => {
expect(readFileMock).toHaveBeenCalledWith(expect.stringContaining("AGENTS.md"), "utf-8")
})
+ it("should load AGENT.md (singular) when AGENTS.md is not found", async () => {
+ // Simulate no .roo/rules-test-mode directory
+ statMock.mockRejectedValueOnce({ code: "ENOENT" })
+
+ // Mock lstat to indicate AGENTS.md doesn't exist but AGENT.md does
+ lstatMock.mockImplementation((filePath: PathLike) => {
+ const pathStr = filePath.toString()
+ if (pathStr.endsWith("AGENTS.md")) {
+ return Promise.reject({ code: "ENOENT" })
+ }
+ if (pathStr.endsWith("AGENT.md")) {
+ return Promise.resolve({
+ isSymbolicLink: vi.fn().mockReturnValue(false),
+ })
+ }
+ return Promise.reject({ code: "ENOENT" })
+ })
+
+ readFileMock.mockImplementation((filePath: PathLike) => {
+ const pathStr = filePath.toString()
+ if (pathStr.endsWith("AGENT.md")) {
+ return Promise.resolve("Agent rules from AGENT.md file (singular)")
+ }
+ return Promise.reject({ code: "ENOENT" })
+ })
+
+ const result = await addCustomInstructions(
+ "mode instructions",
+ "global instructions",
+ "/fake/path",
+ "test-mode",
+ { settings: { maxConcurrentFileReads: 5, todoListEnabled: true, useAgentRules: true } },
+ )
+
+ expect(result).toContain("# Agent Rules Standard (AGENT.md):")
+ expect(result).toContain("Agent rules from AGENT.md file (singular)")
+ expect(readFileMock).toHaveBeenCalledWith(expect.stringContaining("AGENT.md"), "utf-8")
+ })
+
+ it("should prefer AGENTS.md over AGENT.md when both exist", async () => {
+ // Simulate no .roo/rules-test-mode directory
+ statMock.mockRejectedValueOnce({ code: "ENOENT" })
+
+ // Mock lstat to indicate both files exist
+ lstatMock.mockImplementation((filePath: PathLike) => {
+ const pathStr = filePath.toString()
+ if (pathStr.endsWith("AGENTS.md") || pathStr.endsWith("AGENT.md")) {
+ return Promise.resolve({
+ isSymbolicLink: vi.fn().mockReturnValue(false),
+ })
+ }
+ return Promise.reject({ code: "ENOENT" })
+ })
+
+ readFileMock.mockImplementation((filePath: PathLike) => {
+ const pathStr = filePath.toString()
+ if (pathStr.endsWith("AGENTS.md")) {
+ return Promise.resolve("Agent rules from AGENTS.md file (plural)")
+ }
+ if (pathStr.endsWith("AGENT.md")) {
+ return Promise.resolve("Agent rules from AGENT.md file (singular)")
+ }
+ return Promise.reject({ code: "ENOENT" })
+ })
+
+ const result = await addCustomInstructions(
+ "mode instructions",
+ "global instructions",
+ "/fake/path",
+ "test-mode",
+ { settings: { maxConcurrentFileReads: 5, todoListEnabled: true, useAgentRules: true } },
+ )
+
+ // Should contain AGENTS.md content (preferred) and not AGENT.md
+ expect(result).toContain("# Agent Rules Standard (AGENTS.md):")
+ expect(result).toContain("Agent rules from AGENTS.md file (plural)")
+ expect(result).not.toContain("Agent rules from AGENT.md file (singular)")
+ expect(readFileMock).toHaveBeenCalledWith(expect.stringContaining("AGENTS.md"), "utf-8")
+ })
+
it("should return empty string when no instructions provided", async () => {
// Simulate no .roo/rules directory
statMock.mockRejectedValueOnce({ code: "ENOENT" })
diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts
index 22fb6122ec..2d70e45419 100644
--- a/src/core/prompts/sections/custom-instructions.ts
+++ b/src/core/prompts/sections/custom-instructions.ts
@@ -217,40 +217,46 @@ export async function loadRuleFiles(cwd: string): Promise {
}
/**
- * Load AGENTS.md file from the project root if it exists
+ * Load AGENTS.md or AGENT.md file from the project root if it exists
+ * Checks for both AGENTS.md (standard) and AGENT.md (alternative) for compatibility
*/
async function loadAgentRulesFile(cwd: string): Promise {
- try {
- const agentsPath = path.join(cwd, "AGENTS.md")
- let resolvedPath = agentsPath
+ // Try both filenames - AGENTS.md (standard) first, then AGENT.md (alternative)
+ const filenames = ["AGENTS.md", "AGENT.md"]
- // Check if AGENTS.md exists and handle symlinks
+ for (const filename of filenames) {
try {
- const stats = await fs.lstat(agentsPath)
- if (stats.isSymbolicLink()) {
- // Create a temporary fileInfo array to use with resolveSymLink
- const fileInfo: Array<{ originalPath: string; resolvedPath: string }> = []
+ const agentPath = path.join(cwd, filename)
+ let resolvedPath = agentPath
- // Use the existing resolveSymLink function to handle symlink resolution
- await resolveSymLink(agentsPath, fileInfo, 0)
+ // Check if file exists and handle symlinks
+ try {
+ const stats = await fs.lstat(agentPath)
+ if (stats.isSymbolicLink()) {
+ // Create a temporary fileInfo array to use with resolveSymLink
+ const fileInfo: Array<{ originalPath: string; resolvedPath: string }> = []
- // Extract the resolved path from fileInfo
- if (fileInfo.length > 0) {
- resolvedPath = fileInfo[0].resolvedPath
+ // Use the existing resolveSymLink function to handle symlink resolution
+ await resolveSymLink(agentPath, fileInfo, 0)
+
+ // Extract the resolved path from fileInfo
+ if (fileInfo.length > 0) {
+ resolvedPath = fileInfo[0].resolvedPath
+ }
}
+ } catch (err) {
+ // If lstat fails (file doesn't exist), try next filename
+ continue
+ }
+
+ // Read the content from the resolved path
+ const content = await safeReadFile(resolvedPath)
+ if (content) {
+ return `# Agent Rules Standard (${filename}):\n${content}`
}
} catch (err) {
- // If lstat fails (file doesn't exist), return empty
- return ""
+ // Silently ignore errors - agent rules files are optional
}
-
- // Read the content from the resolved path
- const content = await safeReadFile(resolvedPath)
- if (content) {
- return `# Agent Rules Standard (AGENTS.md):\n${content}`
- }
- } catch (err) {
- // Silently ignore errors - AGENTS.md is optional
}
return ""
}
diff --git a/src/core/protect/RooProtectedController.ts b/src/core/protect/RooProtectedController.ts
index e6d57b22b5..f4d80c4d64 100644
--- a/src/core/protect/RooProtectedController.ts
+++ b/src/core/protect/RooProtectedController.ts
@@ -21,6 +21,7 @@ export class RooProtectedController {
".vscode/**",
".rooprotected", // For future use
"AGENTS.md",
+ "AGENT.md", // Alternative singular form for compatibility
]
constructor(cwd: string) {
diff --git a/src/core/protect/__tests__/RooProtectedController.spec.ts b/src/core/protect/__tests__/RooProtectedController.spec.ts
index 0ee6135e81..f19cf17548 100644
--- a/src/core/protect/__tests__/RooProtectedController.spec.ts
+++ b/src/core/protect/__tests__/RooProtectedController.spec.ts
@@ -48,6 +48,10 @@ describe("RooProtectedController", () => {
expect(controller.isWriteProtected("AGENTS.md")).toBe(true)
})
+ it("should protect AGENT.md file", () => {
+ expect(controller.isWriteProtected("AGENT.md")).toBe(true)
+ })
+
it("should not protect other files starting with .roo", () => {
expect(controller.isWriteProtected(".roosettings")).toBe(false)
expect(controller.isWriteProtected(".rooconfig")).toBe(false)
@@ -147,6 +151,7 @@ describe("RooProtectedController", () => {
".vscode/**",
".rooprotected",
"AGENTS.md",
+ "AGENT.md",
])
})
})
diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts
index 6dfb242109..67be67075c 100644
--- a/src/core/task/Task.ts
+++ b/src/core/task/Task.ts
@@ -11,6 +11,7 @@ import { serializeError } from "serialize-error"
import {
type TaskLike,
+ type TaskMetadata,
type TaskEvents,
type ProviderSettings,
type TokenUsage,
@@ -29,11 +30,10 @@ import {
getApiProtocol,
getModelId,
DEFAULT_CONSECUTIVE_MISTAKE_LIMIT,
- DEFAULT_USAGE_COLLECTION_TIMEOUT_MS,
isBlockingAsk,
} from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
-import { CloudService, UnifiedBridgeService } from "@roo-code/cloud"
+import { CloudService, ExtensionBridgeService } from "@roo-code/cloud"
// api
import { ApiHandler, ApiHandlerCreateMessageMetadata, buildApiHandler } from "../../api"
@@ -102,6 +102,7 @@ import { restoreTodoListForTask } from "../tools/updateTodoListTool"
import { AutoApprovalHandler } from "./AutoApprovalHandler"
const MAX_EXPONENTIAL_BACKOFF_SECONDS = 600 // 10 minutes
+const DEFAULT_USAGE_COLLECTION_TIMEOUT_MS = 5000 // 5 seconds
export type TaskOptions = {
provider: ClineProvider
@@ -123,9 +124,11 @@ export type TaskOptions = {
}
export class Task extends EventEmitter implements TaskLike {
- todoList?: TodoItem[]
readonly taskId: string
readonly instanceId: string
+ readonly metadata: TaskMetadata
+
+ todoList?: TodoItem[]
readonly rootTask: Task | undefined = undefined
readonly parentTask: Task | undefined = undefined
@@ -241,7 +244,7 @@ export class Task extends EventEmitter implements TaskLike {
// Task Bridge
enableTaskBridge: boolean
- bridgeService: UnifiedBridgeService | null = null
+ bridgeService: ExtensionBridgeService | null = null
// Streaming
isWaitingForFirstChunk = false
@@ -285,6 +288,18 @@ export class Task extends EventEmitter implements TaskLike {
}
this.taskId = historyItem ? historyItem.id : crypto.randomUUID()
+
+ this.metadata = {
+ taskId: this.taskId,
+ task: historyItem ? historyItem.task : task,
+ images: historyItem ? [] : images,
+ }
+
+ // Normal use-case is usually retry similar history task with new workspace.
+ this.workspacePath = parentTask
+ ? parentTask.workspacePath
+ : getWorkspacePath(path.join(os.homedir(), "Desktop"))
+
this.instanceId = crypto.randomUUID().slice(0, 8)
this.taskNumber = -1
@@ -987,7 +1002,7 @@ export class Task extends EventEmitter implements TaskLike {
private async startTask(task?: string, images?: string[]): Promise {
if (this.enableTaskBridge) {
try {
- this.bridgeService = this.bridgeService || UnifiedBridgeService.getInstance()
+ this.bridgeService = this.bridgeService || ExtensionBridgeService.getInstance()
if (this.bridgeService) {
await this.bridgeService.subscribeToTask(this)
@@ -1052,7 +1067,7 @@ export class Task extends EventEmitter implements TaskLike {
private async resumeTaskFromHistory() {
if (this.enableTaskBridge) {
try {
- this.bridgeService = this.bridgeService || UnifiedBridgeService.getInstance()
+ this.bridgeService = this.bridgeService || ExtensionBridgeService.getInstance()
if (this.bridgeService) {
await this.bridgeService.subscribeToTask(this)
@@ -1303,6 +1318,13 @@ export class Task extends EventEmitter implements TaskLike {
public dispose(): void {
console.log(`[Task] disposing task ${this.taskId}.${this.instanceId}`)
+ // Remove all event listeners to prevent memory leaks
+ try {
+ this.removeAllListeners()
+ } catch (error) {
+ console.error("Error removing event listeners:", error)
+ }
+
// Stop waiting for child task completion.
if (this.pauseInterval) {
clearInterval(this.pauseInterval)
@@ -1446,605 +1468,639 @@ export class Task extends EventEmitter implements TaskLike {
userContent: Anthropic.Messages.ContentBlockParam[],
includeFileDetails: boolean = false,
): Promise {
- if (this.abort) {
- throw new Error(`[RooCode#recursivelyMakeRooRequests] task ${this.taskId}.${this.instanceId} aborted`)
+ interface StackItem {
+ userContent: Anthropic.Messages.ContentBlockParam[]
+ includeFileDetails: boolean
}
- if (this.consecutiveMistakeLimit > 0 && this.consecutiveMistakeCount >= this.consecutiveMistakeLimit) {
- const { response, text, images } = await this.ask(
- "mistake_limit_reached",
- t("common:errors.mistake_limit_guidance"),
- )
+ const stack: StackItem[] = [{ userContent, includeFileDetails }]
- if (response === "messageResponse") {
- userContent.push(
- ...[
- { type: "text" as const, text: formatResponse.tooManyMistakes(text) },
- ...formatResponse.imageBlocks(images),
- ],
- )
+ while (stack.length > 0) {
+ const currentItem = stack.pop()!
+ const currentUserContent = currentItem.userContent
+ const currentIncludeFileDetails = currentItem.includeFileDetails
- await this.say("user_feedback", text, images)
-
- // Track consecutive mistake errors in telemetry.
- TelemetryService.instance.captureConsecutiveMistakeError(this.taskId)
- }
-
- this.consecutiveMistakeCount = 0
- }
-
- // In this Cline request loop, we need to check if this task instance
- // has been asked to wait for a subtask to finish before continuing.
- const provider = this.providerRef.deref()
-
- if (this.isPaused && provider) {
- provider.log(`[subtasks] paused ${this.taskId}.${this.instanceId}`)
- await this.waitForResume()
- provider.log(`[subtasks] resumed ${this.taskId}.${this.instanceId}`)
- const currentMode = (await provider.getState())?.mode ?? defaultModeSlug
-
- if (currentMode !== this.pausedModeSlug) {
- // The mode has changed, we need to switch back to the paused mode.
- await provider.handleModeSwitch(this.pausedModeSlug)
-
- // Delay to allow mode change to take effect before next tool is executed.
- await delay(500)
-
- provider.log(
- `[subtasks] task ${this.taskId}.${this.instanceId} has switched back to '${this.pausedModeSlug}' from '${currentMode}'`,
- )
- }
- }
-
- // Getting verbose details is an expensive operation, it uses ripgrep to
- // top-down build file structure of project which for large projects can
- // take a few seconds. For the best UX we show a placeholder api_req_started
- // message with a loading spinner as this happens.
-
- // Determine API protocol based on provider and model
- const modelId = getModelId(this.apiConfiguration)
- const apiProtocol = getApiProtocol(this.apiConfiguration.apiProvider, modelId)
-
- await this.say(
- "api_req_started",
- JSON.stringify({
- request:
- userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...",
- apiProtocol,
- }),
- )
-
- const {
- showRooIgnoredFiles = true,
- includeDiagnosticMessages = true,
- maxDiagnosticMessages = 50,
- maxReadFileLine = -1,
- } = (await this.providerRef.deref()?.getState()) ?? {}
-
- const parsedUserContent = await processUserContentMentions({
- userContent,
- cwd: this.cwd,
- urlContentFetcher: this.urlContentFetcher,
- fileContextTracker: this.fileContextTracker,
- rooIgnoreController: this.rooIgnoreController,
- showRooIgnoredFiles,
- includeDiagnosticMessages,
- maxDiagnosticMessages,
- maxReadFileLine,
- })
-
- const environmentDetails = await getEnvironmentDetails(this, includeFileDetails)
-
- // Add environment details as its own text block, separate from tool
- // results.
- const finalUserContent = [...parsedUserContent, { type: "text" as const, text: environmentDetails }]
-
- await this.addToApiConversationHistory({ role: "user", content: finalUserContent })
- TelemetryService.instance.captureConversationMessage(this.taskId, "user")
-
- // Since we sent off a placeholder api_req_started message to update the
- // webview while waiting to actually start the API request (to load
- // potential details for example), we need to update the text of that
- // message.
- const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started")
-
- this.clineMessages[lastApiReqIndex].text = JSON.stringify({
- request: finalUserContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"),
- apiProtocol,
- } satisfies ClineApiReqInfo)
-
- await this.saveClineMessages()
- await provider?.postStateToWebview()
-
- try {
- let cacheWriteTokens = 0
- let cacheReadTokens = 0
- let inputTokens = 0
- let outputTokens = 0
- let totalCost: number | undefined
-
- // We can't use `api_req_finished` anymore since it's a unique case
- // where it could come after a streaming message (i.e. in the middle
- // of being updated or executed).
- // Fortunately `api_req_finished` was always parsed out for the GUI
- // anyways, so it remains solely for legacy purposes to keep track
- // of prices in tasks from history (it's worth removing a few months
- // from now).
- const updateApiReqMsg = (cancelReason?: ClineApiReqCancelReason, streamingFailedMessage?: string) => {
- if (lastApiReqIndex < 0 || !this.clineMessages[lastApiReqIndex]) {
- return
- }
-
- const existingData = JSON.parse(this.clineMessages[lastApiReqIndex].text || "{}")
- this.clineMessages[lastApiReqIndex].text = JSON.stringify({
- ...existingData,
- tokensIn: inputTokens,
- tokensOut: outputTokens,
- cacheWrites: cacheWriteTokens,
- cacheReads: cacheReadTokens,
- cost:
- totalCost ??
- calculateApiCostAnthropic(
- this.api.getModel().info,
- inputTokens,
- outputTokens,
- cacheWriteTokens,
- cacheReadTokens,
- ),
- cancelReason,
- streamingFailedMessage,
- } satisfies ClineApiReqInfo)
- }
-
- const abortStream = async (cancelReason: ClineApiReqCancelReason, streamingFailedMessage?: string) => {
- if (this.diffViewProvider.isEditing) {
- await this.diffViewProvider.revertChanges() // closes diff view
- }
-
- // if last message is a partial we need to update and save it
- const lastMessage = this.clineMessages.at(-1)
-
- if (lastMessage && lastMessage.partial) {
- // lastMessage.ts = Date.now() DO NOT update ts since it is used as a key for virtuoso list
- lastMessage.partial = false
- // instead of streaming partialMessage events, we do a save and post like normal to persist to disk
- console.log("updating partial message", lastMessage)
- // await this.saveClineMessages()
- }
-
- // Let assistant know their response was interrupted for when task is resumed
- await this.addToApiConversationHistory({
- role: "assistant",
- content: [
- {
- type: "text",
- text:
- assistantMessage +
- `\n\n[${
- cancelReason === "streaming_failed"
- ? "Response interrupted by API Error"
- : "Response interrupted by user"
- }]`,
- },
- ],
- })
-
- // Update `api_req_started` to have cancelled and cost, so that
- // we can display the cost of the partial stream.
- updateApiReqMsg(cancelReason, streamingFailedMessage)
- await this.saveClineMessages()
-
- // Signals to provider that it can retrieve the saved messages
- // from disk, as abortTask can not be awaited on in nature.
- this.didFinishAbortingStream = true
- }
-
- // Reset streaming state.
- this.currentStreamingContentIndex = 0
- this.currentStreamingDidCheckpoint = false
- this.assistantMessageContent = []
- this.didCompleteReadingStream = false
- this.userMessageContent = []
- this.userMessageContentReady = false
- this.didRejectTool = false
- this.didAlreadyUseTool = false
- this.presentAssistantMessageLocked = false
- this.presentAssistantMessageHasPendingUpdates = false
- if (this.assistantMessageParser) {
- this.assistantMessageParser.reset()
- }
-
- await this.diffViewProvider.reset()
-
- // Yields only if the first chunk is successful, otherwise will
- // allow the user to retry the request (most likely due to rate
- // limit error, which gets thrown on the first chunk).
- const stream = this.attemptApiRequest()
- let assistantMessage = ""
- let reasoningMessage = ""
- this.isStreaming = true
-
- try {
- const iterator = stream[Symbol.asyncIterator]()
- let item = await iterator.next()
- while (!item.done) {
- const chunk = item.value
- item = await iterator.next()
- if (!chunk) {
- // Sometimes chunk is undefined, no idea that can cause
- // it, but this workaround seems to fix it.
- continue
- }
-
- switch (chunk.type) {
- case "reasoning":
- reasoningMessage += chunk.text
- await this.say("reasoning", reasoningMessage, undefined, true)
- break
- case "usage":
- inputTokens += chunk.inputTokens
- outputTokens += chunk.outputTokens
- cacheWriteTokens += chunk.cacheWriteTokens ?? 0
- cacheReadTokens += chunk.cacheReadTokens ?? 0
- totalCost = chunk.totalCost
- break
- case "text": {
- assistantMessage += chunk.text
-
- // Parse raw assistant message chunk into content blocks.
- const prevLength = this.assistantMessageContent.length
- if (this.isAssistantMessageParserEnabled && this.assistantMessageParser) {
- this.assistantMessageContent = this.assistantMessageParser.processChunk(chunk.text)
- } else {
- // Use the old parsing method when experiment is disabled
- this.assistantMessageContent = parseAssistantMessage(assistantMessage)
- }
-
- if (this.assistantMessageContent.length > prevLength) {
- // New content we need to present, reset to
- // false in case previous content set this to true.
- this.userMessageContentReady = false
- }
-
- // Present content to user.
- presentAssistantMessage(this)
- break
- }
- }
-
- if (this.abort) {
- console.log(`aborting stream, this.abandoned = ${this.abandoned}`)
-
- if (!this.abandoned) {
- // Only need to gracefully abort if this instance
- // isn't abandoned (sometimes OpenRouter stream
- // hangs, in which case this would affect future
- // instances of Cline).
- await abortStream("user_cancelled")
- }
-
- break // Aborts the stream.
- }
-
- if (this.didRejectTool) {
- // `userContent` has a tool rejection, so interrupt the
- // assistant's response to present the user's feedback.
- assistantMessage += "\n\n[Response interrupted by user feedback]"
- // Instead of setting this preemptively, we allow the
- // present iterator to finish and set
- // userMessageContentReady when its ready.
- // this.userMessageContentReady = true
- break
- }
-
- if (this.didAlreadyUseTool) {
- assistantMessage +=
- "\n\n[Response interrupted by a tool use result. Only one tool may be used at a time and should be placed at the end of the message.]"
- break
- }
- }
-
- // Create a copy of current token values to avoid race conditions
- const currentTokens = {
- input: inputTokens,
- output: outputTokens,
- cacheWrite: cacheWriteTokens,
- cacheRead: cacheReadTokens,
- total: totalCost,
- }
-
- const drainStreamInBackgroundToFindAllUsage = async (apiReqIndex: number) => {
- const timeoutMs = DEFAULT_USAGE_COLLECTION_TIMEOUT_MS
- const startTime = Date.now()
- const modelId = getModelId(this.apiConfiguration)
-
- // Local variables to accumulate usage data without affecting the main flow
- let bgInputTokens = currentTokens.input
- let bgOutputTokens = currentTokens.output
- let bgCacheWriteTokens = currentTokens.cacheWrite
- let bgCacheReadTokens = currentTokens.cacheRead
- let bgTotalCost = currentTokens.total
-
- // Helper function to capture telemetry and update messages
- const captureUsageData = async (
- tokens: {
- input: number
- output: number
- cacheWrite: number
- cacheRead: number
- total?: number
- },
- messageIndex: number = apiReqIndex,
- ) => {
- if (tokens.input > 0 || tokens.output > 0 || tokens.cacheWrite > 0 || tokens.cacheRead > 0) {
- // Update the shared variables atomically
- inputTokens = tokens.input
- outputTokens = tokens.output
- cacheWriteTokens = tokens.cacheWrite
- cacheReadTokens = tokens.cacheRead
- totalCost = tokens.total
-
- // Update the API request message with the latest usage data
- updateApiReqMsg()
- await this.saveClineMessages()
-
- // Update the specific message in the webview
- const apiReqMessage = this.clineMessages[messageIndex]
- if (apiReqMessage) {
- await this.updateClineMessage(apiReqMessage)
- }
-
- // Capture telemetry
- TelemetryService.instance.captureLlmCompletion(this.taskId, {
- inputTokens: tokens.input,
- outputTokens: tokens.output,
- cacheWriteTokens: tokens.cacheWrite,
- cacheReadTokens: tokens.cacheRead,
- cost:
- tokens.total ??
- calculateApiCostAnthropic(
- this.api.getModel().info,
- tokens.input,
- tokens.output,
- tokens.cacheWrite,
- tokens.cacheRead,
- ),
- })
- }
- }
-
- try {
- // Continue processing the original stream from where the main loop left off
- let usageFound = false
- let chunkCount = 0
-
- // Use the same iterator that the main loop was using
- while (!item.done) {
- // Check for timeout
- if (Date.now() - startTime > timeoutMs) {
- console.warn(
- `[Background Usage Collection] Timed out after ${timeoutMs}ms for model: ${modelId}, processed ${chunkCount} chunks`,
- )
- // Clean up the iterator before breaking
- if (iterator.return) {
- await iterator.return(undefined)
- }
- break
- }
-
- const chunk = item.value
- item = await iterator.next()
- chunkCount++
-
- if (chunk && chunk.type === "usage") {
- usageFound = true
- bgInputTokens += chunk.inputTokens
- bgOutputTokens += chunk.outputTokens
- bgCacheWriteTokens += chunk.cacheWriteTokens ?? 0
- bgCacheReadTokens += chunk.cacheReadTokens ?? 0
- bgTotalCost = chunk.totalCost
- }
- }
-
- if (
- usageFound ||
- bgInputTokens > 0 ||
- bgOutputTokens > 0 ||
- bgCacheWriteTokens > 0 ||
- bgCacheReadTokens > 0
- ) {
- // We have usage data either from a usage chunk or accumulated tokens
- await captureUsageData(
- {
- input: bgInputTokens,
- output: bgOutputTokens,
- cacheWrite: bgCacheWriteTokens,
- cacheRead: bgCacheReadTokens,
- total: bgTotalCost,
- },
- lastApiReqIndex,
- )
- } else {
- console.warn(
- `[Background Usage Collection] Suspicious: request ${apiReqIndex} is complete, but no usage info was found. Model: ${modelId}`,
- )
- }
- } catch (error) {
- console.error("Error draining stream for usage data:", error)
- // Still try to capture whatever usage data we have collected so far
- if (
- bgInputTokens > 0 ||
- bgOutputTokens > 0 ||
- bgCacheWriteTokens > 0 ||
- bgCacheReadTokens > 0
- ) {
- await captureUsageData(
- {
- input: bgInputTokens,
- output: bgOutputTokens,
- cacheWrite: bgCacheWriteTokens,
- cacheRead: bgCacheReadTokens,
- total: bgTotalCost,
- },
- lastApiReqIndex,
- )
- }
- }
- }
-
- // Start the background task and handle any errors
- drainStreamInBackgroundToFindAllUsage(lastApiReqIndex).catch((error) => {
- console.error("Background usage collection failed:", error)
- })
- } catch (error) {
- // Abandoned happens when extension is no longer waiting for the
- // Cline instance to finish aborting (error is thrown here when
- // any function in the for loop throws due to this.abort).
- if (!this.abandoned) {
- // If the stream failed, there's various states the task
- // could be in (i.e. could have streamed some tools the user
- // may have executed), so we just resort to replicating a
- // cancel task.
-
- // Check if this was a user-initiated cancellation BEFORE calling abortTask
- // If this.abort is already true, it means the user clicked cancel, so we should
- // treat this as "user_cancelled" rather than "streaming_failed"
- const cancelReason = this.abort ? "user_cancelled" : "streaming_failed"
-
- const streamingFailedMessage = this.abort
- ? undefined
- : (error.message ?? JSON.stringify(serializeError(error), null, 2))
-
- // Now call abortTask after determining the cancel reason.
- await this.abortTask()
- await abortStream(cancelReason, streamingFailedMessage)
-
- const history = await provider?.getTaskWithId(this.taskId)
-
- if (history) {
- await provider?.initClineWithHistoryItem(history.historyItem)
- }
- }
- } finally {
- this.isStreaming = false
- }
-
- // Need to call here in case the stream was aborted.
- if (this.abort || this.abandoned) {
+ if (this.abort) {
throw new Error(`[RooCode#recursivelyMakeRooRequests] task ${this.taskId}.${this.instanceId} aborted`)
}
- this.didCompleteReadingStream = true
-
- // Set any blocks to be complete to allow `presentAssistantMessage`
- // to finish and set `userMessageContentReady` to true.
- // (Could be a text block that had no subsequent tool uses, or a
- // text block at the very end, or an invalid tool use, etc. Whatever
- // the case, `presentAssistantMessage` relies on these blocks either
- // to be completed or the user to reject a block in order to proceed
- // and eventually set userMessageContentReady to true.)
- const partialBlocks = this.assistantMessageContent.filter((block) => block.partial)
- partialBlocks.forEach((block) => (block.partial = false))
-
- // Can't just do this b/c a tool could be in the middle of executing.
- // this.assistantMessageContent.forEach((e) => (e.partial = false))
-
- // Now that the stream is complete, finalize any remaining partial content blocks
- if (this.isAssistantMessageParserEnabled && this.assistantMessageParser) {
- this.assistantMessageParser.finalizeContentBlocks()
- this.assistantMessageContent = this.assistantMessageParser.getContentBlocks()
- }
- // When using old parser, no finalization needed - parsing already happened during streaming
-
- if (partialBlocks.length > 0) {
- // If there is content to update then it will complete and
- // update `this.userMessageContentReady` to true, which we
- // `pWaitFor` before making the next request. All this is really
- // doing is presenting the last partial message that we just set
- // to complete.
- presentAssistantMessage(this)
- }
-
- // Note: updateApiReqMsg() is now called from within drainStreamInBackgroundToFindAllUsage
- // to ensure usage data is captured even when the stream is interrupted. The background task
- // uses local variables to accumulate usage data before atomically updating the shared state.
- await this.persistGpt5Metadata(reasoningMessage)
- await this.saveClineMessages()
- await this.providerRef.deref()?.postStateToWebview()
-
- // Reset parser after each complete conversation round
- if (this.assistantMessageParser) {
- this.assistantMessageParser.reset()
- }
-
- // Now add to apiConversationHistory.
- // Need to save assistant responses to file before proceeding to
- // tool use since user can exit at any moment and we wouldn't be
- // able to save the assistant's response.
- let didEndLoop = false
-
- if (assistantMessage.length > 0) {
- await this.addToApiConversationHistory({
- role: "assistant",
- content: [{ type: "text", text: assistantMessage }],
- })
-
- TelemetryService.instance.captureConversationMessage(this.taskId, "assistant")
-
- // NOTE: This comment is here for future reference - this was a
- // workaround for `userMessageContent` not getting set to true.
- // It was due to it not recursively calling for partial blocks
- // when `didRejectTool`, so it would get stuck waiting for a
- // partial block to complete before it could continue.
- // In case the content blocks finished it may be the api stream
- // finished after the last parsed content block was executed, so
- // we are able to detect out of bounds and set
- // `userMessageContentReady` to true (note you should not call
- // `presentAssistantMessage` since if the last block i
- // completed it will be presented again).
- // const completeBlocks = this.assistantMessageContent.filter((block) => !block.partial) // If there are any partial blocks after the stream ended we can consider them invalid.
- // if (this.currentStreamingContentIndex >= completeBlocks.length) {
- // this.userMessageContentReady = true
- // }
-
- await pWaitFor(() => this.userMessageContentReady)
-
- // If the model did not tool use, then we need to tell it to
- // either use a tool or attempt_completion.
- const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use")
-
- if (!didToolUse) {
- this.userMessageContent.push({ type: "text", text: formatResponse.noToolsUsed() })
- this.consecutiveMistakeCount++
- }
-
- const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent)
- didEndLoop = recDidEndLoop
- } else {
- // If there's no assistant_responses, that means we got no text
- // or tool_use content blocks from API which we should assume is
- // an error.
- await this.say(
- "error",
- "Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output.",
+ if (this.consecutiveMistakeLimit > 0 && this.consecutiveMistakeCount >= this.consecutiveMistakeLimit) {
+ const { response, text, images } = await this.ask(
+ "mistake_limit_reached",
+ t("common:errors.mistake_limit_guidance"),
)
- await this.addToApiConversationHistory({
- role: "assistant",
- content: [{ type: "text", text: "Failure: I did not provide a response." }],
- })
+ if (response === "messageResponse") {
+ currentUserContent.push(
+ ...[
+ { type: "text" as const, text: formatResponse.tooManyMistakes(text) },
+ ...formatResponse.imageBlocks(images),
+ ],
+ )
+
+ await this.say("user_feedback", text, images)
+
+ // Track consecutive mistake errors in telemetry.
+ TelemetryService.instance.captureConsecutiveMistakeError(this.taskId)
+ }
+
+ this.consecutiveMistakeCount = 0
}
- return didEndLoop // Will always be false for now.
- } catch (error) {
- // This should never happen since the only thing that can throw an
- // error is the attemptApiRequest, which is wrapped in a try catch
- // that sends an ask where if noButtonClicked, will clear current
- // task and destroy this instance. However to avoid unhandled
- // promise rejection, we will end this loop which will end execution
- // of this instance (see `startTask`).
- return true // Needs to be true so parent loop knows to end task.
+ // In this Cline request loop, we need to check if this task instance
+ // has been asked to wait for a subtask to finish before continuing.
+ const provider = this.providerRef.deref()
+
+ if (this.isPaused && provider) {
+ provider.log(`[subtasks] paused ${this.taskId}.${this.instanceId}`)
+ await this.waitForResume()
+ provider.log(`[subtasks] resumed ${this.taskId}.${this.instanceId}`)
+ const currentMode = (await provider.getState())?.mode ?? defaultModeSlug
+
+ if (currentMode !== this.pausedModeSlug) {
+ // The mode has changed, we need to switch back to the paused mode.
+ await provider.handleModeSwitch(this.pausedModeSlug)
+
+ // Delay to allow mode change to take effect before next tool is executed.
+ await delay(500)
+
+ provider.log(
+ `[subtasks] task ${this.taskId}.${this.instanceId} has switched back to '${this.pausedModeSlug}' from '${currentMode}'`,
+ )
+ }
+ }
+
+ // Getting verbose details is an expensive operation, it uses ripgrep to
+ // top-down build file structure of project which for large projects can
+ // take a few seconds. For the best UX we show a placeholder api_req_started
+ // message with a loading spinner as this happens.
+
+ // Determine API protocol based on provider and model
+ const modelId = getModelId(this.apiConfiguration)
+ const apiProtocol = getApiProtocol(this.apiConfiguration.apiProvider, modelId)
+
+ await this.say(
+ "api_req_started",
+ JSON.stringify({
+ request:
+ currentUserContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") +
+ "\n\nLoading...",
+ apiProtocol,
+ }),
+ )
+
+ const {
+ showRooIgnoredFiles = true,
+ includeDiagnosticMessages = true,
+ maxDiagnosticMessages = 50,
+ maxReadFileLine = -1,
+ } = (await this.providerRef.deref()?.getState()) ?? {}
+
+ const parsedUserContent = await processUserContentMentions({
+ userContent: currentUserContent,
+ cwd: this.cwd,
+ urlContentFetcher: this.urlContentFetcher,
+ fileContextTracker: this.fileContextTracker,
+ rooIgnoreController: this.rooIgnoreController,
+ showRooIgnoredFiles,
+ includeDiagnosticMessages,
+ maxDiagnosticMessages,
+ maxReadFileLine,
+ })
+
+ const environmentDetails = await getEnvironmentDetails(this, currentIncludeFileDetails)
+
+ // Add environment details as its own text block, separate from tool
+ // results.
+ const finalUserContent = [...parsedUserContent, { type: "text" as const, text: environmentDetails }]
+
+ await this.addToApiConversationHistory({ role: "user", content: finalUserContent })
+ TelemetryService.instance.captureConversationMessage(this.taskId, "user")
+
+ // Since we sent off a placeholder api_req_started message to update the
+ // webview while waiting to actually start the API request (to load
+ // potential details for example), we need to update the text of that
+ // message.
+ const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started")
+
+ this.clineMessages[lastApiReqIndex].text = JSON.stringify({
+ request: finalUserContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"),
+ apiProtocol,
+ } satisfies ClineApiReqInfo)
+
+ await this.saveClineMessages()
+ await provider?.postStateToWebview()
+
+ try {
+ let cacheWriteTokens = 0
+ let cacheReadTokens = 0
+ let inputTokens = 0
+ let outputTokens = 0
+ let totalCost: number | undefined
+
+ // We can't use `api_req_finished` anymore since it's a unique case
+ // where it could come after a streaming message (i.e. in the middle
+ // of being updated or executed).
+ // Fortunately `api_req_finished` was always parsed out for the GUI
+ // anyways, so it remains solely for legacy purposes to keep track
+ // of prices in tasks from history (it's worth removing a few months
+ // from now).
+ const updateApiReqMsg = (cancelReason?: ClineApiReqCancelReason, streamingFailedMessage?: string) => {
+ if (lastApiReqIndex < 0 || !this.clineMessages[lastApiReqIndex]) {
+ return
+ }
+
+ const existingData = JSON.parse(this.clineMessages[lastApiReqIndex].text || "{}")
+ this.clineMessages[lastApiReqIndex].text = JSON.stringify({
+ ...existingData,
+ tokensIn: inputTokens,
+ tokensOut: outputTokens,
+ cacheWrites: cacheWriteTokens,
+ cacheReads: cacheReadTokens,
+ cost:
+ totalCost ??
+ calculateApiCostAnthropic(
+ this.api.getModel().info,
+ inputTokens,
+ outputTokens,
+ cacheWriteTokens,
+ cacheReadTokens,
+ ),
+ cancelReason,
+ streamingFailedMessage,
+ } satisfies ClineApiReqInfo)
+ }
+
+ const abortStream = async (cancelReason: ClineApiReqCancelReason, streamingFailedMessage?: string) => {
+ if (this.diffViewProvider.isEditing) {
+ await this.diffViewProvider.revertChanges() // closes diff view
+ }
+
+ // if last message is a partial we need to update and save it
+ const lastMessage = this.clineMessages.at(-1)
+
+ if (lastMessage && lastMessage.partial) {
+ // lastMessage.ts = Date.now() DO NOT update ts since it is used as a key for virtuoso list
+ lastMessage.partial = false
+ // instead of streaming partialMessage events, we do a save and post like normal to persist to disk
+ console.log("updating partial message", lastMessage)
+ // await this.saveClineMessages()
+ }
+
+ // Let assistant know their response was interrupted for when task is resumed
+ await this.addToApiConversationHistory({
+ role: "assistant",
+ content: [
+ {
+ type: "text",
+ text:
+ assistantMessage +
+ `\n\n[${
+ cancelReason === "streaming_failed"
+ ? "Response interrupted by API Error"
+ : "Response interrupted by user"
+ }]`,
+ },
+ ],
+ })
+
+ // Update `api_req_started` to have cancelled and cost, so that
+ // we can display the cost of the partial stream.
+ updateApiReqMsg(cancelReason, streamingFailedMessage)
+ await this.saveClineMessages()
+
+ // Signals to provider that it can retrieve the saved messages
+ // from disk, as abortTask can not be awaited on in nature.
+ this.didFinishAbortingStream = true
+ }
+
+ // Reset streaming state.
+ this.currentStreamingContentIndex = 0
+ this.currentStreamingDidCheckpoint = false
+ this.assistantMessageContent = []
+ this.didCompleteReadingStream = false
+ this.userMessageContent = []
+ this.userMessageContentReady = false
+ this.didRejectTool = false
+ this.didAlreadyUseTool = false
+ this.presentAssistantMessageLocked = false
+ this.presentAssistantMessageHasPendingUpdates = false
+ if (this.assistantMessageParser) {
+ this.assistantMessageParser.reset()
+ }
+
+ await this.diffViewProvider.reset()
+
+ // Yields only if the first chunk is successful, otherwise will
+ // allow the user to retry the request (most likely due to rate
+ // limit error, which gets thrown on the first chunk).
+ const stream = this.attemptApiRequest()
+ let assistantMessage = ""
+ let reasoningMessage = ""
+ this.isStreaming = true
+
+ try {
+ const iterator = stream[Symbol.asyncIterator]()
+ let item = await iterator.next()
+ while (!item.done) {
+ const chunk = item.value
+ item = await iterator.next()
+ if (!chunk) {
+ // Sometimes chunk is undefined, no idea that can cause
+ // it, but this workaround seems to fix it.
+ continue
+ }
+
+ switch (chunk.type) {
+ case "reasoning":
+ reasoningMessage += chunk.text
+ await this.say("reasoning", reasoningMessage, undefined, true)
+ break
+ case "usage":
+ inputTokens += chunk.inputTokens
+ outputTokens += chunk.outputTokens
+ cacheWriteTokens += chunk.cacheWriteTokens ?? 0
+ cacheReadTokens += chunk.cacheReadTokens ?? 0
+ totalCost = chunk.totalCost
+ break
+ case "text": {
+ assistantMessage += chunk.text
+
+ // Parse raw assistant message chunk into content blocks.
+ const prevLength = this.assistantMessageContent.length
+ if (this.isAssistantMessageParserEnabled && this.assistantMessageParser) {
+ this.assistantMessageContent = this.assistantMessageParser.processChunk(chunk.text)
+ } else {
+ // Use the old parsing method when experiment is disabled
+ this.assistantMessageContent = parseAssistantMessage(assistantMessage)
+ }
+
+ if (this.assistantMessageContent.length > prevLength) {
+ // New content we need to present, reset to
+ // false in case previous content set this to true.
+ this.userMessageContentReady = false
+ }
+
+ // Present content to user.
+ presentAssistantMessage(this)
+ break
+ }
+ }
+
+ if (this.abort) {
+ console.log(`aborting stream, this.abandoned = ${this.abandoned}`)
+
+ if (!this.abandoned) {
+ // Only need to gracefully abort if this instance
+ // isn't abandoned (sometimes OpenRouter stream
+ // hangs, in which case this would affect future
+ // instances of Cline).
+ await abortStream("user_cancelled")
+ }
+
+ break // Aborts the stream.
+ }
+
+ if (this.didRejectTool) {
+ // `userContent` has a tool rejection, so interrupt the
+ // assistant's response to present the user's feedback.
+ assistantMessage += "\n\n[Response interrupted by user feedback]"
+ // Instead of setting this preemptively, we allow the
+ // present iterator to finish and set
+ // userMessageContentReady when its ready.
+ // this.userMessageContentReady = true
+ break
+ }
+
+ if (this.didAlreadyUseTool) {
+ assistantMessage +=
+ "\n\n[Response interrupted by a tool use result. Only one tool may be used at a time and should be placed at the end of the message.]"
+ break
+ }
+ }
+
+ // Create a copy of current token values to avoid race conditions
+ const currentTokens = {
+ input: inputTokens,
+ output: outputTokens,
+ cacheWrite: cacheWriteTokens,
+ cacheRead: cacheReadTokens,
+ total: totalCost,
+ }
+
+ const drainStreamInBackgroundToFindAllUsage = async (apiReqIndex: number) => {
+ const timeoutMs = DEFAULT_USAGE_COLLECTION_TIMEOUT_MS
+ const startTime = Date.now()
+ const modelId = getModelId(this.apiConfiguration)
+
+ // Local variables to accumulate usage data without affecting the main flow
+ let bgInputTokens = currentTokens.input
+ let bgOutputTokens = currentTokens.output
+ let bgCacheWriteTokens = currentTokens.cacheWrite
+ let bgCacheReadTokens = currentTokens.cacheRead
+ let bgTotalCost = currentTokens.total
+
+ // Helper function to capture telemetry and update messages
+ const captureUsageData = async (
+ tokens: {
+ input: number
+ output: number
+ cacheWrite: number
+ cacheRead: number
+ total?: number
+ },
+ messageIndex: number = apiReqIndex,
+ ) => {
+ if (
+ tokens.input > 0 ||
+ tokens.output > 0 ||
+ tokens.cacheWrite > 0 ||
+ tokens.cacheRead > 0
+ ) {
+ // Update the shared variables atomically
+ inputTokens = tokens.input
+ outputTokens = tokens.output
+ cacheWriteTokens = tokens.cacheWrite
+ cacheReadTokens = tokens.cacheRead
+ totalCost = tokens.total
+
+ // Update the API request message with the latest usage data
+ updateApiReqMsg()
+ await this.saveClineMessages()
+
+ // Update the specific message in the webview
+ const apiReqMessage = this.clineMessages[messageIndex]
+ if (apiReqMessage) {
+ await this.updateClineMessage(apiReqMessage)
+ }
+
+ // Capture telemetry
+ TelemetryService.instance.captureLlmCompletion(this.taskId, {
+ inputTokens: tokens.input,
+ outputTokens: tokens.output,
+ cacheWriteTokens: tokens.cacheWrite,
+ cacheReadTokens: tokens.cacheRead,
+ cost:
+ tokens.total ??
+ calculateApiCostAnthropic(
+ this.api.getModel().info,
+ tokens.input,
+ tokens.output,
+ tokens.cacheWrite,
+ tokens.cacheRead,
+ ),
+ })
+ }
+ }
+
+ try {
+ // Continue processing the original stream from where the main loop left off
+ let usageFound = false
+ let chunkCount = 0
+
+ // Use the same iterator that the main loop was using
+ while (!item.done) {
+ // Check for timeout
+ if (Date.now() - startTime > timeoutMs) {
+ console.warn(
+ `[Background Usage Collection] Timed out after ${timeoutMs}ms for model: ${modelId}, processed ${chunkCount} chunks`,
+ )
+ // Clean up the iterator before breaking
+ if (iterator.return) {
+ await iterator.return(undefined)
+ }
+ break
+ }
+
+ const chunk = item.value
+ item = await iterator.next()
+ chunkCount++
+
+ if (chunk && chunk.type === "usage") {
+ usageFound = true
+ bgInputTokens += chunk.inputTokens
+ bgOutputTokens += chunk.outputTokens
+ bgCacheWriteTokens += chunk.cacheWriteTokens ?? 0
+ bgCacheReadTokens += chunk.cacheReadTokens ?? 0
+ bgTotalCost = chunk.totalCost
+ }
+ }
+
+ if (
+ usageFound ||
+ bgInputTokens > 0 ||
+ bgOutputTokens > 0 ||
+ bgCacheWriteTokens > 0 ||
+ bgCacheReadTokens > 0
+ ) {
+ // We have usage data either from a usage chunk or accumulated tokens
+ await captureUsageData(
+ {
+ input: bgInputTokens,
+ output: bgOutputTokens,
+ cacheWrite: bgCacheWriteTokens,
+ cacheRead: bgCacheReadTokens,
+ total: bgTotalCost,
+ },
+ lastApiReqIndex,
+ )
+ } else {
+ console.warn(
+ `[Background Usage Collection] Suspicious: request ${apiReqIndex} is complete, but no usage info was found. Model: ${modelId}`,
+ )
+ }
+ } catch (error) {
+ console.error("Error draining stream for usage data:", error)
+ // Still try to capture whatever usage data we have collected so far
+ if (
+ bgInputTokens > 0 ||
+ bgOutputTokens > 0 ||
+ bgCacheWriteTokens > 0 ||
+ bgCacheReadTokens > 0
+ ) {
+ await captureUsageData(
+ {
+ input: bgInputTokens,
+ output: bgOutputTokens,
+ cacheWrite: bgCacheWriteTokens,
+ cacheRead: bgCacheReadTokens,
+ total: bgTotalCost,
+ },
+ lastApiReqIndex,
+ )
+ }
+ }
+ }
+
+ // Start the background task and handle any errors
+ drainStreamInBackgroundToFindAllUsage(lastApiReqIndex).catch((error) => {
+ console.error("Background usage collection failed:", error)
+ })
+ } catch (error) {
+ // Abandoned happens when extension is no longer waiting for the
+ // Cline instance to finish aborting (error is thrown here when
+ // any function in the for loop throws due to this.abort).
+ if (!this.abandoned) {
+ // If the stream failed, there's various states the task
+ // could be in (i.e. could have streamed some tools the user
+ // may have executed), so we just resort to replicating a
+ // cancel task.
+
+ // Check if this was a user-initiated cancellation BEFORE calling abortTask
+ // If this.abort is already true, it means the user clicked cancel, so we should
+ // treat this as "user_cancelled" rather than "streaming_failed"
+ const cancelReason = this.abort ? "user_cancelled" : "streaming_failed"
+
+ const streamingFailedMessage = this.abort
+ ? undefined
+ : (error.message ?? JSON.stringify(serializeError(error), null, 2))
+
+ // Now call abortTask after determining the cancel reason.
+ await this.abortTask()
+ await abortStream(cancelReason, streamingFailedMessage)
+
+ const history = await provider?.getTaskWithId(this.taskId)
+
+ if (history) {
+ await provider?.initClineWithHistoryItem(history.historyItem)
+ }
+ }
+ } finally {
+ this.isStreaming = false
+ }
+
+ // Need to call here in case the stream was aborted.
+ if (this.abort || this.abandoned) {
+ throw new Error(
+ `[RooCode#recursivelyMakeRooRequests] task ${this.taskId}.${this.instanceId} aborted`,
+ )
+ }
+
+ this.didCompleteReadingStream = true
+
+ // Set any blocks to be complete to allow `presentAssistantMessage`
+ // to finish and set `userMessageContentReady` to true.
+ // (Could be a text block that had no subsequent tool uses, or a
+ // text block at the very end, or an invalid tool use, etc. Whatever
+ // the case, `presentAssistantMessage` relies on these blocks either
+ // to be completed or the user to reject a block in order to proceed
+ // and eventually set userMessageContentReady to true.)
+ const partialBlocks = this.assistantMessageContent.filter((block) => block.partial)
+ partialBlocks.forEach((block) => (block.partial = false))
+
+ // Can't just do this b/c a tool could be in the middle of executing.
+ // this.assistantMessageContent.forEach((e) => (e.partial = false))
+
+ // Now that the stream is complete, finalize any remaining partial content blocks
+ if (this.isAssistantMessageParserEnabled && this.assistantMessageParser) {
+ this.assistantMessageParser.finalizeContentBlocks()
+ this.assistantMessageContent = this.assistantMessageParser.getContentBlocks()
+ }
+ // When using old parser, no finalization needed - parsing already happened during streaming
+
+ if (partialBlocks.length > 0) {
+ // If there is content to update then it will complete and
+ // update `this.userMessageContentReady` to true, which we
+ // `pWaitFor` before making the next request. All this is really
+ // doing is presenting the last partial message that we just set
+ // to complete.
+ presentAssistantMessage(this)
+ }
+
+ // Note: updateApiReqMsg() is now called from within drainStreamInBackgroundToFindAllUsage
+ // to ensure usage data is captured even when the stream is interrupted. The background task
+ // uses local variables to accumulate usage data before atomically updating the shared state.
+ await this.persistGpt5Metadata(reasoningMessage)
+ await this.saveClineMessages()
+ await this.providerRef.deref()?.postStateToWebview()
+
+ // Reset parser after each complete conversation round
+ if (this.assistantMessageParser) {
+ this.assistantMessageParser.reset()
+ }
+
+ // Now add to apiConversationHistory.
+ // Need to save assistant responses to file before proceeding to
+ // tool use since user can exit at any moment and we wouldn't be
+ // able to save the assistant's response.
+ let didEndLoop = false
+
+ if (assistantMessage.length > 0) {
+ await this.addToApiConversationHistory({
+ role: "assistant",
+ content: [{ type: "text", text: assistantMessage }],
+ })
+
+ TelemetryService.instance.captureConversationMessage(this.taskId, "assistant")
+
+ // NOTE: This comment is here for future reference - this was a
+ // workaround for `userMessageContent` not getting set to true.
+ // It was due to it not recursively calling for partial blocks
+ // when `didRejectTool`, so it would get stuck waiting for a
+ // partial block to complete before it could continue.
+ // In case the content blocks finished it may be the api stream
+ // finished after the last parsed content block was executed, so
+ // we are able to detect out of bounds and set
+ // `userMessageContentReady` to true (note you should not call
+ // `presentAssistantMessage` since if the last block i
+ // completed it will be presented again).
+ // const completeBlocks = this.assistantMessageContent.filter((block) => !block.partial) // If there are any partial blocks after the stream ended we can consider them invalid.
+ // if (this.currentStreamingContentIndex >= completeBlocks.length) {
+ // this.userMessageContentReady = true
+ // }
+
+ await pWaitFor(() => this.userMessageContentReady)
+
+ // If the model did not tool use, then we need to tell it to
+ // either use a tool or attempt_completion.
+ const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use")
+
+ if (!didToolUse) {
+ this.userMessageContent.push({ type: "text", text: formatResponse.noToolsUsed() })
+ this.consecutiveMistakeCount++
+ }
+
+ if (this.userMessageContent.length > 0) {
+ stack.push({
+ userContent: [...this.userMessageContent], // Create a copy to avoid mutation issues
+ includeFileDetails: false, // Subsequent iterations don't need file details
+ })
+
+ // Add periodic yielding to prevent blocking
+ await new Promise((resolve) => setImmediate(resolve))
+ }
+ // Continue to next iteration instead of setting didEndLoop from recursive call
+ continue
+ } else {
+ // If there's no assistant_responses, that means we got no text
+ // or tool_use content blocks from API which we should assume is
+ // an error.
+ await this.say(
+ "error",
+ "Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output.",
+ )
+
+ await this.addToApiConversationHistory({
+ role: "assistant",
+ content: [{ type: "text", text: "Failure: I did not provide a response." }],
+ })
+ }
+
+ // If we reach here without continuing, return false (will always be false for now)
+ return false
+ } catch (error) {
+ // This should never happen since the only thing that can throw an
+ // error is the attemptApiRequest, which is wrapped in a try catch
+ // that sends an ask where if noButtonClicked, will clear current
+ // task and destroy this instance. However to avoid unhandled
+ // promise rejection, we will end this loop which will end execution
+ // of this instance (see `startTask`).
+ return true // Needs to be true so parent loop knows to end task.
+ }
}
+
+ // If we exit the while loop normally (stack is empty), return false
+ return false
}
private async getSystemPrompt(): Promise {
diff --git a/src/core/task/__tests__/Task.dispose.test.ts b/src/core/task/__tests__/Task.dispose.test.ts
new file mode 100644
index 0000000000..1d93d148a4
--- /dev/null
+++ b/src/core/task/__tests__/Task.dispose.test.ts
@@ -0,0 +1,201 @@
+import { Task } from "../Task"
+import { ClineProvider } from "../../webview/ClineProvider"
+import { ProviderSettings } from "@roo-code/types"
+import { vi, describe, test, expect, beforeEach, afterEach } from "vitest"
+
+// Mock dependencies
+vi.mock("../../webview/ClineProvider")
+vi.mock("../../../integrations/terminal/TerminalRegistry", () => ({
+ TerminalRegistry: {
+ releaseTerminalsForTask: vi.fn(),
+ },
+}))
+vi.mock("../../ignore/RooIgnoreController")
+vi.mock("../../protect/RooProtectedController")
+vi.mock("../../context-tracking/FileContextTracker")
+vi.mock("../../../services/browser/UrlContentFetcher")
+vi.mock("../../../services/browser/BrowserSession")
+vi.mock("../../../integrations/editor/DiffViewProvider")
+vi.mock("../../tools/ToolRepetitionDetector")
+vi.mock("../../../api", () => ({
+ buildApiHandler: vi.fn(() => ({
+ getModel: () => ({ info: {}, id: "test-model" }),
+ })),
+}))
+vi.mock("./AutoApprovalHandler")
+
+// Mock TelemetryService
+vi.mock("@roo-code/telemetry", () => ({
+ TelemetryService: {
+ instance: {
+ captureTaskCreated: vi.fn(),
+ captureTaskRestarted: vi.fn(),
+ },
+ },
+}))
+
+describe("Task dispose method", () => {
+ let mockProvider: any
+ let mockApiConfiguration: ProviderSettings
+ let task: Task
+
+ beforeEach(() => {
+ // Reset all mocks
+ vi.clearAllMocks()
+
+ // Mock provider
+ mockProvider = {
+ context: {
+ globalStorageUri: { fsPath: "/test/path" },
+ },
+ getState: vi.fn().mockResolvedValue({ mode: "code" }),
+ log: vi.fn(),
+ }
+
+ // Mock API configuration
+ mockApiConfiguration = {
+ apiProvider: "anthropic",
+ apiKey: "test-key",
+ } as ProviderSettings
+
+ // Create task instance without starting it
+ task = new Task({
+ provider: mockProvider as ClineProvider,
+ apiConfiguration: mockApiConfiguration,
+ startTask: false,
+ })
+ })
+
+ afterEach(() => {
+ // Clean up
+ if (task && !task.abort) {
+ task.dispose()
+ }
+ })
+
+ test("should remove all event listeners when dispose is called", () => {
+ // Add some event listeners using type assertion to bypass strict typing for testing
+ const listener1 = vi.fn(() => {})
+ const listener2 = vi.fn(() => {})
+ const listener3 = vi.fn((taskId: string) => {})
+
+ // Use type assertion to bypass strict event typing for testing
+ ;(task as any).on("TaskStarted", listener1)
+ ;(task as any).on("TaskAborted", listener2)
+ ;(task as any).on("TaskIdle", listener3)
+
+ // Verify listeners are added
+ expect(task.listenerCount("TaskStarted")).toBe(1)
+ expect(task.listenerCount("TaskAborted")).toBe(1)
+ expect(task.listenerCount("TaskIdle")).toBe(1)
+
+ // Spy on removeAllListeners method
+ const removeAllListenersSpy = vi.spyOn(task, "removeAllListeners")
+
+ // Call dispose
+ task.dispose()
+
+ // Verify removeAllListeners was called
+ expect(removeAllListenersSpy).toHaveBeenCalledOnce()
+
+ // Verify all listeners are removed
+ expect(task.listenerCount("TaskStarted")).toBe(0)
+ expect(task.listenerCount("TaskAborted")).toBe(0)
+ expect(task.listenerCount("TaskIdle")).toBe(0)
+ })
+
+ test("should handle errors when removing event listeners", () => {
+ // Mock removeAllListeners to throw an error
+ const originalRemoveAllListeners = task.removeAllListeners
+ task.removeAllListeners = vi.fn(() => {
+ throw new Error("Test error")
+ })
+
+ // Spy on console.error
+ const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {})
+
+ // Call dispose - should not throw
+ expect(() => task.dispose()).not.toThrow()
+
+ // Verify error was logged
+ expect(consoleErrorSpy).toHaveBeenCalledWith("Error removing event listeners:", expect.any(Error))
+
+ // Restore
+ task.removeAllListeners = originalRemoveAllListeners
+ consoleErrorSpy.mockRestore()
+ })
+
+ test("should clean up all resources in correct order", () => {
+ const removeAllListenersSpy = vi.spyOn(task, "removeAllListeners")
+ const consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {})
+
+ // Call dispose
+ task.dispose()
+
+ // Verify dispose was called and logged
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ expect.stringContaining(`[Task] disposing task ${task.taskId}.${task.instanceId}`),
+ )
+
+ // Verify removeAllListeners was called first (before other cleanup)
+ expect(removeAllListenersSpy).toHaveBeenCalledOnce()
+
+ // Clean up
+ consoleLogSpy.mockRestore()
+ })
+
+ test("should prevent memory leaks by removing listeners before other cleanup", () => {
+ // Add multiple listeners of different types using type assertion for testing
+ const listeners = {
+ TaskStarted: vi.fn(() => {}),
+ TaskAborted: vi.fn(() => {}),
+ TaskIdle: vi.fn((taskId: string) => {}),
+ TaskActive: vi.fn((taskId: string) => {}),
+ TaskAskResponded: vi.fn(() => {}),
+ Message: vi.fn((data: { action: "created" | "updated"; message: any }) => {}),
+ TaskTokenUsageUpdated: vi.fn((taskId: string, tokenUsage: any) => {}),
+ TaskToolFailed: vi.fn((taskId: string, tool: any, error: string) => {}),
+ TaskUnpaused: vi.fn(() => {}),
+ }
+
+ // Add all listeners using type assertion to bypass strict typing for testing
+ const taskAny = task as any
+ taskAny.on("TaskStarted", listeners.TaskStarted)
+ taskAny.on("TaskAborted", listeners.TaskAborted)
+ taskAny.on("TaskIdle", listeners.TaskIdle)
+ taskAny.on("TaskActive", listeners.TaskActive)
+ taskAny.on("TaskAskResponded", listeners.TaskAskResponded)
+ taskAny.on("Message", listeners.Message)
+ taskAny.on("TaskTokenUsageUpdated", listeners.TaskTokenUsageUpdated)
+ taskAny.on("TaskToolFailed", listeners.TaskToolFailed)
+ taskAny.on("TaskUnpaused", listeners.TaskUnpaused)
+
+ // Verify all listeners are added
+ expect(task.listenerCount("TaskStarted")).toBe(1)
+ expect(task.listenerCount("TaskAborted")).toBe(1)
+ expect(task.listenerCount("TaskIdle")).toBe(1)
+ expect(task.listenerCount("TaskActive")).toBe(1)
+ expect(task.listenerCount("TaskAskResponded")).toBe(1)
+ expect(task.listenerCount("Message")).toBe(1)
+ expect(task.listenerCount("TaskTokenUsageUpdated")).toBe(1)
+ expect(task.listenerCount("TaskToolFailed")).toBe(1)
+ expect(task.listenerCount("TaskUnpaused")).toBe(1)
+
+ // Call dispose
+ task.dispose()
+
+ // Verify all listeners are removed
+ expect(task.listenerCount("TaskStarted")).toBe(0)
+ expect(task.listenerCount("TaskAborted")).toBe(0)
+ expect(task.listenerCount("TaskIdle")).toBe(0)
+ expect(task.listenerCount("TaskActive")).toBe(0)
+ expect(task.listenerCount("TaskAskResponded")).toBe(0)
+ expect(task.listenerCount("Message")).toBe(0)
+ expect(task.listenerCount("TaskTokenUsageUpdated")).toBe(0)
+ expect(task.listenerCount("TaskToolFailed")).toBe(0)
+ expect(task.listenerCount("TaskUnpaused")).toBe(0)
+
+ // Verify total listener count is 0
+ expect(task.eventNames().length).toBe(0)
+ })
+})
diff --git a/src/core/tools/__tests__/multiApplyDiffTool.spec.ts b/src/core/tools/__tests__/multiApplyDiffTool.spec.ts
new file mode 100644
index 0000000000..0bdedb9cd5
--- /dev/null
+++ b/src/core/tools/__tests__/multiApplyDiffTool.spec.ts
@@ -0,0 +1,401 @@
+import { applyDiffTool } from "../multiApplyDiffTool"
+import { EXPERIMENT_IDS } from "../../../shared/experiments"
+import * as fs from "fs/promises"
+import * as fileUtils from "../../../utils/fs"
+import * as pathUtils from "../../../utils/path"
+
+// Mock dependencies
+vi.mock("fs/promises")
+vi.mock("../../../utils/fs")
+vi.mock("../../../utils/path")
+vi.mock("../../../utils/xml")
+vi.mock("../applyDiffTool", () => ({
+ applyDiffToolLegacy: vi.fn(),
+}))
+
+// Mock TelemetryService
+vi.mock("@roo-code/telemetry", () => ({
+ TelemetryService: {
+ get instance() {
+ return {
+ trackEvent: vi.fn(),
+ trackError: vi.fn(),
+ captureDiffApplicationError: vi.fn(),
+ }
+ },
+ },
+}))
+
+describe("multiApplyDiffTool", () => {
+ let mockCline: any
+ let mockBlock: any
+ let mockAskApproval: any
+ let mockHandleError: any
+ let mockPushToolResult: any
+ let mockRemoveClosingTag: any
+ let mockProvider: any
+
+ beforeEach(() => {
+ vi.clearAllMocks()
+
+ mockProvider = {
+ getState: vi.fn().mockResolvedValue({
+ experiments: {
+ [EXPERIMENT_IDS.MULTI_FILE_APPLY_DIFF]: true,
+ },
+ diagnosticsEnabled: true,
+ writeDelayMs: 0,
+ }),
+ }
+
+ mockCline = {
+ providerRef: {
+ deref: vi.fn().mockReturnValue(mockProvider),
+ },
+ cwd: "/test",
+ taskId: "test-task",
+ consecutiveMistakeCount: 0,
+ consecutiveMistakeCountForApplyDiff: new Map(),
+ recordToolError: vi.fn(),
+ say: vi.fn().mockResolvedValue(undefined),
+ sayAndCreateMissingParamError: vi.fn().mockResolvedValue("Missing parameter error"),
+ ask: vi.fn().mockResolvedValue({ response: "yesButtonClicked", text: "", images: [] }),
+ diffStrategy: {
+ applyDiff: vi.fn().mockResolvedValue({
+ success: true,
+ content: "modified content",
+ }),
+ getProgressStatus: vi.fn(),
+ },
+ diffViewProvider: {
+ reset: vi.fn().mockResolvedValue(undefined),
+ editType: undefined,
+ originalContent: undefined,
+ open: vi.fn().mockResolvedValue(undefined),
+ update: vi.fn().mockResolvedValue(undefined),
+ scrollToFirstDiff: vi.fn(),
+ saveDirectly: vi.fn().mockResolvedValue(undefined),
+ saveChanges: vi.fn().mockResolvedValue(undefined),
+ pushToolWriteResult: vi.fn().mockResolvedValue("File modified successfully"),
+ },
+ api: {
+ getModel: vi.fn().mockReturnValue({ id: "test-model" }),
+ },
+ rooIgnoreController: {
+ validateAccess: vi.fn().mockReturnValue(true),
+ },
+ rooProtectedController: {
+ isWriteProtected: vi.fn().mockReturnValue(false),
+ },
+ fileContextTracker: {
+ trackFileContext: vi.fn().mockResolvedValue(undefined),
+ },
+ didEditFile: false,
+ } as any
+
+ mockAskApproval = vi.fn().mockResolvedValue(true)
+ mockHandleError = vi.fn()
+ mockPushToolResult = vi.fn()
+ mockRemoveClosingTag = vi.fn((tag, value) => value)
+
+ // Mock file system operations
+ ;(fileUtils.fileExistsAtPath as any).mockResolvedValue(true)
+ ;(fs.readFile as any).mockResolvedValue("original content")
+ ;(pathUtils.getReadablePath as any).mockImplementation((cwd: string, path: string) => path)
+ })
+
+ describe("Early content validation", () => {
+ it("should filter out non-string content at parse time", async () => {
+ mockBlock = {
+ params: {
+ args: `
+ test.ts
+
+ valid string content
+
+ `,
+ },
+ partial: false,
+ }
+
+ // Mock parseXml to return mixed content types
+ const parseXml = await import("../../../utils/xml")
+ ;(parseXml.parseXml as any).mockReturnValue({
+ file: {
+ path: "test.ts",
+ diff: [
+ { content: "<<<<<<< SEARCH\ntest\n=======\nreplaced\n>>>>>>> REPLACE" },
+ { content: null },
+ { content: undefined },
+ { content: 42 },
+ { content: "" }, // Empty string should also be filtered
+ { content: "<<<<<<< SEARCH\nmore\n=======\nchanges\n>>>>>>> REPLACE" },
+ ],
+ },
+ })
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete without error and only process valid string content
+ expect(mockPushToolResult).toHaveBeenCalled()
+ expect(mockHandleError).not.toHaveBeenCalled()
+
+ // Verify that only valid diffs were processed
+ const resultCall = mockPushToolResult.mock.calls[0][0]
+ // Should not include the single block notice since we have 2 valid blocks
+ expect(resultCall).not.toContain("Making multiple related changes")
+ })
+ })
+
+ describe("SEARCH block counting with non-string content", () => {
+ it("should handle diffItem.content being undefined", async () => {
+ mockBlock = {
+ params: {
+ path: "test.ts",
+ diff: undefined, // This will result in undefined content
+ },
+ partial: false,
+ }
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete without throwing an error
+ expect(mockPushToolResult).toHaveBeenCalled()
+ expect(mockHandleError).not.toHaveBeenCalled()
+ })
+
+ it("should handle diffItem.content being null", async () => {
+ mockBlock = {
+ params: {
+ args: `
+ test.ts
+
+
+
+ `,
+ },
+ partial: false,
+ }
+
+ // Mock parseXml to return null content
+ const parseXml = await import("../../../utils/xml")
+ ;(parseXml.parseXml as any).mockReturnValue({
+ file: {
+ path: "test.ts",
+ diff: {
+ content: null,
+ },
+ },
+ })
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete without throwing an error
+ expect(mockPushToolResult).toHaveBeenCalled()
+ expect(mockHandleError).not.toHaveBeenCalled()
+ })
+
+ it("should handle diffItem.content being a number", async () => {
+ mockBlock = {
+ params: {
+ args: `
+ test.ts
+
+ 123
+
+ `,
+ },
+ partial: false,
+ }
+
+ // Mock parseXml to return number content
+ const parseXml = await import("../../../utils/xml")
+ ;(parseXml.parseXml as any).mockReturnValue({
+ file: {
+ path: "test.ts",
+ diff: {
+ content: 123, // Number instead of string
+ },
+ },
+ })
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete without throwing an error
+ expect(mockPushToolResult).toHaveBeenCalled()
+ expect(mockHandleError).not.toHaveBeenCalled()
+ })
+
+ it("should correctly count SEARCH blocks when content is a valid string", async () => {
+ const diffContent = `<<<<<<< SEARCH
+old content
+=======
+new content
+>>>>>>> REPLACE
+
+<<<<<<< SEARCH
+another old content
+=======
+another new content
+>>>>>>> REPLACE`
+
+ mockBlock = {
+ params: {
+ path: "test.ts",
+ diff: diffContent,
+ },
+ partial: false,
+ }
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete successfully
+ expect(mockPushToolResult).toHaveBeenCalled()
+ const resultCall = mockPushToolResult.mock.calls[0][0]
+ // Should not include the single block notice since we have 2 blocks
+ expect(resultCall).not.toContain("Making multiple related changes")
+ })
+
+ it("should show single block notice when only one SEARCH block exists", async () => {
+ const diffContent = `<<<<<<< SEARCH
+old content
+=======
+new content
+>>>>>>> REPLACE`
+
+ mockBlock = {
+ params: {
+ path: "test.ts",
+ diff: diffContent,
+ },
+ partial: false,
+ }
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete successfully
+ expect(mockPushToolResult).toHaveBeenCalled()
+ const resultCall = mockPushToolResult.mock.calls[0][0]
+ // Should include the single block notice
+ expect(resultCall).toContain("Making multiple related changes")
+ })
+ })
+
+ describe("Edge cases for diff content", () => {
+ it("should handle empty diff array", async () => {
+ mockBlock = {
+ params: {
+ args: `
+ test.ts
+
+ `,
+ },
+ partial: false,
+ }
+
+ const parseXml = await import("../../../utils/xml")
+ ;(parseXml.parseXml as any).mockReturnValue({
+ file: {
+ path: "test.ts",
+ diff: [],
+ },
+ })
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete without error
+ expect(mockPushToolResult).toHaveBeenCalled()
+ expect(mockHandleError).not.toHaveBeenCalled()
+ })
+
+ it("should handle mixed content types in diff array", async () => {
+ mockBlock = {
+ params: {
+ args: `
+ test.ts
+
+ valid string content
+
+ `,
+ },
+ partial: false,
+ }
+
+ const parseXml = await import("../../../utils/xml")
+ ;(parseXml.parseXml as any).mockReturnValue({
+ file: {
+ path: "test.ts",
+ diff: [
+ { content: "<<<<<<< SEARCH\ntest\n=======\nreplaced\n>>>>>>> REPLACE" },
+ { content: null },
+ { content: undefined },
+ { content: 42 },
+ { content: "<<<<<<< SEARCH\nmore\n=======\nchanges\n>>>>>>> REPLACE" },
+ ],
+ },
+ })
+
+ await applyDiffTool(
+ mockCline,
+ mockBlock,
+ mockAskApproval,
+ mockHandleError,
+ mockPushToolResult,
+ mockRemoveClosingTag,
+ )
+
+ // Should complete without error and count only valid string SEARCH blocks
+ expect(mockPushToolResult).toHaveBeenCalled()
+ expect(mockHandleError).not.toHaveBeenCalled()
+ })
+ })
+})
diff --git a/src/core/tools/codebaseSearchTool.ts b/src/core/tools/codebaseSearchTool.ts
index 236b066306..263fa8755e 100644
--- a/src/core/tools/codebaseSearchTool.ts
+++ b/src/core/tools/codebaseSearchTool.ts
@@ -17,7 +17,7 @@ export async function codebaseSearchTool(
removeClosingTag: RemoveClosingTag,
) {
const toolName = "codebase_search"
- const workspacePath = getWorkspacePath()
+ const workspacePath = cline.cwd && cline.cwd.trim() !== "" ? cline.cwd : getWorkspacePath()
if (!workspacePath) {
// This case should ideally not happen if Cline is initialized correctly
diff --git a/src/core/tools/multiApplyDiffTool.ts b/src/core/tools/multiApplyDiffTool.ts
index db514d2b64..50695b1da7 100644
--- a/src/core/tools/multiApplyDiffTool.ts
+++ b/src/core/tools/multiApplyDiffTool.ts
@@ -12,7 +12,7 @@ import { formatResponse } from "../prompts/responses"
import { fileExistsAtPath } from "../../utils/fs"
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
import { unescapeHtmlEntities } from "../../utils/text-normalization"
-import { parseXml } from "../../utils/xml"
+import { parseXmlForDiff } from "../../utils/xml"
import { EXPERIMENT_IDS, experiments } from "../../shared/experiments"
import { applyDiffToolLegacy } from "./applyDiffTool"
@@ -108,7 +108,10 @@ export async function applyDiffTool(
if (argsXmlTag) {
// Parse file entries from XML (new way)
try {
- const parsed = parseXml(argsXmlTag, ["file.diff.content"]) as ParsedXmlResult
+ // IMPORTANT: We use parseXmlForDiff here instead of parseXml to prevent HTML entity decoding
+ // This ensures exact character matching when comparing parsed content against original file content
+ // Without this, special characters like & would be decoded to & causing diff mismatches
+ const parsed = parseXmlForDiff(argsXmlTag, ["file.diff.content"]) as ParsedXmlResult
const files = Array.isArray(parsed.file) ? parsed.file : [parsed.file].filter(Boolean)
for (const file of files) {
@@ -132,13 +135,17 @@ export async function applyDiffTool(
let diffContent: string
let startLine: number | undefined
- diffContent = diff.content
+ // Ensure content is a string before storing it
+ diffContent = typeof diff.content === "string" ? diff.content : ""
startLine = diff.start_line ? parseInt(diff.start_line) : undefined
- operationsMap[filePath].diff.push({
- content: diffContent,
- startLine,
- })
+ // Only add to operations if we have valid content
+ if (diffContent) {
+ operationsMap[filePath].diff.push({
+ content: diffContent,
+ startLine,
+ })
+ }
}
}
} catch (error) {
diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts
index 677fdab543..3965d9428e 100644
--- a/src/core/webview/ClineProvider.ts
+++ b/src/core/webview/ClineProvider.ts
@@ -24,18 +24,16 @@ import {
type TerminalActionId,
type TerminalActionPromptType,
type HistoryItem,
- type CloudUserInfo,
type InitTaskOptions,
RooCodeEventName,
requestyDefaultModelId,
openRouterDefaultModelId,
glamaDefaultModelId,
- ORGANIZATION_ALLOW_ALL,
DEFAULT_TERMINAL_OUTPUT_CHARACTER_LIMIT,
DEFAULT_WRITE_DELAY_MS,
} from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
-import { CloudService, getRooCodeApiUrl } from "@roo-code/cloud"
+import { type CloudUserInfo, CloudService, ORGANIZATION_ALLOW_ALL, getRooCodeApiUrl } from "@roo-code/cloud"
import { Package } from "../../shared/package"
import { findLast } from "../../shared/array"
@@ -563,18 +561,16 @@ export class ClineProvider
this.log("Resolving webview view")
this.view = webviewView
-
- // Set panel reference according to webview type
const inTabMode = "onDidChangeViewState" in webviewView
+
if (inTabMode) {
- // Tag page type
setPanel(webviewView, "tab")
} else if ("onDidChangeVisibility" in webviewView) {
- // Sidebar Type
setPanel(webviewView, "sidebar")
}
- // Initialize out-of-scope variables that need to receive persistent global state values
+ // Initialize out-of-scope variables that need to receive persistent
+ // global state values.
this.getState().then(
({
terminalShellIntegrationTimeout = Terminal.defaultShellIntegrationTimeout,
@@ -597,18 +593,15 @@ export class ClineProvider
},
)
- // Initialize tts enabled state
this.getState().then(({ ttsEnabled }) => {
setTtsEnabled(ttsEnabled ?? false)
})
- // Initialize tts speed state
this.getState().then(({ ttsSpeed }) => {
setTtsSpeed(ttsSpeed ?? 1)
})
webviewView.webview.options = {
- // Allow scripts in the webview
enableScripts: true,
localResourceRoots: [this.contextProxy.extensionUri],
}
@@ -619,32 +612,31 @@ export class ClineProvider
: this.getHtmlContent(webviewView.webview)
// Sets up an event listener to listen for messages passed from the webview view context
- // and executes code based on the message that is received
+ // and executes code based on the message that is received.
this.setWebviewMessageListener(webviewView.webview)
- // Initialize code index status subscription for the current workspace
+ // Initialize code index status subscription for the current workspace.
this.updateCodeIndexStatusSubscription()
- // Listen for active editor changes to update code index status for the current workspace
+ // Listen for active editor changes to update code index status for the
+ // current workspace.
const activeEditorSubscription = vscode.window.onDidChangeActiveTextEditor(() => {
- // Update subscription when workspace might have changed
+ // Update subscription when workspace might have changed.
this.updateCodeIndexStatusSubscription()
})
this.webviewDisposables.push(activeEditorSubscription)
- // Logs show up in bottom panel > Debug Console
- //console.log("registering listener")
-
- // Listen for when the panel becomes visible
+ // Listen for when the panel becomes visible.
// https://github.com/microsoft/vscode-discussions/discussions/840
if ("onDidChangeViewState" in webviewView) {
- // WebviewView and WebviewPanel have all the same properties except for this visibility listener
- // panel
+ // WebviewView and WebviewPanel have all the same properties except
+ // for this visibility listener panel.
const viewStateDisposable = webviewView.onDidChangeViewState(() => {
if (this.view?.visible) {
this.postMessageToWebview({ type: "action", action: "didBecomeVisible" })
}
})
+
this.webviewDisposables.push(viewStateDisposable)
} else if ("onDidChangeVisibility" in webviewView) {
// sidebar
@@ -653,6 +645,7 @@ export class ClineProvider
this.postMessageToWebview({ type: "action", action: "didBecomeVisible" })
}
})
+
this.webviewDisposables.push(visibilityDisposable)
}
@@ -856,8 +849,8 @@ export class ClineProvider
}
private async getHMRHtmlContent(webview: vscode.Webview): Promise {
- // Try to read the port from the file
- let localPort = "5173" // Default fallback
+ let localPort = "5173"
+
try {
const fs = require("fs")
const path = require("path")
@@ -873,7 +866,6 @@ export class ClineProvider
}
} catch (err) {
console.error("[ClineProvider:Vite] Failed to read Vite port file:", err)
- // Continue with default port if file reading fails
}
const localServerUrl = `localhost:${localPort}`
@@ -883,7 +875,6 @@ export class ClineProvider
await axios.get(`http://${localServerUrl}`)
} catch (error) {
vscode.window.showErrorMessage(t("common:errors.hmr_not_running"))
-
return this.getHtmlContent(webview)
}
@@ -2148,12 +2139,8 @@ export class ClineProvider
return true
}
- /**
- * Handle remote control enabled/disabled state changes
- * Manages UnifiedBridgeService lifecycle
- */
public async handleRemoteControlToggle(enabled: boolean) {
- const { CloudService: CloudServiceImport, UnifiedBridgeService } = await import("@roo-code/cloud")
+ const { CloudService: CloudServiceImport, ExtensionBridgeService } = await import("@roo-code/cloud")
const userInfo = CloudServiceImport.instance.getUserInfo()
@@ -2164,10 +2151,10 @@ export class ClineProvider
return
}
- await UnifiedBridgeService.handleRemoteControlState(
+ await ExtensionBridgeService.handleRemoteControlState(
userInfo,
enabled,
- { ...bridgeConfig, provider: this },
+ { ...bridgeConfig, provider: this, sessionId: vscode.env.sessionId },
(message: string) => this.log(message),
)
@@ -2176,7 +2163,7 @@ export class ClineProvider
if (currentTask && !currentTask.bridgeService) {
try {
- currentTask.bridgeService = UnifiedBridgeService.getInstance()
+ currentTask.bridgeService = ExtensionBridgeService.getInstance()
if (currentTask.bridgeService) {
await currentTask.bridgeService.subscribeToTask(currentTask)
@@ -2201,7 +2188,7 @@ export class ClineProvider
}
}
- UnifiedBridgeService.resetInstance()
+ ExtensionBridgeService.resetInstance()
}
}
diff --git a/src/core/webview/__tests__/ClineProvider.spec.ts b/src/core/webview/__tests__/ClineProvider.spec.ts
index 33e8853deb..dbe0c346fc 100644
--- a/src/core/webview/__tests__/ClineProvider.spec.ts
+++ b/src/core/webview/__tests__/ClineProvider.spec.ts
@@ -4,8 +4,9 @@ import Anthropic from "@anthropic-ai/sdk"
import * as vscode from "vscode"
import axios from "axios"
-import { type ProviderSettingsEntry, type ClineMessage, ORGANIZATION_ALLOW_ALL } from "@roo-code/types"
+import { type ProviderSettingsEntry, type ClineMessage } from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
+import { ORGANIZATION_ALLOW_ALL } from "@roo-code/cloud"
import { ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage"
import { defaultModeSlug } from "../../../shared/modes"
@@ -17,11 +18,9 @@ import { safeWriteJson } from "../../../utils/safeWriteJson"
import { ClineProvider } from "../ClineProvider"
-// Mock setup must come before imports
+// Mock setup must come before imports.
vi.mock("../../prompts/sections/custom-instructions")
-vi.mock("vscode")
-
vi.mock("p-wait-for", () => ({
__esModule: true,
default: vi.fn().mockResolvedValue(undefined),
@@ -95,7 +94,7 @@ vi.mock("../../../services/browser/browserDiscovery", () => ({
testBrowserConnection: vi.fn(),
}))
-// Remove duplicate mock - it's already defined below
+// Remove duplicate mock - it's already defined below.
const mockAddCustomInstructions = vi.fn().mockResolvedValue("Combined instructions")
@@ -228,7 +227,6 @@ vi.mock("../../../integrations/misc/extract-text", () => ({
}),
}))
-// Mock getModels for router model tests
vi.mock("../../../api/providers/fetchers/modelCache", () => ({
getModels: vi.fn().mockResolvedValue({}),
flushModels: vi.fn(),
@@ -324,6 +322,10 @@ vi.mock("@roo-code/cloud", () => ({
},
},
getRooCodeApiUrl: vi.fn().mockReturnValue("https://app.roocode.com"),
+ ORGANIZATION_ALLOW_ALL: {
+ allowAll: true,
+ providers: {},
+ },
}))
afterAll(() => {
diff --git a/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts b/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts
index e55e0910ab..99285bb68e 100644
--- a/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts
+++ b/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts
@@ -7,7 +7,6 @@ import { ContextProxy } from "../../config/ContextProxy"
import { Task } from "../../task/Task"
import type { HistoryItem, ProviderName } from "@roo-code/types"
-// Mock setup
vi.mock("vscode", () => ({
ExtensionContext: vi.fn(),
OutputChannel: vi.fn(),
@@ -54,7 +53,8 @@ vi.mock("vscode", () => ({
},
version: "1.85.0",
}))
-// Create a counter for unique task IDs
+
+// Create a counter for unique task IDs.
let taskIdCounter = 0
vi.mock("../../task/Task", () => ({
@@ -75,8 +75,11 @@ vi.mock("../../task/Task", () => ({
parentTask: options.parentTask,
})),
}))
+
vi.mock("../../prompts/sections/custom-instructions")
+
vi.mock("../../../utils/safeWriteJson")
+
vi.mock("../../../api", () => ({
buildApiHandler: vi.fn().mockReturnValue({
getModel: vi.fn().mockReturnValue({
@@ -85,12 +88,14 @@ vi.mock("../../../api", () => ({
}),
}),
}))
+
vi.mock("../../../integrations/workspace/WorkspaceTracker", () => ({
default: vi.fn().mockImplementation(() => ({
initializeFilePaths: vi.fn(),
dispose: vi.fn(),
})),
}))
+
vi.mock("../../diff/strategies/multi-search-replace", () => ({
MultiSearchReplaceDiffStrategy: vi.fn().mockImplementation(() => ({
getToolDescription: () => "test",
@@ -98,6 +103,7 @@ vi.mock("../../diff/strategies/multi-search-replace", () => ({
applyDiff: vi.fn(),
})),
}))
+
vi.mock("@roo-code/cloud", () => ({
CloudService: {
hasInstance: vi.fn().mockReturnValue(true),
@@ -108,7 +114,12 @@ vi.mock("@roo-code/cloud", () => ({
},
},
getRooCodeApiUrl: vi.fn().mockReturnValue("https://app.roocode.com"),
+ ORGANIZATION_ALLOW_ALL: {
+ allowAll: true,
+ providers: {},
+ },
}))
+
vi.mock("../../../shared/modes", () => ({
modes: [
{
@@ -132,20 +143,25 @@ vi.mock("../../../shared/modes", () => ({
}),
defaultModeSlug: "code",
}))
+
vi.mock("../../prompts/system", () => ({
SYSTEM_PROMPT: vi.fn().mockResolvedValue("mocked system prompt"),
codeMode: "code",
}))
+
vi.mock("../../../api/providers/fetchers/modelCache", () => ({
getModels: vi.fn().mockResolvedValue({}),
flushModels: vi.fn(),
}))
+
vi.mock("../../../integrations/misc/extract-text", () => ({
extractTextFromFile: vi.fn().mockResolvedValue("Mock file content"),
}))
+
vi.mock("p-wait-for", () => ({
default: vi.fn().mockImplementation(async () => Promise.resolve()),
}))
+
vi.mock("fs/promises", () => ({
mkdir: vi.fn().mockResolvedValue(undefined),
writeFile: vi.fn().mockResolvedValue(undefined),
@@ -153,6 +169,7 @@ vi.mock("fs/promises", () => ({
unlink: vi.fn().mockResolvedValue(undefined),
rmdir: vi.fn().mockResolvedValue(undefined),
}))
+
vi.mock("@roo-code/telemetry", () => ({
TelemetryService: {
hasInstance: vi.fn().mockReturnValue(true),
diff --git a/src/extension.ts b/src/extension.ts
index 767e83c42d..6cb6ea4b07 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -12,7 +12,7 @@ try {
console.warn("Failed to load environment variables:", e)
}
-import { CloudService, UnifiedBridgeService } from "@roo-code/cloud"
+import { CloudService, ExtensionBridgeService } from "@roo-code/cloud"
import { TelemetryService, PostHogTelemetryClient } from "@roo-code/telemetry"
import "./utils/path" // Necessary to have access to String.prototype.toPosix.
@@ -141,10 +141,10 @@ export async function activate(context: vscode.ExtensionContext) {
return
}
- UnifiedBridgeService.handleRemoteControlState(
+ ExtensionBridgeService.handleRemoteControlState(
userInfo,
contextProxy.getValue("remoteControlEnabled"),
- { ...bridgeConfig, provider },
+ { ...bridgeConfig, provider, sessionId: vscode.env.sessionId },
(message: string) => outputChannel.appendLine(message),
)
})
@@ -280,7 +280,7 @@ export async function activate(context: vscode.ExtensionContext) {
export async function deactivate() {
outputChannel.appendLine(`${Package.name} extension deactivated`)
- const bridgeService = UnifiedBridgeService.getInstance()
+ const bridgeService = ExtensionBridgeService.getInstance()
if (bridgeService) {
await bridgeService.disconnect()
diff --git a/src/package.json b/src/package.json
index 94b711fc5b..084e42e08e 100644
--- a/src/package.json
+++ b/src/package.json
@@ -3,7 +3,7 @@
"displayName": "%extension.displayName%",
"description": "%extension.description%",
"publisher": "RooVeterinaryInc",
- "version": "3.25.11",
+ "version": "3.25.15",
"icon": "assets/icons/icon.png",
"galleryBanner": {
"color": "#617A91",
@@ -102,7 +102,7 @@
},
{
"command": "roo-cline.accountButtonClicked",
- "title": "Account",
+ "title": "%command.account.title%",
"icon": "$(account)"
},
{
@@ -427,7 +427,7 @@
"@mistralai/mistralai": "^1.3.6",
"@modelcontextprotocol/sdk": "^1.9.0",
"@qdrant/js-client-rest": "^1.14.0",
- "@roo-code/cloud": "^0.11.0",
+ "@roo-code/cloud": "^0.14.0",
"@roo-code/ipc": "workspace:^",
"@roo-code/telemetry": "workspace:^",
"@roo-code/types": "workspace:^",
@@ -474,6 +474,7 @@
"say": "^0.16.0",
"serialize-error": "^12.0.0",
"simple-git": "^3.27.0",
+ "socket.io-client": "^4.8.1",
"sound-play": "^1.1.0",
"stream-json": "^1.8.0",
"string-similarity": "^4.0.4",
diff --git a/src/package.nls.ca.json b/src/package.nls.ca.json
index 90cba19454..1e2f1eedd6 100644
--- a/src/package.nls.ca.json
+++ b/src/package.nls.ca.json
@@ -23,6 +23,7 @@
"command.history.title": "Historial",
"command.marketplace.title": "Mercat",
"command.openInEditor.title": "Obrir a l'Editor",
+ "command.account.title": "Compte",
"command.settings.title": "Configuració",
"command.documentation.title": "Documentació",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.de.json b/src/package.nls.de.json
index 09d9ac760f..b5f099ff66 100644
--- a/src/package.nls.de.json
+++ b/src/package.nls.de.json
@@ -23,6 +23,7 @@
"command.history.title": "Verlauf",
"command.marketplace.title": "Marktplatz",
"command.openInEditor.title": "Im Editor Öffnen",
+ "command.account.title": "Konto",
"command.settings.title": "Einstellungen",
"command.documentation.title": "Dokumentation",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.es.json b/src/package.nls.es.json
index 28d1250bdd..a2479cd770 100644
--- a/src/package.nls.es.json
+++ b/src/package.nls.es.json
@@ -23,6 +23,7 @@
"command.history.title": "Historial",
"command.marketplace.title": "Mercado",
"command.openInEditor.title": "Abrir en Editor",
+ "command.account.title": "Cuenta",
"command.settings.title": "Configuración",
"command.documentation.title": "Documentación",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.fr.json b/src/package.nls.fr.json
index 7d528bf0a6..03052aaf75 100644
--- a/src/package.nls.fr.json
+++ b/src/package.nls.fr.json
@@ -23,6 +23,7 @@
"command.history.title": "Historique",
"command.marketplace.title": "Marché",
"command.openInEditor.title": "Ouvrir dans l'Éditeur",
+ "command.account.title": "Compte",
"command.settings.title": "Paramètres",
"command.documentation.title": "Documentation",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.hi.json b/src/package.nls.hi.json
index a3dc74ae2b..24f8ed402d 100644
--- a/src/package.nls.hi.json
+++ b/src/package.nls.hi.json
@@ -23,6 +23,7 @@
"command.history.title": "इतिहास",
"command.marketplace.title": "मार्केटप्लेस",
"command.openInEditor.title": "एडिटर में खोलें",
+ "command.account.title": "खाता",
"command.settings.title": "सेटिंग्स",
"command.documentation.title": "दस्तावेज़ीकरण",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.id.json b/src/package.nls.id.json
index 2560899f61..98e979ee07 100644
--- a/src/package.nls.id.json
+++ b/src/package.nls.id.json
@@ -11,6 +11,7 @@
"command.history.title": "Riwayat",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Buka di Editor",
+ "command.account.title": "Akun",
"command.settings.title": "Pengaturan",
"command.documentation.title": "Dokumentasi",
"command.openInNewTab.title": "Buka di Tab Baru",
diff --git a/src/package.nls.it.json b/src/package.nls.it.json
index 4c6f6a1602..6f8bb8fbce 100644
--- a/src/package.nls.it.json
+++ b/src/package.nls.it.json
@@ -23,6 +23,7 @@
"command.history.title": "Cronologia",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Apri nell'Editor",
+ "command.account.title": "Account",
"command.settings.title": "Impostazioni",
"command.documentation.title": "Documentazione",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.ja.json b/src/package.nls.ja.json
index 1db66a75ab..c26c46905d 100644
--- a/src/package.nls.ja.json
+++ b/src/package.nls.ja.json
@@ -11,6 +11,7 @@
"command.history.title": "履歴",
"command.marketplace.title": "マーケットプレイス",
"command.openInEditor.title": "エディタで開く",
+ "command.account.title": "アカウント",
"command.settings.title": "設定",
"command.documentation.title": "ドキュメント",
"command.openInNewTab.title": "新しいタブで開く",
diff --git a/src/package.nls.json b/src/package.nls.json
index 0cd834b132..f1c132be65 100644
--- a/src/package.nls.json
+++ b/src/package.nls.json
@@ -11,6 +11,7 @@
"command.history.title": "History",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Open in Editor",
+ "command.account.title": "Account",
"command.settings.title": "Settings",
"command.documentation.title": "Documentation",
"command.openInNewTab.title": "Open In New Tab",
diff --git a/src/package.nls.ko.json b/src/package.nls.ko.json
index db14b2387f..b4d5dd4c14 100644
--- a/src/package.nls.ko.json
+++ b/src/package.nls.ko.json
@@ -23,6 +23,7 @@
"command.history.title": "기록",
"command.marketplace.title": "마켓플레이스",
"command.openInEditor.title": "에디터에서 열기",
+ "command.account.title": "계정",
"command.settings.title": "설정",
"command.documentation.title": "문서",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.nl.json b/src/package.nls.nl.json
index 7bc02b1db2..22d9102f18 100644
--- a/src/package.nls.nl.json
+++ b/src/package.nls.nl.json
@@ -11,6 +11,7 @@
"command.history.title": "Geschiedenis",
"command.marketplace.title": "Marktplaats",
"command.openInEditor.title": "Openen in Editor",
+ "command.account.title": "Account",
"command.settings.title": "Instellingen",
"command.documentation.title": "Documentatie",
"command.openInNewTab.title": "Openen in Nieuw Tabblad",
diff --git a/src/package.nls.pl.json b/src/package.nls.pl.json
index 09cd69b043..cb23404330 100644
--- a/src/package.nls.pl.json
+++ b/src/package.nls.pl.json
@@ -23,6 +23,7 @@
"command.history.title": "Historia",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Otwórz w Edytorze",
+ "command.account.title": "Konto",
"command.settings.title": "Ustawienia",
"command.documentation.title": "Dokumentacja",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.pt-BR.json b/src/package.nls.pt-BR.json
index 1d24259b0c..e3b432e1d5 100644
--- a/src/package.nls.pt-BR.json
+++ b/src/package.nls.pt-BR.json
@@ -23,6 +23,7 @@
"command.history.title": "Histórico",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Abrir no Editor",
+ "command.account.title": "Conta",
"command.settings.title": "Configurações",
"command.documentation.title": "Documentação",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.ru.json b/src/package.nls.ru.json
index ffa94cfb30..91da74c6f1 100644
--- a/src/package.nls.ru.json
+++ b/src/package.nls.ru.json
@@ -11,6 +11,7 @@
"command.history.title": "История",
"command.marketplace.title": "Маркетплейс",
"command.openInEditor.title": "Открыть в редакторе",
+ "command.account.title": "Аккаунт",
"command.settings.title": "Настройки",
"command.documentation.title": "Документация",
"command.openInNewTab.title": "Открыть в новой вкладке",
diff --git a/src/package.nls.tr.json b/src/package.nls.tr.json
index d01702de48..5337db6bb4 100644
--- a/src/package.nls.tr.json
+++ b/src/package.nls.tr.json
@@ -23,6 +23,7 @@
"command.history.title": "Geçmiş",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Düzenleyicide Aç",
+ "command.account.title": "Hesap",
"command.settings.title": "Ayarlar",
"command.documentation.title": "Dokümantasyon",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.vi.json b/src/package.nls.vi.json
index 667f82101a..f8c79b748a 100644
--- a/src/package.nls.vi.json
+++ b/src/package.nls.vi.json
@@ -23,6 +23,7 @@
"command.history.title": "Lịch Sử",
"command.marketplace.title": "Marketplace",
"command.openInEditor.title": "Mở trong Trình Soạn Thảo",
+ "command.account.title": "Tài khoản",
"command.settings.title": "Cài Đặt",
"command.documentation.title": "Tài Liệu",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.zh-CN.json b/src/package.nls.zh-CN.json
index c44bdee5c9..1ea96e772a 100644
--- a/src/package.nls.zh-CN.json
+++ b/src/package.nls.zh-CN.json
@@ -23,6 +23,7 @@
"command.history.title": "历史记录",
"command.marketplace.title": "应用市场",
"command.openInEditor.title": "在编辑器中打开",
+ "command.account.title": "账户",
"command.settings.title": "设置",
"command.documentation.title": "文档",
"configuration.title": "Roo Code",
diff --git a/src/package.nls.zh-TW.json b/src/package.nls.zh-TW.json
index a84e44d598..815a061160 100644
--- a/src/package.nls.zh-TW.json
+++ b/src/package.nls.zh-TW.json
@@ -23,6 +23,7 @@
"command.history.title": "歷史記錄",
"command.marketplace.title": "應用市場",
"command.openInEditor.title": "在編輯器中開啟",
+ "command.account.title": "帳戶",
"command.settings.title": "設定",
"command.documentation.title": "文件",
"configuration.title": "Roo Code",
diff --git a/src/services/code-index/__tests__/manager.spec.ts b/src/services/code-index/__tests__/manager.spec.ts
index 49f725f69b..929f6f93c8 100644
--- a/src/services/code-index/__tests__/manager.spec.ts
+++ b/src/services/code-index/__tests__/manager.spec.ts
@@ -19,7 +19,14 @@ vi.mock("vscode", () => {
index: 0,
},
],
+ createFileSystemWatcher: vi.fn().mockReturnValue({
+ onDidCreate: vi.fn().mockReturnValue({ dispose: vi.fn() }),
+ onDidChange: vi.fn().mockReturnValue({ dispose: vi.fn() }),
+ onDidDelete: vi.fn().mockReturnValue({ dispose: vi.fn() }),
+ dispose: vi.fn(),
+ }),
},
+ RelativePattern: vi.fn().mockImplementation((base, pattern) => ({ base, pattern })),
}
})
@@ -32,6 +39,26 @@ vi.mock("../../../utils/path", () => {
}
})
+// Mock fs/promises for RooIgnoreController
+vi.mock("fs/promises", () => ({
+ default: {
+ readFile: vi.fn().mockRejectedValue(new Error("File not found")), // Simulate no .gitignore/.rooignore
+ },
+}))
+
+// Mock file utils for RooIgnoreController
+vi.mock("../../../utils/fs", () => ({
+ fileExistsAtPath: vi.fn().mockResolvedValue(false), // Simulate no .rooignore file
+}))
+
+// Mock ignore module
+vi.mock("ignore", () => ({
+ default: vi.fn().mockReturnValue({
+ add: vi.fn(),
+ ignores: vi.fn().mockReturnValue(false),
+ }),
+}))
+
vi.mock("../state-manager", () => ({
CodeIndexStateManager: vi.fn().mockImplementation(() => ({
onProgressUpdate: vi.fn(),
diff --git a/src/services/code-index/manager.ts b/src/services/code-index/manager.ts
index 1257b747c6..d82760533d 100644
--- a/src/services/code-index/manager.ts
+++ b/src/services/code-index/manager.ts
@@ -9,6 +9,7 @@ import { CodeIndexServiceFactory } from "./service-factory"
import { CodeIndexSearchService } from "./search-service"
import { CodeIndexOrchestrator } from "./orchestrator"
import { CacheManager } from "./cache-manager"
+import { RooIgnoreController } from "../../core/ignore/RooIgnoreController"
import fs from "fs/promises"
import ignore from "ignore"
import path from "path"
@@ -312,6 +313,7 @@ export class CodeIndexManager {
return
}
+ // Create .gitignore instance
const ignorePath = path.join(workspacePath, ".gitignore")
try {
const content = await fs.readFile(ignorePath, "utf8")
@@ -327,11 +329,16 @@ export class CodeIndexManager {
})
}
+ // Create RooIgnoreController instance
+ const rooIgnoreController = new RooIgnoreController(workspacePath)
+ await rooIgnoreController.initialize()
+
// (Re)Create shared service instances
const { embedder, vectorStore, scanner, fileWatcher } = this._serviceFactory.createServices(
this.context,
this._cacheManager!,
ignoreInstance,
+ rooIgnoreController,
)
// Validate embedder configuration before proceeding
diff --git a/src/services/code-index/service-factory.ts b/src/services/code-index/service-factory.ts
index 68b0f5c0bc..5c1c366107 100644
--- a/src/services/code-index/service-factory.ts
+++ b/src/services/code-index/service-factory.ts
@@ -10,6 +10,7 @@ import { codeParser, DirectoryScanner, FileWatcher } from "./processors"
import { ICodeParser, IEmbedder, IFileWatcher, IVectorStore } from "./interfaces"
import { CodeIndexConfigManager } from "./config-manager"
import { CacheManager } from "./cache-manager"
+import { RooIgnoreController } from "../../core/ignore/RooIgnoreController"
import { Ignore } from "ignore"
import { t } from "../../i18n"
import { TelemetryService } from "@roo-code/telemetry"
@@ -161,8 +162,17 @@ export class CodeIndexServiceFactory {
vectorStore: IVectorStore,
cacheManager: CacheManager,
ignoreInstance: Ignore,
+ rooIgnoreController?: RooIgnoreController,
): IFileWatcher {
- return new FileWatcher(this.workspacePath, context, cacheManager, embedder, vectorStore, ignoreInstance)
+ return new FileWatcher(
+ this.workspacePath,
+ context,
+ cacheManager,
+ embedder,
+ vectorStore,
+ ignoreInstance,
+ rooIgnoreController,
+ )
}
/**
@@ -173,6 +183,7 @@ export class CodeIndexServiceFactory {
context: vscode.ExtensionContext,
cacheManager: CacheManager,
ignoreInstance: Ignore,
+ rooIgnoreController?: RooIgnoreController,
): {
embedder: IEmbedder
vectorStore: IVectorStore
@@ -188,7 +199,14 @@ export class CodeIndexServiceFactory {
const vectorStore = this.createVectorStore()
const parser = codeParser
const scanner = this.createDirectoryScanner(embedder, vectorStore, parser, ignoreInstance)
- const fileWatcher = this.createFileWatcher(context, embedder, vectorStore, cacheManager, ignoreInstance)
+ const fileWatcher = this.createFileWatcher(
+ context,
+ embedder,
+ vectorStore,
+ cacheManager,
+ ignoreInstance,
+ rooIgnoreController,
+ )
return {
embedder,
diff --git a/src/services/marketplace/MarketplaceManager.ts b/src/services/marketplace/MarketplaceManager.ts
index 800eba62e0..0227cdb79d 100644
--- a/src/services/marketplace/MarketplaceManager.ts
+++ b/src/services/marketplace/MarketplaceManager.ts
@@ -4,9 +4,9 @@ import * as path from "path"
import * as vscode from "vscode"
import * as yaml from "yaml"
-import type { MarketplaceItem, MarketplaceItemType, McpMarketplaceItem, OrganizationSettings } from "@roo-code/types"
+import type { MarketplaceItem, MarketplaceItemType, McpMarketplaceItem } from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
-import { CloudService } from "@roo-code/cloud"
+import { type OrganizationSettings, CloudService } from "@roo-code/cloud"
import { GlobalFileNames } from "../../shared/globalFileNames"
import { ensureSettingsDirectoryExists } from "../../utils/globalContext"
diff --git a/src/services/ripgrep/index.ts b/src/services/ripgrep/index.ts
index c694221966..d384b27c91 100644
--- a/src/services/ripgrep/index.ts
+++ b/src/services/ripgrep/index.ts
@@ -150,7 +150,7 @@ export async function regexSearchFiles(
throw new Error("Could not find ripgrep binary")
}
- const args = ["--json", "-e", regex, "--glob", filePattern || "*", "--context", "1", directoryPath]
+ const args = ["--json", "-e", regex, "--glob", filePattern || "*", "--context", "1", "--no-messages", directoryPath]
let output: string
try {
diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts
index f9ac305e07..ebdc137432 100644
--- a/src/shared/ExtensionMessage.ts
+++ b/src/shared/ExtensionMessage.ts
@@ -7,17 +7,15 @@ import type {
TelemetrySetting,
Experiments,
ClineMessage,
- OrganizationAllowList,
- CloudUserInfo,
- ShareVisibility,
+ MarketplaceItem,
} from "@roo-code/types"
+import type { CloudUserInfo, OrganizationAllowList, ShareVisibility } from "@roo-code/cloud"
import { GitCommit } from "../utils/git"
import { McpServer } from "./mcp"
import { Mode } from "./modes"
import { ModelRecord, RouterModels } from "./api"
-import type { MarketplaceItem } from "@roo-code/types"
// Command interface for frontend/backend communication
export interface Command {
diff --git a/src/shared/ProfileValidator.ts b/src/shared/ProfileValidator.ts
index 5a7c1da8bd..afdf1b5232 100644
--- a/src/shared/ProfileValidator.ts
+++ b/src/shared/ProfileValidator.ts
@@ -1,4 +1,5 @@
-import { OrganizationAllowList, ProviderSettings } from "@roo-code/types"
+import type { ProviderSettings } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo-code/cloud"
export class ProfileValidator {
public static isProfileAllowed(profile: ProviderSettings, allowList: OrganizationAllowList): boolean {
diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts
index 2d94896bf5..d59ccd556c 100644
--- a/src/shared/WebviewMessage.ts
+++ b/src/shared/WebviewMessage.ts
@@ -1,14 +1,14 @@
import { z } from "zod"
-import type {
- ProviderSettings,
- PromptComponent,
- ModeConfig,
- InstallMarketplaceItemOptions,
- MarketplaceItem,
- ShareVisibility,
+import {
+ type ProviderSettings,
+ type PromptComponent,
+ type ModeConfig,
+ type InstallMarketplaceItemOptions,
+ type MarketplaceItem,
+ marketplaceItemSchema,
} from "@roo-code/types"
-import { marketplaceItemSchema } from "@roo-code/types"
+import type { ShareVisibility } from "@roo-code/cloud"
import { Mode } from "./modes"
diff --git a/src/shared/__tests__/ProfileValidator.spec.ts b/src/shared/__tests__/ProfileValidator.spec.ts
index f606fdce99..0129f8fc20 100644
--- a/src/shared/__tests__/ProfileValidator.spec.ts
+++ b/src/shared/__tests__/ProfileValidator.spec.ts
@@ -1,6 +1,7 @@
// npx vitest run src/shared/__tests__/ProfileValidator.spec.ts
-import { OrganizationAllowList, ProviderSettings } from "@roo-code/types"
+import { type ProviderSettings } from "@roo-code/types"
+import { type OrganizationAllowList } from "@roo-code/cloud"
import { ProfileValidator } from "../ProfileValidator"
diff --git a/src/shared/cloud.ts b/src/shared/cloud.ts
new file mode 100644
index 0000000000..9adf9294a0
--- /dev/null
+++ b/src/shared/cloud.ts
@@ -0,0 +1,8 @@
+import { CloudUserInfo, OrganizationAllowList, ShareVisibility } from "@roo-code/cloud"
+
+export type { CloudUserInfo, OrganizationAllowList, ShareVisibility }
+
+export const ORGANIZATION_ALLOW_ALL: OrganizationAllowList = {
+ allowAll: true,
+ providers: {},
+} as const
diff --git a/src/utils/__tests__/xml.spec.ts b/src/utils/__tests__/xml.spec.ts
index 0e43cf04a1..f7a282b0c0 100644
--- a/src/utils/__tests__/xml.spec.ts
+++ b/src/utils/__tests__/xml.spec.ts
@@ -1,4 +1,4 @@
-import { parseXml } from "../xml"
+import { parseXml, parseXmlForDiff } from "../xml"
describe("parseXml", () => {
describe("type conversion", () => {
@@ -115,3 +115,126 @@ describe("parseXml", () => {
})
})
})
+
+describe("parseXmlForDiff", () => {
+ describe("HTML entity handling", () => {
+ it("should NOT decode HTML entities like &", () => {
+ const xml = `
+
+ Team Identity & Project Positioning
+
+ `
+
+ const result = parseXmlForDiff(xml) as any
+
+ // The & should remain as-is, not be decoded to &
+ expect(result.root.content).toBe("Team Identity & Project Positioning")
+ })
+
+ it("should preserve & character without encoding", () => {
+ const xml = `
+
+ Team Identity & Project Positioning
+
+ `
+
+ const result = parseXmlForDiff(xml) as any
+
+ // The & should remain as-is
+ expect(result.root.content).toBe("Team Identity & Project Positioning")
+ })
+
+ it("should NOT decode other HTML entities", () => {
+ const xml = `
+
+ <div> "Hello" 'World'
+
+ `
+
+ const result = parseXmlForDiff(xml) as any
+
+ // All HTML entities should remain as-is
+ expect(result.root.content).toBe("<div> "Hello" 'World'")
+ })
+
+ it("should handle mixed content with entities correctly", () => {
+ const xml = `
+
+ if (a < b && c > d) { return "test"; }
+
+ `
+
+ const result = parseXmlForDiff(xml) as any
+
+ // All entities should remain unchanged
+ expect(result.root.code).toBe("if (a < b && c > d) { return "test"; }")
+ })
+ })
+
+ describe("basic functionality (same as parseXml)", () => {
+ it("should correctly parse a simple XML string", () => {
+ const xml = `
+
+ Test Name
+ Some description
+
+ `
+
+ const result = parseXmlForDiff(xml) as any
+
+ expect(result).toHaveProperty("root")
+ expect(result.root).toHaveProperty("name", "Test Name")
+ expect(result.root).toHaveProperty("description", "Some description")
+ })
+
+ it("should handle attributes correctly", () => {
+ const xml = `
+
+ - Item content
+
+ `
+
+ const result = parseXmlForDiff(xml) as any
+
+ expect(result.root.item).toHaveProperty("@_id", "1")
+ expect(result.root.item).toHaveProperty("@_category", "test")
+ expect(result.root.item).toHaveProperty("#text", "Item content")
+ })
+
+ it("should support stopNodes parameter", () => {
+ const xml = `
+
+
+ - Should not parse this
+
+
+ `
+
+ const result = parseXmlForDiff(xml, ["nestedXml"]) as any
+
+ expect(result.root.data.nestedXml).toBeTruthy()
+ expect(result.root.data.nestedXml).toHaveProperty("item", "Should not parse this")
+ })
+ })
+
+ describe("diff-specific use case", () => {
+ it("should preserve exact content for diff matching", () => {
+ // This simulates the actual use case from the issue
+ const xml = `
+
+
+ ./doc.md
+
+ Team Identity & Project Positioning
+
+
+
+ `
+
+ const result = parseXmlForDiff(xml, ["file.diff.content"]) as any
+
+ // The & should remain as-is for exact matching with file content
+ expect(result.args.file.diff.content).toBe("Team Identity & Project Positioning")
+ })
+ })
+})
diff --git a/src/utils/remoteControl.ts b/src/utils/remoteControl.ts
index f003b522d1..e645ce7219 100644
--- a/src/utils/remoteControl.ts
+++ b/src/utils/remoteControl.ts
@@ -1,4 +1,4 @@
-import type { CloudUserInfo } from "@roo-code/types"
+import type { CloudUserInfo } from "@roo-code/cloud"
/**
* Determines if remote control features should be enabled
diff --git a/src/utils/xml.ts b/src/utils/xml.ts
index 0fd6ef574c..f183309d49 100644
--- a/src/utils/xml.ts
+++ b/src/utils/xml.ts
@@ -1,13 +1,28 @@
import { XMLParser } from "fast-xml-parser"
+/**
+ * Options for XML parsing
+ */
+interface ParseXmlOptions {
+ /**
+ * Whether to process HTML entities (e.g., & to &).
+ * Default: true for general parsing, false for diff operations
+ */
+ processEntities?: boolean
+}
+
/**
* Parses an XML string into a JavaScript object
* @param xmlString The XML string to parse
+ * @param stopNodes Optional array of node names to stop parsing at
+ * @param options Optional parsing options
* @returns Parsed JavaScript object representation of the XML
* @throws Error if the XML is invalid or parsing fails
*/
-export function parseXml(xmlString: string, stopNodes?: string[]): unknown {
+export function parseXml(xmlString: string, stopNodes?: string[], options?: ParseXmlOptions): unknown {
const _stopNodes = stopNodes ?? []
+ const processEntities = options?.processEntities ?? true
+
try {
const parser = new XMLParser({
ignoreAttributes: false,
@@ -15,6 +30,7 @@ export function parseXml(xmlString: string, stopNodes?: string[]): unknown {
parseAttributeValue: false,
parseTagValue: false,
trimValues: true,
+ processEntities,
stopNodes: _stopNodes,
})
@@ -25,3 +41,23 @@ export function parseXml(xmlString: string, stopNodes?: string[]): unknown {
throw new Error(`Failed to parse XML: ${errorMessage}`)
}
}
+
+/**
+ * Parses an XML string for diffing purposes, ensuring no HTML entities are decoded.
+ * This is a specialized version of parseXml to be used exclusively by diffing tools
+ * to prevent mismatches caused by entity processing.
+ *
+ * Use this instead of parseXml when:
+ * - Comparing parsed content against original file content
+ * - Performing diff operations where exact character matching is required
+ * - Processing XML that will be used in search/replace operations
+ *
+ * @param xmlString The XML string to parse
+ * @param stopNodes Optional array of node names to stop parsing at
+ * @returns Parsed JavaScript object representation of the XML
+ * @throws Error if the XML is invalid or parsing fails
+ */
+export function parseXmlForDiff(xmlString: string, stopNodes?: string[]): unknown {
+ // Delegate to parseXml with processEntities disabled
+ return parseXml(xmlString, stopNodes, { processEntities: false })
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000000..44f734c197
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "@roo-code/config-typescript/base.json",
+ "compilerOptions": {
+ "types": ["node"]
+ },
+ "exclude": ["node_modules"],
+ "include": ["scripts/*.ts"]
+}
diff --git a/webview-ui/src/components/account/AccountView.tsx b/webview-ui/src/components/account/AccountView.tsx
index f01aec9377..2e75b2d1c6 100644
--- a/webview-ui/src/components/account/AccountView.tsx
+++ b/webview-ui/src/components/account/AccountView.tsx
@@ -1,9 +1,10 @@
import { useEffect, useRef } from "react"
import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
-import type { CloudUserInfo } from "@roo-code/types"
import { TelemetryEventName } from "@roo-code/types"
+import type { CloudUserInfo } from "@roo/cloud"
+
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { useExtensionState } from "@src/context/ExtensionStateContext"
import { vscode } from "@src/utils/vscode"
diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx
index 9b8c96dea1..3b77bbdb7d 100644
--- a/webview-ui/src/components/chat/ChatView.tsx
+++ b/webview-ui/src/components/chat/ChatView.tsx
@@ -434,9 +434,12 @@ const ChatViewComponent: React.ForwardRefRenderFunction {
+ // Reset UI states
setExpandedRows({})
everVisibleMessagesTsRef.current.clear() // Clear for new task
setCurrentFollowUpTs(null) // Clear follow-up answered state for new task
+ setIsCondensing(false) // Reset condensing state when switching tasks
+ // Note: sendingDisabled is not reset here as it's managed by message effects
// Clear any pending auto-approval timeout from previous task
if (autoApproveTimeoutRef.current) {
@@ -897,11 +900,9 @@ const ChatViewComponent: React.ForwardRefRenderFunction textAreaRef.current?.focus())
const visibleMessages = useMemo(() => {
- const currentMessageCount = modifiedMessages.length
- const startIndex = Math.max(0, currentMessageCount - 500)
- const recentMessages = modifiedMessages.slice(startIndex)
-
- const newVisibleMessages = recentMessages.filter((message: ClineMessage) => {
+ // Remove the 500-message limit to prevent array index shifting
+ // Virtuoso is designed to efficiently handle large lists through virtualization
+ const newVisibleMessages = modifiedMessages.filter((message: ClineMessage) => {
if (everVisibleMessagesTsRef.current.has(message.ts)) {
const alwaysHiddenOnceProcessedAsk: ClineAsk[] = [
"api_req_failed",
diff --git a/webview-ui/src/components/chat/ShareButton.tsx b/webview-ui/src/components/chat/ShareButton.tsx
index 04cb1e2b38..4a0559fec7 100644
--- a/webview-ui/src/components/chat/ShareButton.tsx
+++ b/webview-ui/src/components/chat/ShareButton.tsx
@@ -2,8 +2,9 @@ import { useState, useEffect, useRef } from "react"
import { useTranslation } from "react-i18next"
import { SquareArrowOutUpRightIcon } from "lucide-react"
-import type { HistoryItem, ShareVisibility } from "@roo-code/types"
-import { TelemetryEventName } from "@roo-code/types"
+import { type HistoryItem, TelemetryEventName } from "@roo-code/types"
+
+import type { ShareVisibility } from "@roo/cloud"
import { vscode } from "@/utils/vscode"
import { telemetryClient } from "@/utils/TelemetryClient"
diff --git a/webview-ui/src/components/settings/ApiConfigManager.tsx b/webview-ui/src/components/settings/ApiConfigManager.tsx
index e737678c01..0d18f2a55b 100644
--- a/webview-ui/src/components/settings/ApiConfigManager.tsx
+++ b/webview-ui/src/components/settings/ApiConfigManager.tsx
@@ -2,11 +2,21 @@ import { memo, useEffect, useRef, useState } from "react"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { AlertTriangle } from "lucide-react"
-import type { ProviderSettingsEntry, OrganizationAllowList } from "@roo-code/types"
+import type { ProviderSettingsEntry } from "@roo-code/types"
+
+import type { OrganizationAllowList } from "@roo/cloud"
import { useAppTranslation } from "@/i18n/TranslationContext"
-import { Button, Input, Dialog, DialogContent, DialogTitle, StandardTooltip, SearchableSelect } from "@/components/ui"
-import type { SearchableSelectOption } from "@/components/ui"
+import {
+ type SearchableSelectOption,
+ Button,
+ Input,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+ StandardTooltip,
+ SearchableSelect,
+} from "@/components/ui"
interface ApiConfigManagerProps {
currentApiConfigName?: string
diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx
index dcdf072a11..b51b171354 100644
--- a/webview-ui/src/components/settings/ApiOptions.tsx
+++ b/webview-ui/src/components/settings/ApiOptions.tsx
@@ -105,7 +105,11 @@ import { buildDocLink } from "@src/utils/docLinks"
export interface ApiOptionsProps {
uriScheme: string | undefined
apiConfiguration: ProviderSettings
- setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void
+ setApiConfigurationField: (
+ field: K,
+ value: ProviderSettings[K],
+ isUserAction?: boolean,
+ ) => void
fromWelcomeView?: boolean
errorMessage: string | undefined
setErrorMessage: React.Dispatch>
@@ -280,7 +284,7 @@ const ApiOptions = ({
const shouldSetDefault = !modelId
if (shouldSetDefault) {
- setApiConfigurationField(field, defaultValue)
+ setApiConfigurationField(field, defaultValue, false)
}
}
diff --git a/webview-ui/src/components/settings/ModelInfoView.tsx b/webview-ui/src/components/settings/ModelInfoView.tsx
index 8078b03acd..2ba732effa 100644
--- a/webview-ui/src/components/settings/ModelInfoView.tsx
+++ b/webview-ui/src/components/settings/ModelInfoView.tsx
@@ -41,6 +41,12 @@ export const ModelInfoView = ({
supportsLabel={t("settings:modelInfo.supportsPromptCache")}
doesNotSupportLabel={t("settings:modelInfo.noPromptCache")}
/>,
+ typeof modelInfo?.contextWindow === "number" && modelInfo.contextWindow > 0 && (
+ <>
+ {t("settings:modelInfo.contextWindow")}{" "}
+ {modelInfo.contextWindow?.toLocaleString()} tokens
+ >
+ ),
typeof modelInfo?.maxTokens === "number" && modelInfo.maxTokens > 0 && (
<>
{t("settings:modelInfo.maxOutput")}:{" "}
diff --git a/webview-ui/src/components/settings/ModelPicker.tsx b/webview-ui/src/components/settings/ModelPicker.tsx
index a5a3fb6ef3..0753f9fc2b 100644
--- a/webview-ui/src/components/settings/ModelPicker.tsx
+++ b/webview-ui/src/components/settings/ModelPicker.tsx
@@ -3,7 +3,9 @@ import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { Trans } from "react-i18next"
import { ChevronsUpDown, Check, X } from "lucide-react"
-import type { ProviderSettings, ModelInfo, OrganizationAllowList } from "@roo-code/types"
+import type { ProviderSettings, ModelInfo } from "@roo-code/types"
+
+import type { OrganizationAllowList } from "@roo/cloud"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { useSelectedModel } from "@/components/ui/hooks/useSelectedModel"
@@ -44,7 +46,11 @@ interface ModelPickerProps {
serviceName: string
serviceUrl: string
apiConfiguration: ProviderSettings
- setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void
+ setApiConfigurationField: (
+ field: K,
+ value: ProviderSettings[K],
+ isUserAction?: boolean,
+ ) => void
organizationAllowList: OrganizationAllowList
errorMessage?: string
}
@@ -122,7 +128,7 @@ export const ModelPicker = ({
useEffect(() => {
if (!selectedModelId && !isInitialized.current) {
const initialValue = modelIds.includes(selectedModelId) ? selectedModelId : defaultModelId
- setApiConfigurationField(modelIdKey, initialValue)
+ setApiConfigurationField(modelIdKey, initialValue, false) // false = automatic initialization
}
isInitialized.current = true
@@ -194,7 +200,9 @@ export const ModelPicker = ({
value={model}
onSelect={onSelect}
data-testid={`model-option-${model}`}>
-{model}
+
+ {model}
+
(({ onDone, t
}, [])
const setApiConfigurationField = useCallback(
- (field: K, value: ProviderSettings[K]) => {
+ (field: K, value: ProviderSettings[K], isUserAction: boolean = true) => {
setCachedState((prevState) => {
if (prevState.apiConfiguration?.[field] === value) {
return prevState
@@ -227,9 +227,9 @@ const SettingsView = forwardRef(({ onDone, t
const previousValue = prevState.apiConfiguration?.[field]
- // Don't treat initial sync from undefined to a defined value as a user change
- // This prevents the dirty state when the component initializes and auto-syncs the model ID
- const isInitialSync = previousValue === undefined && value !== undefined
+ // Only skip change detection for automatic initialization (not user actions)
+ // This prevents the dirty state when the component initializes and auto-syncs values
+ const isInitialSync = !isUserAction && previousValue === undefined && value !== undefined
if (!isInitialSync) {
setChangeDetected(true)
@@ -629,6 +629,8 @@ const SettingsView = forwardRef(({ onDone, t
alwaysAllowUpdateTodoList={alwaysAllowUpdateTodoList}
followupAutoApproveTimeoutMs={followupAutoApproveTimeoutMs}
allowedCommands={allowedCommands}
+ allowedMaxRequests={allowedMaxRequests ?? undefined}
+ allowedMaxCost={allowedMaxCost ?? undefined}
deniedCommands={deniedCommands}
setCachedStateField={setCachedStateField}
/>
diff --git a/webview-ui/src/components/settings/ThinkingBudget.tsx b/webview-ui/src/components/settings/ThinkingBudget.tsx
index c2aa234983..7a85e61e7a 100644
--- a/webview-ui/src/components/settings/ThinkingBudget.tsx
+++ b/webview-ui/src/components/settings/ThinkingBudget.tsx
@@ -20,7 +20,11 @@ import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel"
interface ThinkingBudgetProps {
apiConfiguration: ProviderSettings
- setApiConfigurationField: (field: K, value: ProviderSettings[K]) => void
+ setApiConfigurationField: (
+ field: K,
+ value: ProviderSettings[K],
+ isUserAction?: boolean,
+ ) => void
modelInfo?: ModelInfo
}
@@ -71,7 +75,7 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
// Set default reasoning effort when model supports it and no value is set
useEffect(() => {
if (isReasoningEffortSupported && !apiConfiguration.reasoningEffort && defaultReasoningEffort) {
- setApiConfigurationField("reasoningEffort", defaultReasoningEffort)
+ setApiConfigurationField("reasoningEffort", defaultReasoningEffort, false)
}
}, [isReasoningEffortSupported, apiConfiguration.reasoningEffort, defaultReasoningEffort, setApiConfigurationField])
@@ -91,7 +95,7 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
// appropriately.
useEffect(() => {
if (isReasoningBudgetSupported && customMaxThinkingTokens > modelMaxThinkingTokens) {
- setApiConfigurationField("modelMaxThinkingTokens", modelMaxThinkingTokens)
+ setApiConfigurationField("modelMaxThinkingTokens", modelMaxThinkingTokens, false)
}
}, [isReasoningBudgetSupported, customMaxThinkingTokens, modelMaxThinkingTokens, setApiConfigurationField])
diff --git a/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx b/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx
index fa7493edc6..9bc235e5f0 100644
--- a/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx
+++ b/webview-ui/src/components/settings/__tests__/ThinkingBudget.spec.tsx
@@ -112,7 +112,7 @@ describe("ThinkingBudget", () => {
)
// Effect should trigger and cap the value
- expect(setApiConfigurationField).toHaveBeenCalledWith("modelMaxThinkingTokens", 8000) // 80% of 10000
+ expect(setApiConfigurationField).toHaveBeenCalledWith("modelMaxThinkingTokens", 8000, false) // 80% of 10000
})
it("should use default thinking tokens if not provided", () => {
diff --git a/webview-ui/src/components/settings/providers/Anthropic.tsx b/webview-ui/src/components/settings/providers/Anthropic.tsx
index f340e73f72..ede2b90208 100644
--- a/webview-ui/src/components/settings/providers/Anthropic.tsx
+++ b/webview-ui/src/components/settings/providers/Anthropic.tsx
@@ -6,6 +6,7 @@ import type { ProviderSettings } from "@roo-code/types"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"
+import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel"
import { inputEventTransform, noTransform } from "../transforms"
@@ -16,9 +17,13 @@ type AnthropicProps = {
export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: AnthropicProps) => {
const { t } = useAppTranslation()
+ const selectedModel = useSelectedModel(apiConfiguration)
const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl)
+ // Check if the current model supports 1M context beta
+ const supports1MContextBeta = selectedModel?.id === "claude-sonnet-4-20250514"
+
const handleInputChange = useCallback(
(
field: K,
@@ -79,6 +84,20 @@ export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: Anthro
>
)}
+ {supports1MContextBeta && (
+
+
{
+ setApiConfigurationField("anthropicBeta1MContext", checked)
+ }}>
+ {t("settings:providers.anthropic1MContextBetaLabel")}
+
+
+ {t("settings:providers.anthropic1MContextBetaDescription")}
+
+
+ )}
>
)
}
diff --git a/webview-ui/src/components/settings/providers/Bedrock.tsx b/webview-ui/src/components/settings/providers/Bedrock.tsx
index 750f631856..6c871e570a 100644
--- a/webview-ui/src/components/settings/providers/Bedrock.tsx
+++ b/webview-ui/src/components/settings/providers/Bedrock.tsx
@@ -2,7 +2,12 @@ import { useCallback, useState, useEffect } from "react"
import { Checkbox } from "vscrui"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
-import { type ProviderSettings, type ModelInfo, BEDROCK_REGIONS } from "@roo-code/types"
+import {
+ type ProviderSettings,
+ type ModelInfo,
+ BEDROCK_REGIONS,
+ BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+} from "@roo-code/types"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StandardTooltip } from "@src/components/ui"
@@ -19,6 +24,9 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo
const { t } = useAppTranslation()
const [awsEndpointSelected, setAwsEndpointSelected] = useState(!!apiConfiguration?.awsBedrockEndpointEnabled)
+ // Check if the selected model supports 1M context (Claude Sonnet 4)
+ const supports1MContextBeta = apiConfiguration?.apiModelId === BEDROCK_CLAUDE_SONNET_4_MODEL_ID
+
// Update the endpoint enabled state when the configuration changes
useEffect(() => {
setAwsEndpointSelected(!!apiConfiguration?.awsBedrockEndpointEnabled)
@@ -159,6 +167,20 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo
>
)}
+ {supports1MContextBeta && (
+
+
{
+ setApiConfigurationField("awsBedrock1MContext", checked)
+ }}>
+ {t("settings:providers.awsBedrock1MContextBetaLabel")}
+
+
+ {t("settings:providers.awsBedrock1MContextBetaDescription")}
+
+
+ )}
{
diff --git a/webview-ui/src/components/settings/providers/Glama.tsx b/webview-ui/src/components/settings/providers/Glama.tsx
index ca1c6590ef..bc3fb71cae 100644
--- a/webview-ui/src/components/settings/providers/Glama.tsx
+++ b/webview-ui/src/components/settings/providers/Glama.tsx
@@ -1,8 +1,9 @@
import { useCallback } from "react"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
-import { type ProviderSettings, type OrganizationAllowList, glamaDefaultModelId } from "@roo-code/types"
+import { type ProviderSettings, glamaDefaultModelId } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import type { RouterModels } from "@roo/api"
import { useAppTranslation } from "@src/i18n/TranslationContext"
diff --git a/webview-ui/src/components/settings/providers/HuggingFace.tsx b/webview-ui/src/components/settings/providers/HuggingFace.tsx
index 8716739d80..94f60cc4c8 100644
--- a/webview-ui/src/components/settings/providers/HuggingFace.tsx
+++ b/webview-ui/src/components/settings/providers/HuggingFace.tsx
@@ -34,7 +34,11 @@ type HuggingFaceModel = {
type HuggingFaceProps = {
apiConfiguration: ProviderSettings
- setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void
+ setApiConfigurationField: (
+ field: keyof ProviderSettings,
+ value: ProviderSettings[keyof ProviderSettings],
+ isUserAction?: boolean,
+ ) => void
}
export const HuggingFace = ({ apiConfiguration, setApiConfigurationField }: HuggingFaceProps) => {
@@ -93,7 +97,7 @@ export const HuggingFace = ({ apiConfiguration, setApiConfigurationField }: Hugg
// Set to "auto" as default
const defaultProvider = "auto"
setSelectedProvider(defaultProvider)
- setApiConfigurationField("huggingFaceInferenceProvider", defaultProvider)
+ setApiConfigurationField("huggingFaceInferenceProvider", defaultProvider, false) // false = automatic default
}
}
}
diff --git a/webview-ui/src/components/settings/providers/IOIntelligence.tsx b/webview-ui/src/components/settings/providers/IOIntelligence.tsx
index cbb23ba641..81e0d546f4 100644
--- a/webview-ui/src/components/settings/providers/IOIntelligence.tsx
+++ b/webview-ui/src/components/settings/providers/IOIntelligence.tsx
@@ -1,12 +1,14 @@
import { useCallback } from "react"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
-import type { ProviderSettings, OrganizationAllowList } from "@roo-code/types"
-import { ioIntelligenceDefaultModelId, ioIntelligenceModels } from "@roo-code/types"
+import { type ProviderSettings, ioIntelligenceDefaultModelId, ioIntelligenceModels } from "@roo-code/types"
+
+import type { OrganizationAllowList } from "@roo/cloud"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"
import { useExtensionState } from "@src/context/ExtensionStateContext"
+
import { ModelPicker } from "../ModelPicker"
import { inputEventTransform } from "../transforms"
diff --git a/webview-ui/src/components/settings/providers/LiteLLM.tsx b/webview-ui/src/components/settings/providers/LiteLLM.tsx
index caf7a173fe..0cb3245ea4 100644
--- a/webview-ui/src/components/settings/providers/LiteLLM.tsx
+++ b/webview-ui/src/components/settings/providers/LiteLLM.tsx
@@ -1,8 +1,9 @@
import { useCallback, useState, useEffect, useRef } from "react"
import { VSCodeTextField, VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
-import { type ProviderSettings, type OrganizationAllowList, litellmDefaultModelId } from "@roo-code/types"
+import { type ProviderSettings, litellmDefaultModelId } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import { RouterName } from "@roo/api"
import { ExtensionMessage } from "@roo/ExtensionMessage"
diff --git a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx
index 736b0253c4..ee462296b5 100644
--- a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx
+++ b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx
@@ -7,11 +7,11 @@ import {
type ProviderSettings,
type ModelInfo,
type ReasoningEffort,
- type OrganizationAllowList,
azureOpenAiDefaultApiVersion,
openAiModelInfoSaneDefaults,
} from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import { ExtensionMessage } from "@roo/ExtensionMessage"
import { useAppTranslation } from "@src/i18n/TranslationContext"
diff --git a/webview-ui/src/components/settings/providers/OpenRouter.tsx b/webview-ui/src/components/settings/providers/OpenRouter.tsx
index f6cad36bf8..cf8b54d0cd 100644
--- a/webview-ui/src/components/settings/providers/OpenRouter.tsx
+++ b/webview-ui/src/components/settings/providers/OpenRouter.tsx
@@ -3,8 +3,9 @@ import { Trans } from "react-i18next"
import { Checkbox } from "vscrui"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
-import { type ProviderSettings, type OrganizationAllowList, openRouterDefaultModelId } from "@roo-code/types"
+import { type ProviderSettings, openRouterDefaultModelId } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import type { RouterModels } from "@roo/api"
import { useAppTranslation } from "@src/i18n/TranslationContext"
diff --git a/webview-ui/src/components/settings/providers/Requesty.tsx b/webview-ui/src/components/settings/providers/Requesty.tsx
index dace21e851..7586b1e084 100644
--- a/webview-ui/src/components/settings/providers/Requesty.tsx
+++ b/webview-ui/src/components/settings/providers/Requesty.tsx
@@ -1,8 +1,9 @@
import { useCallback, useEffect, useState } from "react"
import { VSCodeCheckbox, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
-import { type ProviderSettings, type OrganizationAllowList, requestyDefaultModelId } from "@roo-code/types"
+import { type ProviderSettings, requestyDefaultModelId } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import type { RouterModels } from "@roo/api"
import { vscode } from "@src/utils/vscode"
diff --git a/webview-ui/src/components/settings/providers/Unbound.tsx b/webview-ui/src/components/settings/providers/Unbound.tsx
index 001ebf058e..2dd105a663 100644
--- a/webview-ui/src/components/settings/providers/Unbound.tsx
+++ b/webview-ui/src/components/settings/providers/Unbound.tsx
@@ -2,8 +2,9 @@ import { useCallback, useState, useRef } from "react"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useQueryClient } from "@tanstack/react-query"
-import { type ProviderSettings, type OrganizationAllowList, unboundDefaultModelId } from "@roo-code/types"
+import { type ProviderSettings, unboundDefaultModelId } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import type { RouterModels } from "@roo/api"
import { useAppTranslation } from "@src/i18n/TranslationContext"
@@ -16,7 +17,11 @@ import { ModelPicker } from "../ModelPicker"
type UnboundProps = {
apiConfiguration: ProviderSettings
- setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void
+ setApiConfigurationField: (
+ field: keyof ProviderSettings,
+ value: ProviderSettings[keyof ProviderSettings],
+ isUserAction?: boolean,
+ ) => void
routerModels?: RouterModels
organizationAllowList: OrganizationAllowList
modelValidationError?: string
@@ -109,7 +114,7 @@ export const Unbound = ({
if (!currentModelId || !modelExists) {
const firstAvailableModelId = Object.keys(updatedModels)[0]
- setApiConfigurationField("unboundModelId", firstAvailableModelId)
+ setApiConfigurationField("unboundModelId", firstAvailableModelId, false) // false = automatic model selection
}
}
diff --git a/webview-ui/src/components/settings/utils/__tests__/organizationFilters.test.ts b/webview-ui/src/components/settings/utils/__tests__/organizationFilters.test.ts
index 84183cd3c9..530e5d4942 100644
--- a/webview-ui/src/components/settings/utils/__tests__/organizationFilters.test.ts
+++ b/webview-ui/src/components/settings/utils/__tests__/organizationFilters.test.ts
@@ -1,4 +1,6 @@
-import type { ModelInfo, OrganizationAllowList } from "@roo-code/types"
+import type { ModelInfo } from "@roo-code/types"
+
+import type { OrganizationAllowList } from "@roo/cloud"
import { filterProviders, filterModels } from "../organizationFilters"
diff --git a/webview-ui/src/components/settings/utils/organizationFilters.ts b/webview-ui/src/components/settings/utils/organizationFilters.ts
index 56bd5a3c33..f6f129257a 100644
--- a/webview-ui/src/components/settings/utils/organizationFilters.ts
+++ b/webview-ui/src/components/settings/utils/organizationFilters.ts
@@ -1,4 +1,6 @@
-import type { ProviderName, ModelInfo, OrganizationAllowList } from "@roo-code/types"
+import type { ProviderName, ModelInfo } from "@roo-code/types"
+
+import type { OrganizationAllowList } from "@roo/cloud"
export const filterProviders = (
providers: Array<{ value: string; label: string }>,
diff --git a/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts b/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts
index 76c9878c9d..9d8c627b7f 100644
--- a/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts
+++ b/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts
@@ -5,7 +5,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { renderHook } from "@testing-library/react"
import type { Mock } from "vitest"
-import { ProviderSettings, ModelInfo } from "@roo-code/types"
+import { ProviderSettings, ModelInfo, BEDROCK_CLAUDE_SONNET_4_MODEL_ID } from "@roo-code/types"
import { useSelectedModel } from "../useSelectedModel"
import { useRouterModels } from "../useRouterModels"
@@ -448,4 +448,69 @@ describe("useSelectedModel", () => {
expect(result.current.info?.supportsImages).toBe(false)
})
})
+
+ describe("bedrock provider with 1M context", () => {
+ beforeEach(() => {
+ mockUseRouterModels.mockReturnValue({
+ data: {
+ openrouter: {},
+ requesty: {},
+ glama: {},
+ unbound: {},
+ litellm: {},
+ "io-intelligence": {},
+ },
+ isLoading: false,
+ isError: false,
+ } as any)
+
+ mockUseOpenRouterModelProviders.mockReturnValue({
+ data: {},
+ isLoading: false,
+ isError: false,
+ } as any)
+ })
+
+ it("should enable 1M context window for Bedrock Claude Sonnet 4 when awsBedrock1MContext is true", () => {
+ const apiConfiguration: ProviderSettings = {
+ apiProvider: "bedrock",
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsBedrock1MContext: true,
+ }
+
+ const wrapper = createWrapper()
+ const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
+
+ expect(result.current.id).toBe(BEDROCK_CLAUDE_SONNET_4_MODEL_ID)
+ expect(result.current.info?.contextWindow).toBe(1_000_000)
+ })
+
+ it("should use default context window for Bedrock Claude Sonnet 4 when awsBedrock1MContext is false", () => {
+ const apiConfiguration: ProviderSettings = {
+ apiProvider: "bedrock",
+ apiModelId: BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
+ awsBedrock1MContext: false,
+ }
+
+ const wrapper = createWrapper()
+ const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
+
+ expect(result.current.id).toBe(BEDROCK_CLAUDE_SONNET_4_MODEL_ID)
+ expect(result.current.info?.contextWindow).toBe(200_000)
+ })
+
+ it("should not affect context window for non-Claude Sonnet 4 Bedrock models", () => {
+ const apiConfiguration: ProviderSettings = {
+ apiProvider: "bedrock",
+ apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
+ awsBedrock1MContext: true,
+ }
+
+ const wrapper = createWrapper()
+ const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
+
+ expect(result.current.id).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0")
+ expect(result.current.info?.contextWindow).toBe(200_000)
+ })
+ })
})
diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts
index c67ec796b6..b188f3e342 100644
--- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts
+++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts
@@ -48,6 +48,7 @@ import {
fireworksDefaultModelId,
ioIntelligenceDefaultModelId,
ioIntelligenceModels,
+ BEDROCK_CLAUDE_SONNET_4_MODEL_ID,
} from "@roo-code/types"
import type { ModelRecord, RouterModels } from "@roo/api"
@@ -174,7 +175,7 @@ function getSelectedModel({
}
case "bedrock": {
const id = apiConfiguration.apiModelId ?? bedrockDefaultModelId
- const info = bedrockModels[id as keyof typeof bedrockModels]
+ const baseInfo = bedrockModels[id as keyof typeof bedrockModels]
// Special case for custom ARN.
if (id === "custom-arn") {
@@ -184,7 +185,17 @@ function getSelectedModel({
}
}
- return { id, info }
+ // Apply 1M context for Claude Sonnet 4 when enabled
+ if (id === BEDROCK_CLAUDE_SONNET_4_MODEL_ID && apiConfiguration.awsBedrock1MContext && baseInfo) {
+ // Create a new ModelInfo object with updated context window
+ const info: ModelInfo = {
+ ...baseInfo,
+ contextWindow: 1_000_000,
+ }
+ return { id, info }
+ }
+
+ return { id, info: baseInfo }
}
case "vertex": {
const id = apiConfiguration.apiModelId ?? vertexDefaultModelId
@@ -291,8 +302,41 @@ function getSelectedModel({
default: {
provider satisfies "anthropic" | "gemini-cli" | "human-relay" | "fake-ai"
const id = apiConfiguration.apiModelId ?? anthropicDefaultModelId
- const info = anthropicModels[id as keyof typeof anthropicModels]
- return { id, info }
+ const baseInfo = anthropicModels[id as keyof typeof anthropicModels]
+
+ // Apply 1M context beta tier pricing for Claude Sonnet 4
+ if (
+ provider === "anthropic" &&
+ id === "claude-sonnet-4-20250514" &&
+ apiConfiguration.anthropicBeta1MContext &&
+ baseInfo
+ ) {
+ // Type assertion since we know claude-sonnet-4-20250514 has tiers
+ const modelWithTiers = baseInfo as typeof baseInfo & {
+ tiers?: Array<{
+ contextWindow: number
+ inputPrice?: number
+ outputPrice?: number
+ cacheWritesPrice?: number
+ cacheReadsPrice?: number
+ }>
+ }
+ const tier = modelWithTiers.tiers?.[0]
+ if (tier) {
+ // Create a new ModelInfo object with updated values
+ const info: ModelInfo = {
+ ...baseInfo,
+ contextWindow: tier.contextWindow,
+ inputPrice: tier.inputPrice ?? baseInfo.inputPrice,
+ outputPrice: tier.outputPrice ?? baseInfo.outputPrice,
+ cacheWritesPrice: tier.cacheWritesPrice ?? baseInfo.cacheWritesPrice,
+ cacheReadsPrice: tier.cacheReadsPrice ?? baseInfo.cacheReadsPrice,
+ }
+ return { id, info }
+ }
+ }
+
+ return { id, info: baseInfo }
}
}
}
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx
index 12f13bdf55..ad35452079 100644
--- a/webview-ui/src/context/ExtensionStateContext.tsx
+++ b/webview-ui/src/context/ExtensionStateContext.tsx
@@ -6,10 +6,10 @@ import {
type CustomModePrompts,
type ModeConfig,
type ExperimentId,
- type OrganizationAllowList,
- ORGANIZATION_ALLOW_ALL,
} from "@roo-code/types"
+import { type OrganizationAllowList, ORGANIZATION_ALLOW_ALL } from "@roo/cloud"
+
import { ExtensionMessage, ExtensionState, MarketplaceInstalledMetadata, Command } from "@roo/ExtensionMessage"
import { findLastIndex } from "@roo/array"
import { McpServer } from "@roo/mcp"
diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json
index 0212002329..5964798684 100644
--- a/webview-ui/src/i18n/locales/ca/settings.json
+++ b/webview-ui/src/i18n/locales/ca/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Clau API d'Anthropic",
"getAnthropicApiKey": "Obtenir clau API d'Anthropic",
"anthropicUseAuthToken": "Passar la clau API d'Anthropic com a capçalera d'autorització en lloc de X-Api-Key",
+ "anthropic1MContextBetaLabel": "Activa la finestra de context d'1M (Beta)",
+ "anthropic1MContextBetaDescription": "Amplia la finestra de context a 1 milió de tokens per a Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Activa la finestra de context d'1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Amplia la finestra de context a 1 milió de tokens per a Claude Sonnet 4",
"cerebrasApiKey": "Clau API de Cerebras",
"getCerebrasApiKey": "Obtenir clau API de Cerebras",
"chutesApiKey": "Clau API de Chutes",
@@ -727,6 +731,7 @@
"noComputerUse": "No suporta ús de l'ordinador",
"supportsPromptCache": "Suporta emmagatzematge en caché de prompts",
"noPromptCache": "No suporta emmagatzematge en caché de prompts",
+ "contextWindow": "Finestra de context:",
"maxOutput": "Sortida màxima",
"inputPrice": "Preu d'entrada",
"outputPrice": "Preu de sortida",
diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json
index c0a7c75096..28f3e847fa 100644
--- a/webview-ui/src/i18n/locales/de/settings.json
+++ b/webview-ui/src/i18n/locales/de/settings.json
@@ -261,6 +261,10 @@
"anthropicApiKey": "Anthropic API-Schlüssel",
"getAnthropicApiKey": "Anthropic API-Schlüssel erhalten",
"anthropicUseAuthToken": "Anthropic API-Schlüssel als Authorization-Header anstelle von X-Api-Key übergeben",
+ "anthropic1MContextBetaLabel": "1M Kontextfenster aktivieren (Beta)",
+ "anthropic1MContextBetaDescription": "Erweitert das Kontextfenster für Claude Sonnet 4 auf 1 Million Token",
+ "awsBedrock1MContextBetaLabel": "1M Kontextfenster aktivieren (Beta)",
+ "awsBedrock1MContextBetaDescription": "Erweitert das Kontextfenster für Claude Sonnet 4 auf 1 Million Token",
"cerebrasApiKey": "Cerebras API-Schlüssel",
"getCerebrasApiKey": "Cerebras API-Schlüssel erhalten",
"chutesApiKey": "Chutes API-Schlüssel",
@@ -727,6 +731,7 @@
"noComputerUse": "Unterstützt keine Computernutzung",
"supportsPromptCache": "Unterstützt Prompt-Cache",
"noPromptCache": "Unterstützt keinen Prompt-Cache",
+ "contextWindow": "Kontextfenster:",
"maxOutput": "Maximale Ausgabe",
"inputPrice": "Eingabepreis",
"outputPrice": "Ausgabepreis",
diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json
index 74e2e35239..fca3d1ade9 100644
--- a/webview-ui/src/i18n/locales/en/settings.json
+++ b/webview-ui/src/i18n/locales/en/settings.json
@@ -258,6 +258,10 @@
"anthropicApiKey": "Anthropic API Key",
"getAnthropicApiKey": "Get Anthropic API Key",
"anthropicUseAuthToken": "Pass Anthropic API Key as Authorization header instead of X-Api-Key",
+ "anthropic1MContextBetaLabel": "Enable 1M context window (Beta)",
+ "anthropic1MContextBetaDescription": "Extends context window to 1 million tokens for Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Enable 1M context window (Beta)",
+ "awsBedrock1MContextBetaDescription": "Extends context window to 1 million tokens for Claude Sonnet 4",
"cerebrasApiKey": "Cerebras API Key",
"getCerebrasApiKey": "Get Cerebras API Key",
"chutesApiKey": "Chutes API Key",
@@ -726,6 +730,7 @@
"noComputerUse": "Does not support computer use",
"supportsPromptCache": "Supports prompt caching",
"noPromptCache": "Does not support prompt caching",
+ "contextWindow": "Context Window:",
"maxOutput": "Max output",
"inputPrice": "Input price",
"outputPrice": "Output price",
diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json
index 02f4956dfe..fd6e1e2715 100644
--- a/webview-ui/src/i18n/locales/es/settings.json
+++ b/webview-ui/src/i18n/locales/es/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Clave API de Anthropic",
"getAnthropicApiKey": "Obtener clave API de Anthropic",
"anthropicUseAuthToken": "Pasar la clave API de Anthropic como encabezado de autorización en lugar de X-Api-Key",
+ "anthropic1MContextBetaLabel": "Habilitar ventana de contexto de 1M (Beta)",
+ "anthropic1MContextBetaDescription": "Amplía la ventana de contexto a 1 millón de tokens para Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Habilitar ventana de contexto de 1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Amplía la ventana de contexto a 1 millón de tokens para Claude Sonnet 4",
"cerebrasApiKey": "Clave API de Cerebras",
"getCerebrasApiKey": "Obtener clave API de Cerebras",
"chutesApiKey": "Clave API de Chutes",
@@ -727,6 +731,7 @@
"noComputerUse": "No soporta uso del ordenador",
"supportsPromptCache": "Soporta caché de prompts",
"noPromptCache": "No soporta caché de prompts",
+ "contextWindow": "Ventana de contexto",
"maxOutput": "Salida máxima",
"inputPrice": "Precio de entrada",
"outputPrice": "Precio de salida",
diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json
index 790f5f0a5e..451e51d084 100644
--- a/webview-ui/src/i18n/locales/fr/settings.json
+++ b/webview-ui/src/i18n/locales/fr/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Clé API Anthropic",
"getAnthropicApiKey": "Obtenir la clé API Anthropic",
"anthropicUseAuthToken": "Passer la clé API Anthropic comme en-tête d'autorisation au lieu de X-Api-Key",
+ "anthropic1MContextBetaLabel": "Activer la fenêtre de contexte de 1M (Bêta)",
+ "anthropic1MContextBetaDescription": "Étend la fenêtre de contexte à 1 million de tokens pour Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Activer la fenêtre de contexte de 1M (Bêta)",
+ "awsBedrock1MContextBetaDescription": "Étend la fenêtre de contexte à 1 million de tokens pour Claude Sonnet 4",
"cerebrasApiKey": "Clé API Cerebras",
"getCerebrasApiKey": "Obtenir la clé API Cerebras",
"chutesApiKey": "Clé API Chutes",
@@ -727,6 +731,7 @@
"noComputerUse": "Ne prend pas en charge l'utilisation de l'ordinateur",
"supportsPromptCache": "Prend en charge la mise en cache des prompts",
"noPromptCache": "Ne prend pas en charge la mise en cache des prompts",
+ "contextWindow": "Fenêtre de contexte :",
"maxOutput": "Sortie maximale",
"inputPrice": "Prix d'entrée",
"outputPrice": "Prix de sortie",
diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json
index 23ee616ac2..83a4b7b81b 100644
--- a/webview-ui/src/i18n/locales/hi/settings.json
+++ b/webview-ui/src/i18n/locales/hi/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API कुंजी",
"getAnthropicApiKey": "Anthropic API कुंजी प्राप्त करें",
"anthropicUseAuthToken": "X-Api-Key के बजाय Anthropic API कुंजी को Authorization हेडर के रूप में पास करें",
+ "anthropic1MContextBetaLabel": "1M संदर्भ विंडो सक्षम करें (बीटा)",
+ "anthropic1MContextBetaDescription": "Claude Sonnet 4 के लिए संदर्भ विंडो को 1 मिलियन टोकन तक बढ़ाता है",
+ "awsBedrock1MContextBetaLabel": "1M संदर्भ विंडो सक्षम करें (बीटा)",
+ "awsBedrock1MContextBetaDescription": "Claude Sonnet 4 के लिए संदर्भ विंडो को 1 मिलियन टोकन तक बढ़ाता है",
"cerebrasApiKey": "Cerebras API कुंजी",
"getCerebrasApiKey": "Cerebras API कुंजी प्राप्त करें",
"chutesApiKey": "Chutes API कुंजी",
@@ -728,6 +732,7 @@
"noComputerUse": "कंप्यूटर उपयोग का समर्थन नहीं करता है",
"supportsPromptCache": "प्रॉम्प्ट कैशिंग का समर्थन करता है",
"noPromptCache": "प्रॉम्प्ट कैशिंग का समर्थन नहीं करता है",
+ "contextWindow": "संदर्भ विंडो:",
"maxOutput": "अधिकतम आउटपुट",
"inputPrice": "इनपुट मूल्य",
"outputPrice": "आउटपुट मूल्य",
diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json
index d32c3d6605..fd7edf40cf 100644
--- a/webview-ui/src/i18n/locales/id/settings.json
+++ b/webview-ui/src/i18n/locales/id/settings.json
@@ -263,6 +263,10 @@
"anthropicApiKey": "Anthropic API Key",
"getAnthropicApiKey": "Dapatkan Anthropic API Key",
"anthropicUseAuthToken": "Kirim Anthropic API Key sebagai Authorization header alih-alih X-Api-Key",
+ "anthropic1MContextBetaLabel": "Aktifkan jendela konteks 1M (Beta)",
+ "anthropic1MContextBetaDescription": "Memperluas jendela konteks menjadi 1 juta token untuk Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Aktifkan jendela konteks 1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Memperluas jendela konteks menjadi 1 juta token untuk Claude Sonnet 4",
"cerebrasApiKey": "Cerebras API Key",
"getCerebrasApiKey": "Dapatkan Cerebras API Key",
"chutesApiKey": "Chutes API Key",
@@ -757,6 +761,7 @@
"noComputerUse": "Tidak mendukung computer use",
"supportsPromptCache": "Mendukung prompt caching",
"noPromptCache": "Tidak mendukung prompt caching",
+ "contextWindow": "Jendela Konteks:",
"maxOutput": "Output maksimum",
"inputPrice": "Harga input",
"outputPrice": "Harga output",
diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json
index 2d8cb156a0..c8a8800e4f 100644
--- a/webview-ui/src/i18n/locales/it/settings.json
+++ b/webview-ui/src/i18n/locales/it/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Chiave API Anthropic",
"getAnthropicApiKey": "Ottieni chiave API Anthropic",
"anthropicUseAuthToken": "Passa la chiave API Anthropic come header di autorizzazione invece di X-Api-Key",
+ "anthropic1MContextBetaLabel": "Abilita finestra di contesto da 1M (Beta)",
+ "anthropic1MContextBetaDescription": "Estende la finestra di contesto a 1 milione di token per Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Abilita finestra di contesto da 1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Estende la finestra di contesto a 1 milione di token per Claude Sonnet 4",
"cerebrasApiKey": "Chiave API Cerebras",
"getCerebrasApiKey": "Ottieni chiave API Cerebras",
"chutesApiKey": "Chiave API Chutes",
@@ -728,6 +732,7 @@
"noComputerUse": "Non supporta uso del computer",
"supportsPromptCache": "Supporta cache dei prompt",
"noPromptCache": "Non supporta cache dei prompt",
+ "contextWindow": "Finestra di contesto:",
"maxOutput": "Output massimo",
"inputPrice": "Prezzo input",
"outputPrice": "Prezzo output",
diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json
index b2dedba90c..d3e7b04baf 100644
--- a/webview-ui/src/i18n/locales/ja/settings.json
+++ b/webview-ui/src/i18n/locales/ja/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic APIキー",
"getAnthropicApiKey": "Anthropic APIキーを取得",
"anthropicUseAuthToken": "Anthropic APIキーをX-Api-Keyの代わりにAuthorizationヘッダーとして渡す",
+ "anthropic1MContextBetaLabel": "1Mコンテキストウィンドウを有効にする(ベータ版)",
+ "anthropic1MContextBetaDescription": "Claude Sonnet 4のコンテキストウィンドウを100万トークンに拡張します",
+ "awsBedrock1MContextBetaLabel": "1Mコンテキストウィンドウを有効にする(ベータ版)",
+ "awsBedrock1MContextBetaDescription": "Claude Sonnet 4のコンテキストウィンドウを100万トークンに拡張します",
"cerebrasApiKey": "Cerebras APIキー",
"getCerebrasApiKey": "Cerebras APIキーを取得",
"chutesApiKey": "Chutes APIキー",
@@ -728,6 +732,7 @@
"noComputerUse": "コンピュータ使用をサポートしていません",
"supportsPromptCache": "プロンプトキャッシュをサポート",
"noPromptCache": "プロンプトキャッシュをサポートしていません",
+ "contextWindow": "コンテキストウィンドウ:",
"maxOutput": "最大出力",
"inputPrice": "入力価格",
"outputPrice": "出力価格",
diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json
index 623a92ccd0..a5bcd1f385 100644
--- a/webview-ui/src/i18n/locales/ko/settings.json
+++ b/webview-ui/src/i18n/locales/ko/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API 키",
"getAnthropicApiKey": "Anthropic API 키 받기",
"anthropicUseAuthToken": "X-Api-Key 대신 Authorization 헤더로 Anthropic API 키 전달",
+ "anthropic1MContextBetaLabel": "1M 컨텍스트 창 활성화 (베타)",
+ "anthropic1MContextBetaDescription": "Claude Sonnet 4의 컨텍스트 창을 100만 토큰으로 확장",
+ "awsBedrock1MContextBetaLabel": "1M 컨텍스트 창 활성화 (베타)",
+ "awsBedrock1MContextBetaDescription": "Claude Sonnet 4의 컨텍스트 창을 100만 토큰으로 확장",
"cerebrasApiKey": "Cerebras API 키",
"getCerebrasApiKey": "Cerebras API 키 가져오기",
"chutesApiKey": "Chutes API 키",
@@ -728,6 +732,7 @@
"noComputerUse": "컴퓨터 사용 지원 안 함",
"supportsPromptCache": "프롬프트 캐시 지원",
"noPromptCache": "프롬프트 캐시 지원 안 함",
+ "contextWindow": "컨텍스트 창:",
"maxOutput": "최대 출력",
"inputPrice": "입력 가격",
"outputPrice": "출력 가격",
diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json
index c180fef89f..b54e021be0 100644
--- a/webview-ui/src/i18n/locales/nl/settings.json
+++ b/webview-ui/src/i18n/locales/nl/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API-sleutel",
"getAnthropicApiKey": "Anthropic API-sleutel ophalen",
"anthropicUseAuthToken": "Anthropic API-sleutel als Authorization-header doorgeven in plaats van X-Api-Key",
+ "anthropic1MContextBetaLabel": "1M contextvenster inschakelen (bèta)",
+ "anthropic1MContextBetaDescription": "Breidt het contextvenster uit tot 1 miljoen tokens voor Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "1M contextvenster inschakelen (bèta)",
+ "awsBedrock1MContextBetaDescription": "Breidt het contextvenster uit tot 1 miljoen tokens voor Claude Sonnet 4",
"cerebrasApiKey": "Cerebras API-sleutel",
"getCerebrasApiKey": "Cerebras API-sleutel verkrijgen",
"chutesApiKey": "Chutes API-sleutel",
@@ -728,6 +732,7 @@
"noComputerUse": "Ondersteunt geen computergebruik",
"supportsPromptCache": "Ondersteunt prompt caching",
"noPromptCache": "Ondersteunt geen prompt caching",
+ "contextWindow": "Contextvenster:",
"maxOutput": "Maximale output",
"inputPrice": "Invoerprijs",
"outputPrice": "Uitvoerprijs",
diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json
index 83a46189f9..194bd9029d 100644
--- a/webview-ui/src/i18n/locales/pl/settings.json
+++ b/webview-ui/src/i18n/locales/pl/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Klucz API Anthropic",
"getAnthropicApiKey": "Uzyskaj klucz API Anthropic",
"anthropicUseAuthToken": "Przekaż klucz API Anthropic jako nagłówek Authorization zamiast X-Api-Key",
+ "anthropic1MContextBetaLabel": "Włącz okno kontekstowe 1M (Beta)",
+ "anthropic1MContextBetaDescription": "Rozszerza okno kontekstowe do 1 miliona tokenów dla Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Włącz okno kontekstowe 1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Rozszerza okno kontekstowe do 1 miliona tokenów dla Claude Sonnet 4",
"cerebrasApiKey": "Klucz API Cerebras",
"getCerebrasApiKey": "Pobierz klucz API Cerebras",
"chutesApiKey": "Klucz API Chutes",
@@ -728,6 +732,7 @@
"noComputerUse": "Nie obsługuje użycia komputera",
"supportsPromptCache": "Obsługuje buforowanie podpowiedzi",
"noPromptCache": "Nie obsługuje buforowania podpowiedzi",
+ "contextWindow": "Okno kontekstowe:",
"maxOutput": "Maksymalne wyjście",
"inputPrice": "Cena wejścia",
"outputPrice": "Cena wyjścia",
diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json
index a6bd7fb861..7879dd5154 100644
--- a/webview-ui/src/i18n/locales/pt-BR/settings.json
+++ b/webview-ui/src/i18n/locales/pt-BR/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Chave de API Anthropic",
"getAnthropicApiKey": "Obter chave de API Anthropic",
"anthropicUseAuthToken": "Passar a chave de API Anthropic como cabeçalho Authorization em vez de X-Api-Key",
+ "anthropic1MContextBetaLabel": "Ativar janela de contexto de 1M (Beta)",
+ "anthropic1MContextBetaDescription": "Estende a janela de contexto para 1 milhão de tokens para o Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Ativar janela de contexto de 1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Estende a janela de contexto para 1 milhão de tokens para o Claude Sonnet 4",
"cerebrasApiKey": "Chave de API Cerebras",
"getCerebrasApiKey": "Obter chave de API Cerebras",
"chutesApiKey": "Chave de API Chutes",
@@ -728,6 +732,7 @@
"noComputerUse": "Não suporta uso do computador",
"supportsPromptCache": "Suporta cache de prompts",
"noPromptCache": "Não suporta cache de prompts",
+ "contextWindow": "Janela de Contexto:",
"maxOutput": "Saída máxima",
"inputPrice": "Preço de entrada",
"outputPrice": "Preço de saída",
diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json
index 2cd5470173..3744ecedff 100644
--- a/webview-ui/src/i18n/locales/ru/settings.json
+++ b/webview-ui/src/i18n/locales/ru/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API-ключ",
"getAnthropicApiKey": "Получить Anthropic API-ключ",
"anthropicUseAuthToken": "Передавать Anthropic API-ключ как Authorization-заголовок вместо X-Api-Key",
+ "anthropic1MContextBetaLabel": "Включить контекстное окно 1M (бета)",
+ "anthropic1MContextBetaDescription": "Расширяет контекстное окно до 1 миллиона токенов для Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Включить контекстное окно 1M (бета)",
+ "awsBedrock1MContextBetaDescription": "Расширяет контекстное окно до 1 миллиона токенов для Claude Sonnet 4",
"cerebrasApiKey": "Cerebras API-ключ",
"getCerebrasApiKey": "Получить Cerebras API-ключ",
"chutesApiKey": "Chutes API-ключ",
@@ -728,6 +732,7 @@
"noComputerUse": "Не поддерживает использование компьютера",
"supportsPromptCache": "Поддерживает кэширование подсказок",
"noPromptCache": "Не поддерживает кэширование подсказок",
+ "contextWindow": "Контекстное окно:",
"maxOutput": "Максимум вывода",
"inputPrice": "Цена за вход",
"outputPrice": "Цена за вывод",
diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json
index 96a5b743a6..be1a7a0169 100644
--- a/webview-ui/src/i18n/locales/tr/settings.json
+++ b/webview-ui/src/i18n/locales/tr/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API Anahtarı",
"getAnthropicApiKey": "Anthropic API Anahtarı Al",
"anthropicUseAuthToken": "Anthropic API Anahtarını X-Api-Key yerine Authorization başlığı olarak geçir",
+ "anthropic1MContextBetaLabel": "1M bağlam penceresini etkinleştir (Beta)",
+ "anthropic1MContextBetaDescription": "Claude Sonnet 4 için bağlam penceresini 1 milyon token'a genişletir",
+ "awsBedrock1MContextBetaLabel": "1M bağlam penceresini etkinleştir (Beta)",
+ "awsBedrock1MContextBetaDescription": "Claude Sonnet 4 için bağlam penceresini 1 milyon token'a genişletir",
"cerebrasApiKey": "Cerebras API Anahtarı",
"getCerebrasApiKey": "Cerebras API Anahtarını Al",
"chutesApiKey": "Chutes API Anahtarı",
@@ -728,6 +732,7 @@
"noComputerUse": "Bilgisayar kullanımını desteklemez",
"supportsPromptCache": "İstem önbelleğini destekler",
"noPromptCache": "İstem önbelleğini desteklemez",
+ "contextWindow": "Bağlam Penceresi:",
"maxOutput": "Maksimum çıktı",
"inputPrice": "Giriş fiyatı",
"outputPrice": "Çıkış fiyatı",
diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json
index 1b7df514a9..7526cf31a7 100644
--- a/webview-ui/src/i18n/locales/vi/settings.json
+++ b/webview-ui/src/i18n/locales/vi/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Khóa API Anthropic",
"getAnthropicApiKey": "Lấy khóa API Anthropic",
"anthropicUseAuthToken": "Truyền khóa API Anthropic dưới dạng tiêu đề Authorization thay vì X-Api-Key",
+ "anthropic1MContextBetaLabel": "Bật cửa sổ ngữ cảnh 1M (Beta)",
+ "anthropic1MContextBetaDescription": "Mở rộng cửa sổ ngữ cảnh lên 1 triệu token cho Claude Sonnet 4",
+ "awsBedrock1MContextBetaLabel": "Bật cửa sổ ngữ cảnh 1M (Beta)",
+ "awsBedrock1MContextBetaDescription": "Mở rộng cửa sổ ngữ cảnh lên 1 triệu token cho Claude Sonnet 4",
"cerebrasApiKey": "Khóa API Cerebras",
"getCerebrasApiKey": "Lấy khóa API Cerebras",
"chutesApiKey": "Khóa API Chutes",
@@ -728,6 +732,7 @@
"noComputerUse": "Không hỗ trợ sử dụng máy tính",
"supportsPromptCache": "Hỗ trợ bộ nhớ đệm lời nhắc",
"noPromptCache": "Không hỗ trợ bộ nhớ đệm lời nhắc",
+ "contextWindow": "Cửa sổ ngữ cảnh:",
"maxOutput": "Đầu ra tối đa",
"inputPrice": "Giá đầu vào",
"outputPrice": "Giá đầu ra",
diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json
index 3ebcfb850c..c1985e7490 100644
--- a/webview-ui/src/i18n/locales/zh-CN/settings.json
+++ b/webview-ui/src/i18n/locales/zh-CN/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API 密钥",
"getAnthropicApiKey": "获取 Anthropic API 密钥",
"anthropicUseAuthToken": "将 Anthropic API 密钥作为 Authorization 标头传递,而不是 X-Api-Key",
+ "anthropic1MContextBetaLabel": "启用 1M 上下文窗口 (Beta)",
+ "anthropic1MContextBetaDescription": "为 Claude Sonnet 4 将上下文窗口扩展至 100 万个 token",
+ "awsBedrock1MContextBetaLabel": "启用 1M 上下文窗口 (Beta)",
+ "awsBedrock1MContextBetaDescription": "为 Claude Sonnet 4 将上下文窗口扩展至 100 万个 token",
"cerebrasApiKey": "Cerebras API 密钥",
"getCerebrasApiKey": "获取 Cerebras API 密钥",
"chutesApiKey": "Chutes API 密钥",
@@ -728,6 +732,7 @@
"noComputerUse": "不支持计算机功能调用",
"supportsPromptCache": "支持提示缓存",
"noPromptCache": "不支持提示缓存",
+ "contextWindow": "上下文窗口:",
"maxOutput": "最大输出",
"inputPrice": "输入价格",
"outputPrice": "输出价格",
diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json
index f188a96d51..6a673de60a 100644
--- a/webview-ui/src/i18n/locales/zh-TW/settings.json
+++ b/webview-ui/src/i18n/locales/zh-TW/settings.json
@@ -259,6 +259,10 @@
"anthropicApiKey": "Anthropic API 金鑰",
"getAnthropicApiKey": "取得 Anthropic API 金鑰",
"anthropicUseAuthToken": "將 Anthropic API 金鑰作為 Authorization 標頭傳遞,而非使用 X-Api-Key",
+ "anthropic1MContextBetaLabel": "啟用 1M 上下文視窗 (Beta)",
+ "anthropic1MContextBetaDescription": "為 Claude Sonnet 4 將上下文視窗擴展至 100 萬個 token",
+ "awsBedrock1MContextBetaLabel": "啟用 1M 上下文視窗 (Beta)",
+ "awsBedrock1MContextBetaDescription": "為 Claude Sonnet 4 將上下文視窗擴展至 100 萬個 token",
"cerebrasApiKey": "Cerebras API 金鑰",
"getCerebrasApiKey": "取得 Cerebras API 金鑰",
"chutesApiKey": "Chutes API 金鑰",
@@ -728,6 +732,7 @@
"noComputerUse": "不支援電腦使用",
"supportsPromptCache": "支援提示快取",
"noPromptCache": "不支援提示快取",
+ "contextWindow": "上下文視窗:",
"maxOutput": "最大輸出",
"inputPrice": "輸入價格",
"outputPrice": "輸出價格",
diff --git a/webview-ui/src/utils/__tests__/validate.test.ts b/webview-ui/src/utils/__tests__/validate.test.ts
index 9e693544b9..f14fb89200 100644
--- a/webview-ui/src/utils/__tests__/validate.test.ts
+++ b/webview-ui/src/utils/__tests__/validate.test.ts
@@ -1,4 +1,6 @@
-import { ProviderSettings, OrganizationAllowList } from "@roo-code/types"
+import type { ProviderSettings } from "@roo-code/types"
+
+import type { OrganizationAllowList } from "@roo/cloud"
import { RouterModels } from "@roo/api"
import { getModelValidationError, validateApiConfigurationExcludingModelErrors } from "../validate"
diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts
index 70caf187f0..e4c9ed483d 100644
--- a/webview-ui/src/utils/validate.ts
+++ b/webview-ui/src/utils/validate.ts
@@ -1,7 +1,8 @@
import i18next from "i18next"
-import type { ProviderSettings, OrganizationAllowList } from "@roo-code/types"
+import type { ProviderSettings } from "@roo-code/types"
+import type { OrganizationAllowList } from "@roo/cloud"
import { isRouterName, RouterModels } from "@roo/api"
export function validateApiConfiguration(
diff --git a/webview-ui/vitest.config.ts b/webview-ui/vitest.config.ts
index b9455584bf..80f3f49cf6 100644
--- a/webview-ui/vitest.config.ts
+++ b/webview-ui/vitest.config.ts
@@ -16,6 +16,9 @@ export default defineConfig({
"@": path.resolve(__dirname, "./src"),
"@src": path.resolve(__dirname, "./src"),
"@roo": path.resolve(__dirname, "../src/shared"),
+ // Mock the vscode module for tests since it's not available outside
+ // VS Code extension context.
+ vscode: path.resolve(__dirname, "./src/__mocks__/vscode.ts"),
},
},
})