Skip to content

Add localized compare SEO pages - #7251

Merged
lawrencecchen merged 16 commits into
mainfrom
feat-compare-seo-pages
Jul 6, 2026
Merged

lawrencecchen merged 16 commits into
mainfrom
feat-compare-seo-pages

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add localized /compare pages for AI coding terminal and tool comparisons
  • link Compare from the footer below Guides and include compare pages on Guides
  • add compare pages to sitemap, llms.txt, Markdown/text variants, and Article/FAQ/Breadcrumb schema

Demo Video

  • Not applicable, web content and SEO-only change. Vercel preview is the visual review surface.

Review Trigger

  • Ready for review after local typecheck, production build, locale parity audit, and Vercel preview.

Checklist

  • Compare pages and blog post are localized across all supported locales
  • Compare pages are included in sitemap, Guides, footer, llms.txt, and agent-readable variants
  • Blog SEO keywords are localized through message files
  • Compare page titles in llms.txt are typed exhaustively
  • bun run typecheck
  • source scripts/load-dev-env.sh && bun run build
  • git diff --check

Verification

  • bun run typecheck
  • source scripts/load-dev-env.sh && bun run build
  • compare row/section parity and localized blog keyword audit across all web/messages/*.json
  • git diff --check

Note

Low Risk
Marketing and i18n-only web changes with no auth, data, or core app logic; main risk is bundle/SEO correctness and keeping locale files in sync.

Overview
Adds a Compare content hub at /compare with 18 statically generated, localized comparison pages (cmux vs terminals/IDEs/agent tools plus buying guides), each with tables, sections, FAQs, and Article/Breadcrumb/FAQ JSON-LD.

Wires discovery through the footer and Guides, sitemap, llms.txt, and agent-readable .md/.txt routes; extends articleSchema with optional dateModified. Prunes heavy compare page copy and full blog bodies from the client i18n payload via pruneClientMessages in the locale layout.

Also ships a new blog post on Claude Code as a worktree manager (listing, metadata, sitemap) and links Compare from related landing CTAs.

Reviewed by Cursor Bugbot for commit 26779b2. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features
    • Launched a new Compare hub with per-topic comparison pages, including comparison tables and FAQs.
    • Added Compare to navigation (footer/resources) and updated related CTAs to link to Compare.
    • Published a new blog post on building worktree workflows with Claude Code.
  • SEO & Site Discovery
    • Added localized SEO metadata for Compare pages and expanded the sitemap with /compare and its sub-routes.
  • Localization
    • Extended Compare/Guides content and navigation labels across supported languages (including new blog and page text).

@vercel

vercel Bot commented Jul 3, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jul 6, 2026 7:47am
cmux-staging Building Building Preview, Comment Jul 6, 2026 7:47am

@coderabbitai

coderabbitai Bot commented Jul 3, 2026 •

Copy link
Copy Markdown

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

Adds compare landing and detail pages with shared route data, wires compare navigation into site pages and sitemap, introduces a new blog post, and expands localized compare and navigation content.

Changes

Content Expansion

Layer / File(s) Summary
Compare data and pages
web/app/lib/compare-pages.ts, web/app/[locale]/(landing)/compare/page.tsx, web/app/[locale]/(landing)/compare/[slug]/page.tsx
Defines compare page data and helpers, adds the compare index page, and implements the per-slug compare page with metadata, rendering, and static params.
Compare wiring
web/app/[locale]/(landing)/guides/page.tsx, web/app/[locale]/components/site-footer.tsx, web/app/sitemap.ts, web/app/lib/agent-page-paths.ts, web/app/[locale]/(landing)/best-terminal-for-mac/page.tsx
Adds compare links to the guides index, site footer, sitemap, agent-readable page list, and related landing navigation.
Blog post content
web/app/[locale]/blog/claude-code-best-worktree-manager/page.tsx, web/app/[locale]/components/blog-posts.ts
Adds the new blog post page and inserts the post into the blog post list.
Localized content
web/messages/*.json
Adds compare footer labels, navigation links, blog metadata, and compare content trees across the locale message files.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • manaflow-ai/cmux#7247: Shares the same routing and SEO plumbing, including web/app/lib/agent-page-paths.ts updates that extend the exported readable page list with new routes.
🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 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.
Cmux Swift Actor Isolation ✅ Passed The PR diff only touches TS/JSON web content; no Swift files or actor-isolation-related code changed.
Cmux Swift Blocking Runtime ✅ Passed The PR only changes web/JSON content; no .swift files are in the diff, so the Swift blocking-runtime rule is not applicable.
Cmux Browser Automation Off-Main ✅ Passed PR only changes content/i18n and a docs link; no browser.* socket routing, WebKit waits, mainActor, or policy-test files were touched.
Cmux Expensive Synchronous Load ✅ Passed Diff only touches web TS/JSON files; no Swift files or expensive synchronous agent-history loads were added.
Cmux Cache Substitution Correctness ✅ Passed No fresh-read→cache substitution in persistence/history/undo/snapshot paths; diff only adds compare routes, sitemap entries, and locale copy.
Cmux No Hacky Sleeps ✅ Passed PASS: The PR adds compare/SEO/i18n pages and JSON; targeted scans of all changed TS/TSX files found no sleep/setTimeout/polling/timer code.
Cmux Algorithmic Complexity ✅ Passed New compare lookups are linear over a small static as-const list (~18 pages); no nested rescans, hot-path sorts, or user-data-sized joins were added.
Cmux Swift Concurrency ✅ Passed Diff only touches web TS/JSON files; no Swift code changed, so the concurrency-modernization rule is not applicable.
Cmux Swift @Concurrent ✅ Passed The PR changes only web/i18n files; no Swift sources or async isolation sites were modified, so the rule is not applicable.
Cmux Swift File And Package Boundaries ✅ Passed No production Swift files changed; the diff is web TS/JSON plus submodule pointer updates, and the ghostty submodule delta is Zig-only.
Cmux Swiftpm Lockfiles ✅ Passed Diff only touches web app/message files; no .gitignore, Package.swift/resolved, Xcode project, or workflow changes, so the SwiftPM lockfile rule doesn't apply.
Cmux Swift Logging ✅ Passed Diff only touches web TS/JSON files; no Swift/runtime code was modified and no forbidden logging tokens were added.
Cmux User-Facing Error Privacy ✅ Passed The diff only adds compare/index content, nav, sitemap, and llms entries; no new user-facing error/alert/recovery copy or sensitive implementation details were added.
Cmux Full Internationalization ✅ Passed Compare pages use next-intl, and all 20 routed locales have matching compare/blog message trees with no missing locale entries.
Cmux Swiftui State Layout ✅ Passed No SwiftUI files or state-layout patterns are changed in this PR; it only touches web TS/JSON content and routing.
Cmux Architecture Rethink ✅ Passed Diff only touches web pages/messages; no Swift files or architecture wiring changed, so the Swift-specific rule is not applicable.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PASS: the PR only bumps submodule pointers; the changed ghostty files are Zig/C, with no Swift window/controller changes or close-shortcut rule hits.
Cmux Source Artifacts ✅ Passed All changed paths are intentional source files, pages, configs, or localization catalogs; no temp/cache/build/log/screenshot/artifact paths appear in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed PR changes only web TypeScript/JSON files; no Swift files under any Sources/ path were modified, so the debug-seam rule is not applicable.
Cmux No Ambient Global State ✅ Passed No Swift files changed; the no-ambient-global-state rule applies to production Swift code, so this PR is out of scope for that check.
Title check ✅ Passed The title accurately summarizes the main change: adding localized compare SEO pages.
Description check ✅ Passed The description covers summary, verification, review trigger, and checklist; the template is mostly complete.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-compare-seo-pages

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.

Comment thread web/app/[locale]/(landing)/compare/[slug]/page.tsx Outdated
@greptile-apps

greptile-apps Bot commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a localized /compare hub with 18 sub-pages comparing cmux against AI coding terminals and agent tools, plus a new blog post on Claude Code worktree workflows. All new routes are wired into sitemap, agentReadablePages, guides index, footer, and llms.txt.

  • Compare pages: compare-pages.ts defines the registry; compare/[slug]/page.tsx generates static paths, article/breadcrumb/FAQ JSON-LD schema, and a related-pages CTA from relatedComparePagesFor. layout.tsx introduces pruneClientMessages which strips landing.compare.pages and full blog-post body content from the client i18n bundle (keeping only title/date/summary), reducing client payload.
  • Blog post: claude-code-best-worktree-manager/page.tsx follows the existing two-namespace split (blog.[key] for meta, blog.posts.[key] for body); blogPosts.ts and sitemap/agentReadablePages registries are updated.
  • Locale coverage: All 22 locale message files receive the new landing.compare, landing.links.compare, and blog.posts.claudeCodeBestWorktreeManager keys; km.json still contains unsubstituted pipeline placeholder tokens (__CMUXPH6_, __CMUXPH14_MU_PH7_, etc.) in several fields — this was flagged in a previous review thread and remains unaddressed.

Confidence Score: 4/5

Safe to merge for all locales except Khmer, which will render pipeline placeholder tokens in production until km.json is fixed.

The compare hub, registry wiring, pruneClientMessages optimization, and schema additions are all well-structured. The one outstanding concern is km.json, which ships unsubstituted translation pipeline tokens in multiple user-visible fields — compare hub metaDescription, bestTerminalForAgents sections body, faqA2, and blog agentP1. This was flagged in a prior review thread and remains unfixed in the current head commit.

web/messages/km.json — multiple new fields contain unsubstituted machine-translation pipeline tokens that need to be resolved before this is safe for Khmer-locale users.

Important Files Changed

Filename Overview
web/app/lib/compare-pages.ts New registry of 18 compare pages with slug/key/lastModified; satisfies constraints enforce exhaustiveness in dependent objects.
web/app/lib/agent-page-paths.ts Adds compare pages and new blog post to agentReadablePages and llms.txt; comparePageTitles/llmsCompareDescriptions are exhaustiveness-checked via satisfies.
web/app/[locale]/layout.tsx Adds pruneClientMessages to strip landing.compare.pages and full blog-post bodies from the client i18n payload; all consumers of those keys are server components so hydration is unaffected.
web/app/[locale]/(landing)/compare/[slug]/page.tsx New compare sub-page; uses page.lastModified for both datePublished and dateModified in article schema; relatedComparePagesFor safely handles out-of-bounds array access via filter.
web/app/[locale]/(landing)/compare/page.tsx Compare hub index page; all translation keys are accessed server-side so pruned client messages are not an issue.
web/app/[locale]/(landing)/guides/page.tsx Merges compare pages into ARTICLES via map spread; as const loses literal narrowing on mapped entries but typecheck passes since GuidesPage is a server component.
web/messages/km.json Contains unsubstituted machine-translation pipeline tokens (_CMUXPH6, _CMUXPH14_MU_PH7, PH_MUX, 6_MU, etc.) in multiple new fields — these render as visible garbage to Khmer users and in search snippets.
web/app/sitemap.ts Adds /compare hub and all 18 sub-pages via comparePages registry; new blog post also added.
web/app/[locale]/components/json-ld.tsx Adds optional dateModified field to articleSchema; correctly uses conditional spread to omit the field when absent.
web/tests/agent-page-variants.test.ts New test verifies compare links in llms.txt use the provided origin and not the hardcoded production domain.

Reviews (13): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment on lines +33 to +43
const agentReadableComparePages = comparePages.map((page) => ({
path: comparePath(page.slug),
title: {
bestTerminalForAgents: "Best terminal for AI coding agents",
multipleClaudeAgents: "How to run multiple Claude Code agents in parallel",
cmuxVsSuperset: "cmux vs Superset",
cmuxVsCursor: "cmux vs Cursor",
cmuxVsWarp: "cmux vs Warp",
cmuxVsGhostty: "cmux vs Ghostty",
}[page.key],
}));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Missing landing.links.compare label — registry parity incomplete

The landing-page-registry-parity rule requires every new landing page to have a landing.links label in web/messages/en.json (and every locale) and at least one internal cross-link to it from a sibling page's related list. Neither exists here: landing.links has no "compare" key in any locale file, and no sibling landing page's LandingCTA links to /compare or any /compare/<slug>.

Without the landing.links.compare entry the rule in .github/review-bot-rules/landing-page-registry-parity.md is explicitly violated: "do confirm the new landing.* namespace and landing.links entry exist in every locale." The compare pages are reachable from the footer and guides, but they are not internally cross-linked from any peer page's related links.

Rule Used: When a PR adds a new marketing landing page under ... (source)

Comment on lines +67 to +74
async function ComparePageBody({ params }: { params: Promise<PageParams> }) {
const { slug } = await params;
const page = comparePageForSlug(slug);
if (!page) {
notFound();
}

return <ComparePageContent pageKey={page.key} slug={page.slug} />;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 datePublished is hardcoded to "2026-07-03" rather than using page.lastModified from the comparePages data. All current pages share that date, but future compare pages added with a different lastModified value will emit incorrect structured data without any type error to warn about it. page.lastModified is available in the resolved page object directly above and should be threaded through to ComparePageContent.

Suggested change
async function ComparePageBody({ params }: { params: Promise<PageParams> }) {
const { slug } = await params;
const page = comparePageForSlug(slug);
if (!page) {
notFound();
}
return <ComparePageContent pageKey={page.key} slug={page.slug} />;
async function ComparePageBody({ params }: { params: Promise<PageParams> }) {
const { slug } = await params;
const page = comparePageForSlug(slug);
if (!page) {
notFound();
}
return <ComparePageContent pageKey={page.key} slug={page.slug} lastModified={page.lastModified} />;

Comment thread web/app/lib/agent-page-paths.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@web/app/lib/agent-page-paths.ts`:
- Around line 219-227: The new compare links in buildLlmsText are hardcoded to
the production domain instead of using the passed-in origin like the rest of the
internal links. Update the compare entries in agent-page-paths.ts to build URLs
from origin so agent-page-variant/route.ts and any non-production caller
generate host-correct llms.txt links. Keep the fix localized to buildLlmsText
and its compare-link list.

In `@web/messages/uk.json`:
- Around line 1855-1861: The Ukrainian translations for the product name “Warp”
are being incorrectly localized as “деформація/деформації” in the strings under
bestTerminalForAgents and cmuxVsWarp; update those entries to keep “Warp” as a
proper noun consistently across the table row, summaryBody, and comparison text.
While editing the same section, align the “Cursor CLI” wording in the FAQ so the
question and answer use the same form.
🪄 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

Run ID: ff89f9d0-5148-4fd1-9422-29494da7eb9d

📥 Commits

Reviewing files that changed from the base of the PR and between 6d708d0 and c393775.

📒 Files selected for processing (27)
  • web/app/[locale]/(landing)/compare/[slug]/page.tsx
  • web/app/[locale]/(landing)/compare/page.tsx
  • web/app/[locale]/(landing)/guides/page.tsx
  • web/app/[locale]/components/site-footer.tsx
  • web/app/lib/agent-page-paths.ts
  • web/app/lib/compare-pages.ts
  • web/app/sitemap.ts
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

Comment on lines +219 to +227
"## Comparisons and buying guides",
"",
"- [Best terminal for AI coding agents](https://cmux.com/compare/best-terminal-for-ai-coding-agents): compares cmux, Superset, Warp, Ghostty, iTerm2, tmux, and other terminals for agent-heavy workflows.",
"- [How to run multiple Claude Code agents in parallel](https://cmux.com/compare/multiple-claude-code-agents-parallel): explains branch/worktree isolation, visible workspaces, notification rings, and jump-to-latest-unread review flow.",
"- [cmux vs Superset](https://cmux.com/compare/cmux-vs-superset): native terminal/browser supervision versus an Electron agent orchestration workspace.",
"- [cmux vs Cursor](https://cmux.com/compare/cmux-vs-cursor): terminal agent supervision beside any editor versus an AI editor and hosted agent platform.",
"- [cmux vs Warp](https://cmux.com/compare/cmux-vs-warp): agent supervision terminal versus an AI-enhanced terminal product.",
"- [cmux vs Ghostty](https://cmux.com/compare/cmux-vs-ghostty): cmux as a libghostty-based agent workflow app versus Ghostty as a general-purpose terminal.",
"",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Compare links hardcode production domain instead of using origin.

Every other internal link in buildLlmsText is built from the origin parameter (e.g. ${origin}/download, ${origin}${variantPathForPage(path, "md")}), but the new compare links hardcode https://cmux.com. When buildLlmsText is called with a non-production origin (staging, preview, local dev — see agent-page-variant/route.ts passing request.nextUrl.origin), the generated llms.txt will point agents at production URLs instead of the current host.

🐛 Proposed fix
     "## Comparisons and buying guides",
     "",
-    "- [Best terminal for AI coding agents](https://cmux.com/compare/best-terminal-for-ai-coding-agents): compares cmux, Superset, Warp, Ghostty, iTerm2, tmux, and other terminals for agent-heavy workflows.",
-    "- [How to run multiple Claude Code agents in parallel](https://cmux.com/compare/multiple-claude-code-agents-parallel): explains branch/worktree isolation, visible workspaces, notification rings, and jump-to-latest-unread review flow.",
-    "- [cmux vs Superset](https://cmux.com/compare/cmux-vs-superset): native terminal/browser supervision versus an Electron agent orchestration workspace.",
-    "- [cmux vs Cursor](https://cmux.com/compare/cmux-vs-cursor): terminal agent supervision beside any editor versus an AI editor and hosted agent platform.",
-    "- [cmux vs Warp](https://cmux.com/compare/cmux-vs-warp): agent supervision terminal versus an AI-enhanced terminal product.",
-    "- [cmux vs Ghostty](https://cmux.com/compare/cmux-vs-ghostty): cmux as a libghostty-based agent workflow app versus Ghostty as a general-purpose terminal.",
+    `- [Best terminal for AI coding agents](${origin}/compare/best-terminal-for-ai-coding-agents): compares cmux, Superset, Warp, Ghostty, iTerm2, tmux, and other terminals for agent-heavy workflows.`,
+    `- [How to run multiple Claude Code agents in parallel](${origin}/compare/multiple-claude-code-agents-parallel): explains branch/worktree isolation, visible workspaces, notification rings, and jump-to-latest-unread review flow.`,
+    `- [cmux vs Superset](${origin}/compare/cmux-vs-superset): native terminal/browser supervision versus an Electron agent orchestration workspace.`,
+    `- [cmux vs Cursor](${origin}/compare/cmux-vs-cursor): terminal agent supervision beside any editor versus an AI editor and hosted agent platform.`,
+    `- [cmux vs Warp](${origin}/compare/cmux-vs-warp): agent supervision terminal versus an AI-enhanced terminal product.`,
+    `- [cmux vs Ghostty](${origin}/compare/cmux-vs-ghostty): cmux as a libghostty-based agent workflow app versus Ghostty as a general-purpose terminal.`,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"## Comparisons and buying guides",
"",
"- [Best terminal for AI coding agents](https://cmux.com/compare/best-terminal-for-ai-coding-agents): compares cmux, Superset, Warp, Ghostty, iTerm2, tmux, and other terminals for agent-heavy workflows.",
"- [How to run multiple Claude Code agents in parallel](https://cmux.com/compare/multiple-claude-code-agents-parallel): explains branch/worktree isolation, visible workspaces, notification rings, and jump-to-latest-unread review flow.",
"- [cmux vs Superset](https://cmux.com/compare/cmux-vs-superset): native terminal/browser supervision versus an Electron agent orchestration workspace.",
"- [cmux vs Cursor](https://cmux.com/compare/cmux-vs-cursor): terminal agent supervision beside any editor versus an AI editor and hosted agent platform.",
"- [cmux vs Warp](https://cmux.com/compare/cmux-vs-warp): agent supervision terminal versus an AI-enhanced terminal product.",
"- [cmux vs Ghostty](https://cmux.com/compare/cmux-vs-ghostty): cmux as a libghostty-based agent workflow app versus Ghostty as a general-purpose terminal.",
"",
"## Comparisons and buying guides",
"",
`- [Best terminal for AI coding agents](${origin}/compare/best-terminal-for-ai-coding-agents): compares cmux, Superset, Warp, Ghostty, iTerm2, tmux, and other terminals for agent-heavy workflows.`,
`- [How to run multiple Claude Code agents in parallel](${origin}/compare/multiple-claude-code-agents-parallel): explains branch/worktree isolation, visible workspaces, notification rings, and jump-to-latest-unread review flow.`,
`- [cmux vs Superset](${origin}/compare/cmux-vs-superset): native terminal/browser supervision versus an Electron agent orchestration workspace.`,
`- [cmux vs Cursor](${origin}/compare/cmux-vs-cursor): terminal agent supervision beside any editor versus an AI editor and hosted agent platform.`,
`- [cmux vs Warp](${origin}/compare/cmux-vs-warp): agent supervision terminal versus an AI-enhanced terminal product.`,
`- [cmux vs Ghostty](${origin}/compare/cmux-vs-ghostty): cmux as a libghostty-based agent workflow app versus Ghostty as a general-purpose terminal.`,
"",
🤖 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 `@web/app/lib/agent-page-paths.ts` around lines 219 - 227, The new compare
links in buildLlmsText are hardcoded to the production domain instead of using
the passed-in origin like the rest of the internal links. Update the compare
entries in agent-page-paths.ts to build URLs from origin so
agent-page-variant/route.ts and any non-production caller generate host-correct
llms.txt links. Keep the fix localized to buildLlmsText and its compare-link
list.

Comment thread web/messages/uk.json
Comment on lines +1855 to +1861
],
[
"Warp",
"Функції терміналу штучного інтелекту в керованому продукті",
"Робочий процес ШІ, орієнтований на деформацію",
"Більше блокування платформи"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

"Warp" brand name incorrectly translated to "деформація" (deformation) in several places.

The product name "Warp" is machine-translated to its literal Ukrainian meaning ("деформація"/"деформації") instead of being kept as a proper noun, at:

  • Line 1859 (table cell, bestTerminalForAgents comparison row for Warp)
  • Line 2126 (cmuxVsWarp.summaryBody, starts "Деформація є найсильнішою...")
  • Line 2142 (cmuxVsWarp table row, "Робочий процес деформації продукту")

This produces nonsensical copy for Ukrainian readers even though the section's own title/metaTitle/intro correctly keep "Warp" untranslated elsewhere in the same file.

🌐 Suggested fixes
-                "Робочий процес ШІ, орієнтований на деформацію",
+                "Робочий процес ШІ, орієнтований на Warp",
-          "summaryBody": "Деформація є найсильнішою, коли ви хочете, щоб функції ШІ були інтегровані в термінальний продукт. cmux є найсильнішим, коли ви вже використовуєте агенти CLI і потребуєте рідного, організованого, програмованого місця для запуску багатьох із них.",
+          "summaryBody": "Warp є найсильнішим, коли ви хочете, щоб функції ШІ були інтегровані в термінальний продукт. cmux є найсильнішим, коли ви вже використовуєте агенти CLI і потребуєте рідного, організованого, програмованого місця для запуску багатьох із них.",
-                "Робочий процес деформації продукту"
+                "Робочий процес продукту Warp"

As a secondary, lower-severity note: lines 2115-2116 render "Cursor CLI" in Latin script in the FAQ question but as transliterated "Курсор CLI" in the answer — worth aligning for consistency in the same pass.

Also applies to: 2120-2143

🤖 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 `@web/messages/uk.json` around lines 1855 - 1861, The Ukrainian translations
for the product name “Warp” are being incorrectly localized as
“деформація/деформації” in the strings under bestTerminalForAgents and
cmuxVsWarp; update those entries to keep “Warp” as a proper noun consistently
across the table row, summaryBody, and comparison text. While editing the same
section, align the “Cursor CLI” wording in the FAQ so the question and answer
use the same form.

Source: Learnings

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found and verified against the latest diff

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread web/app/lib/agent-page-paths.ts Outdated
Comment thread web/app/lib/agent-page-paths.ts Outdated
Comment thread web/app/lib/agent-page-paths.ts Outdated
Comment thread web/app/lib/agent-page-paths.ts
Comment thread web/app/lib/agent-page-paths.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

5 issues found across 25 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread web/messages/es.json Outdated
Comment thread web/messages/pt-BR.json
Comment thread web/messages/it.json
Comment thread web/messages/no.json
Comment thread web/messages/da.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
web/messages/no.json (1)

1904-1920: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Duplicate intro text between /compare index and bestTerminalForAgents page.

landing.compare.intro and landing.compare.pages.bestTerminalForAgents.intro are identical strings. Sibling locales (ko.json, pl.json) use distinct copy for the index page vs. this sub-page, so this looks like a copy-paste error rather than intentional duplication — it will render the same paragraph on two different live pages (duplicate content).

Based on cross-locale comparison (ko.json/pl.json use different text for these two keys), this appears unintentional.

🤖 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 `@web/messages/no.json` around lines 1904 - 1920, `landing.compare.intro` and
`landing.compare.pages.bestTerminalForAgents.intro` are duplicated, so update
one of them to unique copy for the `/compare` index versus the
`bestTerminalForAgents` page. Use the existing compare page keys in
`web/messages/no.json` as the target and align the wording with sibling locales
like `ko.json` and `pl.json`, where these two `intro` fields are intentionally
different.
web/messages/pt-BR.json (1)

1904-1920: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Duplicate intro text between /compare index and bestTerminalForAgents page.

landing.compare.intro and landing.compare.pages.bestTerminalForAgents.intro are identical strings here too (same issue found in no.json). Sibling locales (ko.json/pl.json) use distinct copy for these two keys, so this looks like an unintentional copy-paste rather than deliberate duplication.

🤖 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 `@web/messages/pt-BR.json` around lines 1904 - 1920, The compare section
repeats the same intro text in both landing.compare.intro and
landing.compare.pages.bestTerminalForAgents.intro, so update one of them to use
distinct copy. Use the existing compare structure in the pt-BR locale and adjust
the bestTerminalForAgents.intro to different wording, following the pattern used
in sibling locales like ko.json and pl.json, so the index page and the
page-specific entry each have unique messaging.
web/messages/da.json (1)

1848-1999: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Two "sections" entries are duplicated verbatim across different comparison pages.

cmuxVsAlacritty and cmuxVsConductor share identical first two sections entries:

"cmux kan køre enhver CLI-agent eller shell-kommando uden at flytte arbejdet ind i en bestemt runtime."

and the identical "Konteksten forbliver synlig" section body. Unlike bs.json, the remaining 3 sections and most FAQ content in this file ARE properly differentiated per tool (matching the tool-specific English source), so this is a narrower issue than the systemic duplication in bs.json, but it's still worth fixing since it reuses non-differentiated copy for two of five talking points on each page.

🤖 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 `@web/messages/da.json` around lines 1848 - 1999, The first two sections in the
comparison page copy are duplicated across cmuxVsAlacritty and cmuxVsConductor,
so update the localized section content in the shared translation entries to
match each tool-specific source instead of reusing the same text. Locate the
relevant objects under the comparison-page sections array in da.json and replace
the duplicated bodies with the distinct wording for each page, keeping the
remaining sections and FAQ entries unchanged.
web/messages/bs.json (1)

1710-1787: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Update the Bosnian compare table and description

landing.compare.pages.bestTerminalForAgents in bs.json is still on the old 6-tool version; the English/Japanese copy has 16 rows now, including Conductor, Herdr, OpenCode, Cursor, Devin, VS Code, Zed, Kitty, Alacritty, and WezTerm. Update table.rows and metaDescription to match.

🤖 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 `@web/messages/bs.json` around lines 1710 - 1787, The Bosnian compare page copy
is still using the old shorter tool list, so update
landing.compare.pages.bestTerminalForAgents in bs.json to match the newer
English/Japanese structure. Refresh the metaDescription and replace table.rows
with the full 16-row comparison set, including the missing entries such as
Conductor, Herdr, OpenCode, Cursor, Devin, VS Code, Zed, Kitty, Alacritty, and
WezTerm, while keeping the existing compare-page keys and naming consistent.
♻️ Duplicate comments (1)
web/app/lib/agent-page-paths.ts (1)

237-254: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Compare links still hardcode https://cmux.com instead of origin.

Every other internal link in buildLlmsText is built from origin (e.g. ${origin}/download), but the new compare entries hardcode the production domain. When buildLlmsText runs on staging/preview/local origin values, these links will point at production instead of the current host.

🐛 Proposed fix
-    "- [Best terminal for AI coding agents](https://cmux.com/compare/best-terminal-for-ai-coding-agents): compares cmux, Conductor, Superset, Cursor, Devin, VS Code, Zed, Warp, Ghostty, iTerm2, tmux, Kitty, Alacritty, WezTerm, OpenCode, Herdr, and other tools for agent-heavy workflows.",
-    "- [cmux vs Alacritty](https://cmux.com/compare/cmux-vs-alacritty): native macOS agent supervision versus a fast cross-platform OpenGL terminal emulator.",
+    `- [Best terminal for AI coding agents](${origin}/compare/best-terminal-for-ai-coding-agents): compares cmux, Conductor, Superset, Cursor, Devin, VS Code, Zed, Warp, Ghostty, iTerm2, tmux, Kitty, Alacritty, WezTerm, OpenCode, Herdr, and other tools for agent-heavy workflows.`,
+    `- [cmux vs Alacritty](${origin}/compare/cmux-vs-alacritty): native macOS agent supervision versus a fast cross-platform OpenGL terminal emulator.`,
     // ...repeat for the remaining compare links, replacing "https://cmux.com" with `${origin}`
🤖 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 `@web/app/lib/agent-page-paths.ts` around lines 237 - 254, The new compare
links in buildLlmsText are hardcoded to https://cmux.com instead of using the
current origin like the other internal links. Update the compare entries in
agent-page-paths.ts to build URLs from origin so staging, preview, and local
environments point to the active host. Use the buildLlmsText link construction
pattern and the compare link strings as the places to update.
🤖 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 `@web/app/`[locale]/blog/claude-code-best-worktree-manager/page.tsx:
- Around line 35-55: The publish-date string is duplicated in the page metadata
and the BlogSchema usage, which can drift over time. Extract the shared
"2026-07-03T00:00:00Z" value into a single constant in
ClaudeCodeBestWorktreeManagerPage and reuse it for openGraph.publishedTime and
BlogSchema's datePublished so both stay aligned.
- Around line 20-30: The metadata keywords are hardcoded in English instead of
coming from the active locale, so update the page’s metadata generation to read
a locale-specific `metaKeywords` value from the translation/catalog source used
by the `t(...)` calls. Adjust the `page.tsx` metadata logic for this blog page
so `keywords` varies by `locale` the same way `title` and `description` do, and
ensure every locale in `web/i18n/routing.ts` has the corresponding translated
keywords entry.

In `@web/messages/bs.json`:
- Around line 1989-2792: The new comparison entries reuse generic boilerplate
instead of page-specific content, so update each cmuxVsX block to match the
unique English source meaning for its own tool. Rewrite the shared sections and
FAQ answers in each comparison page with tool-specific translations, and fix
tables where the compared tool’s “Najbolje za” simply repeats “Glavni posao”
verbatim. Use the unique symbols like cmuxVsAlacritty, cmuxVsConductor,
cmuxVsDevin, cmuxVsTmux, and cmuxVsWezterm to locate and replace the duplicated
content.

In `@web/messages/de.json`:
- Around line 1777-1820: The German locale comparison tables are incomplete and
out of sync with the source content. Update the table data in the relevant
`landing.compare.pages.*.table.rows` entries to include all missing translated
rows, and make sure `landing.compare.pages.cmuxVsSuperset.table.rows` also
includes the missing “Source model” row. Use the existing table structure and
keys in `web/messages/de.json` to align the German content with the full source
set.

In `@web/messages/it.json`:
- Around line 2218-3109: The compare-page entries from cmuxVsAlacritty through
cmuxVsWezterm are filled with repeated placeholder boilerplate instead of
tool-specific localized copy. Update the table rows, section bodies, and FAQ
answers in each comparison object to match the unique meaning of the
corresponding product named by each key (for example, in cmuxVsDevin,
cmuxVsTmux, cmuxVsWindsurf, etc.) and avoid reusing the same generic “tool
confrontato” phrasing across pages. Use the existing structure in
landing.guides.compare.pages and keep each page’s descriptions aligned with the
specific compared tool rather than templated text.

---

Outside diff comments:
In `@web/messages/bs.json`:
- Around line 1710-1787: The Bosnian compare page copy is still using the old
shorter tool list, so update landing.compare.pages.bestTerminalForAgents in
bs.json to match the newer English/Japanese structure. Refresh the
metaDescription and replace table.rows with the full 16-row comparison set,
including the missing entries such as Conductor, Herdr, OpenCode, Cursor, Devin,
VS Code, Zed, Kitty, Alacritty, and WezTerm, while keeping the existing
compare-page keys and naming consistent.

In `@web/messages/da.json`:
- Around line 1848-1999: The first two sections in the comparison page copy are
duplicated across cmuxVsAlacritty and cmuxVsConductor, so update the localized
section content in the shared translation entries to match each tool-specific
source instead of reusing the same text. Locate the relevant objects under the
comparison-page sections array in da.json and replace the duplicated bodies with
the distinct wording for each page, keeping the remaining sections and FAQ
entries unchanged.

In `@web/messages/no.json`:
- Around line 1904-1920: `landing.compare.intro` and
`landing.compare.pages.bestTerminalForAgents.intro` are duplicated, so update
one of them to unique copy for the `/compare` index versus the
`bestTerminalForAgents` page. Use the existing compare page keys in
`web/messages/no.json` as the target and align the wording with sibling locales
like `ko.json` and `pl.json`, where these two `intro` fields are intentionally
different.

In `@web/messages/pt-BR.json`:
- Around line 1904-1920: The compare section repeats the same intro text in both
landing.compare.intro and landing.compare.pages.bestTerminalForAgents.intro, so
update one of them to use distinct copy. Use the existing compare structure in
the pt-BR locale and adjust the bestTerminalForAgents.intro to different
wording, following the pattern used in sibling locales like ko.json and pl.json,
so the index page and the page-specific entry each have unique messaging.

---

Duplicate comments:
In `@web/app/lib/agent-page-paths.ts`:
- Around line 237-254: The new compare links in buildLlmsText are hardcoded to
https://cmux.com instead of using the current origin like the other internal
links. Update the compare entries in agent-page-paths.ts to build URLs from
origin so staging, preview, and local environments point to the active host. Use
the buildLlmsText link construction pattern and the compare link strings as the
places to update.
🪄 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

Run ID: a9344fe0-ee93-4da0-813c-42aded9fd26e

📥 Commits

Reviewing files that changed from the base of the PR and between c393775 and 3ca5664.

📒 Files selected for processing (26)
  • web/app/[locale]/(landing)/best-terminal-for-mac/page.tsx
  • web/app/[locale]/blog/claude-code-best-worktree-manager/page.tsx
  • web/app/[locale]/components/blog-posts.ts
  • web/app/lib/agent-page-paths.ts
  • web/app/lib/compare-pages.ts
  • web/app/sitemap.ts
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

Comment thread web/app/[locale]/blog/claude-code-best-worktree-manager/page.tsx Outdated
Comment on lines +35 to +55
publishedTime: "2026-07-03T00:00:00Z",
},
twitter: {
card: "summary_large_image",
title: t("metaTitle"),
description: t("metaDescription"),
},
alternates: buildAlternates(locale, "/blog/claude-code-best-worktree-manager"),
};
}

export default function ClaudeCodeBestWorktreeManagerPage() {
const t = useTranslations("blog.posts.claudeCodeBestWorktreeManager");
const tc = useTranslations("common");

return (
<>
<BlogSchema
postKey="claudeCodeBestWorktreeManager"
path="/blog/claude-code-best-worktree-manager"
datePublished="2026-07-03T00:00:00Z"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated publish-date literal risks drift.

"2026-07-03T00:00:00Z" is repeated for openGraph.publishedTime and BlogSchema's datePublished. Extract to a single constant to avoid the two values silently diverging on a future edit.

♻️ Proposed fix
+const PUBLISHED_AT = "2026-07-03T00:00:00Z";
+
 export async function generateMetadata(...) {
   ...
   return {
     ...
     openGraph: {
       ...
-      publishedTime: "2026-07-03T00:00:00Z",
+      publishedTime: PUBLISHED_AT,
     },
     ...
   };
 }

 export default function ClaudeCodeBestWorktreeManagerPage() {
   ...
-      datePublished="2026-07-03T00:00:00Z"
+      datePublished={PUBLISHED_AT}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
publishedTime: "2026-07-03T00:00:00Z",
},
twitter: {
card: "summary_large_image",
title: t("metaTitle"),
description: t("metaDescription"),
},
alternates: buildAlternates(locale, "/blog/claude-code-best-worktree-manager"),
};
}
export default function ClaudeCodeBestWorktreeManagerPage() {
const t = useTranslations("blog.posts.claudeCodeBestWorktreeManager");
const tc = useTranslations("common");
return (
<>
<BlogSchema
postKey="claudeCodeBestWorktreeManager"
path="/blog/claude-code-best-worktree-manager"
datePublished="2026-07-03T00:00:00Z"
const PUBLISHED_AT = "2026-07-03T00:00:00Z";
publishedTime: PUBLISHED_AT,
},
twitter: {
card: "summary_large_image",
title: t("metaTitle"),
description: t("metaDescription"),
},
alternates: buildAlternates(locale, "/blog/claude-code-best-worktree-manager"),
};
}
export default function ClaudeCodeBestWorktreeManagerPage() {
const t = useTranslations("blog.posts.claudeCodeBestWorktreeManager");
const tc = useTranslations("common");
return (
<>
<BlogSchema
postKey="claudeCodeBestWorktreeManager"
path="/blog/claude-code-best-worktree-manager"
datePublished={PUBLISHED_AT}
🤖 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 `@web/app/`[locale]/blog/claude-code-best-worktree-manager/page.tsx around
lines 35 - 55, The publish-date string is duplicated in the page metadata and
the BlogSchema usage, which can drift over time. Extract the shared
"2026-07-03T00:00:00Z" value into a single constant in
ClaudeCodeBestWorktreeManagerPage and reuse it for openGraph.publishedTime and
BlogSchema's datePublished so both stay aligned.

Comment thread web/messages/bs.json
Comment thread web/messages/de.json
Comment thread web/messages/it.json
Comment thread web/messages/ar.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 60761549f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/messages/bs.json
"Podrška za agente",
"Kompromis"
],
"rows": [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore the missing localized compare rows

Because ComparePageContent renders t.raw("table").rows directly, this Bosnian page now shows only the six rows present here. The English data for the same page has 16 rows and 5 sections, so /bs/compare/best-terminal-for-ai-coding-agents drops most compared tools and the final section; the same truncation shows up in several other locale JSON files added in this commit.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce44301b70

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/messages/zh-CN.json Outdated
],
"rows": [
[
"多路复用器",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep product names untranslated

On the Simplified Chinese compare page, the tool column translates brands like cmux/Conductor/Superset into common words; because CompareTable renders this first cell as the product name and key, /zh-CN/compare/best-terminal-for-ai-coding-agents shows 多路复用器 instead of cmux and later duplicates the tmux label. Brand names in these rows need to remain canonical; the same issue appears in the zh-TW/ja tables.

Useful? React with 👍 / 👎.

Comment thread web/messages/es.json
Comment on lines +2544 to +2545
"title": "La programabilidad mantiene los flujos inspeccionables",
"body": "La CLI y la API de socket de cmux exponen paneles, workspaces, lecturas de pantalla, capturas, automatización del navegador, hooks y comandos personalizados. Los equipos pueden scriptar el flujo exacto que necesitan alrededor de los agentes locales."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Replace duplicate Spanish Devin section

For /es/compare/cmux-vs-devin, the last two sections entries have the same title and near-identical bodies. Since ComparePageContent maps these directly and keys by section.title, this page renders duplicate content and hits a duplicate-key warning instead of showing the fifth distinct section that other locales have; one of these entries should be the missing section.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
web/messages/pt-BR.json (1)

1904-3219: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Same non-differentiated boilerplate content issue as flagged previously for bs.json.

The new cmuxVsHerdr/cmuxVsOpencode summaryBody and first-sections entries are properly tool-specific. However cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and cmuxVsWezterm still repeat identical sections body text and near-identical FAQ templates ("cmux substitui [Tool]?" / "Escolha cmux quando o problema for supervisionar muitos agentes..."), with only the tool name swapped. pt-BR is listed among this repo's explicitly high-confidence, professionally-translated locales, so this generic templated content is a content-quality gap of the same kind previously flagged for bs.json, not an acceptable English-fallback case.

🤖 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 `@web/messages/pt-BR.json` around lines 1904 - 3219, The repeated boilerplate
in the comparison pages still needs localization-specific differentiation.
Update the shared templated `sections` and FAQ content in `cmuxVsAlacritty`,
`cmuxVsConductor`, `cmuxVsDevin`, `cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsTmux`,
`cmuxVsVscode`, `cmuxVsWindsurf`, `cmuxVsZed`, and `cmuxVsWezterm` so each page
has tool-specific bodies and answers, not just the tool name swapped in
identical text. Use the existing differentiated patterns in `cmuxVsHerdr` and
`cmuxVsOpencode` as the model, and make sure the unique tradeoffs and use-cases
are reflected in each `sections` entry and FAQ pair.

Source: Learnings

web/messages/pl.json (1)

1769-3189: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Same non-differentiated boilerplate content issue as flagged previously for bs.json.

This commit adds tool-specific summaryBody/first-section content for cmuxVsHerdr and cmuxVsOpencode (good), but cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and cmuxVsWezterm all still share the identical sections body text (e.g. "cmux uruchamia dowolnego agenta CLI albo polecenie shell...") and near-identical FAQ answers, only the tool name changes. Since pl.json is a professionally-translated, high-confidence locale (per this repo's localization policy), this generic templated content undermines the purpose of tool-specific comparison pages the same way it did for bs.json in a prior review round.

Also, bestTerminalForAgents.table.rows here lists only 6 tools, while web/messages/da.json's equivalent table lists 16 (Conductor, Herdr, OpenCode, Cursor, Devin Desktop, VS Code, Zed, Alacritty, Kitty, WezTerm are missing here).

Based on learnings, English-fallback for lower-confidence locales is acceptable, but pl is listed among the explicitly high-confidence, professionally-translated locales expected to have fully translated (and differentiated) 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 `@web/messages/pl.json` around lines 1769 - 3189, Update the Polish locale copy
for the affected comparison pages so the content is tool-specific instead of
reusing the same boilerplate across `cmuxVsAlacritty`, `cmuxVsConductor`,
`cmuxVsDevin`, `cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsTmux`, `cmuxVsVscode`,
`cmuxVsWindsurf`, `cmuxVsZed`, and `cmuxVsWezterm`; use the existing
differentiated pattern already present in `cmuxVsHerdr` and `cmuxVsOpencode` as
the reference. In each of those sections, rewrite the `sections` bodies and FAQ
answers so they mention the specific comparison tool and its unique
workflow/value, not the same generic cmux description with only the product name
swapped. Also expand `bestTerminalForAgents.table.rows` to match the full tool
set used in the equivalent locale, including the missing entries for Conductor,
Herdr, OpenCode, Cursor, Devin Desktop, VS Code, Zed, Alacritty, Kitty, and
WezTerm.

Source: Learnings

web/messages/fr.json (1)

2444-2447: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Typo: "programabilité" → "programmabilité".

Inconsistent with the correct spelling used in the sibling section title at line 2441 in the same object.

💬 Proposed fix
-              "title": "La programabilité garde les workflows inspectables",
+              "title": "La programmabilité garde les workflows inspectables",
🤖 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 `@web/messages/fr.json` around lines 2444 - 2447, The title text in the French
messages object has a spelling typo: “programabilité” should be corrected to the
same spelling used elsewhere in the file. Update the string in the object
containing the title/body around the cmux section so the title reads with
“programmabilité”, keeping the sibling section naming consistent.
web/messages/es.json (1)

2464-2471: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Duplicate section title in cmuxVsDevin.sections causes a duplicate React key.

Lines 2465 and 2469 use the identical title "La programmabilidad mantiene los flujos inspeccionables" for two different sections. The compare detail page renders sections.map((section) => <section key={section.title}>...), so two entries with the same title collide on key, which can cause React to drop/misrender one of the two duplicate sections in this locale.

🐛 Proposed fix
-              "title": "La programmabilidad mantiene los flujos inspeccionables",
-              "body": "La CLI y la API de socket exponen paneles, workspaces, lecturas de pantalla, capturas, automatización de navegador, hooks y comandos personalizados para scriptar el flujo exacto."
+              "title": "El rendimiento se mantiene bajo control",
+              "body": "La CLI y la API de socket exponen paneles, workspaces, lecturas de pantalla, capturas, automatización de navegador, hooks y comandos personalizados para scriptar el flujo exacto."
🤖 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 `@web/messages/es.json` around lines 2464 - 2471, The cmuxVsDevin.sections
entries contain two different items with the same title, which collides with the
React key used by the compare detail page. Update one of the duplicate titles in
this locale so each section in the sections.map render has a unique
section.title, and make sure the wording still matches the intended meaning for
each distinct body.
web/messages/no.json (2)

1989-3218: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Templated/duplicated content across most cmuxVsX comparison pages, including a title/body mismatch in cmuxVsHerdr.

The majority of comparison pages (cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr, cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, cmuxVsWezterm) reuse identical sections titles/bodies and FAQ text word-for-word regardless of which tool is being compared (e.g. "cmux holder agenter synlige" / "cmux organiserer terminaler, browsersjekker, porter..." appears unchanged in at least 11 different pages). In cmuxVsHerdr (lines 2618-2622) this produces an outright title/body mismatch: the generic title "cmux holder agenter synlige" ("cmux keeps agents visible") is paired with body text that is actually about Herdr's SSH-portability strength.

This degrades SEO/content value for these landing pages and doesn't meet the localization bar of genuine, tool-specific translated content — the same category of issue already flagged for it.json's cmuxVsAlacritty→cmuxVsWezterm range. Norwegian (no) is listed among the high-confidence locales expected to carry fully translated copy, so this isn't covered by the lower-confidence-locale English-fallback exception.

🤖 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 `@web/messages/no.json` around lines 1989 - 3218, Replace the repeated
placeholder copy in the cmuxVsX comparison entries with tool-specific Norwegian
content for each comparison page, especially the shared sections and FAQ text in
the cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty,
cmuxVsHerdr, cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf,
cmuxVsZed, and cmuxVsWezterm objects. Update the reusable-looking section
titles/bodies in each page so they reflect the compared product’s actual
strengths and differences rather than the same cmux-focused wording. In
cmuxVsHerdr, fix the title/body mismatch in the first section by aligning the
heading with the Herdr portability/SSH angle or by rewriting the body to match
the generic heading. Keep the locale fully translated and distinct per product
instead of reusing the same text across these comparison pages.

Source: Learnings


1904-1914: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

bestTerminalForAgents.intro duplicates the parent compare.intro verbatim.

Line 1914 is character-for-character identical to the parent compare.intro at line 1908, instead of describing this specific page (compare en.json's distinct page-level intro for the same key).

🤖 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 `@web/messages/no.json` around lines 1904 - 1914, The
bestTerminalForAgents.intro entry in compare.pages duplicates the parent
compare.intro, so replace it with a page-specific intro that matches the
localized intent used for this subpage. Use the
compare.pages.bestTerminalForAgents key in no.json as the target, and align its
wording with the distinct intro text from the corresponding en.json page-level
entry rather than copying the parent text verbatim.
♻️ Duplicate comments (2)
web/messages/de.json (1)

1776-1821: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

bestTerminalForAgents table and cmuxVsSuperset table are still incomplete.

bestTerminalForAgents.table.rows here has only 6 entries (cmux, Superset, Warp, Ghostty, iTerm2, tmux), while web/messages/da.json's equivalent table has 16 (also Conductor, Herdr, OpenCode, Cursor, Devin Desktop, VS Code, Zed, Alacritty, Kitty, WezTerm). Separately, cmuxVsSuperset.table.rows here still has no "Source model"/Quellmodell row, while da.json's equivalent table includes one. Both gaps were raised in a prior review round and remain unresolved in this file; the rest of the sections/FAQ content here is otherwise well-differentiated per tool, unlike some of the other locale files reviewed in this batch.

Also applies to: 2090-2133

🤖 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 `@web/messages/de.json` around lines 1776 - 1821, The German locale tables are
still missing entries: extend bestTerminalForAgents.table.rows in the messages
data to match the complete set of tools already present in the Danish reference,
and add the missing Source model/Quellmodell row to cmuxVsSuperset.table.rows.
Update the table content in the relevant translation object so the entries for
Conductor, Herdr, OpenCode, Cursor, Devin Desktop, VS Code, Zed, Alacritty,
Kitty, and WezTerm are included alongside the existing rows, and ensure the
cmuxVsSuperset comparison table includes the missing model row.
web/messages/bs.json (1)

1989-3219: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Boilerplate sections/FAQ duplication across comparison pages persists.

The newly added summaryBody/first-sections entries for cmuxVsHerdr (line ~2355, 2398) and cmuxVsOpencode (line ~2427, 2470) are properly differentiated per-tool — good. However, cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and cmuxVsWezterm still share word-for-word identical sections bodies (e.g. "cmux organizuje terminale, browser provjere, portove...") and near-identical FAQ answers, only substituting the tool name. This is the exact pattern flagged in a prior review round and marked "Addressed in commit 6076154" — the fix evidently didn't extend to these pages. Since this commit shows the team can produce differentiated copy (as done for Herdr/Opencode), the remaining pages should get the same treatment; generic, non-differentiated comparison content undermines the purpose of these SEO/comparison pages.

Additionally, bestTerminalForAgents.table.rows here only lists 6 tools (cmux, Superset, Warp, Ghostty, iTerm2, tmux), while the fully-localized da.json version of the same table lists 16 tools (also including Conductor, Herdr, OpenCode, Cursor, Devin Desktop, VS Code, Zed, Alacritty, Kitty, WezTerm). This locale's table is out of sync with the more complete reference.

🤖 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 `@web/messages/bs.json` around lines 1989 - 3219, Remove the boilerplate
duplication in the comparison page copy by rewriting the repeated sections and
FAQ entries for cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2,
cmuxVsKitty, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and
cmuxVsWezterm so each page has tool-specific `sections` and FAQ answers instead
of only swapping the product name. Use the differentiated pattern already
present in cmuxVsHerdr and cmuxVsOpencode as the model, and update
`bestTerminalForAgents.table.rows` to match the fuller localized reference by
adding the missing tools so the matrix stays in sync across locales.
🤖 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 `@web/messages/es.json`:
- Around line 2464-2471: The cmuxVsDevin.sections entries contain two different
items with the same title, which collides with the React key used by the compare
detail page. Update one of the duplicate titles in this locale so each section
in the sections.map render has a unique section.title, and make sure the wording
still matches the intended meaning for each distinct body.

In `@web/messages/fr.json`:
- Around line 2444-2447: The title text in the French messages object has a
spelling typo: “programabilité” should be corrected to the same spelling used
elsewhere in the file. Update the string in the object containing the title/body
around the cmux section so the title reads with “programmabilité”, keeping the
sibling section naming consistent.

In `@web/messages/no.json`:
- Around line 1989-3218: Replace the repeated placeholder copy in the cmuxVsX
comparison entries with tool-specific Norwegian content for each comparison
page, especially the shared sections and FAQ text in the cmuxVsAlacritty,
cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr,
cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and
cmuxVsWezterm objects. Update the reusable-looking section titles/bodies in each
page so they reflect the compared product’s actual strengths and differences
rather than the same cmux-focused wording. In cmuxVsHerdr, fix the title/body
mismatch in the first section by aligning the heading with the Herdr
portability/SSH angle or by rewriting the body to match the generic heading.
Keep the locale fully translated and distinct per product instead of reusing the
same text across these comparison pages.
- Around line 1904-1914: The bestTerminalForAgents.intro entry in compare.pages
duplicates the parent compare.intro, so replace it with a page-specific intro
that matches the localized intent used for this subpage. Use the
compare.pages.bestTerminalForAgents key in no.json as the target, and align its
wording with the distinct intro text from the corresponding en.json page-level
entry rather than copying the parent text verbatim.

In `@web/messages/pl.json`:
- Around line 1769-3189: Update the Polish locale copy for the affected
comparison pages so the content is tool-specific instead of reusing the same
boilerplate across `cmuxVsAlacritty`, `cmuxVsConductor`, `cmuxVsDevin`,
`cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsTmux`, `cmuxVsVscode`, `cmuxVsWindsurf`,
`cmuxVsZed`, and `cmuxVsWezterm`; use the existing differentiated pattern
already present in `cmuxVsHerdr` and `cmuxVsOpencode` as the reference. In each
of those sections, rewrite the `sections` bodies and FAQ answers so they mention
the specific comparison tool and its unique workflow/value, not the same generic
cmux description with only the product name swapped. Also expand
`bestTerminalForAgents.table.rows` to match the full tool set used in the
equivalent locale, including the missing entries for Conductor, Herdr, OpenCode,
Cursor, Devin Desktop, VS Code, Zed, Alacritty, Kitty, and WezTerm.

In `@web/messages/pt-BR.json`:
- Around line 1904-3219: The repeated boilerplate in the comparison pages still
needs localization-specific differentiation. Update the shared templated
`sections` and FAQ content in `cmuxVsAlacritty`, `cmuxVsConductor`,
`cmuxVsDevin`, `cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsTmux`, `cmuxVsVscode`,
`cmuxVsWindsurf`, `cmuxVsZed`, and `cmuxVsWezterm` so each page has
tool-specific bodies and answers, not just the tool name swapped in identical
text. Use the existing differentiated patterns in `cmuxVsHerdr` and
`cmuxVsOpencode` as the model, and make sure the unique tradeoffs and use-cases
are reflected in each `sections` entry and FAQ pair.

---

Duplicate comments:
In `@web/messages/bs.json`:
- Around line 1989-3219: Remove the boilerplate duplication in the comparison
page copy by rewriting the repeated sections and FAQ entries for
cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty,
cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and cmuxVsWezterm so each
page has tool-specific `sections` and FAQ answers instead of only swapping the
product name. Use the differentiated pattern already present in cmuxVsHerdr and
cmuxVsOpencode as the model, and update `bestTerminalForAgents.table.rows` to
match the fuller localized reference by adding the missing tools so the matrix
stays in sync across locales.

In `@web/messages/de.json`:
- Around line 1776-1821: The German locale tables are still missing entries:
extend bestTerminalForAgents.table.rows in the messages data to match the
complete set of tools already present in the Danish reference, and add the
missing Source model/Quellmodell row to cmuxVsSuperset.table.rows. Update the
table content in the relevant translation object so the entries for Conductor,
Herdr, OpenCode, Cursor, Devin Desktop, VS Code, Zed, Alacritty, Kitty, and
WezTerm are included alongside the existing rows, and ensure the cmuxVsSuperset
comparison table includes the missing model row.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9d5ae42d-db33-4dc6-b177-557a23939474

📥 Commits

Reviewing files that changed from the base of the PR and between 3ca5664 and 6076154.

📒 Files selected for processing (22)
  • web/app/lib/compare-pages.ts
  • web/app/sitemap.ts
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
web/messages/zh-CN.json (1)

356-374: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Date formatting inconsistency and mistranslated term in the new blog block.

Two issues in the new claudeCodeBestWorktreeManager content:

  1. date uses "2026 年 7 月 3 日" with spaces around the unit characters, while every other date in this file (e.g. "2026年3月4日", "2026年6月23日") has no spaces.
  2. superRepoTitle reads "超级回购模式" — 回购 means "buyback/repurchase" (a finance term), which is the wrong word for "repo" here. The following superRepoP1 correctly uses 超级仓库 for the same concept, so the terminology is inconsistent and the title itself is confusing/incorrect as written.

Based on learnings, zh-CN (zh-Hans) is treated as a high-confidence, professionally-translated locale, so this should be corrected rather than left as-is.

💬 Suggested fix
-        "date": "2026 年 7 月 3 日",
+        "date": "2026年7月3日",
...
-        "superRepoTitle": "超级回购模式",
+        "superRepoTitle": "超级仓库模式",
🤖 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 `@web/messages/zh-CN.json` around lines 356 - 374, The new
claudeCodeBestWorktreeManager block has two localization issues: the date
formatting in date is inconsistent with the rest of zh-CN entries, and
superRepoTitle uses the wrong term for “repo”. Update the date in
claudeCodeBestWorktreeManager to match the no-space Chinese date style used
elsewhere in web/messages/zh-CN.json, and change superRepoTitle to use the same
“超级仓库” terminology already used in superRepoP1 so the translation is consistent
and correct.

Source: Learnings

web/messages/pl.json (1)

500-518: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

cmuxP2 drops a sentence present in the other high-confidence locale.

blog.posts.claudeCodeBestWorktreeManager.cmuxP2 here ends after "...zmienia się workflow" and omits the closing sentence (present in no.json's equivalent) about the best terminal keeping notifications and the Cmd+Shift+U/Cmd+Control+U shortcuts wired into that same surface. Since pl is one of the explicitly high-confidence locales expected to carry fully translated copy for changed strings, this looks like a content-completeness gap rather than an intentional edit.

Based on learnings, only the explicitly high-confidence locales—en, de, fr, es, ja, ko, zh-Hans, zh-Hant, pt-BR, ru, it, pl, uk, tr, da, no—are expected to contain fully translated copy for strings changed in a given PR.

🤖 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 `@web/messages/pl.json` around lines 500 - 518, The pl locale entry for cmuxP2
is incomplete and missing the closing sentence that appears in the matching
high-confidence translation. Update
blog.posts.claudeCodeBestWorktreeManager.cmuxP2 so it includes the full
translated copy, preserving the additional sentence about the best terminal
keeping notifications and the Cmd+Shift+U/Cmd+Control+U shortcuts wired into the
same surface.

Source: Learnings

♻️ Duplicate comments (3)
web/app/[locale]/blog/claude-code-best-worktree-manager/page.tsx (1)

29-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Publish-date literal now duplicated in three places.

"2026-07-03T00:00:00Z"/"2026-07-03" appears in openGraph.publishedTime, BlogSchema's datePublished, and the <time dateTime> attribute. A previous review flagged the two-way duplication; it's grown to three call sites with no shared constant, so the values can silently diverge on a future edit.

♻️ Proposed fix
+const PUBLISHED_AT = "2026-07-03T00:00:00Z";
+const PUBLISHED_DATE = "2026-07-03";
+
 export async function generateMetadata(...) {
   ...
     openGraph: {
       ...
-      publishedTime: "2026-07-03T00:00:00Z",
+      publishedTime: PUBLISHED_AT,
     },
 }

 export default function ClaudeCodeBestWorktreeManagerPage() {
   ...
-        datePublished="2026-07-03T00:00:00Z"
+        datePublished={PUBLISHED_AT}
   ...
-      <time dateTime="2026-07-03" className="text-sm text-muted">
+      <time dateTime={PUBLISHED_DATE} className="text-sm text-muted">

Also applies to: 49-49, 61-61

🤖 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 `@web/app/`[locale]/blog/claude-code-best-worktree-manager/page.tsx at line 29,
The publish date literal is duplicated across the page metadata, BlogSchema, and
the rendered <time> element, so it can drift over time. Introduce a single
shared date constant in claude-code-best-worktree-manager/page.tsx and use it
for openGraph.publishedTime, BlogSchema.datePublished, and the <time dateTime>
attribute to keep all three values in sync.
web/messages/bs.json (1)

2077-2113: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

"Najbolje za" still duplicates "Glavni posao" verbatim across every single-tool comparison table.

For cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr, cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and cmuxVsWezterm, the compared tool's table.rows "Najbolje za" (best-for) cell is word-for-word identical to that same tool's "Glavni posao" (primary job) cell (e.g. Alacritty: "brz, minimalan OpenGL terminal" in both rows; Conductor: "pakovan workspace za zadatke agenata" in both rows).

This was previously flagged (marked "Addressed in commit 6076154") and the unique per-tool sections entry was added, but the table duplication itself was never fixed. For comparison, da.json and pt-BR.json use a generic, non-duplicating phrase in that slot (e.g. da: "Brugere, der foretrækker det sammenlignede værktøjs primære flow"), confirming this is still an outstanding bs.json-specific defect rather than the intended template.

Also applies to: 2159-2194, 2239-2275, 2320-2356, 2401-2437, 2482-2523, 2564-2595, 2637-2672, 2717-2753, 2794-2830, 2871-2907, 2948-2984

🤖 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 `@web/messages/bs.json` around lines 2077 - 2113, The “Najbolje za” cell in
each single-tool comparison table is still duplicating the compared tool’s
“Glavni posao” text, so update the bs.json table rows for cmuxVsAlacritty,
cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr,
cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and
cmuxVsWezterm to use a distinct generic best-for phrase instead of repeating the
primary-job sentence. Keep the existing per-tool sections entry, but make the
table’s final row consistent with the non-duplicating pattern used in da.json
and pt-BR.json.
web/messages/it.json (1)

2313-3264: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Templated/generic placeholder content persists across cmuxVsAlacritty through cmuxVsWezterm — previously flagged, still unresolved.

Despite the prior review comment being marked "Addressed," the current diff still shows the same generic boilerplate across all twelve compare pages (cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr, cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, cmuxVsWezterm):

  • Table rows read "Ruolo principale dello strumento confrontato" (literally "main role of the compared tool") instead of naming the actual tool.
  • FAQ1 answers are all "Non necessariamente. X resta utile nel suo ruolo principale; cmux aggiunge il piano di supervisione per agenti e terminali locali." with only the tool name swapped.
  • Section bodies ("cmux resta indipendente dall'agente", "Il contesto resta visibile", "Le notifiche diventano stato", "Il workflow è programmabile") repeat nearly verbatim across all twelve pages.

This diverges from the tool-specific, detailed comparisons present for the same keys in es.json and fr.json (e.g., Devin's row/FAQ there correctly explains it's a managed AI engineering platform vs. a local terminal; here it's generic filler). This is a high-confidence locale expected to carry genuine, distinct translations, not templated placeholders.

🤖 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 `@web/messages/it.json` around lines 2313 - 3264, The compare-page translations
in `cmuxVsAlacritty` through `cmuxVsWezterm` still contain templated boilerplate
instead of tool-specific Italian copy. Replace the generic table row text, FAQ1
answers, and repeated section bodies in each compare object with distinct
translations that match the actual product being compared, using the specific
keys inside each `cmuxVs*` block to localize the content correctly. Keep the
structure unchanged, but make each comparison read as a true translation rather
than a repeated placeholder across `cmuxVsAlacritty`, `cmuxVsConductor`,
`cmuxVsDevin`, `cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsHerdr`, `cmuxVsOpencode`,
`cmuxVsTmux`, `cmuxVsVscode`, `cmuxVsWindsurf`, `cmuxVsZed`, and
`cmuxVsWezterm`.
🤖 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 `@web/messages/pl.json`:
- Around line 500-518: The pl locale entry for cmuxP2 is incomplete and missing
the closing sentence that appears in the matching high-confidence translation.
Update blog.posts.claudeCodeBestWorktreeManager.cmuxP2 so it includes the full
translated copy, preserving the additional sentence about the best terminal
keeping notifications and the Cmd+Shift+U/Cmd+Control+U shortcuts wired into the
same surface.

In `@web/messages/zh-CN.json`:
- Around line 356-374: The new claudeCodeBestWorktreeManager block has two
localization issues: the date formatting in date is inconsistent with the rest
of zh-CN entries, and superRepoTitle uses the wrong term for “repo”. Update the
date in claudeCodeBestWorktreeManager to match the no-space Chinese date style
used elsewhere in web/messages/zh-CN.json, and change superRepoTitle to use the
same “超级仓库” terminology already used in superRepoP1 so the translation is
consistent and correct.

---

Duplicate comments:
In `@web/app/`[locale]/blog/claude-code-best-worktree-manager/page.tsx:
- Line 29: The publish date literal is duplicated across the page metadata,
BlogSchema, and the rendered <time> element, so it can drift over time.
Introduce a single shared date constant in
claude-code-best-worktree-manager/page.tsx and use it for
openGraph.publishedTime, BlogSchema.datePublished, and the <time dateTime>
attribute to keep all three values in sync.

In `@web/messages/bs.json`:
- Around line 2077-2113: The “Najbolje za” cell in each single-tool comparison
table is still duplicating the compared tool’s “Glavni posao” text, so update
the bs.json table rows for cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin,
cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr, cmuxVsOpencode, cmuxVsTmux,
cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, and cmuxVsWezterm to use a distinct
generic best-for phrase instead of repeating the primary-job sentence. Keep the
existing per-tool sections entry, but make the table’s final row consistent with
the non-duplicating pattern used in da.json and pt-BR.json.

In `@web/messages/it.json`:
- Around line 2313-3264: The compare-page translations in `cmuxVsAlacritty`
through `cmuxVsWezterm` still contain templated boilerplate instead of
tool-specific Italian copy. Replace the generic table row text, FAQ1 answers,
and repeated section bodies in each compare object with distinct translations
that match the actual product being compared, using the specific keys inside
each `cmuxVs*` block to localize the content correctly. Keep the structure
unchanged, but make each comparison read as a true translation rather than a
repeated placeholder across `cmuxVsAlacritty`, `cmuxVsConductor`, `cmuxVsDevin`,
`cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsHerdr`, `cmuxVsOpencode`, `cmuxVsTmux`,
`cmuxVsVscode`, `cmuxVsWindsurf`, `cmuxVsZed`, and `cmuxVsWezterm`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 45766746-134c-45c3-b160-1ff354bb664a

📥 Commits

Reviewing files that changed from the base of the PR and between 6076154 and ce44301.

📒 Files selected for processing (22)
  • web/app/[locale]/blog/claude-code-best-worktree-manager/page.tsx
  • web/app/lib/agent-page-paths.ts
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/messages/no.json (1)

2064-3406: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Generic, non-differentiated content duplicated across comparison pages (same issue previously flagged in bs.json).

Many cmuxVsX pages under landing.compare.pages reuse identical section bodies and near-identical FAQ/table content instead of translating each page's unique English source (see cmuxVsAlacritty, cmuxVsConductor, cmuxVsDevin, cmuxVsIterm2, cmuxVsKitty, cmuxVsHerdr, cmuxVsOpencode, cmuxVsTmux, cmuxVsVscode, cmuxVsWindsurf, cmuxVsZed, cmuxVsWezterm). For example, section 2 body is byte-for-byte identical across most of these pages: "Cmd+Shift+U hopper til nyeste unread pane, og Cmd+Control+U går gjennom unread arbeid uten å tømme tilstanden. Det gjør ferdige eller blokkerte agenter til en review-kø."

Additionally, in several tables (e.g. cmuxVsAlacritty.table.rows), the tool's "Best for" cell duplicates its own "Hovedjobb"/primary-job cell verbatim, a sign of the same broken content-generation pass identified previously in bs.json for this PR.

This is a native-language translation quality issue, not the accepted "English fallback" case from prior learnings — it's non-English, non-differentiated, generic content that misrepresents each comparison for no locale users.

🤖 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 `@web/messages/no.json` around lines 2064 - 3406, Fix the localized comparison
pages so each `cmuxVsX` entry in `landing.compare.pages` has distinct,
source-faithful Norwegian copy instead of reused generic text. Update the
repeated section bodies and FAQ/table cells in symbols like `cmuxVsAlacritty`,
`cmuxVsConductor`, `cmuxVsDevin`, `cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsHerdr`,
`cmuxVsOpencode`, `cmuxVsTmux`, `cmuxVsVscode`, `cmuxVsWindsurf`, `cmuxVsZed`,
and `cmuxVsWezterm` so they reflect each product’s unique comparison points.
Also fix tables where `Best for` simply repeats `Hovedjobb` by writing a
differentiated, locale-appropriate value for that specific product.

Source: Learnings

🤖 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 `@web/messages/no.json`:
- Around line 2064-3406: Fix the localized comparison pages so each `cmuxVsX`
entry in `landing.compare.pages` has distinct, source-faithful Norwegian copy
instead of reused generic text. Update the repeated section bodies and FAQ/table
cells in symbols like `cmuxVsAlacritty`, `cmuxVsConductor`, `cmuxVsDevin`,
`cmuxVsIterm2`, `cmuxVsKitty`, `cmuxVsHerdr`, `cmuxVsOpencode`, `cmuxVsTmux`,
`cmuxVsVscode`, `cmuxVsWindsurf`, `cmuxVsZed`, and `cmuxVsWezterm` so they
reflect each product’s unique comparison points. Also fix tables where `Best
for` simply repeats `Hovedjobb` by writing a differentiated, locale-appropriate
value for that specific product.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fc86ee24-3ef0-46f8-b467-4ea48014f9b5

📥 Commits

Reviewing files that changed from the base of the PR and between ce44301 and 00c6625.

📒 Files selected for processing (21)
  • web/app/lib/agent-page-paths.ts
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json
💤 Files with no reviewable changes (2)
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

Comment thread web/messages/ar.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 117175085b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/messages/tr.json Outdated
"summary": "Kod tabanınızın gerçekten ihtiyaç duyduğu worktree iş akışını oluşturmak için Claude Code, Codex, komut dosyalarını ve cmux temel öğelerini kullanın.",
"date": "3 Temmuz 2026",
"p1": "Yerleşik worktree yöneticilerinin sınırlı olması garanti edilir. Genellikle bir repo, Git, bereketli bir dal akışı ve bir ürün ekibinin kurulumun ne anlama gelmesi gerektiğine dair fikrini varsayarlar. Gerçek kod tabanları bu satırların içinde kalmaz.",
"p2": "cmux</zen>'in <zen>Zen'i, geliştiricilerin kendi araçlarını oluşturmaları ve kodla çalışma yollarının arama alanını keşfetmeleri gerektiğidir. Çalışma ağaçları kullanışlı bir ilkeldir, ancak aynı şekilde çoklu ödemeler, farklı klasörlerdeki backend/frontend depoları, uzak makineler, no-git projeler, yerel komut dosyaları ve bazen de sadece ana kodlama çünkü bu görev için en hızlı şeydir.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Balance the Turkish Zen rich-text tag

On /tr/blog/claude-code-best-worktree-manager, this paragraph is rendered with t.rich("p2", { zen: ... }), but the localized message starts with a closing </zen> before the <zen> opener. next-intl treats this as an invalid message, so the Turkish blog page logs/falls back for this paragraph instead of rendering the linked text; the tag order should wrap the intended phrase as <zen>...</zen>.

Useful? React with 👍 / 👎.

# Conflicts:
#	web/app/[locale]/(landing)/best-terminal-for-mac/page.tsx
#	web/app/[locale]/(landing)/guides/page.tsx
#	web/app/lib/agent-page-paths.ts
Comment thread web/messages/km.json
"superRepoP1": "super repo គឺជាការត្រួតពិនិត្យមួយដែលដឹងពីកន្លែងដែល repos ពិតទាំងអស់រស់នៅ របៀប worktrees ត្រូវបានបង្កើត របៀប repos ពាក់ព័ន្ធត្រូវបានផ្គូផ្គង ស្គ្រីបមួយណារៀបចំកន្លែងធ្វើការនីមួយៗ និងរបៀបដែល PRs ទទួលបានការពិនិត្យ និងបញ្ចូលគ្នា។ cmuxterm-hq គឺជា super repo៖ វាមាន cmux ចម្បង ការទូទាត់ចេញ ក្នុងមួយកិច្ចការ cmux worktrees Zed ការទូទាត់ចេញ ស្គ្រីប hq ជំនាញដែលអាចប្រើឡើងវិញបាន និងភ្នាក់ងារច្បាប់អនុវត្តតាម ដើម្បីជៀសវាងការបោះជំហានលើគ្នាទៅវិញទៅមក។",
"superRepoP2": "ចំណុចមិនមែនថាអ្នកគ្រប់គ្នាគួរចម្លងមែកធាងថតពិតប្រាកដនេះទេ។ ចំណុចនោះគឺថា ឃ្លាំងគ្រប់គ្រងមូលដ្ឋានមួយអាចពិពណ៌នាអំពីប្រព័ន្ធប្រតិបត្តិការវិស្វកម្មទាំងមូលរបស់អ្នក។ អាចបើក repo backend និង frontend repo ជាមួយគ្នាបាន។ កម្មវិធីទូរស័ព្ទ និងគេហទំព័រ API អាចផ្ទុកឡើងវិញជាមួយគ្នាបាន។ សាខាមួយអាចត្រូវបានបង្កើតនៅក្នុង repo មួយ និងសាខាដែលត្រូវគ្នានៅក្នុងមួយផ្សេងទៀត។ រូបរាងនោះជារបស់ក្រុមរបស់អ្នក មិនមែនប៊ូតុង worktree ទូទៅទេ។",
"agentTitle": "អនុញ្ញាតឱ្យភ្នាក់ងារគ្រប់គ្រង worktrees",
"agentP1": "Claude Code និង Codex គឺជាអ្នកគ្រប់គ្រង worktree ប្រសើរជាងអ្នកគ្រប់គ្រង worktree ដែលភ្ជាប់មកជាមួយភាគច្រើន ដោយសារពួកគេអាចអានច្បាប់ repo របស់អ្នក ដំណើរការស្គ្រីបរបស់អ្នក បង្កើត worktrees នៅទូទាំង repos ច្រើន សម្អាតការប៉ះទង្គិច __CMUXPH6_ សាខា ជួសជុលការបើកចំហ _CMUXPH6_ សាខារបស់ពួកគេ ហើយបញ្ចូលចូលគ្នាបន្ទាប់ពី CI ហើយពិនិត្យច្រកចេញចូល។",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Unresolved translation placeholders visible to Khmer users

km.json contains raw translation-pipeline tokens that were never substituted with actual text. Five separate fields across the new content ship broken copy to Khmer-speaking visitors:

  • blog.posts.claudeCodeBestWorktreeManager.agentP1 (line 510): __CMUXPH6_ appears twice in the middle of a sentence.
  • landing.compare.metaDescription (line 1778): __CMUXPH14_MU_PH7_, __CMUXPH14_MU_, ____ — the metaDescription for the entire Compare hub will render garbage in search snippets and social cards for Khmer users.
  • bestTerminalForAgents section body (line 1898): __CMUXPH7_ inside a rendered paragraph.
  • faqA2 for a compare page (line 2242): __CMUXPH7_MU and PH2__CMUXPH7_MU.
  • cmuxVsDevin.summaryBody (line 2329): __CMUXPH8_ and a duplicated list of agent names.

These tokens appear to be protect-tags from the machine-translation pipeline that were not restored before committing. The Khmer locale is a supported locale (it is in web/messages/ and covered by the internationalization rule), so shipping them surfaces broken strings to real users and corrupts the metaDescription for SEO. The affected strings must be retranslated or patched before merging.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0fd984f. Configure here.

Comment thread web/messages/ar.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26779b2105

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/messages/ja.json
"macOSのみ"
],
[
"導体",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Japanese product names canonical

On /ja/compare/best-terminal-for-ai-coding-agents, CompareTable renders the first cell of each row as the product name/key, so translating Conductor to 導体 (and the following brand rows likewise) makes the page show common words instead of the canonical tool names and breaks the product list. Fresh evidence: the Chinese rows in this commit are canonical again, but the Japanese rows still translate these names.

Useful? React with 👍 / 👎.

@lawrencecchen
lawrencecchen merged commit 1a60bf0 into main Jul 6, 2026
28 of 30 checks passed

This branch was successfully deployed

1 active deployment
Preview – cmux — 26779b21 Deployed Jul 6, 2026 by vercel[bot]
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.

1 participant