Skip to content

[codex] Add diff pane file viewer action - #3715

Merged
Kitenite merged 1 commit into
mainfrom
diff-pane-viewer-button
Apr 25, 2026
Merged

Kitenite merged 1 commit into
mainfrom
diff-pane-viewer-button

Conversation

@Kitenite

@Kitenite Kitenite commented Apr 25, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Make the v2 diff file path chip open files in Superset's built-in file viewer.
  • Preserve Shift-click behavior by opening the file viewer in a new tab.
  • Add a separate external-link action for opening the changed file in the configured editor.
  • Normalize v2 file-pane opens to absolute paths so relative diff paths work with the shared file document store.

Validation

  • bunx @biomejs/biome@2.4.2 check <touched files>
  • bun run --cwd apps/desktop typecheck
  • git diff --check

Summary by cubic

Clicking a file in the v2 Diff pane now opens it in the built‑in file viewer, with Shift‑click opening in a new tab. An external‑link button and modifier‑click open the file in your editor; opens use absolute paths for consistent view history, deleted files show a clear toast, and reopening an already‑active file pins its pane.

Written for commit 457516a. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Modifier-click (e.g., Shift+click) opens diff files in a new viewer tab.
    • “Open in file viewer” control added; separate “Open in editor” control launches external editor.
    • External-editor action exposed so the app can route opens to external editors when available.
  • Bug Fixes

    • Unified handling for deleted files shows “File no longer exists” and blocks opens.
    • File paths normalized to prevent mixed-path mismatches when opening or pinning panes.

@coderabbitai

coderabbitai Bot commented Apr 25, 2026 •

Copy link
Copy Markdown
Contributor

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dc70bb59-78ba-4011-b710-2f4a1205fd4a

📥 Commits

Reviewing files that changed from the base of the PR and between a1788a7 and 457516a.

📒 Files selected for processing (6)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileEntry/DiffFileEntry.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx
  • 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
✅ Files skipped from review due to trivial changes (1)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/usePaneRegistry.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx

📝 Walkthrough

Walkthrough

Diff components now accept an injected onOpenFile and a separate onOpenInExternalEditor callback; handlers are threaded through headers, entries, and workspace diff with unified deleted-file checks. The pane registry injects onOpenFile. Page-level file opening normalizes paths to absolute workspace paths.

Changes

Cohort / File(s) Summary
Diff pane public API & wiring
apps/desktop/src/renderer/.../DiffPane/DiffPane.tsx
Added onOpenFile to DiffPane props and signature; forwards onOpenFile and openInExternalEditor to child components.
Diff entry behavior
apps/desktop/src/renderer/.../DiffFileEntry/DiffFileEntry.tsx
onOpenFile now accepts openInNewTab?: boolean; added required onOpenInExternalEditor; unified deleted-file checks and forwarded handlers through placeholders and WorkspaceDiff render paths.
Diff header controls
apps/desktop/src/renderer/.../DiffFileHeader/DiffFileHeader.tsx
Open button uses getSidebarClickIntent(event) to choose between onOpenFile(openInNewTab?) or onOpenInExternalEditor; added dedicated “Open in editor” control; updated aria/tooltip and enabled/disabled logic.
Workspace diff forwarding
apps/desktop/src/renderer/.../WorkspaceDiff/WorkspaceDiff.tsx
onOpenFile typed to accept optional openInNewTab; added optional onOpenInExternalEditor prop and forwards both to DiffFileHeader.
Pane registry injection
apps/desktop/src/renderer/.../usePaneRegistry/usePaneRegistry.tsx
renderPane for diff now injects the registry’s onOpenFile into DiffPane.
Page path normalization
apps/desktop/src/renderer/.../page.tsx
openFilePane normalizes filePath to an absolute workspace path (when worktreePath exists) and uses that normalized path for recordView, pane creation/storage, and “already open” comparisons.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Header as DiffFileHeader
    participant Entry as DiffFileEntry
    participant Pane as DiffPane
    participant Registry as PaneRegistry
    participant Page as Page

    User->>Header: click open (may include modifier)
    Header->>Entry: call onOpenFile(path, openInNewTab?) or onOpenInExternalEditor(path)
    Entry->>Pane: forward onOpenFile / onOpenInExternalEditor
    Pane->>Registry: invoke injected onOpenFile(path, openInNewTab?)
    Registry->>Page: registry's onOpenFile called
    Page->>Page: normalize to absolute workspace path
    Page->>Page: recordView / create or pin pane using normalized path
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I nudged the props and threaded each door,

Paths now tidy, no crumbs on the floor,
Headers hop, entries follow in line,
Open in viewer or editor — all fine 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a diff pane file viewer action, which aligns with the primary objective of making the v2 diff file path chip open files in the built-in file viewer.
Description check ✅ Passed The PR description covers the required sections with clear information about changes, includes both manual and automated summaries, and lists validation steps, though it lacks formal Related Issues and Type of Change sections from the template.
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.

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

✨ 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 diff-pane-viewer-button

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.

@greptile-apps

greptile-apps Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a built-in file viewer action to the v2 diff pane's file path chip, separating it from the external editor action which gets a new dedicated ExternalLink button. It also fixes a bug where relative diff paths were passed directly to the file document store instead of being normalized to absolute paths first.

Confidence Score: 5/5

Safe to merge — the path normalization bug fix is correct and the new UI interactions are well-structured.

All changes are P2 or lower. The path normalization fix properly handles already-absolute paths (toAbsoluteWorkspacePath is idempotent for them), and the UI split between file-viewer and external-editor is clean and consistent across the component tree.

No files require special attention.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx Bug fix: normalizes filePath to absoluteFilePath before passing to pane data and comparison, so relative diff paths work correctly with the shared file document store.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx Adds a dedicated ExternalLink button for opening files in the external editor; file path chip now triggers built-in file viewer with Shift-click support for new-tab opening.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileEntry/DiffFileEntry.tsx Splits handleOpenFile (file viewer) from handleOpenInExternalEditor; extracts showDeletedFileToast to avoid duplication; threads openInNewTab param correctly.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx Adds onOpenFile prop to DiffPane and passes it down to DiffFileEntry alongside the existing onOpenInExternalEditor.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx Threads new onOpenInExternalEditor prop through to DiffFileHeader alongside existing onOpenFile.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/usePaneRegistry.tsx Passes onOpenFile from registry options into DiffPane, connecting the workspace-level file opener to the diff pane.

Sequence Diagram

sequenceDiagram
    participant User
    participant DiffFileHeader
    participant DiffFileEntry
    participant openFilePane (page.tsx)
    participant FileDocumentStore

    User->>DiffFileHeader: Click file chip
    DiffFileHeader->>DiffFileEntry: onOpenFile(event.shiftKey)
    DiffFileEntry->>DiffFileEntry: handleOpenFile(openInNewTab)
    alt file.status === deleted
        DiffFileEntry->>User: toast.error(File no longer exists)
    else
        DiffFileEntry->>openFilePane (page.tsx): onOpenFile(file.path, openInNewTab)
        openFilePane (page.tsx)->>openFilePane (page.tsx): toAbsoluteWorkspacePath(worktreePath, filePath)
        openFilePane (page.tsx)->>FileDocumentStore: openPane / addTab with absoluteFilePath
    end

    User->>DiffFileHeader: Click ExternalLink button
    DiffFileHeader->>DiffFileEntry: onOpenInExternalEditor()
    DiffFileEntry->>DiffFileEntry: handleOpenInExternalEditor()
    alt file.status === deleted
        DiffFileEntry->>User: toast.error(File no longer exists)
    else
        DiffFileEntry->>openFilePane (page.tsx): openInExternalEditor(file.path)
    end
Loading

Reviews (1): Last reviewed commit: "Add diff pane file viewer action" | Re-trigger Greptile

@Kitenite
Kitenite force-pushed the diff-pane-viewer-button branch from dbc3cd7 to 4f3f9e6 Compare April 25, 2026 00:53

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

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.

No issues found across 6 files

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx (1)

65-96: Optional: also honor Cmd/Ctrl-click for "open in new tab".

Currently only event.shiftKey triggers a new tab. PR objective explicitly preserves Shift-click, so this is by design — but on macOS/Windows the most conventional new-tab modifiers for clicking a "link-like" target are ⌘-click / Ctrl-click. Worth considering accepting either modifier so users don't have to learn a chip-specific convention.

♻️ Possible tweak
-						onClick={(event) => onOpenFile?.(event.shiftKey)}
+						onClick={(event) =>
+							onOpenFile?.(
+								event.shiftKey || event.metaKey || event.ctrlKey,
+							)
+						}

Note: middle-click is another common new-tab gesture; if you want to support it, add an onAuxClick handler that checks event.button === 1.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx
around lines 65 - 96, The click handler currently only treats event.shiftKey as
"open in new tab"; update the button handlers around onOpenFile to also treat
event.metaKey (Cmd on macOS) and event.ctrlKey (Ctrl on Windows/Linux) as
new-tab modifiers and optionally support middle-click by adding an onAuxClick
that calls onOpenFile when event.button === 1; specifically modify the onClick
callback that calls onOpenFile?.(event.shiftKey) to compute a boolean like
openInNewTab = event.shiftKey || event.metaKey || event.ctrlKey and pass that to
onOpenFile, and add an onAuxClick handler that checks event.button === 1 and
calls onOpenFile(true) (guarded by existence of onOpenFile).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx:
- Around line 99-114: The tooltip on the Open in editor button doesn't show when
the button is disabled because the class disabled:pointer-events-none prevents
hover events; update DiffFileHeader's Open-in-editor button handling so the
TooltipTrigger can receive pointer events even when onOpenInExternalEditor is
falsy — wrap the button in a non-disabled wrapper element (e.g., a <span>) when
disabled and apply TooltipTrigger asChild to that wrapper, keep the button
disabled and styled the same, and ensure onOpenInExternalEditor remains the
click handler on the button (refer to the ExternalLink button within the
DiffFileHeader component and Tooltip / TooltipTrigger / TooltipContent usage).

---

Nitpick comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx:
- Around line 65-96: The click handler currently only treats event.shiftKey as
"open in new tab"; update the button handlers around onOpenFile to also treat
event.metaKey (Cmd on macOS) and event.ctrlKey (Ctrl on Windows/Linux) as
new-tab modifiers and optionally support middle-click by adding an onAuxClick
that calls onOpenFile when event.button === 1; specifically modify the onClick
callback that calls onOpenFile?.(event.shiftKey) to compute a boolean like
openInNewTab = event.shiftKey || event.metaKey || event.ctrlKey and pass that to
onOpenFile, and add an onAuxClick handler that checks event.button === 1 and
calls onOpenFile(true) (guarded by existence of onOpenFile).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1205e466-1669-4dc1-b364-cc8e0566e5b8

📥 Commits

Reviewing files that changed from the base of the PR and between 99db5be and dbc3cd7.

📒 Files selected for processing (6)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileEntry/DiffFileEntry.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx
  • 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

@Kitenite
Kitenite force-pushed the diff-pane-viewer-button branch from 4f3f9e6 to a1788a7 Compare April 25, 2026 00:55
@Kitenite
Kitenite force-pushed the diff-pane-viewer-button branch from a1788a7 to 457516a Compare April 25, 2026 01:07
@Kitenite
Kitenite merged commit 09323ff into main Apr 25, 2026
5 of 6 checks passed
@Kitenite
Kitenite deleted the diff-pane-viewer-button branch April 25, 2026 01:10
@github-actions

Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch

Thank you for your contribution! 🎉

MocA-Love pushed a commit to MocA-Love/superset that referenced this pull request Apr 25, 2026
MocA-Love added a commit to MocA-Love/superset that referenced this pull request Apr 25, 2026
upstream の 10 commits は #426 と #427 で fork 固有の差分を保ちながら個別に
cherry-pick 取り込み済み。本 merge は ours strategy で **記録だけ** マージ済みに
することで behind=0 を達成し、git 履歴上の追跡を正しくする。

Cherry-pick 取り込み済 (PR #426):
- 5aab22a fix closed picker filters (ParadevAI#3702) → cdb52f9
- 99db5be [codex] simplify workspace controls (ParadevAI#3714) → f079606
- 186078a fix(chat): prevent ask_user question from shadowing sandbox access prompt (ParadevAI#3662) → 09d6b57
- 47893c2 fix desktop workspace creation title clamp (ParadevAI#3718) → 6a8c4ae
- 09323ff Add diff pane file viewer action (ParadevAI#3715) → 817ed8d
- a5891c6 remove pending launch log (ParadevAI#3721) → 0764d03
- c83de0c Add Tiptap table support (ParadevAI#3719) → e67a885
- 486b621 [codex] Fix v2 terminal lifecycle after sleep (ParadevAI#3711) → b71fbbb (+ #426 内 review fixups)

Cherry-pick 取り込み済 (PR #427):
- e07aef6 feat(desktop): play v2 notification hooks client-side (ParadevAI#3675) → 27ac18a
- eae6008 [codex] Port v2 terminal hotkeys to v1 (ParadevAI#3724) → 05a77b8 (+ #427 内 Windows .ps1 v2 化)

Fork 固有領域は変更ゼロで保持: 19 tRPC procedures (workspaces.githubExtended)、
AudioScheduler / Aivis TTS / notification-manager、terminal suggestion handler
(新 terminalKeyboardHandler.ts に移植)、TERMINAL_OPTIONS、SUPERSET_WORKSPACE_NAME、
MainWindowEffects、INCEPTION_AUTH_PROVIDER_ID、v1MigrationState、TiptapPromptEditor、
electron-builder.ts (dmg.size="4g", fileAssociations)、Service Status Dashboard、
Linux daemon systemd、Worktree auto-sync、Windows support、DnD scratch route 他。
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