From d7ba5f2457bd16054b4fe439493bac48f0340f62 Mon Sep 17 00:00:00 2001 From: Rohit Ghumare Date: Thu, 13 Aug 2026 13:22:43 +0100 Subject: [PATCH 1/2] feat(console): open coder file rows in the shell explorer first The open-in menu on coder file-change rows leads with the console's own surface: 'open in shell' navigates to #/ext/shell/open/[:line], which the shell explorer page consumes (re-rooting to the file's folder when it lives outside the browsed one). The shell worker serves both the coder::* functions that produce these rows and that page, so the route always resolves when the menu is visible. External editors and copy path keep their places below. Refs MOT-4407. --- .../chat/coder/OpenInEditorButton.tsx | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/console/web/src/components/chat/coder/OpenInEditorButton.tsx b/console/web/src/components/chat/coder/OpenInEditorButton.tsx index 90deef580..8540a2460 100644 --- a/console/web/src/components/chat/coder/OpenInEditorButton.tsx +++ b/console/web/src/components/chat/coder/OpenInEditorButton.tsx @@ -11,13 +11,14 @@ import { copyTextToClipboard } from '@/lib/clipboard' import { EDITORS, type EditorId, editorById } from '@/lib/editor-links' /** - * "open in editor" affordance for coder file-change rows: one button that - * always opens a menu of editors (cursor / vs code / zed) — each entry - * launches that editor via its URL scheme — plus "copy path", the fallback - * when the browser isn't on the machine that has the files. No editor is - * privileged; the menu is shown every time so the choice stays explicit. - * Renders nothing for non-absolute paths (result resolution failed — - * `coder` results are jail-resolved absolute on success). + * "open in editor" affordance for coder file-change rows: the console's + * own shell explorer first (`#/ext/shell/open/[:line]` — + * the shell worker serves both the `coder::*` surface that produced this + * row and that page, so the route always resolves), then external + * editors (cursor / vs code / zed) via their URL schemes, plus "copy + * path" — the fallback when the browser isn't on the machine that has + * the files. Renders nothing for non-absolute paths (result resolution + * failed — `coder` results are jail-resolved absolute on success). */ export function OpenInEditorButton({ path, @@ -29,6 +30,14 @@ export function OpenInEditorButton({ const [copied, setCopied] = useState(false) if (!path.startsWith('/')) return null + const openInShell = () => { + const anchor = + typeof line === 'number' && Number.isInteger(line) && line > 0 + ? `:${line}` + : '' + window.location.hash = `#/ext/shell/open/${encodeURIComponent(path)}${anchor}` + } + const openWith = (id: EditorId) => { window.location.href = editorById(id).buildUrl(path, line) } @@ -54,6 +63,10 @@ export function OpenInEditorButton({ + + open in shell + + {EDITORS.map((e) => ( openWith(e.id)}> open in {e.label} From acc5eb1622094c2b85ffadbfb674a80c9128c6f0 Mon Sep 17 00:00:00 2001 From: Rohit Ghumare Date: Thu, 13 Aug 2026 13:34:23 +0100 Subject: [PATCH 2/2] fix(console): file-row menu trigger label matches its contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The menu leads with open-in-shell and ends with copy path — 'open in editor' undersold it; the trigger now reads 'open file'. --- console/web/src/components/chat/coder/OpenInEditorButton.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/web/src/components/chat/coder/OpenInEditorButton.tsx b/console/web/src/components/chat/coder/OpenInEditorButton.tsx index 8540a2460..a6917a616 100644 --- a/console/web/src/components/chat/coder/OpenInEditorButton.tsx +++ b/console/web/src/components/chat/coder/OpenInEditorButton.tsx @@ -56,8 +56,8 @@ export function OpenInEditorButton({