Skip to content

upstream merge 2026-04-27 PR-D5: PR action header (#3777, scope-limited)#452

Merged
MocA-Love merged 2 commits into
mainfrom
upstream/batch-2026-04-27-pr-d5
Apr 28, 2026
Merged

upstream merge 2026-04-27 PR-D5: PR action header (#3777, scope-limited)#452
MocA-Love merged 2 commits into
mainfrom
upstream/batch-2026-04-27-pr-d5

Conversation

@MocA-Love
Copy link
Copy Markdown
Owner

Summary

upstream 2026-04-27 後半バッチ第5弾 (最終)。PR-D5: PR action header (864a81c03) (1 commit)。

依存: #451 (PR-D4) の上に乗っている。PR-D1 → PR-D2 → PR-D3 → PR-D4 → PR-D5 の順でマージしてください

取り込み

SHA upstream 規模 概要
(cherry-picked) superset-sh#3777 39 files / +2455 / -209 v2 sidebar に PR action header 追加 (gated by CREATE_PR_BUTTON_ENABLED=false)。PR status / merge dropdown UI、usePRFlowState/Dispatch hooks、host-service git.getPullRequestrepoOwner/repoName 拡張

Fork 側コンフリクト解決

upstream は v2 sidebar / dashboard layout / sidebar state schema / WorkspaceSidebar / page.tsx を大きく再構築するが、fork 側にも独自実装が多く乗っている。各ファイルで fork 機能を保持しつつ upstream の主要機能だけ取り込む:

apps/desktop/src/renderer/routes/_authenticated/_dashboard/layout.tsx

  • fork の bg-tertiary 外側 wrapper、isTearoff / isScratchRoute 条件レンダリング、<KeepAliveWorkspaces />維持
  • upstream の <div id="workspace-right-sidebar-slot"> portal は外側に追加 (PR action header の portal 出口として後で利用)

WorkspaceSidebar.tsx

  • fork の reactive useLiveQuery (v2WorkspaceLocalState を eq(state.workspaceId, workspaceId) で購読) を 維持.get() snapshot だと persist 更新が render に反映されない。
  • upstream の SidebarTabId = "changes" | "files" | "review" 型と isSidebarTabId バリデータは採用 (review が top-level tab に昇格)
  • fork 側の changesSubtab UI (Changes 内 Diffs/Review サブタブ) は upstream 整理で UI が削除されたため、変数も同時削除。schema.ts では永続化スキーマとしては残し、既存ユーザーの persisted row 互換を保つ

SidebarHeader.tsx

  • fork の <Fragment key={tab.id}>{btn}</Fragment> ラップ + Tooltip 制御を維持。upstream の直接 button 出力は採用せず

useReviewTab.tsx

  • fork の badge=0 抑制 FORK NOTE を維持 (openCommentCount > 0 ? ... : undefined)
  • upstream の icon: LuMessageSquare 追加 も採用

dashboardSidebarLocal/schema.ts

  • activeTab の enum を ["changes", "files", "review"] に拡張 (upstream 同等)
  • changesSubtab永続化スキーマとして残置 (FORK NOTE)。既存 row migration 互換のため。UI 側で参照は無いが、後で fork が in-Changes review UX を再導入する際の移行先として残す

apps/desktop/.../v2-workspace/$workspaceId/page.tsx (本 PR の主要トレードオフ)

fork は page.tsx に大量の独自 import (alert, ResizableHandle, workspaceTrpc, useNavigate, HotkeyLabel, dispatchBrowserShortcutEvent, electronTrpc, getBaseName, createWorkspaceMemo, getV2NotificationSourcesForPane, useV2NotificationStore, useV2PaneNotificationStatus, toAbsoluteWorkspacePath, toRelativeWorkspacePath, useStore, StoreApi, useRightSidebarOpenViewWidth, addBrowserShortcutListener, HiMiniXMark, TbLayoutColumns/Rows, etc) と機能 (command palette、各種 hotkey、pane notification、workspace memos、custom layout など) を持っており、upstream の page.tsx 大規模再構築 (700→近い行数の置換) とは 構造的に統合不能

判断として fork の page.tsx (PR-D4 までの状態) を完全採用864a81c03 の page.tsx 変更 (PR action header の portal mount via createPortal to workspace-right-sidebar-slot) は 本 PR のスコープ外。PRActionHeader / usePRFlow* hooks / portal slot の追加自体は WorkspaceSidebar で取り込まれているため、後続 PR で fork の page.tsx に portal mount 部分だけ手動移植すれば足りる。

つまり本 PR では PR action header の UI コンポーネントとフロー hooks は導入されているが、portal で sidebar slot にマウントされない = 画面には出ない 状態。後続 PR で page.tsx に portal mount 部分のみ追記して有効化する想定。

Fork 固有機能ヘルスチェック

baseline と比較し全項目健在:

  • 19 個の独自 tRPC procedures 健在 (PR 系 replyToPullRequestComment / setPullRequestDraftState / updatePullRequestAssignees 等は upstream PR action header と並行運用)
  • fork 専用依存維持
  • fork マーカー全項目健在
  • dmg.size = "4g" 維持

Test plan

  • bun install 整合性 OK
  • bun run typecheck 全 28 task green
  • bun run lint biome green
  • (手動) v2 sidebar の review tab 動作 (top-level tab として表示)
  • (手動) PR action header は portal 未マウントなので非表示を確認
  • (後続 PR) page.tsx に createPortal mount を移植して PR action header を有効化

saddlepaddle and others added 2 commits April 28, 2026 09:14
…et-sh#3805)

Move the chat session switcher into the v2 pane header via
renderTitle so the chat pane stops rendering its own h-8 header
underneath the pane header. Also drop the dev-only "Copy raw chat
JSON" button and the now-unused onRawSnapshotChange/ChatRawSnapshot
plumbing in both v1 and v2.
…set-sh#3777)

* wip

* chore(desktop): integrate PR action header behind a flag

Wires the cherry-picked wip into v2 alongside the recent main refactor:
restores `v2UserPreferencesSchema` + `pendingWorkspaceSchema` fields the
wip dropped, points the sidebar-open read at user prefs (where the toggle
hotkey writes), adds `focusRequestId` route param + `getDefaultBranchName`
import the wip referenced without declaring, and drops the removed
`changesSubtab` write. PR action header rendering is gated behind a
`PR_ACTION_HEADER_ENABLED = false` constant — empty bar still renders so
sidebar layout stays consistent. Flip to true once chat lands in v2 and
the slash-command flow is verified end-to-end.

* feat(desktop): v1-style PR status + restore main's v2 workspace page

Restores main's page.tsx (PR superset-sh#3747 refactor) — the wip's inline
openFilePane stored unconverted paths and tripped workspace-fs's
ensureWithinRoot for callers that didn't pre-normalize. Re-adds the
pendingReveal prop and widens onSelectDiffFile on WorkspaceSidebar so
main's page.tsx props line up.

PRActionHeader now mirrors v1's PRButton: when a PR exists and is open,
the right side renders a link + chevron dropdown with squash / merge /
rebase, wired to workspaceTrpc.github.mergePR. After a successful merge,
triggers pullRequests.refreshByWorkspaces and refetches the local
queries so the UI reflects merged state immediately instead of waiting
for the 30s background sync. Closed/merged/draft PRs render the link
without the dropdown.

Gating: renamed PR_ACTION_HEADER_ENABLED → CREATE_PR_BUTTON_ENABLED to
reflect that only the create-PR dispatch is gated (chat doesn't exist
in v2 yet). The status group + merge dropdown always render.

Also: refresh button on the Changes tab that invalidates getStatus,
getDiff, listCommits, listBranches, and getBaseBranch in parallel and
spins while in flight. getPullRequest now returns repoOwner/repoName
(needed for the merge mutation).

* feat(desktop): render v2 sidebar full-height via portal

Restores the full-height v2 sidebar layout that was on the wip: the
sidebar now portals into the workspace-right-sidebar-slot div in
layout.tsx (next to TopBar) instead of rendering inside the page below
TopBar via ResizablePanelGroup.

Width is persisted on v2UserPreferences.rightSidebarWidth (new field,
default 340) with a setter on useV2UserPreferences. The renderer's
explicit-width ResizablePanel handles drag-resize and double-click reset.
Resize dragging is forwarded to useBrowserShellInteractionPassthrough so
the browser pane keeps ignoring clicks during resize.

The workspace area no longer needs the resizable panel group since it's
the only thing in the page now — it expands to fill flex-1, and the
sidebar floats next to it via portal.

Also drops the unused commitCount prop on ChangesHeader (caught by lint
after the wip's refactor stopped using it).

* feat(desktop): icon-only PR action header + sidebar overflow guards

PRActionHeader now mirrors v1's PRButton state machine using just icons —
dropped the badge text on the left ("Open"/"Not published"/"Ready"
etc.). State is conveyed by the icon itself:

- loading           → empty (was: text-only)
- unavailable       → muted PR icon with tooltip explaining why
- no-pr             → clickable PR icon (gated → muted icon, tooltip
                      "Create PR coming soon")
- pr-exists open    → link with PR-state icon + chevron merge dropdown
- pr-exists closed/
  merged/draft      → link with PR-state icon (no merge dropdown)
- busy              → link + spinner
- error             → muted icon, click to retry

selectActionButton now returns the raw UnavailableReason so the
component renders the tooltip (decouples copy from the selector).

Also fixes the sidebar blowing past its width on the Review tab:
ReviewTabContent only had overflow-y-auto, so wide content escaped
horizontally. Added min-w-0 + overflow-x-hidden to ReviewTabContent and
the WorkspaceSidebar tab content wrapper as a defense-in-depth guard
for any future tab.

* feat(desktop): CI/review status dots + hover detail card on PR badge

PR badge now carries two ambient indicators next to the number — a CI
rollup dot (success/failure/pending, circle icons) and a review decision
dot (approved/changes-requested/pending, user icons). Distinct icon
families so they read as "build" vs "people" at 12px. Suppressed for
closed/merged PRs (post-state CI is noise) and for PRs with no checks
or no review requested (quiet for trivial PRs).

Hovering the link now opens a 320px card with the title (line-clamped),
state pill, branch, full check rollup ("8 of 10 passing"), review
status, "Updated 2h ago", and a "View on GitHub" link. Pulled in via
@superset/ui/hover-card so animations + portal placement come for free.

Extracted computeChecksRollup + coerceCheckStatus to a shared util so
useReviewTab and the new dots draw from the same source — keeps the
sidebar tab and the badge from drifting on edge cases.

Co-located the new pieces under PRActionHeader/components/PRStatusGroup
following the project's per-component-folder convention.

* polish(desktop): state-tinted PR badge, drop review indicators, files first

PR badge now wears the PR state color: open is emerald-tinted (border +
bg + divider), merged violet, closed rose, draft muted. Tinting the
whole bordered group makes state legible at a glance without the icon
having to carry it alone.

Dropped the review-decision dot and the "Review" line in the hover
detail card — review noise was redundant with the Review tab's own
indicator and made the badge feel busy. Only the CI checks dot remains
next to the PR number.

Sidebar tab order is now Files → Changes → Review (Files first).

* fix(desktop): address PR review feedback

Bot reviews flagged a mix of stale concerns (already addressed in earlier
commits) and live issues. Fixing the live ones:

- page.tsx: restore min-w-[320px] on the workspace area so dragging the
  sidebar wider can't collapse the editor pane to unusable width (lost
  when we portaled the sidebar out of the resizable panel group)
- page.tsx: initialize sidebarSlotEl synchronously via useState init so
  users with rightSidebarOpen=true persisted don't see a 1-frame flash
  on mount; the slot is mounted by the parent layout before this child
  renders, so a synchronous lookup is safe
- PRStatusGroup: catch refresh failures after a successful merge —
  previously the rejection escaped the async onSuccess silently and
  left the UI stale. Now logs and shows a soft toast
- useChangesTab: catch refresh failures from the Changes-tab refresh
  button — previously void-discarded
- git.ts getBranchSyncStatus: log when git.status() fails instead of
  silently misreporting a dirty repo as clean. Defaults to false on
  failure with a comment explaining why over-reporting on every transient
  blip would be more annoying than briefly under-reporting

Cleanup:
- Drop dead _unavailableTooltip helper in getPRFlowState (byte-for-byte
  copy of the one in PRActionHeader, orphaned during cherry-pick)
- Drop dead rightSidebarOpen + rightSidebarWidth from
  workspaceLocalStateSchema — both moved to v2UserPreferences and the
  per-workspace fields are written by nobody and read by nobody

Dead-code-but-harmless-to-fix-now (will matter once create-PR ships):
- Replace deprecated unescape() with TextEncoder for UTF-8 base64 in
  usePRFlowDispatch.encodeAsDataUrl
- buildPRContext: stop emitting literal `<default>` when defaultBranch
  is null; instruct the agent to resolve via `gh repo view` instead
- create-pr.md: quote refs in `git push -u origin -- "<branch>"` and the
  `<base>..HEAD` ranges to prevent shell injection on crafted names
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 168c3077-17c6-41f9-8a6d-fc062ea5e7a5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upstream/batch-2026-04-27-pr-d5

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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch
  • ⚠️ Electric Fly.io app

Thank you for your contribution! 🎉

@MocA-Love MocA-Love changed the base branch from upstream/batch-2026-04-27-pr-d4 to main April 28, 2026 00:36
@MocA-Love MocA-Love merged commit 0221792 into main Apr 28, 2026
12 of 13 checks passed
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: 286cd471d4

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

/>
)}
</div>
<div id="workspace-right-sidebar-slot" className="flex h-full shrink-0" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep right-sidebar slot in the main workspace row

The new workspace-right-sidebar-slot is rendered as a sibling of the main flex-1 content inside a flex-col container, and it has h-full shrink-0. In this layout, that makes the slot consume full parent height on the vertical axis, which can force the actual workspace row to collapse or overflow; the portal target should live inside the horizontal workspace row (or not use h-full here) so it doesn’t steal main-axis space.

Useful? React with 👍 / 👎.

Comment on lines +30 to +31
if (loadError && !sync && !pr) {
return { kind: "error", pr: null, message: loadError.message };
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 Preserve error state when PR query fails

getPRFlowState only returns kind: "error" when both sync and pr are missing, so a failed git.getPullRequest request with a successful sync response is treated as a normal no-PR/unavailable state instead of an error. In that scenario (e.g., stale pullRequestId or transient PR fetch failure), the UI silently hides the failure and can misrepresent PR state.

Useful? React with 👍 / 👎.

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.

3 participants