Skip to content

chore(upstream): PR6 v2 review tab first pass (#3463)#182

Merged
MocA-Love merged 3 commits intomainfrom
upstream-merge/pr6-v2-review-tab
Apr 15, 2026
Merged

chore(upstream): PR6 v2 review tab first pass (#3463)#182
MocA-Love merged 3 commits intomainfrom
upstream-merge/pr6-v2-review-tab

Conversation

@MocA-Love
Copy link
Copy Markdown
Owner

@MocA-Love MocA-Love commented Apr 15, 2026

概要

upstream superset-sh#3463 feat(desktop): v2 review tab first pass — PR info, checks, comments (commit de70163f5) を取り込みます。20ファイル +2031/-16。v2 workspace sidebar に v1 相当の Review タブを追加する単独機能追加コミット。

主な変更

  • v2 workspace sidebar に Review タブを追加 (WorkspaceSidebar.tsx, SidebarHeader.tsx)
  • 新規 hooks/useReviewTab/: useReviewTab.tsx, types.ts + 4 component (PRHeader, ChecksSection, CommentsSection, ReviewTabContent)
  • 新規 hooks/usePaneRegistry/components/CommentPane/: CommentPane.tsx, comment-pane.css (mermaid dark theme + code block stable identity)
  • usePaneRegistry.tsxcomment kind 追加
  • v2-workspace/$workspaceId/page.tsxopenCommentPane callback 追加
  • v2-workspace/$workspaceId/types.tsCommentPaneData 型追加
  • apps/desktop/plans/20260413-1600-v2-review-tab.md ドキュメント

v1 Review タブからの移植版。v2-native host-service endpoints (git.getPullRequest, git.getPullRequestThreads) を使用。

手動 conflict 解決

apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx で content conflict。

  • fork HEAD は addMemoTabuseCommandPalette hook ベースの handleQuickOpen を持っていた
  • upstream は openCommentPane (新) と useState ベースの簡易 handleQuickOpen を入れた
  • 解決: 両方温存。addMemoTabuseCommandPalette 配線はそのまま、upstream の openCommentPane を追加 (FORK NOTE コメント付き)。openCommentPaneWorkspaceSidebaronOpenComment prop に渡される

フォーク適応修正 (追加1コミット)

531e704b8 fix(fork): address Codex pre-review on PR6 review tab

Codex 事前レビューで 4 件の問題を検出、3 件修正 + 1 件 defer しました。

1. useReviewTab.tsx review thread 返信コメント脱落 (High)

upstream は thread.comments[0] だけを NormalizedComment 化しており、review thread 内の返信コメントが全て落ちていました。v1 は thread 内の全コメントを平坦化していたので同じ挙動に戻しました。

// Before
for (const thread of data.reviewThreads) {
  const first = thread.comments[0];
  if (!first) continue;
  comments.push({ ... /* only first */ });
}

// After
for (const thread of data.reviewThreads) {
  for (const c of thread.comments) {
    comments.push({ ... /* every comment */ });
  }
}

2. CommentPane.tsx XSS/navigation リスク (High)

ReactMarkdowncodetable しか差し替えていなかったため:

  • <a> がデフォルトで main window を外部 URL に遷移させる可能性
  • <img> が任意のリモート画像 (tracking pixel 含む) を読み込む可能性

既存の共有 MarkdownRenderer と同じガードを入れました:

  • CommentLink: onClickpreventDefault + electronTrpcClient.external.openUrl で外部ブラウザに逃がす (他の v2 Terminal pane 等と同じパターン)
  • CommentImage: renderer/components/MarkdownRenderer/components/SafeImage でラップ。data: URL のみ許可

3. useReviewTab.tsx badge が 0 を表示 (Minor)

openCommentCount が 0 でも badge: 0 を返していたため、Review タブに 0 バッジが出ていました。Changes タブと同じく undefined で抑制:

badge: openCommentCount > 0 ? openCommentCount : undefined,

Defer: review comment の GitHub URL 欠落

Codex が指摘した「review comments に GitHub URL が付かないので comment を GitHub で開く」問題は、packages/host-service/src/trpc/router/git/ の GraphQL query と types 両方の schema 変更が必要で、この cherry-pick のスコープ外 (host-service 側改修が必要)。upstream に別途フィードバックすべき問題。

テスト

背景

PR1〜5 の 12 コミット取り込みが完了した後に upstream に追加された単独コミット。

Summary by CodeRabbit

リリースノート

  • 新機能
    • Review タブを完全実装。PR のチェック実行状況をリアルタイム表示
    • コメント管理機能を追加。アクティブと解決済みコメントを分類表示
    • コメント詳細ペインを実装。コメント内容をマークダウンで表示し、コピーボタンを搭載
    • PR ヘッダーに PR ステータスと審査状況バッジを表示

AviPeltz and others added 2 commits April 16, 2026 00:42
…uperset-sh#3463)

* feat(desktop): add Review tab to v2 workspace sidebar

Port the v1 Review tab functionality into the v2 workspace sidebar,
replacing the "Checks — Coming soon" stub. Uses v2-native host-service
endpoints (git.getPullRequest, git.getPullRequestThreads) instead of
v1 electron endpoints.

Features:
- PR header with title, state icon, review decision badge
- Collapsible CI checks section with status icons and links
- PR comments with avatars, timestamps, and preview text
- Copy individual comments or copy all to clipboard
- Comment pane: click a comment to view rendered markdown in a tab
- GitHub link in pane header to open comment on GitHub
- Copyable tables in rendered markdown

* fix(desktop): address review tab PR feedback

- Fix memory leaks: add timeout cleanup refs in CommentPane and
  CopyableTable, clear previous timeout on rapid clicks
- Add error state: show "Unable to load review status" when tRPC
  query fails instead of infinite loading spinner
- Fix getIcon fallback: show MessageSquare icon when avatarUrl is
  missing instead of rendering <img src={undefined}>
- Add aria-label to comment open button for screen readers
- Add aria-hidden to decorative arrow icon in PRHeader
- Add group-focus-visible:opacity-100 to PRHeader arrow for keyboard nav

* fix(desktop): add .catch() to all clipboard promise chains

Prevents unhandled promise rejections in the renderer if
electronTrpcClient.external.copyText.mutate() fails.

* fix(desktop): guard state updates after unmount in CommentPane

Add isMountedRef to both CommentPane and CopyableTable to prevent
setCopied calls after unmount when the async clipboard IPC resolves
after the component is gone.

* fix(desktop): fix comments not loading until refresh

The threads query had staleTime: 30_000 which cached empty results
when the query fired before the host-service had PR data synced.
Remove staleTime so every mount/refocus fetches fresh data (background
polling at 30s still runs via refetchInterval).

Also tighten the enabled condition to use prQuery.isSuccess instead
of !!prQuery.data for clearer intent, and use composite key for
CheckRow to handle duplicate check names.

* fix(desktop): unmount guard in CommentsSection + single-pass check status

- Add isMountedRef to CommentsSection so markCopied doesn't set state
  after unmount (same pattern as CommentPane/CopyableTable)
- Rewrite computeChecksStatus as single loop instead of 3 passes
  (filter + some(failure) + some(pending) each called coerceCheckStatus)

* feat(desktop): render mermaid diagrams + syntax highlighting in comment pane

Use the existing CodeBlock component which handles mermaid via
@streamdown/mermaid and syntax highlighting via react-syntax-highlighter.

* fix(desktop): lighten mermaid diagram background in comment pane

* fix(desktop): hide mermaid label + lighten actual diagram background

- Hide the "mermaid" label and action buttons on the block wrapper
- Strip the outer border/padding so it blends with the page
- Target the SVG element itself to lighten its background color

* fix(desktop): revert hacky mermaid overrides, use CSS text color instead

Revert the custom Streamdown/SyntaxHighlighter approach. Go back to
using the shared CodeBlock component. Instead of changing the mermaid
canvas background, override the SVG text fill and node/edge label
colors via CSS to use --foreground, making them readable on both
light and dark themes.

* fix(desktop): use mermaid themeVariables for light text in dark mode

Use Streamdown directly with custom themeVariables to set light text
colors (primaryTextColor, nodeTextColor, labelTextColor, etc.) on the
dark mermaid theme. Removes the CSS hacks that couldn't override
mermaid's inline SVG styles.

* fix(desktop): mermaid dark theme contrast + hide label/wrapper chrome

- Use theme: "base" with full dark color palette so themeVariables
  actually control node fills (dark gray nodes, light text)
- Hide "mermaid" label and action buttons via CSS
- Strip background/border from outer block and inner wrapper so
  diagram sits directly on the page background

* fix(desktop): extract CommentCodeBlock as standalone component

Move code block rendering out of useMemo into a proper React component
so the component identity is stable across renders. Prevents unmount/
remount of Streamdown/SyntaxHighlighter when the theme changes.

Mermaid theme variable objects extracted as module-level constants.
Three functional issues Codex found on upstream superset-sh#3463 cherry-pick:

1. useReviewTab.tsx normalizeThreadsToComments only picked
   thread.comments[0], silently dropping every reply in a review
   thread. v1 flattened all comments per thread. Loop over
   thread.comments instead so the listing and badge match the real
   PR state.

2. CommentPane.tsx fed ReactMarkdown the raw comment body without
   overriding <a> or <img>. GitHub-supplied links would navigate the
   main window away, and arbitrary remote images would load. Add
   CommentLink (opens via electronTrpcClient.external.openUrl) and
   CommentImage (uses SafeImage, which only renders data: URLs).

3. useReviewTab.tsx returned badge: openCommentCount unconditionally,
   so the tab showed a "0" badge when there were no open comments.
   Changes tab already suppresses zero badges; match that.

Deferred (upstream bug, host-service schema change required):
- Review comments never get a GitHub URL because the GraphQL query
  and host-service types in packages/host-service don't fetch/expose
  reviewComment.url. Fixing this needs host-service router changes
  and is out of scope for this cherry-pick.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Warning

Rate limit exceeded

@MocA-Love has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 21 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 46 minutes and 21 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 86395fcc-f1c5-4d4b-bf2c-4a4afcdf9e57

📥 Commits

Reviewing files that changed from the base of the PR and between c9418eb and 83deb6d.

📒 Files selected for processing (20)
  • apps/desktop/plans/20260413-1600-v2-review-tab.md
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/WorkspaceSidebar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/components/SidebarHeader/SidebarHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/ChecksSection/ChecksSection.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/ChecksSection/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/CommentsSection/CommentsSection.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/CommentsSection/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/PRHeader/PRHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/PRHeader/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/ReviewTabContent/ReviewTabContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/components/ReviewTabContent/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/types.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/hooks/useReviewTab/useReviewTab.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/CommentPane/CommentPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/CommentPane/comment-pane.css
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/CommentPane/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/usePaneRegistry.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/types.ts
📝 Walkthrough

Walkthrough

A Review tab feature is added to the v2 workspace sidebar, replacing a "Coming soon" stub. The implementation includes a useReviewTab hook fetching PR metadata and normalized comments, new UI components (PRHeader, ChecksSection, CommentsSection, ReviewTabContent), a CommentPane for viewing individual comments with Markdown rendering, type definitions for normalized data shapes, and integration with the pane registry system.

Changes

Cohort / File(s) Summary
Plan Documentation
apps/desktop/plans/20260413-1600-v2-review-tab.md
Workspace documentation plan specifying implementation strategy, data sources, tab behavior, file structure, and acceptance checklists for the Review tab feature.
Review Tab Hook & Types
apps/desktop/src/renderer/.../WorkspaceSidebar/hooks/useReviewTab/useReviewTab.tsx, types.ts, index.ts
New useReviewTab hook fetching PR and comment data via tRPC, normalizing checks/comments/review decisions, computing badge count and aggregated check status. Type definitions for NormalizedPR, NormalizedCheck, NormalizedComment.
Review Tab Components
apps/desktop/src/renderer/.../WorkspaceSidebar/hooks/useReviewTab/components/ReviewTabContent/*, PRHeader/*, ChecksSection/*, CommentsSection/*
New UI components: ReviewTabContent orchestrates PR/checks/comments display; PRHeader renders PR title with review decision badge; ChecksSection shows collapsible checks with status icons and duration; CommentsSection displays active/resolved comments with copy/open actions and per-comment row interaction.
Comment Pane & Integration
apps/desktop/src/renderer/.../usePaneRegistry/components/CommentPane/*, usePaneRegistry.tsx, page.tsx, types.ts
New CommentPane component rendering comment body with syntax-highlighted code blocks, Mermaid diagram support, copyable tables, and sanitized Markdown. Integrates with pane registry; page.tsx adds openCommentPane callback to activate/create comment panes; types.ts adds CommentPaneData to pane union.
Sidebar & Badge Updates
apps/desktop/src/renderer/.../WorkspaceSidebar/WorkspaceSidebar.tsx, SidebarHeader/SidebarHeader.tsx
WorkspaceSidebar accepts optional onOpenComment prop, wires useReviewTab hook, replaces static checks tab with dynamic reviewTab. SidebarHeader badge now renders when count is ≥0 (instead of >0) to display zero-state badges.
Comment Pane Styling
apps/desktop/src/renderer/.../usePaneRegistry/components/CommentPane/comment-pane.css
Comprehensive stylesheet for Markdown rendering in comment pane, including typography, headings, links, code blocks, syntax highlighting, tables, blockquotes, Mermaid diagram styling, and GitHub-flavored elements.

Sequence Diagram

sequenceDiagram
    participant User
    participant ReviewTab as Review Tab
    participant useReviewTab as useReviewTab Hook
    participant tRPC as tRPC / Server
    participant CommentPane as Comment Pane
    
    User->>ReviewTab: View Review Tab
    ReviewTab->>useReviewTab: Initialize hook
    useReviewTab->>tRPC: Fetch PR metadata (getPullRequest)
    tRPC-->>useReviewTab: PR + checks + status
    useReviewTab->>tRPC: Fetch PR threads (getPullRequestThreads)
    tRPC-->>useReviewTab: Comments + threads
    useReviewTab->>ReviewTab: Normalized PR & comments
    ReviewTab->>ReviewTab: Render PRHeader, ChecksSection, CommentsSection
    
    User->>ReviewTab: Click on comment
    ReviewTab->>ReviewTab: onOpenComment callback
    ReviewTab->>CommentPane: Trigger pane creation/activation
    CommentPane->>User: Display comment with Markdown + actions
    
    User->>CommentPane: Click "Copy All"
    CommentPane->>tRPC: copyText (external IPC)
    tRPC-->>CommentPane: Text copied
    CommentPane->>User: Show "Copied" feedback
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Review tabs now bloom in the sidebar's embrace,
With comments and checks in their rightful place,
PR headers sparkle, decisions shine bright,
Copy and open—feedback delight!

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upstream-merge/pr6-v2-review-tab

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

❤️ Share

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

Copy link
Copy Markdown

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

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: 531e704b80

ℹ️ 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".

Codex review on #182: when getPullRequest transitions to null (e.g. PR
closed/unlinked), React Query keeps the last successful
getPullRequestThreads data in cache. The previous code normalized
comments directly from that cached data without checking `pr`, so the
Review tab kept showing stale comments and badge count after the PR
was gone.

Gate comments on `pr` existence so the list clears immediately.
@MocA-Love
Copy link
Copy Markdown
Owner Author

83deb6d で対応しました。pr が null になったら comments も空配列にリセットするよう gate を追加しました。

@MocA-Love MocA-Love merged commit 35d95f3 into main Apr 15, 2026
6 checks passed
MocA-Love added a commit that referenced this pull request Apr 15, 2026
-s ours merge to record that upstream commits a3e34bf through
de70163 (13 commits) are semantically already present on origin/main
via the PR1-6 cherry-pick series (PRs #176, #177, #178, #179, #180,
#182), plus fork-adaptation fixes layered on top.

This merge target is de70163 specifically (not upstream/main) so
newer upstream commits (9fff075 and later) remain visible in future
behind counts.

Upstream commits covered by this audit merge:
- a3e34bf  fix(desktop): restore cmd+click requirement for v1 terminal file links (superset-sh#3457)  [PR1/#176]
- 57557f8  fix(desktop): gate v2 workspace children on collection readiness (superset-sh#3464)       [PR1/#176]
- 4ee2e61  fix(desktop): use native clipboard for copy path in v2 sidebar (superset-sh#3462)         [PR1/#176]
- 87d6e93  feat(desktop): close settings with Escape key (superset-sh#3466)                          [PR1/#176]
- 9c7f5f4  chore(desktop): auto-restart host-service on bundle change in dev (superset-sh#3461)      [PR1/#176]
- 93140d9  fix(mcp): accept MCP resource URL as valid OAuth audience (superset-sh#3459)              [PR2/#177]
- be9e000  fix(desktop): drive tray menu off events, fetch real org name (superset-sh#3458)          [PR2/#177]
- c5f791e  feat(v2): unify workspace delete through host-service (superset-sh#3443)                  [PR3/#178]
- 2c24d93  feat(desktop): paginated branch picker with checkout + open actions (superset-sh#3397)    [PR4/#179]
- 2bf1049  feat(desktop/hotkeys): v1 directional pane focus + best-effort v1 override migrator (superset-sh#3460)  [PR5/#180]
- 1294a7d  feat(desktop/hotkeys): restore Cmd+Alt+Arrow for tab/workspace nav (superset-sh#3472)    [PR5/#180]
- de70163  feat(desktop): v2 review tab first pass — PR info, checks, comments (superset-sh#3463)    [PR6/#182]

Intentionally skipped (version bump, fork has independent versioning):
- 1e23353  chore(desktop): bump version to 1.5.5 (superset-sh#3473)

Fork-adaptation fixes layered on top of the cherry-picks:
- PR1: host-service-coordinator alias import fix, settings Escape
       selector narrowing (role-based + popper wrapper), Escape
       close uses replace navigation
- PR2: dual quit mode preservation (requestQuit "release"/"stop"),
       trayUpdateToken guard for stale async fetchHostInfo results
- PR4: ChangesHeader.normalizeBranchName regex rewrite (lint false
       positive), worktree add uses fullRef for remote-tracking
       refs, syncTimedOut reset on pendingId change, GIT_REFS.md
       barrel example fix
- PR5: migrate.ts re-sanitize of existing localStorage overrides
       (v2 marker bump intent), FOCUS_PANE_* enabled:isActive for
       KeepAliveWorkspaces, CATEGORY_ORDER merges Navigation (upstream)
       and Browser (fork)
- PR6: normalizeThreadsToComments flattens all thread.comments (not
       just first), CommentPane overrides <a> (openUrl) and <img>
       (SafeImage), zero-badge suppression, pr-null comments gate

Fork features verified intact (Explore agent audit of combined
36d4de4..35d95f3 range):
- BROWSER_RELOAD / BROWSER_HARD_RELOAD hotkeys
- dual quit mode menu in tray
- v1 terminal cold-restore + retry reconnect (out of range but
  unaffected)
- KeepAliveWorkspaces (FOCUS_PANE_* gated on isActive)
- useCommandPalette + addMemoTab in v2 workspace
- host-service-coordinator rename alias pattern
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.

2 participants