Skip to content

🔴 URGENT: fix(i18n) resolve stale translations in memoized dialog components#419

Closed
DScoNOIZ wants to merge 65 commits into
Zoo-Code-Org:mainfrom
DScoNOIZ:main
Closed

🔴 URGENT: fix(i18n) resolve stale translations in memoized dialog components#419
DScoNOIZ wants to merge 65 commits into
Zoo-Code-Org:mainfrom
DScoNOIZ:main

Conversation

@DScoNOIZ
Copy link
Copy Markdown

@DScoNOIZ DScoNOIZ commented May 31, 2026

Fixes issue with stale translations in memoized dialog components.

roomote Bot and others added 30 commits May 16, 2026 19:11
* test(list-files,search-files): unskip read-only e2e tools

* chore: tighten list_files replay predicates

* test(e2e): replace opaque smoke codes with explicit instructions

* test(e2e): log say messages when running against real endpoints

* test(e2e): restore replay result validation

* test(e2e): address review feedback on readonly tool fixtures

* fix(e2e): address readonly tool review feedback

* test(e2e): address search-files review feedback

* test: fix Windows list-files cwd assertions

* test: fix Windows list-files expected file path

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
* test(read-file): unskipping read-file tests

* test(list-files,search-files): unskip read-only e2e tools

* test: unskip mutating vscode e2e tool suites

* test(e2e): replace opaque smoke codes with explicit instructions

* test(e2e): address review feedback on readonly tool fixtures

* test(list-files,search-files): unskip read-only e2e tools

* test(e2e): replace opaque smoke codes with explicit instructions

* test(e2e): address review feedback on readonly tool fixtures

* test(e2e): address search-files review feedback

* test(e2e): address mutating tool review feedback

* test: validate mutating replay payload fixtures

* test: drop read-file fixture whitespace churn

---------

Co-authored-by: Elliott de Launay <edelauna@gmail.com>
Co-authored-by: Roomote <roomote@roocode.com>
…-Org#160)

* fix: cap default glm output reservation

* test: align zai e2e max_tokens expectations

---------

Co-authored-by: Roomote <roomote@roocode.com>
* update default zai model to glm-5.1

* change default model to glm-4.7 per coding plan recs
Co-authored-by: Roomote <roomote@roocode.com>
* test: add xai provider e2e coverage

* test(xai): updates from local testing

* fix(api): dedupe Responses API streamed tool calls

* Fix Z.ai e2e state reset and Responses API tool fallback

* Fix xAI e2e probe isolation

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Naved  Merchant <naved.merchant@gmail.com>
* test(e2e): unskip use_mcp_tool replay coverage

* test(e2e): relax mcp completion wording checks

* test(e2e): use real MCP prompts in use_mcp_tool suite

* test(e2e): unskip use_mcp_tool replay coverage with local MCP server

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
* refactor(core): extract monolith helpers

Refs Zoo-Code-Org#8

* fix: address PR 27 review feedback

* fix: defensively copy pending edit images

* fix: preserve reasoning summary field

* test: cover api conversation edge cases

* docs: clarify reasoning summary fallback
* FEATURE: Add Xiaomi MiMo as a first-class API provider

- New MimoHandler with reasoning_content passthrough for multi-turn tool calling
- Custom message conversion preserving MiMo's interleaved thinking chain
- Strip OpenAI-specific extensions (strict, additionalProperties) from tool schemas
- Models: mimo-v2.5-pro, mimo-v2.5, mimo-v2-flash with official pricing
- UI settings with 4 base URL options (3 Token Plan regions + Pay-as-you-go)
- Full wiring: types, schema, model picker, i18n, provider config

* Update openrouter.ts

* Preserve Mimo reasoning fields & switch AMS endpoint

Update Mimo provider config and UI to use the token-plan-ams endpoint instead of the old FRA host. Allow Mimo assistant messages with string content to include and preserve a reasoning_content field when present. Also avoid attaching mapped reasoning_details when converting messages for Mimo models (skip mapping if modelId matches /mimo/i) to preserve the provider's original shape. Types, API handler, transform logic, and the settings UI were updated to keep Mimo-specific reasoning data intact and align the endpoint selection.

* Add MiMo i18n translations to all 17 locales and unit tests

Also hide the "not sure which model" hint for the MiMo provider
since it's a static model list, not fetched dynamically.

* Address CodeRabbit review feedback

Fix Japanese translation consistency, strengthen base URL tests to
verify actual values, and add ModelPicker test for MiMo hint hiding.

* Expand MiMo test coverage and remove dev/null files from PR

Added tests for tool_call_partial streaming, cache token usage,
API error handling, message conversion pipeline, empty delta chunks,
and tools parameter presence/absence. Removed dev/null/ hook files
that were accidentally included in the branch.

* Use data-testid for automaticFetch hint instead of i18n key matching

* Remove mimo-v2-flash model that no longer supports thinking mode

* Replace mimo-v2-flash with mimo-v2-pro model

* Drop mimo-v2-flash since it doesn't support thinking mode

* Address maintainer feedback: revert unrelated changes, add i18n, fix stream_options

* Update doc links to use puter developer URLs

* Fix i18n: JP spacing, FR translations, add multimodal support to message conversion

* Add docstrings and document mimo-v2-flash exclusion rationale

* Address edelauna review: sanitize tool IDs, use handleProviderError, fix prompt cache, clean up comments

* Fold text into last tool message to preserve reasoning continuity

* Refactor: use shared convertToR1Format, processToolCalls, cleanup unused imports/props

* Remove dead temperature param, add 2-tier pricing, clarify strict stripping

* Remove strict/additionalProperties stripping — proxy no longer rejects it

* Use longContextPricing instead of tiers for cost calculation

* Remove stale convertToolsForOpenAI tests (stripping removed)
…#199)

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Naved  Merchant <naved.merchant@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Roomote <roomote@roocode.com>
…Org#207)

* chore: split packages/core integration coverage lane

* [Chore] Fix core integration lane follow-up issues

* [Chore] Relax Windows worktree integration matching

* [Chore] Align worktree delete integration assertion with service contract

* chore: Move core dual-lane test:coverage inside the package

* chore: Flag core unit/integration Codecov uploads separately

* chore: tighten core coverage lane wiring

* Optimize CI cache and coverage uploads

* chore: add merge queue triggers for required CI

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
…-Org#210)

* test: add comprehensive unit tests for MimoHandler provider

Add 45 unit tests covering the MimoHandler provider:
- Constructor: model selection, default model fallback, base URL config
- getModel(): model info for v2.5-pro, v2.5, unknown models
- completePrompt(): happy path, multi-turn, JSON mode, model override
- createMessage() with Anthropic format and custom baseUrl
- Edge cases: empty choices, null content, network/rate limit errors
- Streaming: multi-tool calls, parallel tools, tool call IDs, interruption
- Sanitization: model ID, tool call IDs, prompt caching
- convertToR1Format: empty arrays, thinking blocks, nested structures

All 45 tests passing.

* fix: sanitize mimo streaming tool call ids

---------

Co-authored-by: Roomote <roomote@roocode.com>
* test(tools): add unit tests for SwitchModeTool

- Add comprehensive test suite for SwitchModeTool (18 tests)
- Cover mode slug validation (valid/invalid/missing)
- Test error propagation from mode loading
- Validate approval flow with correct params
- Test mode switching delegation to Controller
- Verify resolve() returns correct messages for both paths
- Follow existing test patterns from ask.spec.ts

* test: tighten switch mode review feedback cases

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…Org#226)

Closes Zoo-Code-Org#193

The temporary diagnostics file generated via the 'Report Issue' feature
retained the legacy 'roo-diagnostics-' prefix from the Roo Code fork.
This commit replaces it with 'zoo-diagnostics-' to match Zoo Code
branding.

Changes:
- diagnosticsHandler.ts: rename temp file template from
  roo-diagnostics- to zoo-diagnostics-
- diagnosticsHandler.spec.ts: update two assertions that matched the
  old prefix
* Merge upstream/main (Roo Code sunset) into Zoo Code

* test: updating e2e collision and optimization 4.7 tests

* chore: remove web-roo-code website and evals packages

* fix: deepseek e2e fixture matching and mock model list fallback

* refactor: make reasoningEffort optional in GetModelReasoningOptions

* test(deepseek): updating fixture format

* test: adding back coverage for telemetry and marketplace

* fix(Announcement): reverting finalRelease message key

* fix(ModeSelector): adding back telemetry

* fix(DismissibleUpsell): adding back telemetry

* fix(Announcement): adding back className

* fix(McpView): keeping marketplace view

* fix: adding back marketplace buttons

* fix: adding back telemetry

* fix: merge history

* test: bumping coverage

* merge: feedback
…oo-Code-Org#148)

* test: add Gemini provider e2e coverage

* fix(gemini): INVALID_ARGUMENT when loaded too many MCPs

* fix(gemini): resolve $ref, deep-merge allOf, align e2e fixtures

* refactor: dropping extra command

* fix: preserve top-level Gemini schema fields with allOf

* fix: guard recursive Gemini schema refs

* fix(gemini): preserve keyword-named tool parameters during schema sanitization

* test(gemini-e2e): wire aimock recording and use real model id

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
…o-Code-Org#154) (Zoo-Code-Org#240)

remark-gfm treats a single ~ around text (e.g. "~10", "1~3") as strikethrough,
unlike VS Code's markdown. Pass { singleTilde: false } so only "~~text~~"
renders as strikethrough.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…ode-Org#215) (Zoo-Code-Org#233)

* fix(openai): omit temperature for models that don't support it (Zoo-Code-Org#215)

claude-opus-4-7 (and similar) reject requests through the OpenAI-Compatible
provider with a 400 error because 'temperature' is deprecated/unsupported.
Honor the model's existing supportsTemperature flag (already respected by
openai-native, gemini, lite-llm and vercel-ai-gateway) and omit temperature
from the streaming request when it is explicitly set to false. undefined keeps
sending temperature, preserving current behavior for all other models.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* test(openai): cover both temperature branches behind supportsTemperature gate (Zoo-Code-Org#215)

Add two tests so the temperature expression's branches are fully exercised:
- explicit modelTemperature (left side of the `??`)
- deepseek-reasoner default of DEEP_SEEK_DEFAULT_TEMPERATURE (truthy ternary)

Closes the partial-branch gap codecov/patch flagged on line 162.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
* chore: prepare v3.55.0 release

* chore: genericize release announcement highlight keys

* chore: remove v3.55.0 release artwork

---------

Co-authored-by: Roomote <roomote@roocode.com>
…e-Org#260)

* docs: clarify stable release version lane

* docs: use generic release version placeholders

---------

Co-authored-by: Roomote <roomote@roocode.com>
…Code-Org#245) (Zoo-Code-Org#261)

releaseTerminalsForTask only disassociated the terminal (taskId = undefined)
without aborting a still-running command, so cancel (✕) left the process
orphaned and the terminal stuck "busy" until a manual kill. Now abort the
running process for busy terminals on release. Adds TerminalRegistry tests.

Co-authored-by: Armando Vaquera <263793884+proyectoauraorg@users.noreply.github.com>
…-Org#186) (Zoo-Code-Org#230)

* fix(diff): repair truncated Grok diffs by reinserting missing markers (Zoo-Code-Org#186)

Grok frequently truncates streamed diffs, leaving SEARCH blocks without the
======= separator and/or the >>>>>>> REPLACE closer, which makes applyDiff
fail with 'Expected ======= was not found'. repairTruncatedDiff() detects
incomplete blocks and reinserts the missing markers while preserving valid
blocks and escaped markers.

* test(diff): add fixture-based regression tests for truncated Grok diffs (Zoo-Code-Org#186)

Per review feedback: end-to-end applyDiff() regression guards using realistic
truncated-Grok fixtures (missing >>>>>>> REPLACE, missing ======= separator),
plus a well-formed multi-block diff that must pass through unchanged.

* refactor(diff): address CodeRabbit review on truncated-diff repair (Zoo-Code-Org#186)

- Use a local repairedDiff in applyDiff instead of reassigning the diffContent
  parameter, keeping the original input observable.
- When a block has a closer but no ======= separator, splice the separator in
  before the existing >>>>>>> REPLACE rather than synthesizing a second closer.
- Strip leading Grok header directives (:start_line:, :end_line:, -------) before
  the first-line-is-SEARCH heuristic so metadata isn't treated as content; the
  directives are preserved on the SEARCH section.

* fix: remove unused needsRepair variable in repairTruncatedDiff

Address review feedback from @edelauna (code review #3284681514):
needsRepair was assigned but never read, making it a dead store.
The variable served no functional purpose in the repair loop,
so it has been removed.

---------

Co-authored-by: Armando Vaquera <263793884+proyectoauraorg@users.noreply.github.com>
* chore(webview): migrate build to Vite 8

* update lockfile

* remove minify on nightly mode
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 31, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR fixes stale translations in memoized consumers when language changes by adding i18n.language to the translate callback dependency array, with comprehensive test coverage for language switching scenarios. It also refines task delegation logic to more explicitly validate parent state before delegation and exempts delegated subtasks from tool failure blocks.

Changes

Translation Language Switching Fix

Layer / File(s) Summary
TranslationContext language dependency fix
webview-ui/src/i18n/TranslationContext.tsx
Updated useCallback implementation of the translate function to include i18n.language in the dependency array, with adjusted eslint suppression comments; ensures translate callback updates when language changes.
Test setup and language switching coverage
webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx
Refactored test mocks using vi.hoisted to centralize language state and translation data; extended TestComponent with interpolation rendering; added beforeEach reset hook; introduced regression tests validating that memoized and non-memoized consumers re-render and update translated strings after language change; added interpolation assertion for notifications.error.
TypeScript compiler configuration update
webview-ui/tsconfig.json
Added compilerOptions.ignoreDeprecations set to 6.0 to adjust deprecation warning handling.

Task Delegation Logic Refinement

Layer / File(s) Summary
Subtask completion failure guard
src/core/tools/AttemptCompletionTool.ts
attempt_completion is now prevented on tool failure only for non-delegated tasks; subtasks with parentTaskId are exempt from the "tool failed this turn" guard.
Parent state validation during delegation
src/core/tools/AttemptCompletionTool.ts
Refactored delegation path to directly check parent state at delegation time; when child is active, the tool fetches parent history to explicitly verify the parent is still awaiting the child; if parent is no longer awaiting, logs a warning and falls through to normal completion flow.
Error messages and delegation fallback handling
src/core/tools/AttemptCompletionTool.ts, src/core/webview/ClineProvider.ts
Updated delegation-history failure log message to reference child task id; added warning when reopenParentFromDelegation returns false; simplified reopenParentFromDelegation validation by removing cancelledDelegationChildIds blacklist check and relying only on status and awaitingChildId comparison.

Sequence Diagrams

sequenceDiagram
  participant User
  participant UI as TranslationContext
  participant i18n as i18n Language State
  participant Consumer as Memoized Consumer

  User->>i18n: changeLanguage("ru")
  i18n->>UI: language changed to "ru"
  UI->>UI: translate callback recreated (i18n.language in deps)
  UI->>Consumer: new translate callback provided
  Consumer->>Consumer: re-render with updated translations
  Consumer->>User: display "Russian translations"
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested reviewers

  • taltas
  • hannesrudolph

🐰 Translations now sing in every tongue,
Parents and children, both young and sprung,
With language switching clean and bright,
And delegations perfectly right!
The memoized minds remember the change—
No stale words in this updated range! 🌍✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning Description is incomplete; it lacks the required Related GitHub Issue link, Test Procedure, and Pre-Submission Checklist sections specified in the template. Add the missing template sections: link to the approved GitHub Issue under 'Related GitHub Issue', detail test procedures in 'Test Procedure', and complete the 'Pre-Submission Checklist' with checkmarks.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed Title clearly identifies the main change: fixing stale translations in memoized dialog components via the i18n translation mechanism.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
webview-ui/src/i18n/TranslationContext.tsx (1)

44-44: ⚡ Quick win

Add a regression test for language-change re-render behavior.

This fix is correct, but please add a Vitest case that switches language and asserts useAppTranslation() consumers (including memoized dialog-like consumers) receive updated strings, so this doesn’t regress.

As per coding guidelines, "webview-ui/src/**/*.{ts,tsx}: Prefer local webview-ui tests for React/webview behavior such as component rendering, local state, hooks, form dirty-state, validation, or prop wiring. Add or update Vitest coverage under webview-ui/src/**/__tests__ instead of reaching for apps/vscode-e2e."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/i18n/TranslationContext.tsx` at line 44, Add a Vitest unit
test that verifies language-change re-rendering: mount a small test app that
uses TranslationContext/TranslationProvider and a consumer hook
useAppTranslation (include a memoized dialog-like consumer component) then call
i18n.changeLanguage inside act and assert that the rendered strings update
accordingly; place the test under the webview-ui src tests for React behavior,
use testing-library/react to render and query text, and ensure you test both a
normal consumer and a memoized consumer to prevent regressions of the
TranslationContext update behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@webview-ui/src/i18n/TranslationContext.tsx`:
- Line 44: Add a Vitest unit test that verifies language-change re-rendering:
mount a small test app that uses TranslationContext/TranslationProvider and a
consumer hook useAppTranslation (include a memoized dialog-like consumer
component) then call i18n.changeLanguage inside act and assert that the rendered
strings update accordingly; place the test under the webview-ui src tests for
React behavior, use testing-library/react to render and query text, and ensure
you test both a normal consumer and a memoized consumer to prevent regressions
of the TranslationContext update behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c5fe08e-4fc1-4335-90dd-122b1b789bd9

📥 Commits

Reviewing files that changed from the base of the PR and between 71db2e6 and ddeb2b7.

📒 Files selected for processing (1)
  • webview-ui/src/i18n/TranslationContext.tsx

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx (2)

101-109: ⚡ Quick win

Interpolation test no longer exercises interpolation.

The notifications.error mock value ("Operation failed", Line 11) contains no {{message}} placeholder, so the result.replace("{{message}}", ...) branch in mockI18n.t is never hit. The assertion passes even though { message: "Test error" } is ignored, so the test named "should handle interpolation correctly" validates nothing about interpolation.

♻️ Restore a placeholder so interpolation is actually asserted
-		"notifications.error": "Operation failed",
+		"notifications.error": "Operation failed: {{message}}",
-		"notifications.error": "Ошибка операции",
+		"notifications.error": "Ошибка операции: {{message}}",
-		expect(getByTestId("translation-interpolation")).toHaveTextContent("Operation failed")
+		expect(getByTestId("translation-interpolation")).toHaveTextContent("Operation failed: Test error")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx` around lines 101 -
109, The test "should handle interpolation correctly" never exercises
interpolation because the mocked translation value for notifications.error lacks
the {{message}} placeholder; update the mock in the test (mockI18n.t or the
notifications.error entry used by TranslationProvider/TestComponent) to include
the placeholder (e.g., "Operation failed: {{message}}") and change the assertion
to expect the interpolated string (e.g., "Operation failed: Test error") so the
result.replace("{{message}}", ...) branch in mockI18n.t is actually executed and
verified.

111-171: 🏗️ Heavy lift

Strengthen the memoized consumer regression assertion

TranslationProvider already recreates the translate callback on language changes via useCallback(..., [i18n, i18n.language]), and webview-ui/vite.config.ts enables babel-plugin-react-compiler. However, the test primarily asserts rendered text after mockI18n.changeLanguage("ru") + rerender, so it’s still tightly coupled to the test environment’s transform/re-render behavior.

To make the test guard the compiler-sensitive bug directly, assert that the t function reference from useAppTranslation() changes when the language switches (not just the output strings), e.g. by capturing const { t } = useAppTranslation() in a probe component and expect(tAfter).not.toBe(tBefore). (See webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx 111-171 and 173-209.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx` around lines 111 -
171, The test should assert that the translate function identity from
useAppTranslation() changes when language changes: add a small Probe component
that calls const { t } = useAppTranslation() and stores that t reference (e.g.
in a ref or exported variables accessible to the test) before and after calling
mockI18n.changeLanguage("ru"); keep the existing render/rerender of
TranslationProvider + consumers, then assert expect(tAfter).not.toBe(tBefore).
Reference the useAppTranslation hook, TranslationProvider,
mockI18n.changeLanguage, and the existing MemoizedConsumer/NormalConsumer when
adding the Probe and the before/after assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx`:
- Around line 101-109: The test "should handle interpolation correctly" never
exercises interpolation because the mocked translation value for
notifications.error lacks the {{message}} placeholder; update the mock in the
test (mockI18n.t or the notifications.error entry used by
TranslationProvider/TestComponent) to include the placeholder (e.g., "Operation
failed: {{message}}") and change the assertion to expect the interpolated string
(e.g., "Operation failed: Test error") so the result.replace("{{message}}", ...)
branch in mockI18n.t is actually executed and verified.
- Around line 111-171: The test should assert that the translate function
identity from useAppTranslation() changes when language changes: add a small
Probe component that calls const { t } = useAppTranslation() and stores that t
reference (e.g. in a ref or exported variables accessible to the test) before
and after calling mockI18n.changeLanguage("ru"); keep the existing
render/rerender of TranslationProvider + consumers, then assert
expect(tAfter).not.toBe(tBefore). Reference the useAppTranslation hook,
TranslationProvider, mockI18n.changeLanguage, and the existing
MemoizedConsumer/NormalConsumer when adding the Probe and the before/after
assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0041f2f7-f5dd-4c20-8ffa-4ddf4a2900f0

📥 Commits

Reviewing files that changed from the base of the PR and between ddeb2b7 and ca1b751.

📒 Files selected for processing (3)
  • webview-ui/src/i18n/TranslationContext.tsx
  • webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx
  • webview-ui/tsconfig.json
✅ Files skipped from review due to trivial changes (1)
  • webview-ui/tsconfig.json

@DScoNOIZ DScoNOIZ changed the title 🔴 URGENT: Fix i18n translation not updating in dialogs (React.memo + useCallback bug) fix(i18n): resolve stale translations in memoized dialog components May 31, 2026
@DScoNOIZ DScoNOIZ changed the title fix(i18n): resolve stale translations in memoized dialog components 🔴 URGENT: fix(i18n) resolve stale translations in memoized dialog components May 31, 2026
@DScoNOIZ
Copy link
Copy Markdown
Author

@coderabbitai The regression test has already been added in this PR — see webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx. It covers:

  1. Normal consumer re-renders on language change
  2. React.memo-wrapped consumer re-renders on language change
  3. Delete dialog translations update correctly after language switch

All 4 tests pass ✅

The fix ensures i18n.language is in the useCallback dependency array so the translate function reference updates when language changes, triggering proper re-renders across all useAppTranslation() consumers — including memoized dialog components.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 31, 2026

Tip

For best results, initiate chat on the files or code changes.

@DScoNOIZ Thanks for pointing that out! The test coverage in webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx looks comprehensive — covering normal consumers, React.memo-wrapped consumers, and the delete dialog scenario. The fix adding i18n.language to the useCallback dependency array is well-validated. ✅

(∩^ω^)⊃━☆゚.*・。゚


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx (1)

101-109: ⚡ Quick win

Test name doesn't match what's actually tested.

The test is named "should handle interpolation correctly" but the translation key "notifications.error" has no interpolation placeholder in the mock (line 11 shows "Operation failed" with no {{message}}). The test verifies that passing options doesn't break translation, but doesn't verify that interpolation actually works.

Consider either:

  1. Using a translation with a {{message}} placeholder and asserting the interpolated result, or
  2. Renaming to "should handle translation options without breaking"
✨ Option 1: Test actual interpolation

Add a translation with a placeholder to the mock (around line 11):

 	en: {
 		"settings.autoApprove.title": "Auto-Approve",
-		"notifications.error": "Operation failed",
+		"notifications.error": "Operation failed: {{message}}",

And update the Russian translation similarly (around line 23):

 	ru: {
 		"settings.autoApprove.title": "Авто-Одобрение",
-		"notifications.error": "Ошибка операции",
+		"notifications.error": "Ошибка операции: {{message}}",

Then update the assertion (line 108):

-		expect(getByTestId("translation-interpolation")).toHaveTextContent("Operation failed")
+		expect(getByTestId("translation-interpolation")).toHaveTextContent("Operation failed: Test error")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx` around lines 101 -
109, The test name "should handle interpolation correctly" is misleading because
the mocked translation for "notifications.error" has no {{message}} placeholder;
either change the test to actually assert interpolation by updating the mock
translations to include a placeholder for "notifications.error" (and matching
Russian variant) and update the assertion in TranslationContext.spec.tsx to
expect the interpolated string from TestComponent, or rename the test to "should
handle translation options without breaking" and keep the current mock and
assertion; locate the test and mocks around the
TestComponent/TranslationProvider usage and the "notifications.error" key to
apply the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx`:
- Around line 101-109: The test name "should handle interpolation correctly" is
misleading because the mocked translation for "notifications.error" has no
{{message}} placeholder; either change the test to actually assert interpolation
by updating the mock translations to include a placeholder for
"notifications.error" (and matching Russian variant) and update the assertion in
TranslationContext.spec.tsx to expect the interpolated string from
TestComponent, or rename the test to "should handle translation options without
breaking" and keep the current mock and assertion; locate the test and mocks
around the TestComponent/TranslationProvider usage and the "notifications.error"
key to apply the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c5e544c7-86f8-4039-af68-7b34fc4d0910

📥 Commits

Reviewing files that changed from the base of the PR and between 55076fa and 0ce3998.

📒 Files selected for processing (4)
  • src/package.json
  • webview-ui/src/i18n/TranslationContext.tsx
  • webview-ui/src/i18n/__tests__/TranslationContext.spec.tsx
  • webview-ui/tsconfig.json
✅ Files skipped from review due to trivial changes (2)
  • src/package.json
  • webview-ui/tsconfig.json

@navedmerchant
Copy link
Copy Markdown
Contributor

Please do not bump the version, it will be done when we do a weekly release

@navedmerchant
Copy link
Copy Markdown
Contributor

Also please check the tests are failing

* test: unskip subtasks e2e suite

* test: tighten subtasks cancellation replay

* test(e2e): validation and bumping codecov

* fix: prevent child delegation start after parent metadata failure

* chore: address delegation review cleanup

* fix: delegated subtask lifecycle races

* fix: harden delegated subtask cancellation

* test(e2e): simplyfying e2e tests

---------

Co-authored-by: Roomote <roomote@roocode.com>
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
@DScoNOIZ
Copy link
Copy Markdown
Author

DScoNOIZ commented Jun 1, 2026

Please do not bump the version, it will be done when we do a weekly release
I updated the version only because VISUAL STUDIO CODE doesn't apply updates to the installed .vsix if the package versions match. When merging, simply ignore this file. Best regards. I needed to test the package.

@DScoNOIZ
Copy link
Copy Markdown
Author

DScoNOIZ commented Jun 1, 2026

Also please check the tests are failing
All my tests pass perfectly. Is it the same for you?

proyectoauraorg and others added 3 commits June 1, 2026 13:30
… with native path (Zoo-Code-Org#222)

Add unit coverage for ReadFileTool: input validation, rooignore blocking,
directory/binary/image handling, image memory limits, approval flow, slice and
indentation modes, output structure, and the legacy multi-file format.

Source changes:
- Drop the temporary "[read_file] Legacy format detected" debug console.warn.
- Mirror the native path in the legacy read path: set didToolFailInCurrentTurn
  on rooignore blocks, directory reads, and read errors so a failed legacy read
  fails the tool turn consistently.
- Recognize re-hydrated bare-`files` calls in isLegacyReadFileParams (history
  persisted before the _legacyFormat flag existed).

Co-authored-by: Armando Vaquera <263793884+proyectoauraorg@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/webview/ClineProvider.ts`:
- Around line 3137-3189: In cancelTask’s success branch (the block that runs
when runDelegationTransition succeeds) clear the persisted child lineage before
re-creating the task: set historyItem.parentTaskId = undefined and
historyItem.rootTaskId = undefined, then await
this.updateTaskHistory(historyItem) (handle/log any update error similarly to
the failure branch) so the subsequent call to createTaskWithHistoryItem({
...historyItem, rootTask, parentTask }) will not rehydrate the child as
delegated; keep the existing local updates to parentTask/rootTask and the
cancelledDelegationChildIds deletion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 55b03c0e-1006-4fa4-bb90-a6a6a0b68e31

📥 Commits

Reviewing files that changed from the base of the PR and between 0ce3998 and 218d777.

📒 Files selected for processing (2)
  • src/core/tools/AttemptCompletionTool.ts
  • src/core/webview/ClineProvider.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/webview/ClineProvider.ts`:
- Around line 3137-3189: In cancelTask’s success branch (the block that runs
when runDelegationTransition succeeds) clear the persisted child lineage before
re-creating the task: set historyItem.parentTaskId = undefined and
historyItem.rootTaskId = undefined, then await
this.updateTaskHistory(historyItem) (handle/log any update error similarly to
the failure branch) so the subsequent call to createTaskWithHistoryItem({
...historyItem, rootTask, parentTask }) will not rehydrate the child as
delegated; keep the existing local updates to parentTask/rootTask and the
cancelledDelegationChildIds deletion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 55b03c0e-1006-4fa4-bb90-a6a6a0b68e31

📥 Commits

Reviewing files that changed from the base of the PR and between 0ce3998 and 218d777.

📒 Files selected for processing (2)
  • src/core/tools/AttemptCompletionTool.ts
  • src/core/webview/ClineProvider.ts
🛑 Comments failed to post (1)
src/core/webview/ClineProvider.ts (1)

3137-3189: ⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Task lineage restoration =="
rg -n -C3 '\b(parentTaskId|rootTaskId|parentTask|rootTask|historyItem)\b' src/core/task/Task.ts

echo
echo "== cancelTask detach branches =="
rg -n -C4 '\[cancelTask\]|parentTaskId: undefined|rootTaskId: undefined|parentTask = undefined|rootTask = undefined' \
  src/core/webview/ClineProvider.ts

echo
echo "== downstream uses of live parentTaskId =="
rg -n -C3 '\bparentTaskId\b' \
  src/core/tools/AttemptCompletionTool.ts \
  src/core/webview/ClineProvider.ts \
  src/core/task/Task.ts

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 31956


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate createTaskWithHistoryItem in ClineProvider.ts =="
rg -n "createTaskWithHistoryItem" src/core/webview/ClineProvider.ts

echo
echo "== Show implementation of createTaskWithHistoryItem (and createTaskFromHistory if any) =="
rg -n -C2 "async (createTaskWithHistoryItem|createTaskFromHistoryItem|createTaskWithHistory)" src/core/webview/ClineProvider.ts

echo
# Print a reasonable window around the definition(s)
python3 - <<'PY'
import re, subprocess, os, sys, textwrap, json, pathlib
from pathlib import Path

path="src/core/webview/ClineProvider.ts"
txt=Path(path).read_text(encoding='utf-8', errors='ignore').splitlines()
# find lines containing "createTaskWithHistoryItem("
idx=[i for i,l in enumerate(txt) if "createTaskWithHistoryItem" in l and "=>" not in l]
print("candidate lines:", idx[:20])
PY

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 1503


🏁 Script executed:

#!/bin/bash
set -euo pipefail

set -euo pipefail

path="src/core/webview/ClineProvider.ts"
echo "== Candidate definition/uses around createTaskWithHistoryItem in $path =="
rg -n "createTaskWithHistoryItem\(" "$path" | head -n 20

echo
# Get exact definition line numbers by searching for "createTaskWithHistoryItem(" and following for "async" or "public"
def_lines=$(rg -n "createTaskWithHistoryItem\(" "$path" | cut -d: -f1 | head -n 5 | tr '\n' ' ')
echo "Top 5 line numbers from matches: $def_lines"

# Print ranges around the first match lines (likely definition)
for ln in $(echo "$def_lines"); do
  start=$((ln-40))
  end=$((ln+40))
  echo
  echo "--- Context around line $ln ---"
  sed -n "${start},${end}p" "$path" | nl -ba | head -n 200
done

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 790


🏁 Script executed:

#!/bin/bash
set -euo pipefail

path="src/core/webview/ClineProvider.ts"

echo "== Candidate definition/uses around createTaskWithHistoryItem =="
rg -n "createTaskWithHistoryItem\(" "$path" | head -n 30

echo
echo "== Context around the earliest match (likely definition) =="
first=$(rg -n "createTaskWithHistoryItem\(" "$path" | head -n 1 | cut -d: -f1)
echo "first match line: $first"
start=$((first-60))
end=$((first+120))
sed -n "${start},${end}p" "$path" | nl -ba | head -n 260

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 745


🏁 Script executed:

#!/bin/bash
set -euo pipefail

path="src/core/webview/ClineProvider.ts"
# earliest match
first=$(rg -n "createTaskWithHistoryItem\(" "$path" | head -n 1 | cut -d: -f1)
echo "first match line: $first"
start=$((first-80))
end=$((first+200))
sed -n "${start},${end}p" "$path" | nl -ba | head -n 320

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 149


🏁 Script executed:

#!/bin/bash
set -euo pipefail
path="src/core/webview/ClineProvider.ts"

echo "== Earliest occurrence of createTaskWithHistoryItem( in ClineProvider.ts =="
first=$(rg -n "createTaskWithHistoryItem\(" "$path" | head -n 1 | cut -d: -f1)
echo "first match line: $first"

start=$((first-80))
end=$((first+260))
sed -n "${start},${end}p" "$path" | nl -ba

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 225


🏁 Script executed:

#!/bin/bash
set -euo pipefail

path="src/core/webview/ClineProvider.ts"

# Print the createTaskWithHistoryItem body (avoid `nl`, use `sed` with line ranges)
# We’ll grab a wider window around its definition.
start=930
end=1180
sed -n "${start},${end}p" "$path"

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 9502


🏁 Script executed:

#!/bin/bash
set -euo pipefail
path="src/core/webview/ClineProvider.ts"

# Print a broader window around cancelTask where the success/failure branches occur
start=3020
end=3210
sed -n "${start},${end}p" "$path"

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 6192


Fix success-path cancellation to clear the child’s persisted lineage (historyItem.parentTaskId/rootTaskId)

cancelTask()’s success branch only nulls the in-memory parentTask/rootTask locals; it does not clear historyItem.parentTaskId / historyItem.rootTaskId. Since createTaskWithHistoryItem({ ...historyItem, rootTask, parentTask }) passes that historyItem into new Task(...) and Task derives task.parentTaskId / task.rootTaskId from historyItem, the rehydrated child will still look delegated even though the delegated parent was detached (unlike the failure branch, which clears and persists the child lineage). This can cause incorrect delegation/subtask behavior later.

Mirror the failure branch by clearing + persisting the child history on the success path (set historyItem.parentTaskId = undefined and historyItem.rootTaskId = undefined, then await this.updateTaskHistory(historyItem)) before calling createTaskWithHistoryItem.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/ClineProvider.ts` around lines 3137 - 3189, In cancelTask’s
success branch (the block that runs when runDelegationTransition succeeds) clear
the persisted child lineage before re-creating the task: set
historyItem.parentTaskId = undefined and historyItem.rootTaskId = undefined,
then await this.updateTaskHistory(historyItem) (handle/log any update error
similarly to the failure branch) so the subsequent call to
createTaskWithHistoryItem({ ...historyItem, rootTask, parentTask }) will not
rehydrate the child as delegated; keep the existing local updates to
parentTask/rootTask and the cancelledDelegationChildIds deletion.

@DScoNOIZ DScoNOIZ changed the title 🔴 URGENT: fix(i18n) resolve stale translations in memoized dialog components fix(tree-sitter): re-enable Swift WASM tests with JIT warmup + docs Jun 4, 2026
@DScoNOIZ DScoNOIZ changed the title fix(tree-sitter): re-enable Swift WASM tests with JIT warmup + docs 🔴 URGENT: fix(i18n) resolve stale translations in memoized dialog components Jun 4, 2026
@DScoNOIZ DScoNOIZ closed this Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.