Skip to content

upstream取り込み: v2 terminal modifier-keyed links + DnD (#3512 + #3542)#312

Merged
MocA-Love merged 2 commits intomainfrom
upstream-merge/pr6-v2-terminal-dnd-links
Apr 18, 2026
Merged

upstream取り込み: v2 terminal modifier-keyed links + DnD (#3512 + #3542)#312
MocA-Love merged 2 commits intomainfrom
upstream-merge/pr6-v2-terminal-dnd-links

Conversation

@MocA-Love
Copy link
Copy Markdown
Owner

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

概要

upstream から v2 terminal 系 2 commit を同梱で取り込む PR。behind 3 → 1。

取り込み commit

SHA 内容 分類
064db9f77 feat(desktop): modifier-keyed v2 terminal file links + folder sidebar reveal (superset-sh#3512) — 17 files +376/-30 おそらく安全
0b62387ba fix(desktop): wire drag-and-drop for files in v2 terminal panes (superset-sh#3542) — 2 files +63/-1 おそらく安全

fork 適応修正

  1. page.tsx cherry-pick conflict 3箇所を手動マージ:

    • 上部 setup で fork の navigate / rightSidebarOpenViewWidth / electronTrpc.settings / showPresetsBar setup を維持しつつ、upstream の const collections = useCollections() を追加
    • fork の recordRecentlyViewed helper を維持したまま、selectedFilePathactiveFilePanePath + useState + useEffect パターンに upstream rename を適用
    • usePaneRegistry が options { onOpenFile, onRevealPath } 引数を取る形へ
  2. onOpenFile 型吸収: fork の openFilePane(filePath, displayName?) と upstream 契約 (path, openInNewTab?) が第二引数の型で衝突。terminal Cmd+click は displayName を使わないので useCallback((filePath) => openFilePane(filePath)) でラップし stable ref 化。

  3. TerminalPane.tsx BrowserPaneData mode: 064 は新規 BrowserPane を { url } だけで作るが、fork BrowserPaneDatamode: \"docs\" | \"preview\" | \"generic\" が必須。terminal URL open には mode: \"generic\" を付与。

  4. revealPath: upstream そのまま。sidebarState schema の activeTab: \"changes\" | \"files\"fileTree.reveal() 経路は fork でも整合(Codex 確認済)。

fork 独自領域 (非変更)

SpreadsheetViewer, GitHubSyncService, auto-updater, quit lifecycle, Better Auth, Electron IPC clipboard, shiki-theme.ts, fileDocumentStore, packages/panes はいずれも未タッチ。

検証

  • typecheck: 全26タスク pass
  • lint: 3件(main baseline と同じ pre-existing、regression なし)

Codex pre-review

Yes(全6項目):

  1. usePaneRegistry options 引数化が FilePaneTabTitle / FilePaneHeaderExtras 経路と非干渉
  2. revealPath の sidebarState 更新パス整合(activeTab = \"files\" + selectedFilePathfileTree.reveal()
  3. onOpenFile wrapper で情報欠損なし(memo displayName 経路は別ルート)
  4. BrowserPaneData fix で reloadToken / hardReloadToken 回帰なし
  5. LinkHoverTooltip / useLinkHoverState は fork 独自領域未参照
  6. silent regression なし

テストチェックリスト

  • v2 terminal で Cmd+click → file pane で開く
  • v2 terminal で Cmd+Shift+click → external editor(remote workspace では toast)
  • v2 terminal で Cmd+click (directory) → sidebar reveal + files tab に切替
  • v2 terminal で Cmd+click (URL) → BrowserPane が開く
  • Link hover で tooltip 表示(modifier live 追従)
  • v2 terminal にファイル DnD → paste 動作

Summary by CodeRabbit

リリースノート

  • 新機能
    • ターミナルリンクのホバー時にツールチップを表示
    • Shift+クリックで外部エディタでファイルを開く機能を追加
    • ターミナルへのドラッグ&ドロップペースト機能を実装
    • ターミナルリンクから無関連側バーでファイルを表示可能に
    • URLリンク時のShift+クリック時に新ブラウザーペインで開く機能を追加

… reveal (superset-sh#3512)

* feat(desktop): v2 terminal honors terminalLinkBehavior setting

When the user's "Terminal file links" setting is "file-viewer", Cmd/Ctrl-clicking a file path in a v2 workspace terminal now opens the file in an in-app FilePane instead of the external editor — matching the v1 behavior the setting already controls.

Directories and the "external-editor" setting continue to fall through to the existing openFileInEditor path.

* feat(desktop): modifier-keyed v2 terminal file links + folder sidebar reveal

Replaces the settings-based branch with a modifier-key pattern:

- Cmd/Ctrl-click a file path → opens in an in-app FilePane.
- Cmd/Ctrl+Shift-click a file or directory → opens in the external editor (with an upfront toast for remote workspaces, same pattern as FilesTab's Open in editor guard).
- Cmd/Ctrl-click a directory path → force-opens the sidebar, reveals the folder in the file tree (ancestors expand, row scrolls into view and highlights).

Implementation reuses the existing selectedFilePath → fileTree.reveal machinery in FilesTab by promoting selectedFilePath from a pane-store derivation to a useState, synced from the active file pane via useEffect. Folder focus is just a direct setSelectedFilePath — the existing sidebar code path handles reveal + scroll + highlight without changes. Folder paths now also flow through getParentForCreation, so the "New File" toolbar button creates inside the focused folder.

Three callbacks (onOpenFile / onRevealPath / onOpenExternal) are plumbed from page.tsx through usePaneRegistry to TerminalPane. The shift-modifier path goes through openExternal, which checks workspaceHost.hostMachineId !== machineId and toasts for remote workspaces instead of firing a mutation the remote won't satisfy.

v1 code untouched; DB schema untouched; v2 settings UI untouched (terminalLinkBehavior still honored by v1).

* refactor(desktop): drop callback refs in v2 TerminalPane, use effect deps directly

* refactor(desktop): move v2 pane actions into a PaneActionsProvider context

Removes the terminal-specific callback plumbing from usePaneRegistry (which should only care about how to render each pane kind) and moves onOpenFile / onRevealPath / onOpenExternal into a React context scoped to the workspace page. TerminalPane consumes via usePaneActions() instead of taking them as props.

* refactor(desktop): drop PaneActionsProvider, pass actions through usePaneRegistry

The context indirection wasn't worth it for a single consumer (TerminalPane). Passing the three callbacks through usePaneRegistry options is simpler and has no actual downside since usePaneRegistry is only called from one place anyway.

* fix(desktop): v2 terminal folder reveal switches sidebar to Files tab

Previously revealing a directory only toggled rightSidebarOpen + setSelectedFilePath, but the sidebar would stay on whichever tab the user had last (e.g., Changes/Review), leaving FilesTab unmounted so the reveal effect never fired. Update the same v2WorkspaceLocalState transaction to also force sidebarState.activeTab back to "files".

* fix(desktop): auto-expand revealed directory + extract useOpenInExternalEditor

- useFileTree.reveal now also expands the target itself when it's a directory,
  using stateRef so there's no staleness concern. All reveal call sites benefit.
- Extract useOpenInExternalEditor hook (remote check + toast + mutate) so
  TerminalPane can consume it directly instead of through a callback. Drops one
  prop from usePaneRegistry and removes the local workspaceHost liveQuery from
  page.tsx. FilesTab's handleOpenInEditor could migrate to the same hook in a
  follow-up to dedupe the pattern.

* feat(desktop): v2 terminal URL links open in internal browser by default

Cmd/Ctrl-click a URL in a v2 terminal now opens a BrowserPane in the current
tab. Cmd/Ctrl+Shift-click still opens in the external browser.

Widens TerminalLinkHandlers.onUrlClick to receive the MouseEvent (v1's helper
just threads it through unused — behavior unchanged).

* feat(desktop): v2 terminal shows hover tooltip describing cmd-click action

Adds onLinkHover/onLinkLeave callbacks to TerminalLinkHandlers, wired through
LinkDetectorAdapter, UrlLinkProvider, and WordLinkDetector so every detected
link participates.

In v2 TerminalPane, a new LinkHoverTooltip component tracks hover + live
modifier state (global keydown/keyup listeners scoped to hover duration) and
portals a positioned tooltip to document.body when meta/ctrl is held. Content
flips on shift:
- File:   Open in editor       | shift: Open externally
- Folder: Reveal in sidebar    | shift: Open externally
- URL:    Open in browser      | shift: Open in external browser

v1's helpers.ts doesn't opt into the new callbacks, so v1 hover behavior is
unchanged.

* refactor(desktop): match tooltip styling, surface configured editor name

- Tooltip now uses the same bg-foreground/text-background/rounded-md/px-3/py-1.5/text-xs
  tokens as the project's TooltipContent, so it visually matches the rest of
  the app (was a custom border/popover style before).
- Shift-modifier tooltip text now says "Open in Cursor" / "Open in VS Code" /
  etc. based on the user's configured defaultEditor setting, resolved via
  electronTrpcClient.settings.getDefaultEditor + getAppOption display label.
  Falls back to "Open externally" if no editor is configured.

* refactor(desktop): split LinkHoverTooltip hook/component, tighten modifier listener

- Move useLinkHoverState into its own hooks/ folder (was exported alongside
  the component in violation of the one-component-per-file rule).
- Effect now re-subscribes on hover start/end only (deps: hovering boolean),
  not on every modifier change.
- Filter to Meta/Control/Shift/Alt key events so typing a letter while
  hovering doesn't churn state.
- Skip setState when modifier/shift values didn't actually change, avoiding
  identity-change re-renders on repeat keydowns.
- Extract tooltip offset constant.

* fix(desktop): block external open while host data loads, surface editor-query failures

- useOpenInExternalEditor now treats an unloaded workspaceHost as non-local
  (workspaceHost?.hostMachineId !== machineId) so Cmd+Shift-click doesn't
  fire the mutation against a potentially remote workspace before locality
  is confirmed.
- LinkHoverTooltip's getDefaultEditor catch now console.warn's the error
  before falling back to null, so settings RPC failures stay observable.
…rset-sh#3542)

* fix(desktop): wire drag-and-drop for files in v2 terminal panes

Drops from Finder or the file tree now focus the terminal, shell-escape
the path, and paste it at the cursor. A dashed overlay indicates an
active drag.

* fix(desktop): handle multi-file terminal drops, align priority with v1

Check dataTransfer.files before text/plain (native Finder drags win over
internal drags) and escape every dropped path, not just the first.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 18, 2026

📝 Walkthrough

Walkthrough

ターミナルリンクプロバイダーとマネージャーに、ホバー/リーブコールバック機能を追加し、ファイルオープン/パス表示の統合を実装します。リンク検出器、ホバー状態追跡、外部エディタ統合、ドラッグ&ドロップペースト機能も新規追加します。

Changes

Cohort / File(s) Summary
Terminal Link Providers
apps/desktop/src/renderer/lib/terminal/links/link-detector-adapter.ts, apps/desktop/src/renderer/lib/terminal/links/word-link-detector.ts
リンク検出器のコンストラクタにホバー/リーブコールバックパラメータを追加し、リンク作成時にこれらのコールバックをwireします。
Terminal Link Management
apps/desktop/src/renderer/lib/terminal/terminal-link-manager.ts, apps/desktop/src/renderer/lib/terminal/terminal-runtime-registry.ts
新しいLinkHoverInfo型を追加し、TerminalLinkHandlersにホバー/リーブハンドラーを追加します。URLクリックシグネチャを更新し、リンクプロバイダーへコールバックを伝播します。
Link Hover State Tracking
apps/desktop/src/renderer/routes/.../TerminalPane/hooks/useLinkHoverState/useLinkHoverState.ts, apps/desktop/src/renderer/routes/.../TerminalPane/hooks/useLinkHoverState/index.ts
ホバー中のリンク情報と修飾キー状態を追跡するuseLinkHoverStateフックを新規追加します。
Link Hover UI
apps/desktop/src/renderer/routes/.../TerminalPane/components/LinkHoverTooltip/LinkHoverTooltip.tsx, apps/desktop/src/renderer/routes/.../TerminalPane/components/LinkHoverTooltip/index.ts
ホバー時に外部エディターとファイル/URL操作ガイドを表示するツールチップコンポーネントを新規追加します。
External Editor Integration
apps/desktop/src/renderer/routes/.../useOpenInExternalEditor/useOpenInExternalEditor.ts, apps/desktop/src/renderer/routes/.../useOpenInExternalEditor/index.ts
外部エディターでファイルを開くためのuseOpenInExternalEditorフックを新規追加します。ホストマシンID検証も含みます。
TerminalPane Component Updates
apps/desktop/src/renderer/routes/.../TerminalPane/TerminalPane.tsx, apps/desktop/src/renderer/routes/.../TerminalPane/utils.ts
ファイルオープン/パス表示コールバック、ホバートラッキング、ドラッグ&ドロップペースト機能を追加します。修飾キーベースのリンク処理も実装します。
Pane Registry Integration
apps/desktop/src/renderer/routes/.../usePaneRegistry/usePaneRegistry.tsx
UsePaneRegistryOptionsインターフェースを追加し、ファイルオープン/パス表示コールバックをTerminalPaneに伝播します。
Workspace View Integration
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
選択ファイルパスの状態管理、パス表示コールバックの実装、サイドバー同期機能を追加します。
File Tree & Legacy Terminal
apps/desktop/src/renderer/hooks/host-service/useFileTree/useFileTree.ts, apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts, apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/link-providers/multi-line-link-provider.ts, apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/link-providers/url-link-provider.ts
ファイルツリーの展開ロジック、URLクリックハンドラー、マルチラインリンクプロバイダーにホバー/リーブサポートを追加します。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 ホバーのね、かるくふれてね、
リンクたちが、そよ風のようにね、
ファイルひらき、パス示して、
ターミナルは、今日も楽し、
ウサギより、お祝いだよ🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed タイトルは upstream からの v2 terminal 関連の 2 つのコミット取り込み内容(modifier-keyed links + DnD)を簡潔に表現している。
Description check ✅ Passed PR の説明は日本語で詳細な overview、取り込むコミット情報、fork 適応修正 4 項目、検証結果(typecheck・lint)、Codex pre-review、テストチェックリストを網羅している。

✏️ 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 upstream-merge/pr6-v2-terminal-dnd-links

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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/hooks/host-service/useFileTree/useFileTree.ts (1)

484-503: ⚠️ Potential issue | 🟠 Major

reveal のパス境界判定をディレクトリ境界ベースにしてください。

Line 486 の startsWith(rootPath) だと、rootPath=/work/app に対して /work/app-old も通り、ターミナルリンク経由でルート外の expand() / listDirectory が走り得ます。既存の isWithinPath を使うと境界を正しく扱えます。

修正案
-			if (!rootPath || !absolutePath.startsWith(rootPath)) return;
+			if (!rootPath || !isWithinPath(rootPath, absolutePath)) return;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/renderer/hooks/host-service/useFileTree/useFileTree.ts`
around lines 484 - 503, The reveal function currently uses startsWith(rootPath)
to check path membership which allows paths like /work/app-old; change the
membership checks to use the existing isWithinPath utility (e.g., replace
startsWith(rootPath) with isWithinPath(rootPath, absolutePath)) and also use
isWithinPath when iterating ancestors (replace the
current.length/rootPath.length checks with isWithinPath(rootPath, current) or
equivalent) so expand() / listDirectory() are only called for true descendants;
keep references to reveal, rootPath, isWithinPath, expand and
stateRef.current.entriesByPath when making the changes.
🧹 Nitpick comments (1)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/components/LinkHoverTooltip/LinkHoverTooltip.tsx (1)

39-57: 必要になるまで default editor の取得を遅延してもよさそうです。

現状は tooltip が表示されない terminal pane の mount 時にも毎回 getDefaultEditor.query() が走ります。defaultEditor は Shift + file link のラベルでだけ必要なので、その条件に絞ると余分な tRPC 呼び出しを減らせます。

♻️ 変更例
 export function LinkHoverTooltip({ hoveredLink }: LinkHoverTooltipProps) {
 	const [defaultEditor, setDefaultEditor] = useState<ExternalApp | null>(null);
+	const needsDefaultEditor =
+		hoveredLink?.modifier === true &&
+		hoveredLink.shift &&
+		hoveredLink.info.kind !== "url";
 
 	useEffect(() => {
+		if (!needsDefaultEditor) return;
 		let cancelled = false;
 		electronTrpcClient.settings.getDefaultEditor
 			.query()
@@
 		return () => {
 			cancelled = true;
 		};
-	}, []);
+	}, [needsDefaultEditor]);
 
 	if (!hoveredLink || !hoveredLink.modifier) return null;

Also applies to: 59-61

🤖 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/TerminalPane/components/LinkHoverTooltip/LinkHoverTooltip.tsx
around lines 39 - 57, 現在の useEffect 無条件でマウント時に
electronTrpcClient.settings.getDefaultEditor.query() を実行しているため不要な tRPC
呼び出しが発生しています。修正は LinkHoverTooltip コンポーネント内の該当 useEffect を「tooltip が表示され、かつ
Shift+file-link のラベルが必要なとき」にのみ実行するように条件化し(例:依存配列に tooltipVisible や
isShiftFileLink フラグを追加してその変化でフェッチする)、fetch のキャンセルロジック(cancelled フラグや
cleanup)を維持して setDefaultEditor の呼び出しを保護してください。同様の変更をもう一箇所の useEffect(該当する別の
getDefaultEditor.query() 呼び出し、コメントの指摘箇所 59-61 相当)にも適用してください。
🤖 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/TerminalPane/TerminalPane.tsx:
- Around line 183-188: onUrlClick の外部ブラウザ起動失敗ログで full URL を出力しないように修正してください: 電子
RPC 呼び出しの catch 内 (electronTrpcClient.external.openUrl.mutate のエラーハンドラ) で error
はログに残して構いませんが、渡される url をそのまま出力しないでください。代わりに new URL(url).origin
を安全に取得する処理を入れ(無効な URL の可能性を try/catch で扱う)、ログは「[v2 Terminal] Failed to open URL
origin: <origin>」か「[v2 Terminal] Failed to open URL (origin
unknown)」のどちらかにし、クエリやパス等の機密部分は一切出力しないようにしてください (関数: onUrlClick、呼び出し:
electronTrpcClient.external.openUrl.mutate)。

---

Outside diff comments:
In `@apps/desktop/src/renderer/hooks/host-service/useFileTree/useFileTree.ts`:
- Around line 484-503: The reveal function currently uses startsWith(rootPath)
to check path membership which allows paths like /work/app-old; change the
membership checks to use the existing isWithinPath utility (e.g., replace
startsWith(rootPath) with isWithinPath(rootPath, absolutePath)) and also use
isWithinPath when iterating ancestors (replace the
current.length/rootPath.length checks with isWithinPath(rootPath, current) or
equivalent) so expand() / listDirectory() are only called for true descendants;
keep references to reveal, rootPath, isWithinPath, expand and
stateRef.current.entriesByPath when making the changes.

---

Nitpick comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/hooks/usePaneRegistry/components/TerminalPane/components/LinkHoverTooltip/LinkHoverTooltip.tsx:
- Around line 39-57: 現在の useEffect 無条件でマウント時に
electronTrpcClient.settings.getDefaultEditor.query() を実行しているため不要な tRPC
呼び出しが発生しています。修正は LinkHoverTooltip コンポーネント内の該当 useEffect を「tooltip が表示され、かつ
Shift+file-link のラベルが必要なとき」にのみ実行するように条件化し(例:依存配列に tooltipVisible や
isShiftFileLink フラグを追加してその変化でフェッチする)、fetch のキャンセルロジック(cancelled フラグや
cleanup)を維持して setDefaultEditor の呼び出しを保護してください。同様の変更をもう一箇所の useEffect(該当する別の
getDefaultEditor.query() 呼び出し、コメントの指摘箇所 59-61 相当)にも適用してください。
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f8b028b-3c82-4330-b5e3-fb590884161d

📥 Commits

Reviewing files that changed from the base of the PR and between 3d44553 and 39b0d6b.

📒 Files selected for processing (18)
  • apps/desktop/src/renderer/hooks/host-service/useFileTree/useFileTree.ts
  • apps/desktop/src/renderer/lib/terminal/links/link-detector-adapter.ts
  • apps/desktop/src/renderer/lib/terminal/links/word-link-detector.ts
  • apps/desktop/src/renderer/lib/terminal/terminal-link-manager.ts
  • apps/desktop/src/renderer/lib/terminal/terminal-runtime-registry.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useOpenInExternalEditor/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useOpenInExternalEditor/useOpenInExternalEditor.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/components/LinkHoverTooltip/LinkHoverTooltip.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/components/LinkHoverTooltip/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/hooks/useLinkHoverState/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/hooks/useLinkHoverState/useLinkHoverState.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/utils.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/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/link-providers/multi-line-link-provider.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/link-providers/url-link-provider.ts

Comment on lines +183 to +188
onUrlClick: (event, url) => {
if (event.shiftKey) {
electronTrpcClient.external.openUrl.mutate(url).catch((error) => {
console.error("[v2 Terminal] Failed to open URL:", url, error);
});
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

失敗ログに URL 全体を出さないでください。

url には query token、認証コード、個人情報が含まれ得るため、外部ブラウザ起動失敗時でも full URL を console.error に渡すのは避けたいです。origin だけ、または URL なしのログにしてください。

修正案
 			onUrlClick: (event, url) => {
 				if (event.shiftKey) {
 					electronTrpcClient.external.openUrl.mutate(url).catch((error) => {
-						console.error("[v2 Terminal] Failed to open URL:", url, error);
+						let origin: string | undefined;
+						try {
+							origin = new URL(url).origin;
+						} catch {
+							origin = undefined;
+						}
+						console.error("[v2 Terminal] Failed to open URL:", {
+							origin,
+							error,
+						});
 					});
 					return;
 				}
📝 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
onUrlClick: (event, url) => {
if (event.shiftKey) {
electronTrpcClient.external.openUrl.mutate(url).catch((error) => {
console.error("[v2 Terminal] Failed to open URL:", url, error);
});
return;
onUrlClick: (event, url) => {
if (event.shiftKey) {
electronTrpcClient.external.openUrl.mutate(url).catch((error) => {
let origin: string | undefined;
try {
origin = new URL(url).origin;
} catch {
origin = undefined;
}
console.error("[v2 Terminal] Failed to open URL:", {
origin,
error,
});
});
return;
🤖 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/TerminalPane/TerminalPane.tsx
around lines 183 - 188, onUrlClick の外部ブラウザ起動失敗ログで full URL を出力しないように修正してください: 電子
RPC 呼び出しの catch 内 (electronTrpcClient.external.openUrl.mutate のエラーハンドラ) で error
はログに残して構いませんが、渡される url をそのまま出力しないでください。代わりに new URL(url).origin
を安全に取得する処理を入れ(無効な URL の可能性を try/catch で扱う)、ログは「[v2 Terminal] Failed to open URL
origin: <origin>」か「[v2 Terminal] Failed to open URL (origin
unknown)」のどちらかにし、クエリやパス等の機密部分は一切出力しないようにしてください (関数: onUrlClick、呼び出し:
electronTrpcClient.external.openUrl.mutate)。

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: 39b0d6bfac

ℹ️ 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 on lines +177 to +180
if (link.isDirectory) {
onRevealPath(link.resolvedPath);
} else {
onOpenFile(link.resolvedPath);
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 Route directory word-links away from file-pane open

This branch now relies on link.isDirectory to decide between onRevealPath and onOpenFile, but word-link hits are still synthesized as non-directories in the link manager. That means Cmd/Ctrl+click on bare directory names detected via the word provider (for example dot-directories shown by ls -a) is treated as a file and opened in a file pane instead of revealing the folder in the sidebar, which breaks the new directory-link behavior for a common terminal output pattern.

Useful? React with 👍 / 👎.

@MocA-Love MocA-Love merged commit 9b9b194 into main Apr 18, 2026
6 checks passed
MocA-Love added a commit that referenced this pull request Apr 18, 2026
- 064db9f feat(desktop): modifier-keyed v2 terminal file links + folder sidebar reveal (superset-sh#3512) → PR #312
- 0b62387 fix(desktop): wire drag-and-drop for files in v2 terminal panes (superset-sh#3542) → PR #312
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