diff --git a/.husky/pre-push b/.husky/pre-push index 9e41e80cf8..4cf91d9580 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -18,14 +18,17 @@ fi $pnpm_cmd run check-types -# Load .env.local if it exists +# Use dotenvx to securely load .env.local and run commands that depend on it if [ -f ".env.local" ]; then - export $(grep -v '^#' .env.local | xargs) -fi - -# Run tests if RUN_TESTS_ON_PUSH is set to true -if [ "$RUN_TESTS_ON_PUSH" = "true" ]; then - $pnpm_cmd run test + # Check if RUN_TESTS_ON_PUSH is set to true and run tests with dotenvx + if npx dotenvx get RUN_TESTS_ON_PUSH -f .env.local 2>/dev/null | grep -q "^true$"; then + npx dotenvx run -f .env.local -- $pnpm_cmd run test + fi +else + # Fallback: run tests if RUN_TESTS_ON_PUSH is set in regular environment + if [ "$RUN_TESTS_ON_PUSH" = "true" ]; then + $pnpm_cmd run test + fi fi # Check for new changesets. diff --git a/.roo/commands/release.md b/.roo/commands/release.md index 8adf57e6f0..707844cdc4 100644 --- a/.roo/commands/release.md +++ b/.roo/commands/release.md @@ -16,14 +16,14 @@ argument-hint: patch | minor | major [list of changes] ``` -- Always include contributor attribution using format: (thanks @username!) -- For PRs that close issues, also include the issue number and reporter: "- Fix: Description (#123 by @reporter, PR by @contributor)" -- For PRs without linked issues, use the standard format: "- Add support for feature (thanks @contributor!)" +- Always include contributor attribution and the PR number: use "(PR # by @username)". +- For PRs that close issues, include both the issue number and the PR number and authors: "- Fix: Description (#123 by @reporter, PR #456 by @contributor)" +- For PRs without linked issues, include the PR number and author: "- Add support for feature (PR #456 by @contributor)" - Provide brief descriptions of each item to explain the change - Order the list from most important to least important - Example formats: - - With issue: "- Fix: Resolve memory leak in extension (#456 by @issueReporter, PR by @prAuthor)" - - Without issue: "- Add support for Gemini 2.5 Pro caching (thanks @contributor!)" + - With issue: "- Fix: Resolve memory leak in extension (#456 by @issueReporter, PR #789 by @prAuthor)" + - Without issue: "- Add support for Gemini 2.5 Pro caching (PR #789 by @contributor)" - CRITICAL: Include EVERY SINGLE PR in the changeset - don't assume you know which ones are important. Count the total PRs to verify completeness and cross-reference the list to ensure nothing is missed. 6. If the generate_image tool is available, create a release image at `releases/[version]-release.png` diff --git a/.roo/rules-issue-fixer/1_Workflow.xml b/.roo/rules-issue-fixer/1_Workflow.xml index 62a3fd7c26..c6f2b570a0 100644 --- a/.roo/rules-issue-fixer/1_Workflow.xml +++ b/.roo/rules-issue-fixer/1_Workflow.xml @@ -17,7 +17,7 @@ Then retrieve the issue: - gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + gh api repos/[owner]/[repo]/issues/[issue-number] --jq '{number,title,body,state,labels,assignees,milestone,createdAt:.created_at,updatedAt:.updated_at,closedAt:.closed_at,author:.user.login}' If the command fails with an authentication error (e.g., "gh: Not authenticated" or "HTTP 401"), ask the user to authenticate: @@ -49,7 +49,7 @@ - Any decisions or changes to requirements - gh issue view [issue number] --repo [owner]/[repo] --comments + gh api repos/[owner]/[repo]/issues/[issue-number]/comments --paginate --jq '.[].body' Also check for: diff --git a/.roo/rules-issue-fixer/4_github_cli_usage.xml b/.roo/rules-issue-fixer/4_github_cli_usage.xml index e12fb06a5b..b4fa19b3cc 100644 --- a/.roo/rules-issue-fixer/4_github_cli_usage.xml +++ b/.roo/rules-issue-fixer/4_github_cli_usage.xml @@ -29,23 +29,23 @@ - Retrieve the issue details at the start + Retrieve the issue details at the start using the REST Issues API. Always use first to get the full issue content - gh issue view [issue-number] --repo [owner]/[repo] --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + gh api repos/[owner]/[repo]/issues/[issue-number] --jq '{number,title,body,state,labels,assignees,milestone,createdAt:.created_at,updatedAt:.updated_at,closedAt:.closed_at,author:.user.login}' - gh issue view 123 --repo octocat/hello-world --json number,title,body,state,labels,assignees,milestone,createdAt,updatedAt,closedAt,author + gh api repos/octocat/hello-world/issues/123 --jq '{number,title,body,state,labels,assignees,milestone,createdAt:.created_at,updatedAt:.updated_at,closedAt:.closed_at,author:.user.login}' - Get additional context and requirements from issue comments + Get additional context and requirements from issue comments. Always use after viewing issue to see full discussion - gh issue view [issue-number] --repo [owner]/[repo] --comments + gh api repos/[owner]/[repo]/issues/[issue-number]/comments --paginate --jq '.[].body' - gh issue view 123 --repo octocat/hello-world --comments + gh api repos/octocat/hello-world/issues/123/comments --paginate --jq '.[].body' @@ -109,6 +109,30 @@ + + + Inspect associations with GitHub Projects (new Projects experience) for a given issue + Use when project context is relevant to understanding priority, ownership, or workflow + gh api graphql -f query=' +query($owner:String!, $repo:String!, $number:Int!) { + repository(owner:$owner, name:$repo) { + issue(number:$number) { + projectsV2(first:20) { + nodes { + title + url + } + } + } + } +} +' -F owner=[owner] -F repo=[repo] -F number=[issue-number] + + This uses the projectsV2 field from the new GitHub Projects experience for issue-level project context. + + + + Create a pull request diff --git a/CHANGELOG.md b/CHANGELOG.md index c15ddb28ad..a199cb3ce9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,76 @@ # Roo Code Changelog +## [3.32.1] - 2025-11-14 + +![3.32.1 Release - Bug Fixes](/releases/3.32.1-release.png) + +- Fix: Add abort controller for request cancellation in OpenAI native protocol (PR #9276 by @daniel-lxs) +- Fix: Resolve duplicate tool blocks causing 'tool has already been used' error in native protocol mode (PR #9275 by @daniel-lxs) +- Fix: Prevent duplicate tool_result blocks in native protocol mode for read_file (PR #9272 by @daniel-lxs) +- Fix: Correct OpenAI Native handling of encrypted reasoning blocks to prevent errors during condensing (PR #9263 by @hannesrudolph) +- Fix: Disable XML parser for native tool protocol to prevent parsing conflicts (PR #9277 by @daniel-lxs) + +## [3.32.0] - 2025-11-14 + +![3.32.0 Release - GPT-5.1 models and OpenAI prompt caching](/releases/3.32.0-release.png) + +- Feature: Add GPT-5.1 models to OpenAI provider (PR #9252 by @hannesrudolph) +- Feature: Support for OpenAI Responses 24 hour prompt caching (PR #9259 by @hannesrudolph) +- Fix: Repair the share button in the UI (PR #9253 by @hannesrudolph) +- Docs: Include PR numbers in the release guide to improve traceability (PR #9236 by @hannesrudolph) + +## [3.31.3] - 2025-11-13 + +![3.31.3 Release - Kangaroo Decrypting a Message](/releases/3.31.3-release.png) + +- Fix: OpenAI Native encrypted_content handling and remove gpt-5-chat-latest verbosity flag (#9225 by @politsin, PR by @hannesrudolph) +- Fix: Roo Code Cloud provider Anthropic input token normalization to avoid double-counting (thanks @hannesrudolph!) +- Refactor: Rename sliding-window to context-management and truncateConversationIfNeeded to manageContext (thanks @hannesrudolph!) + +## [3.31.2] - 2025-11-12 + +- Fix: Apply updated API profile settings when provider/model unchanged (#9208 by @hannesrudolph, PR by @hannesrudolph) +- Migrate conversation continuity to plugin-side encrypted reasoning items using Responses API for improved reliability (thanks @hannesrudolph!) +- Fix: Include mcpServers in getState() for auto-approval (#9190 by @bozoweed, PR by @daniel-lxs) +- Batch settings updates from the webview to the extension host for improved performance (thanks @cte!) +- Fix: Replace rate-limited badges with badgen.net to improve README reliability (thanks @daniel-lxs!) + +## [3.31.1] - 2025-11-11 + +![3.31.1 Release - Kangaroo Stuck in the Clouds](/releases/3.31.1-release.png) + +- Fix: Prevent command_output ask from blocking in cloud/headless environments (thanks @daniel-lxs!) +- Add IPC command for sending messages to the current task (thanks @mrubens!) +- Fix: Model switch re-applies selected profile, ensuring task configuration stays in sync (#9179 by @hannesrudolph, PR by @hannesrudolph) +- Move auto-approval logic from `ChatView` to `Task` for better architecture (thanks @cte!) +- Add custom Button component with variant system (thanks @brunobergher!) + +## [3.31.0] - 2025-11-07 + +![3.31.0 Release - Todo List and Task Header Improvements](/releases/3.31.0-release.png) + +- Improvements to to-do lists and task headers (thanks @brunobergher!) +- Fix: Prevent crash when streaming chunks have null choices array (thanks @daniel-lxs!) +- Fix: Prevent context condensing on settings save when provider/model unchanged (#4430 by @hannesrudolph, PR by @daniel-lxs) +- Fix: Respect custom OpenRouter URL for all API operations (#8947 by @sstraus, PR by @roomote) +- Add comprehensive error logging to Roo Cloud provider (thanks @daniel-lxs!) +- UX: Less caffeinated kangaroo (thanks @brunobergher!) + +## [3.30.3] - 2025-11-06 + +![3.30.3 Release - Moonshot Brain](/releases/3.30.3-release.png) + +- Feat: Add kimi-k2-thinking model to Moonshot provider (thanks @daniel-lxs!) +- Fix: Auto-retry on empty assistant response to prevent task failures (#9076 by @Akillatech, PR by @daniel-lxs) +- Fix: Use system role for OpenAI Compatible provider when streaming is disabled (#8215 by @whitfin, PR by @roomote) +- Fix: Prevent notification sound on attempt_completion with queued messages (#8537 by @hannesrudolph, PR by @roomote) +- Feat: Auto-switch to imported mode with architect fallback for better mode detection (#8239 by @hannesrudolph, PR by @daniel-lxs) +- Feat: Add MiniMax-M2-Stable model and enable prompt caching (#9070 by @nokaka, PR by @roomote) +- Feat: Improve diff appearance in main chat view (thanks @hannesrudolph!) +- UX: Home screen visuals (thanks @brunobergher!) +- Docs: Clarify that setting 0 disables Error & Repetition Limit (thanks @roomote!) +- Chore: Update dependency @changesets/cli to v2.29.7 (thanks @renovate!) + ## [3.30.2] - 2025-11-05 ![3.30.2 Release - Eliminating UI Flicker](/releases/3.30.2-release.png) diff --git a/README.md b/README.md index 14de4ab109..e45e471177 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@

- VS Code + VS Code + Installs + Rating X YouTube Join Discord @@ -35,7 +37,7 @@ - [简体中文](locales/zh-CN/README.md) - [繁體中文](locales/zh-TW/README.md) - ... - + --- @@ -167,16 +169,6 @@ We love community contributions! Get started by reading our [CONTRIBUTING.md](CO --- -## Contributors - -Thanks to all our contributors who have helped make Roo Code better! - - - -[![Contributors](https://contrib.rocks/image?repo=RooCodeInc/roo-code&max=120&columns=12&cacheBust=0000000000)](https://github.com/RooCodeInc/roo-code/graphs/contributors) - - - ## License [Apache 2.0 © 2025 Roo Code, Inc.](./LICENSE) diff --git a/apps/web-roo-code/src/app/reviewer/content.ts b/apps/web-roo-code/src/app/reviewer/content.ts index 58c15dc2d0..988dee73a1 100644 --- a/apps/web-roo-code/src/app/reviewer/content.ts +++ b/apps/web-roo-code/src/app/reviewer/content.ts @@ -10,10 +10,10 @@ export const content: AgentPageContent = { agentName: "PR Reviewer", hero: { icon: "GitPullRequest", - heading: "Get comprehensive code reviews that save you time, not tokens.", + heading: "Code reviews that catch what other AI tools (and most humans) miss.", paragraphs: [ - "Regular AI code review tools cap model usage to protect their margins from fixed monthly prices. That leads to shallow prompts, limited context, and missed issues.", - "Roo Code's PR Reviewer flips the script: you bring your own key and leverage it to the max – to find real issues, increase code quality and keep your pull request queue moving.", + "Run-of-the-mill, token-saving AI code review tools will surely catch syntax errors and style issues, but they'll usually miss the bugs that actually matter: logic flaws, security vulnerabilities, and misunderstood requirements.", + "Roo Code's PR Reviewer uses advanced reasoning models and full repository context to find the issues that slip through—before they reach production.", ], image: { url: hero.src, @@ -60,34 +60,33 @@ export const content: AgentPageContent = { ], }, whyBetter: { - heading: "Why Roo's PR Reviewer is so much better", + heading: "Why Roo's PR Reviewer is different", features: [ { - title: "Our agents, your provider keys", + title: "Bring your own key, get uncompromised reviews", paragraphs: [ - "We orchestrate the review, optimize the hell out of the prompts, integrate with GitHub, keep you properly posted.", - "We're thoughtful about token usage, but not incentivized to skimp to grow our margins.", + "Most AI review tools use fixed pricing, which means they skimp on tokens to protect their margins. That leads to shallow analysis and missed issues.", + "With Roo, you bring your own API key. We optimize prompts for depth, not cost-cutting, so reviews focus on real problems like business logic, security vulnerabilities, and architectural issues.", ], icon: "Blocks", }, { - title: "Advanced reasoning and workflows", + title: "Advanced reasoning that understands what matters", description: - "We optimize for state-of-the-art reasoning models and leverage powerful workflows (Diff analysis → Context Gathering → Impact Mapping → Contract checks) to produce crisp, actionable comments at the right level.", + "We leverage state-of-the-art reasoning models with sophisticated workflows: diff analysis, context gathering, impact mapping, and contract validation. This catches the subtle bugs that surface-level tools miss—misunderstood requirements, edge cases, and integration risks.", icon: "ListChecks", }, { - title: "Fully repository-aware", + title: "Repository-aware, not snippet-aware", description: - "Reviews traverse code ownership, dependency graphs, and historical patterns to surface risk and deviations, not noise.", + "Roo analyzes your entire codebase context—dependency graphs, code ownership, team conventions, and historical patterns. It understands how changes interact with existing systems, not just whether individual lines look correct.", icon: "BookMarked", }, ], }, cta: { - heading: "Stop wasting time.", - description: - "Give Roo Code's PR Reviewer your model key and turn painful reviews into a tangible quality advantage.", + heading: "Ready for better code reviews?", + description: "Start finding the issues that matter with AI-powered reviews built for depth, not cost-cutting.", buttonText: "Start 14-day Free Trial", }, } diff --git a/apps/web-roo-code/src/app/shared/AgentLandingContent.tsx b/apps/web-roo-code/src/app/shared/AgentLandingContent.tsx index 70fb3cde32..8d99c03355 100644 --- a/apps/web-roo-code/src/app/shared/AgentLandingContent.tsx +++ b/apps/web-roo-code/src/app/shared/AgentLandingContent.tsx @@ -19,7 +19,6 @@ import { Button } from "@/components/ui" import { AnimatedBackground } from "@/components/homepage" import { AgentCarousel } from "@/components/reviewer/agent-carousel" import { EXTERNAL_LINKS } from "@/lib/constants" -import { trackGoogleAdsConversion } from "@/lib/analytics/google-ads" import { type AgentPageContent, type IconName } from "./agent-page-content" /** @@ -47,13 +46,13 @@ export function AgentLandingContent({ content }: { content: AgentPageContent }) return ( <> {/* Hero Section */} -

+
-
-
+
+
-

+

{content.hero.icon && (() => { const Icon = getIcon(content.hero.icon) @@ -62,7 +61,7 @@ export function AgentLandingContent({ content }: { content: AgentPageContent }) {content.hero.heading}

-
+
{content.hero.paragraphs.map((paragraph, index) => (

{paragraph}

))} @@ -97,7 +96,6 @@ export function AgentLandingContent({ content }: { content: AgentPageContent }) href={EXTERNAL_LINKS.CLOUD_APP_SIGNUP_PRO} target="_blank" rel="noopener noreferrer" - onClick={trackGoogleAdsConversion} className="flex w-full items-center justify-center"> {content.hero.cta.buttonText} @@ -110,23 +108,16 @@ export function AgentLandingContent({ content }: { content: AgentPageContent })
{content.hero.image && ( -
-
-
- {content.hero.image.alt -
+
+
+ {content.hero.image.alt
)} @@ -226,7 +217,6 @@ export function AgentLandingContent({ content }: { content: AgentPageContent }) href={EXTERNAL_LINKS.CLOUD_APP_SIGNUP_PRO} target="_blank" rel="noopener noreferrer" - onClick={trackGoogleAdsConversion} className="flex items-center justify-center"> {content.cta.buttonText} diff --git a/apps/web-roo-code/src/components/providers/google-analytics-provider.tsx b/apps/web-roo-code/src/components/providers/google-analytics-provider.tsx deleted file mode 100644 index 7c0a7edfc6..0000000000 --- a/apps/web-roo-code/src/components/providers/google-analytics-provider.tsx +++ /dev/null @@ -1,60 +0,0 @@ -"use client" - -import { useEffect, useState } from "react" -import Script from "next/script" -import { hasConsent, onConsentChange } from "@/lib/analytics/consent-manager" - -// Google Tag Manager ID -const GTM_ID = "AW-17391954825" - -/** - * Google Analytics Provider - * Implements Google's standard gtag.js loading pattern - */ -export function GoogleAnalyticsProvider({ children }: { children: React.ReactNode }) { - const [shouldLoad, setShouldLoad] = useState(false) - - useEffect(() => { - // Check initial consent status - if (hasConsent()) { - setShouldLoad(true) - } - - // Listen for consent changes - const unsubscribe = onConsentChange((consented) => { - if (consented) { - setShouldLoad(true) - } - }) - - return unsubscribe - }, []) - - return ( - <> - {shouldLoad && ( - <> - {/* Google tag (gtag.js) */} - - - )} - {children} - - ) -} - -// Declare global types for TypeScript -declare global { - interface Window { - dataLayer: unknown[] - gtag: (...args: unknown[]) => void - } -} diff --git a/apps/web-roo-code/src/components/providers/google-tag-manager-provider.tsx b/apps/web-roo-code/src/components/providers/google-tag-manager-provider.tsx new file mode 100644 index 0000000000..d08281896c --- /dev/null +++ b/apps/web-roo-code/src/components/providers/google-tag-manager-provider.tsx @@ -0,0 +1,65 @@ +"use client" + +import { useEffect, useState } from "react" +import Script from "next/script" +import { hasConsent, onConsentChange } from "@/lib/analytics/consent-manager" + +// Google Tag Manager Container ID +const GTM_ID = "GTM-M2JZHV8N" + +/** + * Google Tag Manager Provider + * Loads GTM only after user consent is given, following GDPR requirements + */ +export function GoogleTagManagerProvider({ children }: { children: React.ReactNode }) { + const [shouldLoad, setShouldLoad] = useState(false) + + useEffect(() => { + // Check initial consent status + if (hasConsent()) { + setShouldLoad(true) + } + + // Listen for consent changes + const unsubscribe = onConsentChange((consented) => { + if (consented) { + setShouldLoad(true) + } + }) + + return unsubscribe + }, []) + + return ( + <> + {shouldLoad && ( + <> + {/* Google Tag Manager Script */} +