Repository navigation
feat(reborn): localize shell, chat, and extensions UI - #5685
Conversation
|
| Reviewer | State | Verdict | Findings | Last update |
|---|---|---|---|---|
ironloop/common-reviewer (reviewer) |
Superseded | N/A | N/A | 2026-07-07T09:53:42.610Z |
Reviewer summaries
| Reviewer | Detail |
|---|---|
ironloop/common-reviewer (reviewer) |
Superseded by a newer PR head. New head: c4c863e. Previous verdict: Approved. |
Recent activity
| Time | Reviewer | State | Detail |
|---|---|---|---|
| 2026-07-06T13:54:04.062Z | ironloop/common-reviewer (reviewer) |
Queued | Waiting for this reviewer lane to become available. |
| 2026-07-06T13:54:04.087Z | ironloop/common-reviewer (reviewer) |
Queued | Added to the local review work handoff. |
| 2026-07-06T13:54:07.898Z | ironloop/common-reviewer (reviewer) |
Started | Reviewer worker started attempt 1. |
| 2026-07-06T13:54:13.401Z | ironloop/common-reviewer (reviewer) |
Workspace ready | Prepared isolated checkout (merge_ref) at 4cb305e. |
| 2026-07-06T13:57:00.865Z | ironloop/common-reviewer (reviewer) |
Superseded | Old-head reviewer is still running after newer head c4c863e replaced it. Codex is reviewing; process live; elapsed 2m 48s; timeout in 17m 12s; last heartbeat 2026-07-06T13:57:00.865Z. Activity (stderr): ...ates/ironclaw_webui_v2/static/js/pages/extensions/hooks/useExtensions-pairing.test.mjs --- duration_ms: 93.107358 ty…. |
| 2026-07-06T13:57:11.763Z | ironloop/common-reviewer (reviewer) |
Result captured | Approved; 0 blocking findings. |
| 2026-07-06T13:57:11.763Z | ironloop/common-reviewer (reviewer) |
Completed | Review completed and terminal status was persisted. |
| 2026-07-07T09:53:42.610Z | ironloop/common-reviewer (reviewer) |
Superseded | A newer PR head replaced this review (c4c863e). |
Available commands
@ironloopai agents@ironloopai review@ironloopai review --agent <agent-id-or-alias>@ironloopai status
Run metadata
Admission: webhook accepted the request and IronLoop persisted review state before this projection.
|
@claude review |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (14)
💤 Files with no reviewable changes (14)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR localizes WebUI text across app shell, chat, extensions, Slack, and modal surfaces; adds locale packs for multiple languages; changes repeated locale registration to merge packs; and removes a static Slack pairing success message from the API response. ChangesWebUI i18n rollout
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
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. Comment |
Coverage ratchetReborn integration-tier coverageLine coverage (Reborn crates): 85.41% — 276407 / 323624 lines Per-crate breakdown (65 crates, lowest-covered first)
This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors. Exemptions (4 entry/entries excluded from the accounting above)
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
crates/ironclaw_webui_v2/static/js/components/sidebar-threads.js (1)
29-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLocalization wiring checks out;
labelKey/t(...)usage is consistent with command-palette.js and theinterpolateParamscontract.Note: the fallback-title logic
t("thread.fallback", { id: thread.id.slice(0, 8) })(Line 120) is now duplicated verbatim incommand-palette.js(Line 26). Not urgent, but worth a shared helper if a third call site appears.
[optional_and_nitpick]Also applies to: 76-87, 117-124, 132-136
🤖 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 `@crates/ironclaw_webui_v2/static/js/components/sidebar-threads.js` around lines 29 - 46, The thread fallback-title logic is duplicated between sidebar-threads.js and command-palette.js, making the same t("thread.fallback", { id: thread.id.slice(0, 8) }) pattern harder to maintain. Extract this into a shared helper or small utility used by the thread title rendering code in both places. Keep the existing interpolateParams/t(...) behavior intact and reference the helper from the current thread title call sites.crates/ironclaw_webui_v2/static/js/pages/chat/components/onboarding-pairing-card.test.mjs (1)
50-236: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMissing coverage for the non-paste-strategy branch.
None of the four tests set
onboarding.strategyto a non-paste value, so thepairing.connectFromExtensions/common.dismissrender path (onboarding-pairing-card.js lines 51-71) is never exercised — a wrong key name or param would ship undetected.🤖 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 `@crates/ironclaw_webui_v2/static/js/pages/chat/components/onboarding-pairing-card.test.mjs` around lines 50 - 236, The current onboarding-pairing-card tests only cover the paste strategy and miss the non-paste branch in OnboardingPairingCard, so issues in the connect-from-extensions/dismiss rendering path could slip through. Add at least one test case that sets onboarding.strategy to a non-paste value and verifies the pair of localized labels from useT, especially pairing.connectFromExtensions and common.dismiss, are rendered with the expected params in OnboardingPairingCard. Keep the existing success/error coverage, but ensure this alternate branch is exercised through the same component entry point.crates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.js (1)
380-413: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
tis out of scope inModalShell— ReferenceError on render.
ModalShellis a standalone function (Line 380) taking only{ onClose, title, children }. It never receivestas a prop and doesn't calluseT()itself.tis a localconstinsideConfigureModal(Line 20) and is not visible here. Referencingt("common.close")at Line 408 will throwReferenceError: t is not definedthe moment the close button renders, breaking every modal that usesModalShell(loading, error, no-config, pairing, and the main config states).🐛 Proposed fix
-function ModalShell({ onClose, title, children }) { +function ModalShell({ onClose, title, children }) { + const t = useT(); const titleId = React.useId();🤖 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 `@crates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.js` around lines 380 - 413, `ModalShell` is using `t("common.close")` even though `t` is not in scope there, so the close button render will throw a ReferenceError. Update `ModalShell` to get its own translation context (for example by calling `useT()` inside `ModalShell`) or pass `t` in explicitly from `ConfigureModal`, and keep the `aria-label` wiring on the close button using that in-scope translator.crates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.js (1)
63-116: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winButton click handlers use stale
labelsclosure — locale resync doesn't stick past first click.
syncCodeBlockLabelscorrectly refreshes idle button text and stashes fresh strings indataset.labelWrap/labelNoWrap/labelCopy/labelCopied/labelShowMore/labelShowLessfor an already-enhanced block. But only the copy button'ssetTimeoutreset (copyBtn.dataset.labelCopy || labels.copy) actually reads that dataset back. Every other handler still closes over the originallabelsobject captured when the block was first enhanced:
wrapBtnclick (Line 70):wrapBtn.textContent = wrapped ? labels.noWrap : labels.wrap;copyBtnclick, immediate state (Lines 78-80):copyBtn.textContent = labels.copied;andtoast(labels.codeCopied, ...)toggleclick (Line 111):toggle.textContent = expanded ? labels.showLess : labels.showMore;Once a user switches locale while a code block is already mounted (exactly the scenario this resync path was added for), clicking wrap/copy/expand will render the old language forever — the resync only fixes the idle text, not any subsequent interaction. This partially defeats the purpose of
syncCodeBlockLabelsand isn't caught by the new test, which only asserts the copy-reset dataset pattern exists.🛠️ Proposed fix: read the resynced dataset in every handler, not just the copy reset
const wrapBtn = mkBtn(labels.wrap); wrapBtn.dataset.codeBlockRole = "wrap"; wrapBtn.addEventListener("click", () => { wrapped = !wrapped; pre.dataset.wrapped = wrapped ? "1" : "0"; pre.style.whiteSpace = wrapped ? "pre-wrap" : ""; - wrapBtn.textContent = wrapped ? labels.noWrap : labels.wrap; + wrapBtn.textContent = wrapped + ? wrapBtn.dataset.labelNoWrap || labels.noWrap + : wrapBtn.dataset.labelWrap || labels.wrap; }); const copyBtn = mkBtn(labels.copy); copyBtn.dataset.codeBlockRole = "copy"; copyBtn.addEventListener("click", async () => { try { await navigator.clipboard.writeText(codeEl ? codeEl.innerText : pre.innerText); copyBtn.dataset.copied = "1"; - copyBtn.textContent = labels.copied; - toast(labels.codeCopied, { tone: "success" }); + copyBtn.textContent = copyBtn.dataset.labelCopied || labels.copied; + toast(copyBtn.dataset.labelCodeCopied || labels.codeCopied, { tone: "success" }); setTimeout(() => { copyBtn.dataset.copied = "0"; copyBtn.textContent = copyBtn.dataset.labelCopy || labels.copy; }, 1400); } catch { // clipboard unavailable } });toggle.addEventListener("click", () => { expanded = !expanded; toggle.dataset.expanded = expanded ? "1" : "0"; pre.style.maxHeight = expanded ? "none" : `${COLLAPSE_PX}px`; pre.style.overflowY = expanded ? "visible" : "hidden"; - toggle.textContent = expanded ? labels.showLess : labels.showMore; + toggle.textContent = expanded + ? toggle.dataset.labelShowLess || labels.showLess + : toggle.dataset.labelShowMore || labels.showMore; });And extend
syncCodeBlockLabelsto also stashlabelCodeCopiedon the copy button so the toast picks it up:const copyBtn = frame.querySelector('[data-code-block-role="copy"]'); if (copyBtn) { copyBtn.dataset.labelCopy = labels.copy; copyBtn.dataset.labelCopied = labels.copied; + copyBtn.dataset.labelCodeCopied = labels.codeCopied; copyBtn.textContent = copyBtn.dataset.copied === "1" ? labels.copied : labels.copy; }🤖 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 `@crates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.js` around lines 63 - 116, The code block button handlers in markdown-renderer.js still use the originally captured labels object, so locale refresh only works until the first click. Update the wrap, copy, and expand handlers in the code block setup logic to read the current strings from the button datasets populated by syncCodeBlockLabels instead of closing over labels, and make sure the copy toast also uses a resynced dataset value (for example a labelCodeCopied entry) so all interactions stay in the active locale after switching languages.crates/ironclaw_webui_v2/static/js/pages/chat/components/attachment-preview.js (1)
86-124: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUntranslated filename fallback.
Line 88 still falls back to the literal
"attachment"instead oft("common.attachment"), which the siblingattachments.js(stageFiles) now uses for the same missing-filename scenario. This fallback is displayed in the modal title/alt text (Lines 93, 131), so it should be localized for consistency with the rest of this PR.🌐 Proposed fix
- const filename = attachment.filename || "attachment"; + const filename = attachment.filename || t("common.attachment");🤖 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 `@crates/ironclaw_webui_v2/static/js/pages/chat/components/attachment-preview.js` around lines 86 - 124, The fallback filename in attachment-preview.js is still hardcoded as "attachment" instead of using the localized string. Update the attachment filename fallback in the attachment preview flow (the code that sets filename before rendering ModalHeader/PreviewBody) to use t("common.attachment"), matching the behavior already used in attachments.js via stageFiles so the modal title and related text are localized consistently.crates/ironclaw_webui_v2/static/js/pages/chat/lib/attachments.js (1)
154-194: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winInconsistent filename-fallback localization.
Lines 186/194 now use
t("common.file")/t("common.attachment")for missing filenames, but the sibling fallback at Line 156 (file.name || "file") and Line 163 (name: file.name || "file") still embed a hardcoded English"file"into otherwise-translated messages (chat.attachmentUnsupportedType,chat.attachmentTooLarge). Same fallback need, different treatment within one function.🌐 Proposed fix
if (!isAcceptedFile(file, cfg.accept)) { errors.push( - t("chat.attachmentUnsupportedType", { name: file.name || "file" }), + t("chat.attachmentUnsupportedType", { name: file.name || t("common.file") }), ); continue; } if (file.size > cfg.maxFileBytes) { errors.push( t("chat.attachmentTooLarge", { - name: file.name || "file", + name: file.name || t("common.file"), max: formatBytes(cfg.maxFileBytes), }), ); continue; }🤖 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 `@crates/ironclaw_webui_v2/static/js/pages/chat/lib/attachments.js` around lines 154 - 194, The filename fallback handling in attachments validation is inconsistent: some messages already use localized fallbacks via t("common.file") and t("common.attachment"), but isAcceptedFile and the chat.attachmentUnsupportedType/chat.attachmentTooLarge branches still hardcode "file". Update the fallback in attach validation logic within the attachment processing flow so all user-facing messages use the same localized fallback source, keeping the behavior consistent across the readAsDataUrl, attachmentKindFromMime, and validation paths.
🤖 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
`@crates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.test.mjs`:
- Around line 22-39: The current test only checks source text patterns in
markdown-renderer.test.mjs and misses the stale-closure behavior in the
wrap/toggle and copy flows. Update the markdown-renderer test to use a
DOM/jsdom-style interaction against the renderer in markdown-renderer.js,
exercising enhance, locale change, re-enhance, and button clicks so it verifies
the latest translated labels are used by the click handlers and copied/toast
state, not just the dataset fallback.
---
Outside diff comments:
In `@crates/ironclaw_webui_v2/static/js/components/sidebar-threads.js`:
- Around line 29-46: The thread fallback-title logic is duplicated between
sidebar-threads.js and command-palette.js, making the same t("thread.fallback",
{ id: thread.id.slice(0, 8) }) pattern harder to maintain. Extract this into a
shared helper or small utility used by the thread title rendering code in both
places. Keep the existing interpolateParams/t(...) behavior intact and reference
the helper from the current thread title call sites.
In
`@crates/ironclaw_webui_v2/static/js/pages/chat/components/attachment-preview.js`:
- Around line 86-124: The fallback filename in attachment-preview.js is still
hardcoded as "attachment" instead of using the localized string. Update the
attachment filename fallback in the attachment preview flow (the code that sets
filename before rendering ModalHeader/PreviewBody) to use
t("common.attachment"), matching the behavior already used in attachments.js via
stageFiles so the modal title and related text are localized consistently.
In
`@crates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.js`:
- Around line 63-116: The code block button handlers in markdown-renderer.js
still use the originally captured labels object, so locale refresh only works
until the first click. Update the wrap, copy, and expand handlers in the code
block setup logic to read the current strings from the button datasets populated
by syncCodeBlockLabels instead of closing over labels, and make sure the copy
toast also uses a resynced dataset value (for example a labelCodeCopied entry)
so all interactions stay in the active locale after switching languages.
In
`@crates/ironclaw_webui_v2/static/js/pages/chat/components/onboarding-pairing-card.test.mjs`:
- Around line 50-236: The current onboarding-pairing-card tests only cover the
paste strategy and miss the non-paste branch in OnboardingPairingCard, so issues
in the connect-from-extensions/dismiss rendering path could slip through. Add at
least one test case that sets onboarding.strategy to a non-paste value and
verifies the pair of localized labels from useT, especially
pairing.connectFromExtensions and common.dismiss, are rendered with the expected
params in OnboardingPairingCard. Keep the existing success/error coverage, but
ensure this alternate branch is exercised through the same component entry
point.
In `@crates/ironclaw_webui_v2/static/js/pages/chat/lib/attachments.js`:
- Around line 154-194: The filename fallback handling in attachments validation
is inconsistent: some messages already use localized fallbacks via
t("common.file") and t("common.attachment"), but isAcceptedFile and the
chat.attachmentUnsupportedType/chat.attachmentTooLarge branches still hardcode
"file". Update the fallback in attach validation logic within the attachment
processing flow so all user-facing messages use the same localized fallback
source, keeping the behavior consistent across the readAsDataUrl,
attachmentKindFromMime, and validation paths.
In
`@crates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.js`:
- Around line 380-413: `ModalShell` is using `t("common.close")` even though `t`
is not in scope there, so the close button render will throw a ReferenceError.
Update `ModalShell` to get its own translation context (for example by calling
`useT()` inside `ModalShell`) or pass `t` in explicitly from `ConfigureModal`,
and keep the `aria-label` wiring on the close button using that in-scope
translator.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a844d05c-6adc-43dc-bfbf-c9050b51e218
📒 Files selected for processing (50)
crates/ironclaw_webui_v2/static/js/app/app.jscrates/ironclaw_webui_v2/static/js/components/command-palette.jscrates/ironclaw_webui_v2/static/js/components/page-header.jscrates/ironclaw_webui_v2/static/js/components/sidebar-threads.jscrates/ironclaw_webui_v2/static/js/components/slack-pairing-section.jscrates/ironclaw_webui_v2/static/js/components/slack-setup-panel.jscrates/ironclaw_webui_v2/static/js/components/slack-setup-panel.test.mjscrates/ironclaw_webui_v2/static/js/design-system/modal.jscrates/ironclaw_webui_v2/static/js/design-system/modal.test.mjscrates/ironclaw_webui_v2/static/js/i18n/ar.jscrates/ironclaw_webui_v2/static/js/i18n/de.jscrates/ironclaw_webui_v2/static/js/i18n/en.jscrates/ironclaw_webui_v2/static/js/i18n/es.jscrates/ironclaw_webui_v2/static/js/i18n/fr.jscrates/ironclaw_webui_v2/static/js/i18n/hi.jscrates/ironclaw_webui_v2/static/js/i18n/ja.jscrates/ironclaw_webui_v2/static/js/i18n/ko.jscrates/ironclaw_webui_v2/static/js/i18n/pt-BR.jscrates/ironclaw_webui_v2/static/js/i18n/uk.jscrates/ironclaw_webui_v2/static/js/i18n/zh-CN.jscrates/ironclaw_webui_v2/static/js/lib/i18n.jscrates/ironclaw_webui_v2/static/js/lib/i18n.test.mjscrates/ironclaw_webui_v2/static/js/lib/slack-pairing-api.jscrates/ironclaw_webui_v2/static/js/lib/slack-pairing-api.test.mjscrates/ironclaw_webui_v2/static/js/pages/chat/chat.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/approval-card.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/attachment-chip.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/attachment-preview.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/code-block.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.test.mjscrates/ironclaw_webui_v2/static/js/pages/chat/components/message-bubble.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/onboarding-pairing-card.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/onboarding-pairing-card.test.mjscrates/ironclaw_webui_v2/static/js/pages/chat/components/tool-activity.jscrates/ironclaw_webui_v2/static/js/pages/chat/hooks/useHistory.jscrates/ironclaw_webui_v2/static/js/pages/chat/lib/attachments.jscrates/ironclaw_webui_v2/static/js/pages/chat/lib/chat.test.mjscrates/ironclaw_webui_v2/static/js/pages/chat/lib/gates.jscrates/ironclaw_webui_v2/static/js/pages/chat/lib/gates.test.mjscrates/ironclaw_webui_v2/static/js/pages/chat/lib/useHistory.test.mjscrates/ironclaw_webui_v2/static/js/pages/extensions/components/action-toast.jscrates/ironclaw_webui_v2/static/js/pages/extensions/components/channels-tab.jscrates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.jscrates/ironclaw_webui_v2/static/js/pages/extensions/components/extension-card.jscrates/ironclaw_webui_v2/static/js/pages/extensions/components/extensions-tabs.jscrates/ironclaw_webui_v2/static/js/pages/extensions/components/mcp-tab.jscrates/ironclaw_webui_v2/static/js/pages/extensions/hooks/useExtensions-pairing.test.mjscrates/ironclaw_webui_v2/static/js/pages/extensions/hooks/useExtensions.jscrates/ironclaw_webui_v2/static/js/pages/extensions/lib/extensions-schema.js
💤 Files with no reviewable changes (2)
- crates/ironclaw_webui_v2/static/js/lib/slack-pairing-api.test.mjs
- crates/ironclaw_webui_v2/static/js/lib/slack-pairing-api.js
|
🚅 Deployed to the ironclaw-pr-5685 environment in ironclaw-ci-preview
|
🗂️ Archived IronLoop Review: reviewerThis result is from an older PR head and is no longer the active review.
Archived summaryNo concrete blocking issues found in the WebUI v2 i18n/localization changes. The touched frontend tests and diff checks passed. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.js (1)
122-122: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winHoist the repeated modal title computation.
t("extensions.configureName").replace("{name}", extensionName)is duplicated across 5 render branches. Compute once nearextensionNameand reuse.♻️ Proposed dedup
const extensionName = extension?.displayName || extension?.packageRef?.id || t("extensions.defaultName"); + const modalTitle = t("extensions.configureName").replace("{name}", extensionName); const { secrets = [], fields = [], onboarding, isLoading, error } = useExtensionSetup(extension?.packageRef);Then replace each
title=${t("extensions.configureName").replace("{name}", extensionName)}withtitle=${modalTitle}.Also applies to: 159-159, 175-175, 185-185, 194-194
🤖 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 `@crates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.js` at line 122, The modal title expression is duplicated across multiple render branches in configure-modal.js, so hoist it into a single reused value. Compute the translated title once near extensionName in the configure modal render logic, give it a clear name like modalTitle, and replace each repeated t("extensions.configureName").replace("{name}", extensionName) usage with that shared value.
🤖 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.
Outside diff comments:
In
`@crates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.js`:
- Line 122: The modal title expression is duplicated across multiple render
branches in configure-modal.js, so hoist it into a single reused value. Compute
the translated title once near extensionName in the configure modal render
logic, give it a clear name like modalTitle, and replace each repeated
t("extensions.configureName").replace("{name}", extensionName) usage with that
shared value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 42076624-141a-427e-9388-f0622b0e1250
📒 Files selected for processing (8)
crates/ironclaw_webui_v2/src/static_assets/assets.rscrates/ironclaw_webui_v2/static/js/components/slack-setup-panel.jscrates/ironclaw_webui_v2/static/js/components/slack-setup-panel.test.mjscrates/ironclaw_webui_v2/static/js/design-system/modal.test.mjscrates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.jscrates/ironclaw_webui_v2/static/js/pages/chat/components/markdown-renderer.test.mjscrates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.jscrates/ironclaw_webui_v2/static/js/pages/extensions/components/configure-modal.test.mjs
There was a problem hiding this comment.
✅ IronLoop Review: reviewer
Verdict: ✅ Approved
Findings: 0 blocking / 0 notes
Next: No reviewer action needed.
Head: 26c3b3fe0afd5c8d8accf5c6251373fc7961e04a
Run details
Status: Current
Needs human: no
Needs validation: no
Summary
No concrete blocking issues found in the WebUI v2 i18n/localization changes. The touched frontend tests and diff checks passed.
Findings
None.
Developer follow-up
After fixing this feedback:
- Push the fix to this PR branch.
- Re-run this reviewer with
@ironloop review --agent reviewerif you only changed this reviewer's findings. - Re-run all reviewers with
@ironloop reviewwhen the fix may affect multiple areas. - Use
@ironloop statusto check queued/running/completed/stale/stalled state while reviewers run.
Superseded by a later IronLoop approved review for this reviewer.
There was a problem hiding this comment.
✅ IronLoop Review: reviewer
Verdict: ✅ Approved
Findings: 0 blocking / 0 notes
Next: No reviewer action needed.
Head: c665304084287c894c2bbb883369d031b96816d7
Run details
Status: Current
Needs human: no
Needs validation: no
Summary
No concrete blocking issues found in the WebUI v2 localization and UI label changes. The changed JavaScript regression tests pass.
Findings
None.
Developer follow-up
After fixing this feedback:
- Push the fix to this PR branch.
- Re-run this reviewer with
@ironloop review --agent reviewerif you only changed this reviewer's findings. - Re-run all reviewers with
@ironloop reviewwhen the fix may affect multiple areas. - Use
@ironloop statusto check queued/running/completed/stale/stalled state while reviewers run.
Summary
registerPackto safely merge repeated locale registrations.Validation
node --checkover changed JS/MJS filesgit diff --checkSecurity Impact
No security-sensitive behavior changes. This only changes frontend copy/localization behavior.
Database Impact
No schema or migration changes.
Blast Radius
Limited to Reborn frontend static JS for the public shell, Chat, Extensions, shared Slack setup/pairing UI, and i18n locale packs.
Rollback Plan
Revert this PR to restore the prior hardcoded English UI copy in these surfaces.