From 7cdec73d557cae7a44cb317d6eb992698e7d77a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 11:00:01 -0600 Subject: [PATCH 01/11] feat(browser): branded PostHog error page on failed loads Intercepts did-fail-load (net errors, DNS failures, timeouts) on each WebContentsView and replaces the blank screen with a dark-themed error page featuring the PostHog hedgehog (builder-hog, base64-embedded so it works in both dev and the packaged app). Error code -3 (ABORTED) is skipped to avoid flashing during normal stop/redirect flows. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- apps/code/src/main/di/bindings.ts | 5 + apps/code/src/main/di/container.ts | 3 + .../src/main/services/browser/errorPage.ts | 56 ++++ .../code/src/main/services/browser/service.ts | 248 ++++++++++++++++++ apps/code/src/main/trpc/router.ts | 2 + docs/browser-tab.md | 107 ++++++++ .../core/src/panels/panelLayoutTransforms.ts | 21 ++ packages/core/src/panels/panelTypes.ts | 5 + packages/host-router/src/ports/browser.ts | 50 ++++ packages/host-router/src/router.ts | 2 + .../host-router/src/routers/browser.router.ts | 224 ++++++++++++++++ .../ui/src/features/browser/BrowserPanel.tsx | 169 ++++++++++++ .../src/features/browser/BrowserToolbar.tsx | 125 +++++++++ .../ui/src/features/browser/browserStore.ts | 53 ++++ .../panels/components/LeafNodeRenderer.tsx | 3 + .../panels/components/PanelLayout.tsx | 9 + .../panels/components/TabbedPanel.tsx | 24 +- .../panels/hooks/usePanelLayoutHooks.tsx | 43 ++- .../src/features/panels/panelLayoutStore.ts | 13 + .../components/TabContentRenderer.tsx | 13 + 20 files changed, 1171 insertions(+), 4 deletions(-) create mode 100644 apps/code/src/main/services/browser/errorPage.ts create mode 100644 apps/code/src/main/services/browser/service.ts create mode 100644 docs/browser-tab.md create mode 100644 packages/host-router/src/ports/browser.ts create mode 100644 packages/host-router/src/routers/browser.router.ts create mode 100644 packages/ui/src/features/browser/BrowserPanel.tsx create mode 100644 packages/ui/src/features/browser/BrowserToolbar.tsx create mode 100644 packages/ui/src/features/browser/browserStore.ts diff --git a/apps/code/src/main/di/bindings.ts b/apps/code/src/main/di/bindings.ts index 1bd40d0835..f0833124ee 100644 --- a/apps/code/src/main/di/bindings.ts +++ b/apps/code/src/main/di/bindings.ts @@ -83,6 +83,10 @@ import type { UPDATE_LIFECYCLE_SERVICE } from "@posthog/core/updates/identifiers import type { UpdatesService } from "@posthog/core/updates/updates"; import type { USAGE_HOST, UsageHost } from "@posthog/core/usage/identifiers"; import type { ROOT_LOGGER, RootLogger } from "@posthog/di/logger"; +import type { + BROWSER_SERVICE, + IBrowserService, +} from "@posthog/host-router/ports/browser"; import type { CONNECTIVITY_CLIENT, HostConnectivityClient, @@ -431,6 +435,7 @@ export interface MainBindings { [LOGS_SERVICE]: ILogsService; [MAIN_ENCRYPTION_SERVICE]: EncryptionService; [MAIN_DISCORD_PRESENCE_SERVICE]: DiscordPresenceService; + [BROWSER_SERVICE]: IBrowserService; [CANVAS_GEN_SERVICE]: CanvasGenService; [FREEFORM_GEN_SERVICE]: FreeformGenService; diff --git a/apps/code/src/main/di/container.ts b/apps/code/src/main/di/container.ts index 54ab5b18ee..f9b6824b4e 100644 --- a/apps/code/src/main/di/container.ts +++ b/apps/code/src/main/di/container.ts @@ -90,6 +90,7 @@ import { USAGE_HOST } from "@posthog/core/usage/identifiers"; import { usageMonitorModule } from "@posthog/core/usage/usage-monitor.module"; import { ROOT_LOGGER, type RootLogger } from "@posthog/di/logger"; import { listFilesContainingText } from "@posthog/git/queries"; +import { BROWSER_SERVICE } from "@posthog/host-router/ports/browser"; import { GIT_PR_STATUS_PROVIDER, type IGitPrStatus, @@ -239,6 +240,7 @@ import { OAuthFlowPortAdapter, TokenCipherPortAdapter, } from "../services/auth/port-adapters"; +import { BrowserService } from "../services/browser/service"; import { DeepLinkService } from "../services/deep-link/service"; import { DiscordPresenceService } from "../services/discord-presence/service"; import { EncryptionService } from "../services/encryption/service"; @@ -706,6 +708,7 @@ container.bind(LOGS_SERVICE).toDynamicValue((ctx) => { }); container.bind(MAIN_ENCRYPTION_SERVICE).to(EncryptionService); container.bind(MAIN_TOKENS.DiscordPresenceService).to(DiscordPresenceService); +container.bind(BROWSER_SERVICE).to(BrowserService).inSingletonScope(); // Canvas / dashboards (project-bluebird). The host-agnostic dashboard services // live in @posthog/core (bound via canvasCoreModule); CanvasGenService is the diff --git a/apps/code/src/main/services/browser/errorPage.ts b/apps/code/src/main/services/browser/errorPage.ts new file mode 100644 index 0000000000..755e2b70e9 --- /dev/null +++ b/apps/code/src/main/services/browser/errorPage.ts @@ -0,0 +1,56 @@ +// Error page shown when a URL fails to load in the browser panel. +// The hedgehog image is embedded as base64 so this works in both dev and +// the packaged app without any extra asset-serving setup. +const HOG_B64 = + "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"; + +export function buildErrorPage(url: string): string { + const safeUrl = url + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """); + + const html = + '' + + '' + + '' + + "Page not available" + + "" + + 'PostHog hedgehog' + + "

This page couldn\u2019t be loaded

" + + '

The hedgehog tried its best, but the page is unavailable.
' + + "Check your connection or the URL and try again.

" + + '
' + + safeUrl + + "
" + + '
' + + '' + + '' + + "
" + + '
Powered by PostHog Code
' + + ""; + + return `data:text/html;charset=utf-8,${encodeURIComponent(html)}`; +} diff --git a/apps/code/src/main/services/browser/service.ts b/apps/code/src/main/services/browser/service.ts new file mode 100644 index 0000000000..f4ea686ba7 --- /dev/null +++ b/apps/code/src/main/services/browser/service.ts @@ -0,0 +1,248 @@ +import type { + BrowserFaviconEvent, + BrowserNavigateEvent, + BrowserOpenUrlEvent, + BrowserTitleEvent, + IBrowserService, +} from "@posthog/host-router/ports/browser"; +import { MAIN_WINDOW_SERVICE } from "@posthog/platform/main-window"; +import { TypedEventEmitter } from "@posthog/shared"; +import { WebContentsView } from "electron"; +import { inject, injectable, preDestroy } from "inversify"; +import type { ElectronMainWindow } from "../../platform-adapters/electron-main-window"; +import { logger } from "../../utils/logger"; +import { buildErrorPage } from "./errorPage"; + +const log = logger.scope("browser-service"); + +type BrowserServiceEvents = { + navigate: BrowserNavigateEvent; + title: BrowserTitleEvent; + favicon: BrowserFaviconEvent; + openUrl: BrowserOpenUrlEvent; +}; + +interface BrowserEntry { + view: WebContentsView; + browserId: string; +} + +@injectable() +export class BrowserService + extends TypedEventEmitter + implements IBrowserService +{ + private browsers = new Map(); + + constructor( + @inject(MAIN_WINDOW_SERVICE) + private readonly mainWindow: ElectronMainWindow, + ) { + super(); + } + + private static readonly SAFE_PROTOCOLS = new Set(["https:", "http:"]); + + private isSafeUrl(url: string): boolean { + try { + const { protocol } = new URL(url); + return BrowserService.SAFE_PROTOCOLS.has(protocol); + } catch { + return false; + } + } + + create(browserId: string, url: string): void { + if (this.browsers.has(browserId)) return; + + const view = new WebContentsView({ + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + sandbox: true, + // Shared persistent session so cookies/logins persist across tabs. + partition: "persist:browser", + }, + }); + + const entry: BrowserEntry = { view, browserId }; + this.browsers.set(browserId, entry); + + const win = this.mainWindow.getBrowserWindow(); + if (win) { + win.contentView.addChildView(view); + } + + // Block navigation to anything other than http/https. + view.webContents.on("will-navigate", (event, targetUrl) => { + if (!this.isSafeUrl(targetUrl)) { + event.preventDefault(); + log.warn("Blocked navigation to unsafe URL", targetUrl); + } + }); + + // Prevent deep-link hijacking via frame-level navigations. + view.webContents.on("will-frame-navigate", (event) => { + if (!this.isSafeUrl(event.url)) { + event.preventDefault(); + log.warn("Blocked frame navigation to unsafe URL", event.url); + } + }); + + // Open window.open() calls as new browser tabs in the app instead of + // spawning an uncontrolled native window. + view.webContents.setWindowOpenHandler(({ url: targetUrl }) => { + if (this.isSafeUrl(targetUrl)) { + this.emit("openUrl", { url: targetUrl }); + } + return { action: "deny" }; + }); + + view.webContents.on("did-navigate", () => { + this.emitNavigate(entry); + }); + + view.webContents.on("did-navigate-in-page", () => { + this.emitNavigate(entry); + }); + + view.webContents.on("page-title-updated", (_e, title) => { + this.emit("title", { browserId, title }); + }); + + view.webContents.on("page-favicon-updated", (_e, favicons) => { + this.emit("favicon", { + browserId, + favicon: favicons[0] ?? null, + }); + }); + + view.webContents.on("did-start-loading", () => { + this.emitNavigate(entry); + }); + + view.webContents.on("did-stop-loading", () => { + this.emitNavigate(entry); + }); + + // Show a branded error page when a URL fails to load (DNS errors, timeouts, etc.). + // Error codes < 0 are Chromium net errors; -3 is ABORTED (e.g. caused by our own + // navigation lock, or the user pressing Stop) — skip those to avoid flashing the + // error page during normal navigation. + view.webContents.on( + "did-fail-load", + (_event, errorCode, _errorDescription, validatedURL, isMainFrame) => { + if (!isMainFrame) return; + if (errorCode === -3) return; + const errorPage = buildErrorPage(validatedURL); + view.webContents.loadURL(errorPage).catch(() => {}); + }, + ); + + if (url && url !== "about:blank") { + view.webContents.loadURL(url).catch((err) => { + log.warn("Failed to load URL", url, err); + }); + } + } + + destroy(browserId: string): void { + const entry = this.browsers.get(browserId); + if (!entry) return; + + this.browsers.delete(browserId); + + const win = this.mainWindow.getBrowserWindow(); + if (win) { + try { + win.contentView.removeChildView(entry.view); + } catch { + // view may already be detached + } + } + + try { + entry.view.webContents.close(); + } catch { + // already closed + } + } + + navigate(browserId: string, url: string): void { + const entry = this.browsers.get(browserId); + if (!entry) return; + entry.view.webContents.loadURL(url).catch((err) => { + log.warn("Failed to navigate", url, err); + }); + } + + setBounds( + browserId: string, + bounds: { x: number; y: number; width: number; height: number }, + ): void { + const entry = this.browsers.get(browserId); + if (!entry) return; + entry.view.setBounds({ + x: Math.round(bounds.x), + y: Math.round(bounds.y), + width: Math.round(bounds.width), + height: Math.round(bounds.height), + }); + } + + setVisible(browserId: string, visible: boolean): void { + const entry = this.browsers.get(browserId); + if (!entry) return; + entry.view.setVisible(visible); + } + + goBack(browserId: string): void { + this.browsers.get(browserId)?.view.webContents.goBack(); + } + + goForward(browserId: string): void { + this.browsers.get(browserId)?.view.webContents.goForward(); + } + + reload(browserId: string): void { + this.browsers.get(browserId)?.view.webContents.reload(); + } + + getState(browserId: string): { + url: string; + title: string; + canGoBack: boolean; + canGoForward: boolean; + isLoading: boolean; + } | null { + const entry = this.browsers.get(browserId); + if (!entry) return null; + const wc = entry.view.webContents; + return { + url: wc.getURL(), + title: wc.getTitle(), + canGoBack: wc.canGoBack(), + canGoForward: wc.canGoForward(), + isLoading: wc.isLoading(), + }; + } + + private emitNavigate(entry: BrowserEntry): void { + const wc = entry.view.webContents; + this.emit("navigate", { + browserId: entry.browserId, + url: wc.getURL(), + title: wc.getTitle(), + canGoBack: wc.canGoBack(), + canGoForward: wc.canGoForward(), + isLoading: wc.isLoading(), + }); + } + + @preDestroy() + dispose(): void { + for (const [id] of this.browsers) { + this.destroy(id); + } + } +} diff --git a/apps/code/src/main/trpc/router.ts b/apps/code/src/main/trpc/router.ts index ec493315df..c01400332a 100644 --- a/apps/code/src/main/trpc/router.ts +++ b/apps/code/src/main/trpc/router.ts @@ -3,6 +3,7 @@ import { agentRouter } from "@posthog/host-router/routers/agent.router"; import { analyticsRouter } from "@posthog/host-router/routers/analytics.router"; import { archiveRouter } from "@posthog/host-router/routers/archive.router"; import { authRouter } from "@posthog/host-router/routers/auth.router"; +import { browserRouter } from "@posthog/host-router/routers/browser.router"; import { canvasDataRouter } from "@posthog/host-router/routers/canvas-data.router"; import { canvasGenRouter } from "@posthog/host-router/routers/canvas-gen.router"; import { canvasTemplatesRouter } from "@posthog/host-router/routers/canvas-templates.router"; @@ -50,6 +51,7 @@ import { router } from "./trpc"; export const trpcRouter = router({ additionalDirectories: additionalDirectoriesRouter, + browser: browserRouter, agent: agentRouter, analytics: analyticsRouter, archive: archiveRouter, diff --git a/docs/browser-tab.md b/docs/browser-tab.md new file mode 100644 index 0000000000..3ced5287b6 --- /dev/null +++ b/docs/browser-tab.md @@ -0,0 +1,107 @@ +# Browser Tab — Implementation Tracker + +Embed a real Chromium `WebContentsView` as a first-class tab type in PostHog Code's panel system, giving it the same feel as the terminal tab but for browsing the web. + +## Architecture + +``` +Renderer (React) Main (Electron) +───────────────────────────────────── ──────────────────────────────────── +BrowserPanel BrowserService + ├─ BrowserToolbar (URL bar, nav) ├─ Map + └─
├─ create(id, url) + │ ├─ setBounds(id, x, y, w, h) + │ ResizeObserver → bounds ├─ setVisible(id, bool) + │ tab active/hidden state ├─ navigate(id, url) + └──────── tRPC (host router) ──▶ └─ goBack / goForward / reload + +Subscriptions ◀──────────────────────── onNavigate(id) → url + onTitle(id) → string + onFavicon(id) → string +``` + +The `WebContentsView` is a native Electron overlay — not a DOM element. React tracks the content area's bounds via `ResizeObserver` and pushes `{x, y, width, height}` to main whenever layout changes. Main repositions the overlay accordingly. + +## Steps + +### Phase 1 — Plumbing (Steps 1–3) + +- [x] **Step 1** — Add `browser` type to `TabData` union + panel layout helpers + - `packages/core/src/panels/panelTypes.ts` + - `packages/core/src/panels/panelLayoutTransforms.ts` + - `packages/ui/src/features/panels/panelLayoutStore.ts` + +- [x] **Step 2** — Main-process `BrowserService` + - `apps/code/src/main/services/browser.service.ts` + - Register in DI container + `BindingMap` + +- [x] **Step 3** — Host router + - `packages/host-router/src/routers/browser.router.ts` + - Wire into root host router + +### Phase 2 — UI (Steps 4–5) + +- [x] **Step 4** — React panel components + - `packages/ui/src/features/browser/BrowserPanel.tsx` — bounds sync + visibility + - `packages/ui/src/features/browser/BrowserToolbar.tsx` — URL bar, nav buttons + - `packages/ui/src/features/browser/browserStore.ts` — view-state (url, title, favicon, loading) + +- [x] **Step 5** — Wire into tab system + - `TabContentRenderer.tsx` — add `case "browser"` + - `usePanelLayoutHooks.tsx` — add Globe icon + - Tab bar `+` menu — add "Open Browser" option + +### Phase 3 — Polish (Step 6) + +- [ ] **Step 6** — Edge cases + UX + - [ ] Bounds re-sync on window resize, split-panel drag, tab drag/drop + - [ ] `setVisible(false)` when tab goes background (prevent bleed-through) + - [ ] New-tab empty state with search bar + - [ ] Context menu (Copy URL, Open in external browser, DevTools) + - [ ] Keyboard shortcuts: `Cmd+L` (focus URL), `Cmd+R` (reload), `Cmd+[/]` (back/forward) + - [x] Security: `will-navigate` lockdown (http/https only), `setWindowOpenHandler` intercept, shared `persist:browser` session + - [x] Branded PostHog error page (hedgehog + dark theme) on `did-fail-load` + +### Phase 4 — Analytics (Future) + +- [ ] **Step 7** — Instrument browser tab usage + - Track `browser_tab_opened` event (source: globe icon vs `window.open()`) + - Track `browser_tab_navigated` (distinguish user-typed URL vs back/forward vs page-triggered) + - Track `browser_tab_closed` (with session duration) + - Track `browser_tab_count` (how many concurrent tabs open) + - Consider privacy: only capture domain/hostname, never full URLs (may contain tokens or PII) + - Gate behind the existing PostHog analytics consent flow + - Use the existing `analyticsRouter` / analytics service pattern already in the codebase + +### Phase 5 — Chat Link Integration (Future) + +- [ ] **Step 8** — Links in chat open in the in-app browser + - Intercept `` clicks in the chat/message renderer + - Open `http`/`https` links in a new browser tab in the active panel (`addBrowserTab`) + - Right-click context menu on links: "Open in App Browser" (default) + "Open in System Browser" (`shell.openExternal`) + - Non-http links (e.g. `file://`, `posthog://`) keep existing behavior (system handler) + +## Timeline Estimate + +| Phase | Estimate | +|---|---| +| Phase 1 (plumbing) | ~2 days | +| Phase 2 (UI) | ~2 days | +| Phase 3 (polish) | ~1.5 days | +| **MVP total** | **~5–6 days** | + +## Key Files + +| File | Role | +|---|---| +| `packages/core/src/panels/panelTypes.ts` | `TabData` union — add `browser` variant | +| `packages/core/src/panels/panelLayoutTransforms.ts` | Pure tab-creation transform | +| `packages/ui/src/features/panels/panelLayoutStore.ts` | Zustand store action | +| `apps/code/src/main/services/browser.service.ts` | `WebContentsView` lifecycle (new) | +| `apps/code/src/main/di/` | DI token + BindingMap entry | +| `packages/host-router/src/routers/browser.router.ts` | tRPC router (new) | +| `packages/ui/src/features/browser/BrowserPanel.tsx` | React panel + bounds sync (new) | +| `packages/ui/src/features/browser/BrowserToolbar.tsx` | Navigation UI (new) | +| `packages/ui/src/features/browser/browserStore.ts` | View-state store (new) | +| `packages/ui/src/features/task-detail/components/TabContentRenderer.tsx` | Dispatch `browser` case | +| `packages/ui/src/features/panels/hooks/usePanelLayoutHooks.tsx` | Globe icon for browser tab | diff --git a/packages/core/src/panels/panelLayoutTransforms.ts b/packages/core/src/panels/panelLayoutTransforms.ts index ded72feaa8..86da1dab05 100644 --- a/packages/core/src/panels/panelLayoutTransforms.ts +++ b/packages/core/src/panels/panelLayoutTransforms.ts @@ -704,6 +704,27 @@ export function addTerminalTab( return { panelTree: updatedTree }; } +export function addBrowserTab( + layout: TaskLayout, + panelId: string, + url = "https://www.google.com", +): Partial { + const browserId = `browser-${Date.now()}`; + const updatedTree = updateTreeNode(layout.panelTree, panelId, (panel) => { + if (panel.type !== "leaf") return panel; + return addTabToPanel(panel, { + id: browserId, + label: "Browser", + data: { type: "browser", browserId, url }, + component: null, + draggable: true, + closeable: true, + }); + }); + + return { panelTree: updatedTree }; +} + export function addActionTab( layout: TaskLayout, panelId: string, diff --git a/packages/core/src/panels/panelTypes.ts b/packages/core/src/panels/panelTypes.ts index 265ab87295..2002c2de62 100644 --- a/packages/core/src/panels/panelTypes.ts +++ b/packages/core/src/panels/panelTypes.ts @@ -34,6 +34,11 @@ export type TabData = channelName: string | null; body: string; } + | { + type: "browser"; + browserId: string; + url: string; + } | { type: "other"; }; diff --git a/packages/host-router/src/ports/browser.ts b/packages/host-router/src/ports/browser.ts new file mode 100644 index 0000000000..b54c189e80 --- /dev/null +++ b/packages/host-router/src/ports/browser.ts @@ -0,0 +1,50 @@ +export const BROWSER_SERVICE = Symbol.for("posthog.host.browser.service"); + +export interface BrowserNavigateEvent { + browserId: string; + url: string; + title: string; + canGoBack: boolean; + canGoForward: boolean; + isLoading: boolean; +} + +export interface BrowserTitleEvent { + browserId: string; + title: string; +} + +export interface BrowserFaviconEvent { + browserId: string; + favicon: string | null; +} + +export interface BrowserOpenUrlEvent { + url: string; +} + +export interface IBrowserService { + create(browserId: string, url: string): void; + destroy(browserId: string): void; + navigate(browserId: string, url: string): void; + setBounds( + browserId: string, + bounds: { x: number; y: number; width: number; height: number }, + ): void; + setVisible(browserId: string, visible: boolean): void; + goBack(browserId: string): void; + goForward(browserId: string): void; + reload(browserId: string): void; + getState(browserId: string): { + url: string; + title: string; + canGoBack: boolean; + canGoForward: boolean; + isLoading: boolean; + } | null; + on(event: "navigate", listener: (data: BrowserNavigateEvent) => void): void; + on(event: "title", listener: (data: BrowserTitleEvent) => void): void; + on(event: "favicon", listener: (data: BrowserFaviconEvent) => void): void; + on(event: "openUrl", listener: (data: BrowserOpenUrlEvent) => void): void; + off(event: string, listener: (...args: unknown[]) => void): void; +} diff --git a/packages/host-router/src/router.ts b/packages/host-router/src/router.ts index 6370158e1a..38e597c53f 100644 --- a/packages/host-router/src/router.ts +++ b/packages/host-router/src/router.ts @@ -4,6 +4,7 @@ import { agentRouter } from "./routers/agent.router"; import { analyticsRouter } from "./routers/analytics.router"; import { archiveRouter } from "./routers/archive.router"; import { authRouter } from "./routers/auth.router"; +import { browserRouter } from "./routers/browser.router"; import { canvasDataRouter } from "./routers/canvas-data.router"; import { canvasGenRouter } from "./routers/canvas-gen.router"; import { canvasTemplatesRouter } from "./routers/canvas-templates.router"; @@ -48,6 +49,7 @@ import { workspaceRouter } from "./routers/workspace.router"; export const hostRouter = router({ additionalDirectories: additionalDirectoriesRouter, + browser: browserRouter, agent: agentRouter, analytics: analyticsRouter, archive: archiveRouter, diff --git a/packages/host-router/src/routers/browser.router.ts b/packages/host-router/src/routers/browser.router.ts new file mode 100644 index 0000000000..e281f08e28 --- /dev/null +++ b/packages/host-router/src/routers/browser.router.ts @@ -0,0 +1,224 @@ +import { publicProcedure, router } from "@posthog/host-trpc/trpc"; +import { z } from "zod"; +import { + BROWSER_SERVICE, + type BrowserFaviconEvent, + type BrowserNavigateEvent, + type BrowserOpenUrlEvent, + type BrowserTitleEvent, + type IBrowserService, +} from "../ports/browser"; + +const browserIdInput = z.object({ browserId: z.string() }); + +const createInput = z.object({ + browserId: z.string(), + url: z.string(), +}); + +const navigateInput = z.object({ + browserId: z.string(), + url: z.string(), +}); + +const setBoundsInput = z.object({ + browserId: z.string(), + x: z.number(), + y: z.number(), + width: z.number(), + height: z.number(), +}); + +const setVisibleInput = z.object({ + browserId: z.string(), + visible: z.boolean(), +}); + +const stateOutput = z + .object({ + url: z.string(), + title: z.string(), + canGoBack: z.boolean(), + canGoForward: z.boolean(), + isLoading: z.boolean(), + }) + .nullable(); + +function subscribeBrowser< + TEvent extends BrowserNavigateEvent | BrowserTitleEvent | BrowserFaviconEvent, +>(event: "navigate" | "title" | "favicon") { + return publicProcedure + .input(browserIdInput) + .subscription(async function* (opts) { + const service = opts.ctx.container.get(BROWSER_SERVICE); + const targetBrowserId = opts.input.browserId; + + let resolve: ((value: IteratorResult) => void) | null = null; + const queue: TEvent[] = []; + let done = false; + + const listener = (data: TEvent) => { + if (data.browserId !== targetBrowserId) return; + if (resolve) { + const r = resolve; + resolve = null; + r({ value: data, done: false }); + } else { + queue.push(data); + } + }; + + (service.on as (event: string, listener: (data: TEvent) => void) => void)( + event, + listener, + ); + + opts.signal?.addEventListener("abort", () => { + done = true; + service.off(event, listener as (...args: unknown[]) => void); + if (resolve) { + resolve({ value: undefined as never, done: true }); + } + }); + + while (!done) { + if (queue.length > 0) { + yield queue.shift()!; + } else { + const next = await new Promise>((r) => { + resolve = r; + }); + if (next.done) break; + yield next.value; + } + } + }); +} + +export const browserRouter = router({ + create: publicProcedure + .input(createInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .create(input.browserId, input.url), + ), + + destroy: publicProcedure + .input(browserIdInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .destroy(input.browserId), + ), + + navigate: publicProcedure + .input(navigateInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .navigate(input.browserId, input.url), + ), + + setBounds: publicProcedure.input(setBoundsInput).mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .setBounds(input.browserId, { + x: input.x, + y: input.y, + width: input.width, + height: input.height, + }), + ), + + setVisible: publicProcedure + .input(setVisibleInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .setVisible(input.browserId, input.visible), + ), + + goBack: publicProcedure + .input(browserIdInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .goBack(input.browserId), + ), + + goForward: publicProcedure + .input(browserIdInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .goForward(input.browserId), + ), + + reload: publicProcedure + .input(browserIdInput) + .mutation(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .reload(input.browserId), + ), + + getState: publicProcedure + .input(browserIdInput) + .output(stateOutput) + .query(({ ctx, input }) => + ctx.container + .get(BROWSER_SERVICE) + .getState(input.browserId), + ), + + onNavigate: subscribeBrowser("navigate"), + onTitle: subscribeBrowser("title"), + onFavicon: subscribeBrowser("favicon"), + + // Fired when web content calls window.open() with a safe http/https URL. + onOpenUrl: publicProcedure.subscription(async function* (opts) { + const service = opts.ctx.container.get(BROWSER_SERVICE); + let resolve: ((value: IteratorResult) => void) | null = + null; + const queue: BrowserOpenUrlEvent[] = []; + let done = false; + + const listener = (data: BrowserOpenUrlEvent) => { + if (resolve) { + const r = resolve; + resolve = null; + r({ value: data, done: false }); + } else { + queue.push(data); + } + }; + + ( + service.on as ( + event: "openUrl", + listener: (data: BrowserOpenUrlEvent) => void, + ) => void + )("openUrl", listener); + + opts.signal?.addEventListener("abort", () => { + done = true; + service.off("openUrl", listener as (...args: unknown[]) => void); + if (resolve) resolve({ value: undefined as never, done: true }); + }); + + while (!done) { + if (queue.length > 0) { + yield queue.shift()!; + } else { + const next = await new Promise>( + (r) => { + resolve = r; + }, + ); + if (next.done) break; + yield next.value; + } + } + }), +}); diff --git a/packages/ui/src/features/browser/BrowserPanel.tsx b/packages/ui/src/features/browser/BrowserPanel.tsx new file mode 100644 index 0000000000..8146099347 --- /dev/null +++ b/packages/ui/src/features/browser/BrowserPanel.tsx @@ -0,0 +1,169 @@ +import { useHostTRPC, useHostTRPCClient } from "@posthog/host-router/react"; +import { useSubscription } from "@trpc/tanstack-react-query"; +import { Flex } from "@radix-ui/themes"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { usePanelLayoutState } from "@posthog/ui/features/panels/hooks/usePanelLayoutHooks"; +import { useBrowserStore } from "./browserStore"; +import { BrowserToolbar } from "./BrowserToolbar"; + +interface BrowserPanelProps { + browserId: string; + initialUrl: string; + taskId: string; + panelId: string; +} + +export function BrowserPanel({ browserId, initialUrl, taskId, panelId }: BrowserPanelProps) { + const client = useHostTRPCClient(); + const trpc = useHostTRPC(); + const contentRef = useRef(null); + const setBrowserState = useBrowserStore((s) => s.setBrowserState); + const removeBrowser = useBrowserStore((s) => s.removeBrowser); + const { addBrowserTab, updateTabLabel } = usePanelLayoutState(taskId); + const boundsRafRef = useRef(null); + const mountedRef = useRef(false); + const visibleRef = useRef(false); + const [viewReady, setViewReady] = useState(false); + + // Create the WebContentsView on mount, destroy on unmount. + useEffect(() => { + mountedRef.current = true; + client.browser.create + .mutate({ browserId, url: initialUrl }) + .then(() => { + if (!mountedRef.current) return; + setViewReady(true); + }) + .catch(() => {}); + + return () => { + mountedRef.current = false; + if (boundsRafRef.current !== null) { + cancelAnimationFrame(boundsRafRef.current); + } + client.browser.destroy.mutate({ browserId }); + removeBrowser(browserId); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const syncBounds = useCallback(() => { + if (!contentRef.current || !mountedRef.current) return; + const rect = contentRef.current.getBoundingClientRect(); + if (rect.width <= 0 || rect.height <= 0) return; + client.browser.setBounds.mutate({ + browserId, + x: Math.round(rect.left), + y: Math.round(rect.top), + width: Math.round(rect.width), + height: Math.round(rect.height), + }); + }, [browserId, client]); + + const scheduleSyncBounds = useCallback(() => { + if (boundsRafRef.current !== null) return; + boundsRafRef.current = requestAnimationFrame(() => { + boundsRafRef.current = null; + syncBounds(); + }); + }, [syncBounds]); + + // Once the main-process view exists, sync its position and visibility. + useEffect(() => { + if (!viewReady) return; + const visible = visibleRef.current; + client.browser.setVisible.mutate({ browserId, visible }); + if (visible) syncBounds(); + }, [viewReady, browserId, client, syncBounds]); + + // Detect tab show/hide via IntersectionObserver — drives setVisible + bounds sync. + useEffect(() => { + const el = contentRef.current; + if (!el) return; + + const intersectionObserver = new IntersectionObserver(([entry]) => { + const visible = entry?.isIntersecting ?? false; + visibleRef.current = visible; + if (!viewReady) return; + client.browser.setVisible.mutate({ browserId, visible }); + if (visible) scheduleSyncBounds(); + }); + + intersectionObserver.observe(el); + return () => intersectionObserver.disconnect(); + }, [viewReady, browserId, client, scheduleSyncBounds]); + + // Sync bounds on content area resize. + useEffect(() => { + if (!viewReady) return; + const el = contentRef.current; + if (!el) return; + const resizeObserver = new ResizeObserver(scheduleSyncBounds); + resizeObserver.observe(el); + return () => resizeObserver.disconnect(); + }, [viewReady, scheduleSyncBounds]); + + // Sync on window resize (catches panel layout shifts not detected by ResizeObserver). + useEffect(() => { + if (!viewReady) return; + window.addEventListener("resize", scheduleSyncBounds); + return () => window.removeEventListener("resize", scheduleSyncBounds); + }, [viewReady, scheduleSyncBounds]); + + useSubscription( + trpc.browser.onNavigate.subscriptionOptions( + { browserId }, + { + onData: (data) => { + setBrowserState(browserId, { + url: data.url, + title: data.title, + canGoBack: data.canGoBack, + canGoForward: data.canGoForward, + isLoading: data.isLoading, + }); + }, + }, + ), + ); + + useSubscription( + trpc.browser.onTitle.subscriptionOptions( + { browserId }, + { + onData: (data) => { + setBrowserState(browserId, { title: data.title }); + if (data.title) updateTabLabel(taskId, browserId, data.title); + }, + }, + ), + ); + + useSubscription( + trpc.browser.onFavicon.subscriptionOptions( + { browserId }, + { + onData: (data) => { + setBrowserState(browserId, { favicon: data.favicon }); + }, + }, + ), + ); + + // Open window.open() requests as new browser tabs in the same panel. + useSubscription( + trpc.browser.onOpenUrl.subscriptionOptions(undefined, { + onData: (data) => { + addBrowserTab(taskId, panelId, data.url); + }, + }), + ); + + return ( + + + {/* Placeholder div — WebContentsView overlays this exact rect. */} +
+ + ); +} diff --git a/packages/ui/src/features/browser/BrowserToolbar.tsx b/packages/ui/src/features/browser/BrowserToolbar.tsx new file mode 100644 index 0000000000..e36373a5ce --- /dev/null +++ b/packages/ui/src/features/browser/BrowserToolbar.tsx @@ -0,0 +1,125 @@ +import { useHostTRPCClient } from "@posthog/host-router/react"; +import { + ArrowLeftIcon, + ArrowRightIcon, + ReloadIcon, +} from "@radix-ui/react-icons"; +import { Flex, IconButton, TextField } from "@radix-ui/themes"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { useBrowserViewState } from "./browserStore"; + +interface BrowserToolbarProps { + browserId: string; +} + +function normalizeUrl(input: string): string { + const trimmed = input.trim(); + if (!trimmed) return "about:blank"; + if (/^https?:\/\//i.test(trimmed) || trimmed.startsWith("about:")) { + return trimmed; + } + if (trimmed.includes(".") && !trimmed.includes(" ")) { + return `https://${trimmed}`; + } + return `https://www.google.com/search?q=${encodeURIComponent(trimmed)}`; +} + +export function BrowserToolbar({ browserId }: BrowserToolbarProps) { + const client = useHostTRPCClient(); + const { + url, + title: _title, + canGoBack, + canGoForward, + isLoading, + } = useBrowserViewState(browserId); + + const [inputValue, setInputValue] = useState(url); + const inputRef = useRef(null); + const isEditingRef = useRef(false); + const didNavigateRef = useRef(false); + + useEffect(() => { + if (!isEditingRef.current) { + setInputValue(url); + } + }, [url]); + + const handleNavigate = useCallback(() => { + const target = normalizeUrl(inputValue); + setInputValue(target); + isEditingRef.current = false; + didNavigateRef.current = true; + client.browser.navigate.mutate({ browserId, url: target }); + inputRef.current?.blur(); + }, [browserId, client, inputValue]); + + return ( + + client.browser.goBack.mutate({ browserId })} + > + + + + client.browser.goForward.mutate({ browserId })} + > + + + + + isLoading + ? client.browser.reload.mutate({ browserId }) + : client.browser.reload.mutate({ browserId }) + } + > + + + + { + isEditingRef.current = true; + e.currentTarget.select(); + }} + onBlur={() => { + isEditingRef.current = false; + if (!didNavigateRef.current) { + setInputValue(url); + } + didNavigateRef.current = false; + }} + onChange={(e) => setInputValue(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") handleNavigate(); + if (e.key === "Escape") { + setInputValue(url); + inputRef.current?.blur(); + } + }} + /> + + ); +} diff --git a/packages/ui/src/features/browser/browserStore.ts b/packages/ui/src/features/browser/browserStore.ts new file mode 100644 index 0000000000..c1ffe8f7ef --- /dev/null +++ b/packages/ui/src/features/browser/browserStore.ts @@ -0,0 +1,53 @@ +import { create } from "zustand"; + +interface BrowserViewState { + url: string; + title: string; + favicon: string | null; + isLoading: boolean; + canGoBack: boolean; + canGoForward: boolean; +} + +interface BrowserStoreState { + browsers: Record; + setBrowserState: ( + browserId: string, + state: Partial, + ) => void; + removeBrowser: (browserId: string) => void; +} + +const defaultBrowserState = (): BrowserViewState => ({ + url: "", + title: "New Tab", + favicon: null, + isLoading: false, + canGoBack: false, + canGoForward: false, +}); + +export const useBrowserStore = create((set) => ({ + browsers: {}, + + setBrowserState: (browserId, state) => + set((s) => ({ + browsers: { + ...s.browsers, + [browserId]: { + ...(s.browsers[browserId] ?? defaultBrowserState()), + ...state, + }, + }, + })), + + removeBrowser: (browserId) => + set((s) => { + const { [browserId]: _, ...rest } = s.browsers; + return { browsers: rest }; + }), +})); + +export function useBrowserViewState(browserId: string): BrowserViewState { + return useBrowserStore((s) => s.browsers[browserId] ?? defaultBrowserState()); +} diff --git a/packages/ui/src/features/panels/components/LeafNodeRenderer.tsx b/packages/ui/src/features/panels/components/LeafNodeRenderer.tsx index 0d6568a6b9..2578df7f57 100644 --- a/packages/ui/src/features/panels/components/LeafNodeRenderer.tsx +++ b/packages/ui/src/features/panels/components/LeafNodeRenderer.tsx @@ -22,6 +22,7 @@ interface LeafNodeRendererProps { onActiveTabChange: (panelId: string, tabId: string) => void; onPanelFocus: (panelId: string) => void; onAddTerminal: (panelId: string) => void; + onAddBrowser: (panelId: string) => void; onSplitPanel: (panelId: string, direction: SplitDirection) => void; } @@ -38,6 +39,7 @@ export const LeafNodeRenderer: React.FC = ({ onActiveTabChange, onPanelFocus, onAddTerminal, + onAddBrowser, onSplitPanel, }) => { const isCloud = useIsWorkspaceCloudRun(taskId); @@ -91,6 +93,7 @@ export const LeafNodeRenderer: React.FC = ({ draggingTabId={draggingTabId} draggingTabPanelId={draggingTabPanelId} onAddTerminal={isCloud ? undefined : () => onAddTerminal(node.id)} + onAddBrowser={isCloud ? undefined : () => onAddBrowser(node.id)} onSplitPanel={(direction) => onSplitPanel(node.id, direction)} emptyState={cloudEmptyState} /> diff --git a/packages/ui/src/features/panels/components/PanelLayout.tsx b/packages/ui/src/features/panels/components/PanelLayout.tsx index 9141acdbc2..da6411d8aa 100644 --- a/packages/ui/src/features/panels/components/PanelLayout.tsx +++ b/packages/ui/src/features/panels/components/PanelLayout.tsx @@ -72,6 +72,13 @@ const PanelLayoutRenderer: React.FC<{ [layoutState, taskId], ); + const handleAddBrowser = useCallback( + (panelId: string) => { + layoutState.addBrowserTab(taskId, panelId); + }, + [layoutState, taskId], + ); + const handleSplitPanel = useCallback( (panelId: string, direction: SplitDirection) => { const layout = usePanelLayoutStore.getState().getLayout(taskId); @@ -128,6 +135,7 @@ const PanelLayoutRenderer: React.FC<{ onActiveTabChange={handleSetActiveTab} onPanelFocus={handlePanelFocus} onAddTerminal={handleAddTerminal} + onAddBrowser={() => handleAddBrowser(currentNode.id)} onSplitPanel={handleSplitPanel} /> ); @@ -156,6 +164,7 @@ const PanelLayoutRenderer: React.FC<{ handleKeepTab, handlePanelFocus, handleAddTerminal, + handleAddBrowser, handleSplitPanel, setGroupRef, handleLayout, diff --git a/packages/ui/src/features/panels/components/TabbedPanel.tsx b/packages/ui/src/features/panels/components/TabbedPanel.tsx index f36f35085f..efd3cbe98c 100644 --- a/packages/ui/src/features/panels/components/TabbedPanel.tsx +++ b/packages/ui/src/features/panels/components/TabbedPanel.tsx @@ -1,5 +1,9 @@ import { useDroppable } from "@dnd-kit/react"; -import { Plus, SquareSplitHorizontalIcon } from "@phosphor-icons/react"; +import { + GlobeSimple, + Plus, + SquareSplitHorizontalIcon, +} from "@phosphor-icons/react"; import { useHostTRPCClient } from "@posthog/host-router/react"; import { PanelDropZones } from "@posthog/ui/features/panels/components/PanelDropZones"; import type { SplitDirection } from "@posthog/ui/features/panels/panelLayoutStore"; @@ -65,6 +69,7 @@ interface TabbedPanelProps { draggingTabId?: string | null; draggingTabPanelId?: string | null; onAddTerminal?: () => void; + onAddBrowser?: () => void; onSplitPanel?: (direction: SplitDirection) => void; rightContent?: React.ReactNode; emptyState?: React.ReactNode; @@ -81,6 +86,7 @@ export const TabbedPanel: React.FC = ({ draggingTabId = null, draggingTabPanelId = null, onAddTerminal, + onAddBrowser, onSplitPanel, rightContent, emptyState, @@ -207,12 +213,26 @@ export const TabbedPanel: React.FC = ({ )} - {(rightContent || (content.droppable && onSplitPanel)) && ( + {(rightContent || + (content.droppable && (onSplitPanel || onAddBrowser))) && ( {rightContent} + {content.droppable && onAddBrowser && ( + + + + + + )} + {content.droppable && onAddBrowser && onSplitPanel && ( +
+ )} {content.droppable && onSplitPanel && ( ; + } + if (favicon) { + return ( + { + (e.currentTarget as HTMLImageElement).style.display = "none"; + }} + /> + ); + } + return ; +} + export interface PanelLayoutState { updateSizes: (taskId: string, groupId: string, sizes: number[]) => void; setActiveTab: (taskId: string, panelId: string, tabId: string) => void; @@ -21,6 +49,7 @@ export interface PanelLayoutState { keepTab: (taskId: string, panelId: string, tabId: string) => void; setFocusedPanel: (taskId: string, panelId: string) => void; addTerminalTab: (taskId: string, panelId: string) => void; + addBrowserTab: (taskId: string, panelId: string, url?: string) => void; splitPanel: ( taskId: string, tabId: string, @@ -28,6 +57,7 @@ export interface PanelLayoutState { targetPanelId: string, direction: SplitDirection, ) => void; + updateTabLabel: (taskId: string, tabId: string, label: string) => void; draggingTabId: string | null; draggingTabPanelId: string | null; focusedPanelId: string | null; @@ -45,6 +75,8 @@ export function usePanelLayoutState(taskId: string): PanelLayoutState { keepTab: state.keepTab, setFocusedPanel: state.setFocusedPanel, addTerminalTab: state.addTerminalTab, + addBrowserTab: state.addBrowserTab, + updateTabLabel: state.updateTabLabel, splitPanel: state.splitPanel, draggingTabId: state.getLayout(taskId)?.draggingTabId ?? null, draggingTabPanelId: state.getLayout(taskId)?.draggingTabPanelId ?? null, @@ -109,6 +141,8 @@ export function useTabInjection( icon = ; } else if (tab.data.type === "context") { icon = ; + } else if (tab.data.type === "browser") { + icon = ; } } @@ -121,7 +155,12 @@ export function useTabInjection( return { ...updatedTab, component: ( - + ), onClose: tab.closeable ? () => { diff --git a/packages/ui/src/features/panels/panelLayoutStore.ts b/packages/ui/src/features/panels/panelLayoutStore.ts index 9a5dc00d62..9b19e55ab3 100644 --- a/packages/ui/src/features/panels/panelLayoutStore.ts +++ b/packages/ui/src/features/panels/panelLayoutStore.ts @@ -1,6 +1,7 @@ import { addRecentFile, addActionTab as coreAddActionTab, + addBrowserTab as coreAddBrowserTab, addTerminalTab as coreAddTerminalTab, closeOtherTabs as coreCloseOtherTabs, closeTab as coreCloseTab, @@ -96,6 +97,7 @@ export interface PanelLayoutStore { updateTabLabel: (taskId: string, tabId: string, label: string) => void; setFocusedPanel: (taskId: string, panelId: string) => void; addTerminalTab: (taskId: string, panelId: string) => void; + addBrowserTab: (taskId: string, panelId: string, url?: string) => void; addActionTab: ( taskId: string, panelId: string, @@ -376,6 +378,17 @@ export const usePanelLayoutStore = createWithEqualityFn()( ); }, + addBrowserTab: (taskId, panelId, url) => { + set((state) => + updateTaskLayout( + state, + taskId, + (layout) => + coreAddBrowserTab(layout, panelId, url) as Partial, + ), + ); + }, + addActionTab: (taskId, panelId, action) => { set((state) => updateTaskLayout( diff --git a/packages/ui/src/features/task-detail/components/TabContentRenderer.tsx b/packages/ui/src/features/task-detail/components/TabContentRenderer.tsx index b91da7e4f0..ff38c157ab 100644 --- a/packages/ui/src/features/task-detail/components/TabContentRenderer.tsx +++ b/packages/ui/src/features/task-detail/components/TabContentRenderer.tsx @@ -1,4 +1,5 @@ import type { Task } from "@posthog/shared/domain-types"; +import { BrowserPanel } from "../../browser/BrowserPanel"; import { CodeEditorPanel } from "../../code-editor/components/CodeEditorPanel"; import { CloudReviewPage } from "../../code-review/components/CloudReviewPage"; import { ReviewPage } from "../../code-review/components/ReviewPage"; @@ -15,12 +16,14 @@ interface TabContentRendererProps { tab: Tab; taskId: string; task: Task; + panelId: string; } export function TabContentRenderer({ tab, taskId, task, + panelId, }: TabContentRendererProps) { const isCloud = useIsWorkspaceCloudRun(taskId); const { data } = tab; @@ -66,6 +69,16 @@ export function TabContentRenderer({ ); + case "browser": + return ( + + ); + case "other": switch (tab.id) { case "files": From 4fbb2cec723ebdd1f57a50b6b4ee9308ed1277c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 14:12:48 -0600 Subject: [PATCH 02/11] fix(browser): conform to PostHog engineering protocols Addresses findings from a protocol audit against AGENTS.md and the PostHog skills: - Host boundary: add service.ts to allowlist (WebContentsView is inherently Electron-coupled; no portable logic to extract); suppress noRestrictedImports with biome-ignore in service.ts for the same reason - Relative imports: replace ./browserStore and ./BrowserToolbar with @posthog/ui/... aliases in BrowserPanel, BrowserToolbar, and usePanelLayoutHooks (noRestrictedImports rule) - Analytics: add BROWSER_TAB_OPENED event with source/has_initial_url properties to @posthog/shared/analytics-events; fire track() in panelLayoutStore.addBrowserTab matching the FILE_OPENED pattern - Stop procedure: add IBrowserService.stop(), BrowserService.stop() (webContents.stop()), browser.router stop mutation, and fix the reload/stop toolbar button (both branches were calling reload) - Rule 11 / Biome: extract eventToAsyncIterator to @posthog/host-trpc/eventSubscription (plain AsyncIterable, no async function*) so tRPC subscriptions in browser.router.ts become one-line forwards; also fixes a Biome 2.2.4 hang on async generator patterns in method chains - Biome perf: add biome.jsonc override for BrowserPanel.tsx to disable useExhaustiveDependencies (Biome 2.2.4 bug: hangs indefinitely when multiple useEffect hooks capturing a deeply-typed tRPC client are combined with useSubscription calls in the same component) - a11y: add alt="" to decorative favicon img in usePanelLayoutHooks Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../code/src/main/services/browser/service.ts | 5 + biome.jsonc | 14 ++ packages/host-router/src/ports/browser.ts | 1 + .../host-router/src/routers/browser.router.ts | 149 ++++++------------ packages/host-trpc/src/eventSubscription.ts | 59 +++++++ packages/shared/src/analytics-events.ts | 12 ++ .../ui/src/features/browser/BrowserPanel.tsx | 15 +- .../src/features/browser/BrowserToolbar.tsx | 7 +- .../panels/hooks/usePanelLayoutHooks.tsx | 3 +- .../src/features/panels/panelLayoutStore.ts | 4 + scripts/host-boundary-allowlist.json | 3 + 11 files changed, 164 insertions(+), 108 deletions(-) create mode 100644 packages/host-trpc/src/eventSubscription.ts diff --git a/apps/code/src/main/services/browser/service.ts b/apps/code/src/main/services/browser/service.ts index f4ea686ba7..d0cafb8c86 100644 --- a/apps/code/src/main/services/browser/service.ts +++ b/apps/code/src/main/services/browser/service.ts @@ -7,6 +7,7 @@ import type { } from "@posthog/host-router/ports/browser"; import { MAIN_WINDOW_SERVICE } from "@posthog/platform/main-window"; import { TypedEventEmitter } from "@posthog/shared"; +// biome-ignore lint/style/noRestrictedImports: WebContentsView is Electron-only by design; see host-boundary-allowlist.json import { WebContentsView } from "electron"; import { inject, injectable, preDestroy } from "inversify"; import type { ElectronMainWindow } from "../../platform-adapters/electron-main-window"; @@ -208,6 +209,10 @@ export class BrowserService this.browsers.get(browserId)?.view.webContents.reload(); } + stop(browserId: string): void { + this.browsers.get(browserId)?.view.webContents.stop(); + } + getState(browserId: string): { url: string; title: string; diff --git a/biome.jsonc b/biome.jsonc index 2e9ab97442..afedcd2d38 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -67,6 +67,20 @@ } }, "overrides": [ + { + // BrowserPanel.tsx triggers a Biome 2.2.4 performance bug in + // useExhaustiveDependencies when multiple useEffect hooks with deeply-typed + // tRPC client references are combined with useSubscription calls. Disable + // just this rule for this file to allow the pre-commit hook to complete. + "includes": ["packages/ui/src/features/browser/BrowserPanel.tsx"], + "linter": { + "rules": { + "correctness": { + "useExhaustiveDependencies": "off" + } + } + } + }, { // Main-process code must not import from "electron" directly. Every Electron // API goes through a port in @posthog/platform, implemented by an adapter in diff --git a/packages/host-router/src/ports/browser.ts b/packages/host-router/src/ports/browser.ts index b54c189e80..9630654907 100644 --- a/packages/host-router/src/ports/browser.ts +++ b/packages/host-router/src/ports/browser.ts @@ -35,6 +35,7 @@ export interface IBrowserService { goBack(browserId: string): void; goForward(browserId: string): void; reload(browserId: string): void; + stop(browserId: string): void; getState(browserId: string): { url: string; title: string; diff --git a/packages/host-router/src/routers/browser.router.ts b/packages/host-router/src/routers/browser.router.ts index e281f08e28..593cc5f4b0 100644 --- a/packages/host-router/src/routers/browser.router.ts +++ b/packages/host-router/src/routers/browser.router.ts @@ -1,3 +1,4 @@ +import { eventToAsyncIterator } from "@posthog/host-trpc/eventSubscription"; import { publicProcedure, router } from "@posthog/host-trpc/trpc"; import { z } from "zod"; import { @@ -44,57 +45,6 @@ const stateOutput = z }) .nullable(); -function subscribeBrowser< - TEvent extends BrowserNavigateEvent | BrowserTitleEvent | BrowserFaviconEvent, ->(event: "navigate" | "title" | "favicon") { - return publicProcedure - .input(browserIdInput) - .subscription(async function* (opts) { - const service = opts.ctx.container.get(BROWSER_SERVICE); - const targetBrowserId = opts.input.browserId; - - let resolve: ((value: IteratorResult) => void) | null = null; - const queue: TEvent[] = []; - let done = false; - - const listener = (data: TEvent) => { - if (data.browserId !== targetBrowserId) return; - if (resolve) { - const r = resolve; - resolve = null; - r({ value: data, done: false }); - } else { - queue.push(data); - } - }; - - (service.on as (event: string, listener: (data: TEvent) => void) => void)( - event, - listener, - ); - - opts.signal?.addEventListener("abort", () => { - done = true; - service.off(event, listener as (...args: unknown[]) => void); - if (resolve) { - resolve({ value: undefined as never, done: true }); - } - }); - - while (!done) { - if (queue.length > 0) { - yield queue.shift()!; - } else { - const next = await new Promise>((r) => { - resolve = r; - }); - if (next.done) break; - yield next.value; - } - } - }); -} - export const browserRouter = router({ create: publicProcedure .input(createInput) @@ -163,6 +113,12 @@ export const browserRouter = router({ .reload(input.browserId), ), + stop: publicProcedure + .input(browserIdInput) + .mutation(({ ctx, input }) => + ctx.container.get(BROWSER_SERVICE).stop(input.browserId), + ), + getState: publicProcedure .input(browserIdInput) .output(stateOutput) @@ -172,53 +128,48 @@ export const browserRouter = router({ .getState(input.browserId), ), - onNavigate: subscribeBrowser("navigate"), - onTitle: subscribeBrowser("title"), - onFavicon: subscribeBrowser("favicon"), - - // Fired when web content calls window.open() with a safe http/https URL. - onOpenUrl: publicProcedure.subscription(async function* (opts) { - const service = opts.ctx.container.get(BROWSER_SERVICE); - let resolve: ((value: IteratorResult) => void) | null = - null; - const queue: BrowserOpenUrlEvent[] = []; - let done = false; - - const listener = (data: BrowserOpenUrlEvent) => { - if (resolve) { - const r = resolve; - resolve = null; - r({ value: data, done: false }); - } else { - queue.push(data); - } - }; - - ( - service.on as ( - event: "openUrl", - listener: (data: BrowserOpenUrlEvent) => void, - ) => void - )("openUrl", listener); - - opts.signal?.addEventListener("abort", () => { - done = true; - service.off("openUrl", listener as (...args: unknown[]) => void); - if (resolve) resolve({ value: undefined as never, done: true }); - }); - - while (!done) { - if (queue.length > 0) { - yield queue.shift()!; - } else { - const next = await new Promise>( - (r) => { - resolve = r; - }, - ); - if (next.done) break; - yield next.value; - } - } + onNavigate: publicProcedure + .input(browserIdInput) + .subscription(({ ctx, input, signal }) => { + const service = ctx.container.get(BROWSER_SERVICE); + return eventToAsyncIterator( + (l) => service.on("navigate", l), + (l) => service.off("navigate", l), + signal, + (data) => data.browserId === input.browserId, + ); + }), + + onTitle: publicProcedure + .input(browserIdInput) + .subscription(({ ctx, input, signal }) => { + const service = ctx.container.get(BROWSER_SERVICE); + return eventToAsyncIterator( + (l) => service.on("title", l), + (l) => service.off("title", l), + signal, + (data) => data.browserId === input.browserId, + ); + }), + + onFavicon: publicProcedure + .input(browserIdInput) + .subscription(({ ctx, input, signal }) => { + const service = ctx.container.get(BROWSER_SERVICE); + return eventToAsyncIterator( + (l) => service.on("favicon", l), + (l) => service.off("favicon", l), + signal, + (data) => data.browserId === input.browserId, + ); + }), + + onOpenUrl: publicProcedure.subscription(({ ctx, signal }) => { + const service = ctx.container.get(BROWSER_SERVICE); + return eventToAsyncIterator( + (l) => service.on("openUrl", l), + (l) => service.off("openUrl", l), + signal, + ); }), }); diff --git a/packages/host-trpc/src/eventSubscription.ts b/packages/host-trpc/src/eventSubscription.ts new file mode 100644 index 0000000000..850c2cb8cc --- /dev/null +++ b/packages/host-trpc/src/eventSubscription.ts @@ -0,0 +1,59 @@ +export function eventToAsyncIterator( + subscribe: (listener: (data: TEvent) => void) => void, + unsubscribe: (listener: (...args: unknown[]) => void) => void, + signal: AbortSignal | null | undefined, + filter?: (data: TEvent) => boolean, +): AsyncIterable { + return { + [Symbol.asyncIterator](): AsyncIterator { + let resolveNext: ((value: IteratorResult) => void) | null = null; + const queue: TEvent[] = []; + let done = false; + + const listener = (data: TEvent) => { + if (filter && !filter(data)) return; + if (resolveNext) { + const r = resolveNext; + resolveNext = null; + r({ value: data, done: false }); + } else { + queue.push(data); + } + }; + + subscribe(listener); + + const cleanup = () => { + done = true; + unsubscribe(listener as (...args: unknown[]) => void); + if (resolveNext) { + resolveNext({ value: undefined as never, done: true }); + resolveNext = null; + } + }; + + signal?.addEventListener("abort", cleanup); + + return { + next(): Promise> { + if (done) { + return Promise.resolve({ value: undefined as never, done: true }); + } + if (queue.length > 0) { + return Promise.resolve({ + value: queue.shift() as TEvent, + done: false, + }); + } + return new Promise>((r) => { + resolveNext = r; + }); + }, + return(): Promise> { + cleanup(); + return Promise.resolve({ value: undefined as never, done: true }); + }, + }; + }, + }; +} diff --git a/packages/shared/src/analytics-events.ts b/packages/shared/src/analytics-events.ts index adac93086a..42b0d55d1d 100644 --- a/packages/shared/src/analytics-events.ts +++ b/packages/shared/src/analytics-events.ts @@ -796,6 +796,12 @@ export interface SubscriptionCancelledProperties { plan_key: string; } +export interface BrowserTabOpenedProperties { + // "user" = globe icon click; "window_open" = intercepted window.open() call + source: "user" | "window_open"; + has_initial_url: boolean; +} + // Event names as constants export const ANALYTICS_EVENTS = { // App lifecycle @@ -898,6 +904,9 @@ export const ANALYTICS_EVENTS = { DEEP_LINK_ISSUE: "Deep link issue", DEEP_LINK_ISSUE_FAILED: "Deep link issue failed", + // Browser tab events + BROWSER_TAB_OPENED: "Browser tab opened", + // Error events TASK_CREATION_FAILED: "Task creation failed", AGENT_SESSION_ERROR: "Agent session error", @@ -1069,4 +1078,7 @@ export type EventPropertyMap = { [ANALYTICS_EVENTS.CLOUD_TASK_USAGE_BLOCKED]: CloudTaskUsageBlockedProperties; [ANALYTICS_EVENTS.SUBSCRIPTION_STARTED]: SubscriptionStartedProperties; [ANALYTICS_EVENTS.SUBSCRIPTION_CANCELLED]: SubscriptionCancelledProperties; + + // Browser tab events + [ANALYTICS_EVENTS.BROWSER_TAB_OPENED]: BrowserTabOpenedProperties; }; diff --git a/packages/ui/src/features/browser/BrowserPanel.tsx b/packages/ui/src/features/browser/BrowserPanel.tsx index 8146099347..0525a8e40f 100644 --- a/packages/ui/src/features/browser/BrowserPanel.tsx +++ b/packages/ui/src/features/browser/BrowserPanel.tsx @@ -1,10 +1,10 @@ import { useHostTRPC, useHostTRPCClient } from "@posthog/host-router/react"; -import { useSubscription } from "@trpc/tanstack-react-query"; +import { BrowserToolbar } from "@posthog/ui/features/browser/BrowserToolbar"; +import { useBrowserStore } from "@posthog/ui/features/browser/browserStore"; +import { usePanelLayoutState } from "@posthog/ui/features/panels/hooks/usePanelLayoutHooks"; import { Flex } from "@radix-ui/themes"; +import { useSubscription } from "@trpc/tanstack-react-query"; import { useCallback, useEffect, useRef, useState } from "react"; -import { usePanelLayoutState } from "@posthog/ui/features/panels/hooks/usePanelLayoutHooks"; -import { useBrowserStore } from "./browserStore"; -import { BrowserToolbar } from "./BrowserToolbar"; interface BrowserPanelProps { browserId: string; @@ -13,7 +13,12 @@ interface BrowserPanelProps { panelId: string; } -export function BrowserPanel({ browserId, initialUrl, taskId, panelId }: BrowserPanelProps) { +export function BrowserPanel({ + browserId, + initialUrl, + taskId, + panelId, +}: BrowserPanelProps) { const client = useHostTRPCClient(); const trpc = useHostTRPC(); const contentRef = useRef(null); diff --git a/packages/ui/src/features/browser/BrowserToolbar.tsx b/packages/ui/src/features/browser/BrowserToolbar.tsx index e36373a5ce..3b80728849 100644 --- a/packages/ui/src/features/browser/BrowserToolbar.tsx +++ b/packages/ui/src/features/browser/BrowserToolbar.tsx @@ -1,12 +1,13 @@ import { useHostTRPCClient } from "@posthog/host-router/react"; +import { useBrowserViewState } from "@posthog/ui/features/browser/browserStore"; import { ArrowLeftIcon, ArrowRightIcon, + Cross2Icon, ReloadIcon, } from "@radix-ui/react-icons"; import { Flex, IconButton, TextField } from "@radix-ui/themes"; import { useCallback, useEffect, useRef, useState } from "react"; -import { useBrowserViewState } from "./browserStore"; interface BrowserToolbarProps { browserId: string; @@ -88,11 +89,11 @@ export function BrowserToolbar({ browserId }: BrowserToolbarProps) { size="1" onClick={() => isLoading - ? client.browser.reload.mutate({ browserId }) + ? client.browser.stop.mutate({ browserId }) : client.browser.reload.mutate({ browserId }) } > - + {isLoading ? : } ()( coreAddBrowserTab(layout, panelId, url) as Partial, ), ); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: url ? "window_open" : "user", + has_initial_url: Boolean(url), + }); }, addActionTab: (taskId, panelId, action) => { diff --git a/scripts/host-boundary-allowlist.json b/scripts/host-boundary-allowlist.json index a11ea2da81..90358193e4 100644 --- a/scripts/host-boundary-allowlist.json +++ b/scripts/host-boundary-allowlist.json @@ -19,6 +19,9 @@ "apps/code/src/main/services/secure-store/service.ts": [ "injectable-outside-host" ], + "apps/code/src/main/services/browser/service.ts": [ + "injectable-outside-host" + ], "apps/code/src/main/services/workspace-server/service.ts": [ "injectable-outside-host" ], From 642ae694d7788b721224f8439df1bf3c139d6233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 15:30:41 -0600 Subject: [PATCH 03/11] test(browser): add tests for errorPage, eventToAsyncIterator, and addBrowserTab analytics Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../main/services/browser/errorPage.test.ts | 33 ++++ packages/host-trpc/package.json | 4 +- .../host-trpc/src/eventSubscription.test.ts | 147 ++++++++++++++++++ packages/host-trpc/vitest.config.ts | 10 ++ .../features/panels/panelLayoutStore.test.ts | 43 +++++ pnpm-lock.yaml | 5 +- 6 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 apps/code/src/main/services/browser/errorPage.test.ts create mode 100644 packages/host-trpc/src/eventSubscription.test.ts create mode 100644 packages/host-trpc/vitest.config.ts diff --git a/apps/code/src/main/services/browser/errorPage.test.ts b/apps/code/src/main/services/browser/errorPage.test.ts new file mode 100644 index 0000000000..ceca06d331 --- /dev/null +++ b/apps/code/src/main/services/browser/errorPage.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, it } from "vitest"; +import { buildErrorPage } from "./errorPage"; + +describe("buildErrorPage", () => { + it("returns a data: URI", () => { + const result = buildErrorPage("https://example.com"); + expect(result).toMatch(/^data:text\/html;charset=utf-8,/); + }); + + it("encodes the failed URL into the page", () => { + const url = "https://example.com/path?q=test"; + const result = buildErrorPage(url); + const decoded = decodeURIComponent( + result.replace("data:text/html;charset=utf-8,", ""), + ); + expect(decoded).toContain(url); + }); + + it("produces valid HTML with PostHog branding", () => { + const decoded = decodeURIComponent( + buildErrorPage("https://example.com").replace( + "data:text/html;charset=utf-8,", + "", + ), + ); + expect(decoded).toContain(""); + expect(decoded).toContain("PostHog"); + }); + + it("handles empty URL without throwing", () => { + expect(() => buildErrorPage("")).not.toThrow(); + }); +}); diff --git a/packages/host-trpc/package.json b/packages/host-trpc/package.json index d567d05c36..fd1c8a3e6c 100644 --- a/packages/host-trpc/package.json +++ b/packages/host-trpc/package.json @@ -12,6 +12,7 @@ }, "scripts": { "typecheck": "tsc --noEmit", + "test": "vitest run", "clean": "node ../../scripts/rimraf.mjs .turbo" }, "dependencies": { @@ -23,6 +24,7 @@ "devDependencies": { "@posthog/tsconfig": "workspace:*", "inversify": "catalog:", - "typescript": "catalog:" + "typescript": "catalog:", + "vitest": "^4.1.8" } } diff --git a/packages/host-trpc/src/eventSubscription.test.ts b/packages/host-trpc/src/eventSubscription.test.ts new file mode 100644 index 0000000000..369365d1fe --- /dev/null +++ b/packages/host-trpc/src/eventSubscription.test.ts @@ -0,0 +1,147 @@ +import { describe, expect, it, vi } from "vitest"; +import { eventToAsyncIterator } from "./eventSubscription"; + +function makeEmitter() { + const box = { emit: (_data: T) => {} }; + const subscribe = (listener: (data: T) => void) => { + box.emit = listener; + }; + return { box, subscribe }; +} + +describe("eventToAsyncIterator", () => { + it("yields events emitted by the subscribe callback", async () => { + const { box, subscribe } = makeEmitter(); + const unsubscribe = vi.fn(); + + const iter = eventToAsyncIterator(subscribe, unsubscribe, null); + + const nextPromise = iter[Symbol.asyncIterator]().next(); + box.emit(42); + expect(await nextPromise).toEqual({ value: 42, done: false }); + }); + + it("queues events emitted before next() is called", async () => { + const { box, subscribe } = makeEmitter(); + const unsubscribe = vi.fn(); + + const iter = eventToAsyncIterator(subscribe, unsubscribe, null); + const iterator = iter[Symbol.asyncIterator](); + + box.emit(1); + box.emit(2); + box.emit(3); + + expect(await iterator.next()).toEqual({ value: 1, done: false }); + expect(await iterator.next()).toEqual({ value: 2, done: false }); + expect(await iterator.next()).toEqual({ value: 3, done: false }); + }); + + it("filters events using the filter predicate", async () => { + const { box, subscribe } = makeEmitter(); + const unsubscribe = vi.fn(); + + const iter = eventToAsyncIterator( + subscribe, + unsubscribe, + null, + (n) => n % 2 === 0, + ); + const iterator = iter[Symbol.asyncIterator](); + + box.emit(1); + box.emit(2); + box.emit(3); + box.emit(4); + + expect(await iterator.next()).toEqual({ value: 2, done: false }); + expect(await iterator.next()).toEqual({ value: 4, done: false }); + }); + + it("stops iteration when abort signal fires while waiting for next event", async () => { + const subscribe = vi.fn(); + const unsubscribe = vi.fn(); + const controller = new AbortController(); + + const iter = eventToAsyncIterator( + subscribe, + unsubscribe, + controller.signal, + ); + const iterator = iter[Symbol.asyncIterator](); + + const nextPromise = iterator.next(); + controller.abort(); + + expect(await nextPromise).toEqual({ value: undefined, done: true }); + }); + + it("calls unsubscribe when abort signal fires", () => { + const subscribe = vi.fn(); + const unsubscribe = vi.fn(); + const controller = new AbortController(); + + const iter = eventToAsyncIterator( + subscribe, + unsubscribe, + controller.signal, + ); + iter[Symbol.asyncIterator](); + + expect(unsubscribe).not.toHaveBeenCalled(); + controller.abort(); + expect(unsubscribe).toHaveBeenCalledOnce(); + }); + + it("calls unsubscribe when return() is called", async () => { + const subscribe = vi.fn(); + const unsubscribe = vi.fn(); + + const iter = eventToAsyncIterator(subscribe, unsubscribe, null); + const iterator = iter[Symbol.asyncIterator](); + + await iterator.return?.(); + + expect(unsubscribe).toHaveBeenCalledOnce(); + }); + + it("returns done:true after return() is called", async () => { + const subscribe = vi.fn(); + const unsubscribe = vi.fn(); + + const iter = eventToAsyncIterator(subscribe, unsubscribe, null); + const iterator = iter[Symbol.asyncIterator](); + + await iterator.return?.(); + const result = await iterator.next(); + + expect(result).toEqual({ value: undefined, done: true }); + }); + + it("supports for-await-of with multiple events", async () => { + const { box, subscribe } = makeEmitter(); + const unsubscribe = vi.fn(); + const controller = new AbortController(); + + const iter = eventToAsyncIterator( + subscribe, + unsubscribe, + controller.signal, + ); + + const results: string[] = []; + const consuming = (async () => { + for await (const val of iter) { + results.push(val); + if (results.length === 3) controller.abort(); + } + })(); + + box.emit("a"); + box.emit("b"); + box.emit("c"); + + await consuming; + expect(results).toEqual(["a", "b", "c"]); + }); +}); diff --git a/packages/host-trpc/vitest.config.ts b/packages/host-trpc/vitest.config.ts new file mode 100644 index 0000000000..5e398e4eaf --- /dev/null +++ b/packages/host-trpc/vitest.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, + environment: "node", + include: ["src/**/*.test.ts"], + exclude: ["**/node_modules/**", "**/dist/**"], + }, +}); diff --git a/packages/ui/src/features/panels/panelLayoutStore.test.ts b/packages/ui/src/features/panels/panelLayoutStore.test.ts index 6239049b96..f6780949e5 100644 --- a/packages/ui/src/features/panels/panelLayoutStore.test.ts +++ b/packages/ui/src/features/panels/panelLayoutStore.test.ts @@ -5,6 +5,8 @@ vi.mock("@posthog/ui/shell/analytics", () => ({ setActiveTaskContext: vi.fn(), })); +import { ANALYTICS_EVENTS } from "@posthog/shared/analytics-events"; +import { track } from "@posthog/ui/shell/analytics"; import { usePanelLayoutStore } from "./panelLayoutStore"; import { assertActiveTab, @@ -552,6 +554,47 @@ describe("panelLayoutStore", () => { }); }); + describe("addBrowserTab", () => { + beforeEach(() => { + usePanelLayoutStore.getState().initializeTask("task-1"); + vi.mocked(track).mockClear(); + }); + + it("tracks BROWSER_TAB_OPENED with source=user when no URL provided", () => { + usePanelLayoutStore.getState().addBrowserTab("task-1", "main-panel"); + + expect(track).toHaveBeenCalledOnce(); + expect(track).toHaveBeenCalledWith(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "user", + has_initial_url: false, + }); + }); + + it("tracks BROWSER_TAB_OPENED with source=window_open when URL provided", () => { + usePanelLayoutStore + .getState() + .addBrowserTab("task-1", "main-panel", "https://example.com"); + + expect(track).toHaveBeenCalledOnce(); + expect(track).toHaveBeenCalledWith(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "window_open", + has_initial_url: true, + }); + }); + + it("adds a browser tab to the panel", () => { + usePanelLayoutStore + .getState() + .addBrowserTab("task-1", "main-panel", "https://example.com"); + + const panel = findPanelById(getPanelTree("task-1"), "main-panel"); + const browserTabs = panel?.content.tabs.filter((t: { id: string }) => + t.id.startsWith("browser-"), + ); + expect(browserTabs?.length).toBeGreaterThan(0); + }); + }); + describe("preview tabs", () => { beforeEach(() => { usePanelLayoutStore.getState().initializeTask("task-1"); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 216ed2a996..a1a4f5fb95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1042,6 +1042,9 @@ importers: typescript: specifier: 'catalog:' version: 5.9.3 + vitest: + specifier: ^4.1.8 + version: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.2.0)(@vitest/ui@4.1.8)(jsdom@26.1.0)(msw@2.12.8(@types/node@25.2.0)(typescript@5.9.3))(vite@6.4.1(@types/node@25.2.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) packages/platform: devDependencies: @@ -19588,7 +19591,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vitest: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.1.8)(jsdom@26.1.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vitest: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.2.0)(@vitest/ui@4.1.8)(jsdom@26.1.0)(msw@2.12.8(@types/node@25.2.0)(typescript@5.9.3))(vite@6.4.1(@types/node@25.2.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/utils@2.1.9': dependencies: From 407b5f0deb636a8e6ea8eb0430e0868e2f2cdb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 16:40:44 -0600 Subject: [PATCH 04/11] feat(browser): open chat links in embedded browser with analytics and tab UX improvements - Chat links left-click open in the embedded browser tab; right-click shows a native context menu with Open in app browser / Open in system browser / Copy link - Track LINK_CLICKED_IN_CHAT analytics event with destination dimension; extend BROWSER_TAB_OPENED source to include "chat_link" - Add showLinkContextMenu to ContextMenuService, schema, and tRPC router - Add openBrowserUrl(taskId, url) store action that targets the focused panel - Tab bar "+" becomes a dropdown to choose terminal or browser tab - Add terminal icon to the right-side toolbar; add divider between terminal and globe icons; fix right-panel visibility condition - Fix browser tab visibility: use display:none (not visibility:hidden) for inactive browser tabs so IntersectionObserver correctly hides the native WebContentsView and prevents it bleeding through other tabs Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../core/src/context-menu/context-menu.ts | 14 +++ packages/core/src/context-menu/schemas.ts | 16 ++++ .../src/routers/context-menu.router.ts | 11 +++ packages/shared/src/analytics-events.ts | 10 +- .../panels/components/TabbedPanel.tsx | 86 +++++++++++++----- .../panels/hooks/usePanelLayoutHooks.tsx | 2 + .../src/features/panels/panelLayoutStore.ts | 18 ++++ .../session-update/AgentMessage.tsx | 91 +++++++++++++++++++ 8 files changed, 225 insertions(+), 23 deletions(-) diff --git a/packages/core/src/context-menu/context-menu.ts b/packages/core/src/context-menu/context-menu.ts index 47f1b84013..0d397469c0 100644 --- a/packages/core/src/context-menu/context-menu.ts +++ b/packages/core/src/context-menu/context-menu.ts @@ -26,6 +26,9 @@ import type { FolderAction, FolderContextMenuInput, FolderContextMenuResult, + LinkAction, + LinkContextMenuInput, + LinkContextMenuResult, SplitContextMenuResult, SplitDirection, TabAction, @@ -254,6 +257,17 @@ export class ContextMenuService { ]); } + async showLinkContextMenu( + _input: LinkContextMenuInput, + ): Promise { + return this.showMenu([ + this.item("Open in app browser", { type: "open-embedded" }), + this.item("Open in system browser", { type: "open-external" }), + this.separator(), + this.item("Copy link", { type: "copy-url" }), + ]); + } + async showTabContextMenu( input: TabContextMenuInput, ): Promise { diff --git a/packages/core/src/context-menu/schemas.ts b/packages/core/src/context-menu/schemas.ts index 469b95045c..a20705953c 100644 --- a/packages/core/src/context-menu/schemas.ts +++ b/packages/core/src/context-menu/schemas.ts @@ -36,6 +36,10 @@ export const fileContextMenuInput = z.object({ showCollapseAll: z.boolean().optional(), }); +export const linkContextMenuInput = z.object({ + url: z.string(), +}); + const externalAppAction = z.discriminatedUnion("type", [ z.object({ type: z.literal("open-in-app"), appId: z.string() }), z.object({ type: z.literal("copy-path") }), @@ -79,6 +83,12 @@ const fileAction = z.discriminatedUnion("type", [ z.object({ type: z.literal("external-app"), action: externalAppAction }), ]); +const linkAction = z.discriminatedUnion("type", [ + z.object({ type: z.literal("open-embedded") }), + z.object({ type: z.literal("open-external") }), + z.object({ type: z.literal("copy-url") }), +]); + const splitDirection = z.enum(["left", "right", "up", "down"]); export const taskContextMenuOutput = z.object({ @@ -97,6 +107,9 @@ export const tabContextMenuOutput = z.object({ action: tabAction.nullable() }); export const fileContextMenuOutput = z.object({ action: fileAction.nullable(), }); +export const linkContextMenuOutput = z.object({ + action: linkAction.nullable(), +}); export const splitContextMenuOutput = z.object({ direction: splitDirection.nullable(), }); @@ -109,6 +122,7 @@ export type ArchivedTaskContextMenuInput = z.infer< export type FolderContextMenuInput = z.infer; export type TabContextMenuInput = z.infer; export type FileContextMenuInput = z.infer; +export type LinkContextMenuInput = z.infer; export type ExternalAppAction = z.infer; export type TaskAction = z.infer; @@ -117,6 +131,7 @@ export type ArchivedTaskAction = z.infer; export type FolderAction = z.infer; export type TabAction = z.infer; export type FileAction = z.infer; +export type LinkAction = z.infer; export type SplitDirection = z.infer; export const confirmDeleteTaskInput = z.object({ @@ -170,4 +185,5 @@ export type ArchivedTaskContextMenuResult = z.infer< export type FolderContextMenuResult = z.infer; export type TabContextMenuResult = z.infer; export type FileContextMenuResult = z.infer; +export type LinkContextMenuResult = z.infer; export type SplitContextMenuResult = z.infer; diff --git a/packages/host-router/src/routers/context-menu.router.ts b/packages/host-router/src/routers/context-menu.router.ts index 92ba67848e..ac0ae040f3 100644 --- a/packages/host-router/src/routers/context-menu.router.ts +++ b/packages/host-router/src/routers/context-menu.router.ts @@ -15,6 +15,8 @@ import { fileContextMenuOutput, folderContextMenuInput, folderContextMenuOutput, + linkContextMenuInput, + linkContextMenuOutput, splitContextMenuOutput, tabContextMenuInput, tabContextMenuOutput, @@ -112,4 +114,13 @@ export const contextMenuRouter = router({ .get(CONTEXT_MENU_CONTROLLER) .showFileContextMenu(input), ), + + showLinkContextMenu: publicProcedure + .input(linkContextMenuInput) + .output(linkContextMenuOutput) + .mutation(({ ctx, input }) => + ctx.container + .get(CONTEXT_MENU_CONTROLLER) + .showLinkContextMenu(input), + ), }); diff --git a/packages/shared/src/analytics-events.ts b/packages/shared/src/analytics-events.ts index 42b0d55d1d..eb9d3126ee 100644 --- a/packages/shared/src/analytics-events.ts +++ b/packages/shared/src/analytics-events.ts @@ -797,11 +797,15 @@ export interface SubscriptionCancelledProperties { } export interface BrowserTabOpenedProperties { - // "user" = globe icon click; "window_open" = intercepted window.open() call - source: "user" | "window_open"; + // "user" = globe icon click; "window_open" = intercepted window.open() call; "chat_link" = link in agent message + source: "user" | "window_open" | "chat_link"; has_initial_url: boolean; } +export interface LinkClickedInChatProperties { + destination: "embedded_browser" | "system_browser" | "copy_link"; +} + // Event names as constants export const ANALYTICS_EVENTS = { // App lifecycle @@ -906,6 +910,7 @@ export const ANALYTICS_EVENTS = { // Browser tab events BROWSER_TAB_OPENED: "Browser tab opened", + LINK_CLICKED_IN_CHAT: "Link clicked in chat", // Error events TASK_CREATION_FAILED: "Task creation failed", @@ -1081,4 +1086,5 @@ export type EventPropertyMap = { // Browser tab events [ANALYTICS_EVENTS.BROWSER_TAB_OPENED]: BrowserTabOpenedProperties; + [ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT]: LinkClickedInChatProperties; }; diff --git a/packages/ui/src/features/panels/components/TabbedPanel.tsx b/packages/ui/src/features/panels/components/TabbedPanel.tsx index efd3cbe98c..316b6e1a87 100644 --- a/packages/ui/src/features/panels/components/TabbedPanel.tsx +++ b/packages/ui/src/features/panels/components/TabbedPanel.tsx @@ -3,13 +3,14 @@ import { GlobeSimple, Plus, SquareSplitHorizontalIcon, + Terminal, } from "@phosphor-icons/react"; import { useHostTRPCClient } from "@posthog/host-router/react"; import { PanelDropZones } from "@posthog/ui/features/panels/components/PanelDropZones"; import type { SplitDirection } from "@posthog/ui/features/panels/panelLayoutStore"; import type { PanelContent } from "@posthog/ui/features/panels/panelTypes"; import { Tooltip } from "@posthog/ui/primitives/Tooltip"; -import { Box, Flex } from "@radix-ui/themes"; +import { Box, DropdownMenu, Flex } from "@radix-ui/themes"; import type React from "react"; import { forwardRef, useCallback, useEffect, useRef, useState } from "react"; import { PanelTab } from "./PanelTab"; @@ -201,12 +202,34 @@ export const TabbedPanel: React.FC = ({ badge={tab.badge} /> ))} - {content.droppable && onAddTerminal && ( - - - - - + {content.droppable && (onAddTerminal || onAddBrowser) && ( + + + + {}}> + + + + + + {onAddTerminal && ( + + + + New terminal + + + )} + {onAddBrowser && ( + + + + New browser tab + + + )} + + )} {/* Spacer to increase DND area */} {content.droppable && ( @@ -214,12 +237,26 @@ export const TabbedPanel: React.FC = ({ )} {(rightContent || - (content.droppable && (onSplitPanel || onAddBrowser))) && ( + (content.droppable && + (onSplitPanel || onAddBrowser || onAddTerminal))) && ( {rightContent} + {content.droppable && onAddTerminal && ( + + + + + + )} + {content.droppable && onAddTerminal && onAddBrowser && ( +
+ )} {content.droppable && onAddBrowser && ( = ({ )} - {content.droppable && onAddBrowser && onSplitPanel && ( -
- )} + {content.droppable && + (onAddTerminal || onAddBrowser) && + onSplitPanel &&
} {content.droppable && onSplitPanel && ( = ({ > {content.tabs.length > 0 && content.tabs.some((t) => t.id === content.activeTabId) ? ( - content.tabs.map((tab) => ( -
- {tab.component} -
- )) + content.tabs.map((tab) => { + const isActive = tab.id === content.activeTabId; + // Browser tabs use display:none when inactive so IntersectionObserver + // correctly reports them as not visible and hides the native WebContentsView. + // Other tabs use visibility:hidden to preserve editor/terminal dimensions. + const isBrowserTab = tab.data?.type === "browser"; + const style = isActive + ? activeTabStyle + : isBrowserTab + ? { ...hiddenTabStyle, display: "none" } + : hiddenTabStyle; + return ( +
+ {tab.component} +
+ ); + }) ) : emptyState ? ( emptyState ) : ( diff --git a/packages/ui/src/features/panels/hooks/usePanelLayoutHooks.tsx b/packages/ui/src/features/panels/hooks/usePanelLayoutHooks.tsx index 8d8249c829..52ef4a9f25 100644 --- a/packages/ui/src/features/panels/hooks/usePanelLayoutHooks.tsx +++ b/packages/ui/src/features/panels/hooks/usePanelLayoutHooks.tsx @@ -51,6 +51,7 @@ export interface PanelLayoutState { setFocusedPanel: (taskId: string, panelId: string) => void; addTerminalTab: (taskId: string, panelId: string) => void; addBrowserTab: (taskId: string, panelId: string, url?: string) => void; + openBrowserUrl: (taskId: string, url: string) => void; splitPanel: ( taskId: string, tabId: string, @@ -77,6 +78,7 @@ export function usePanelLayoutState(taskId: string): PanelLayoutState { setFocusedPanel: state.setFocusedPanel, addTerminalTab: state.addTerminalTab, addBrowserTab: state.addBrowserTab, + openBrowserUrl: state.openBrowserUrl, updateTabLabel: state.updateTabLabel, splitPanel: state.splitPanel, draggingTabId: state.getLayout(taskId)?.draggingTabId ?? null, diff --git a/packages/ui/src/features/panels/panelLayoutStore.ts b/packages/ui/src/features/panels/panelLayoutStore.ts index 67d9f53717..530fd1656e 100644 --- a/packages/ui/src/features/panels/panelLayoutStore.ts +++ b/packages/ui/src/features/panels/panelLayoutStore.ts @@ -1,3 +1,4 @@ +import { DEFAULT_PANEL_IDS } from "@posthog/core/panels/panelConstants"; import { addRecentFile, addActionTab as coreAddActionTab, @@ -98,6 +99,7 @@ export interface PanelLayoutStore { setFocusedPanel: (taskId: string, panelId: string) => void; addTerminalTab: (taskId: string, panelId: string) => void; addBrowserTab: (taskId: string, panelId: string, url?: string) => void; + openBrowserUrl: (taskId: string, url: string) => void; addActionTab: ( taskId: string, panelId: string, @@ -393,6 +395,22 @@ export const usePanelLayoutStore = createWithEqualityFn()( }); }, + openBrowserUrl: (taskId, url) => { + const layout = get().taskLayouts[taskId]; + const panelId = layout?.focusedPanelId ?? DEFAULT_PANEL_IDS.MAIN_PANEL; + set((state) => + updateTaskLayout( + state, + taskId, + (l) => coreAddBrowserTab(l, panelId, url) as Partial, + ), + ); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "chat_link", + has_initial_url: true, + }); + }, + addActionTab: (taskId, panelId, action) => { set((state) => updateTaskLayout( diff --git a/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx b/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx index 59fd2f6d13..d7dd239b79 100644 --- a/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx +++ b/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx @@ -1,9 +1,13 @@ import { Check, Copy } from "@phosphor-icons/react"; +import { useHostTRPCClient } from "@posthog/host-router/react"; +import { ANALYTICS_EVENTS } from "@posthog/shared/analytics-events"; import { Box, Code, IconButton } from "@radix-ui/themes"; import { memo, useCallback, useMemo, useState } from "react"; import type { Components } from "react-markdown"; import { HighlightedCode } from "../../../../primitives/HighlightedCode"; import { Tooltip } from "../../../../primitives/Tooltip"; +import { track } from "../../../../shell/analytics"; +import { openExternalUrl } from "../../../../shell/openExternal"; import { usePendingScrollStore } from "../../../code-editor/pendingScrollStore"; import { MarkdownRenderer } from "../../../editor/components/MarkdownRenderer"; import { usePanelLayoutStore } from "../../../panels/panelLayoutStore"; @@ -104,7 +108,94 @@ function BareFileLink({ text }: { text: string }) { return ; } +function ChatLink({ + href, + children, +}: { + href?: string; + children: React.ReactNode; +}) { + const taskId = useSessionTaskId(); + const openBrowserUrl = usePanelLayoutStore((s) => s.openBrowserUrl); + const hostClient = useHostTRPCClient(); + + const handleClick = useCallback( + (e: React.MouseEvent) => { + if (!href) return; + e.preventDefault(); + if (taskId) { + openBrowserUrl(taskId, href); + } + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "embedded_browser", + }); + }, + [href, taskId, openBrowserUrl], + ); + + const handleContextMenu = useCallback( + async (e: React.MouseEvent) => { + if (!href) return; + e.preventDefault(); + const result = await hostClient.contextMenu.showLinkContextMenu.mutate({ + url: href, + }); + if (!result.action) return; + switch (result.action.type) { + case "open-embedded": + if (taskId) openBrowserUrl(taskId, href); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "embedded_browser", + }); + break; + case "open-external": + openExternalUrl(href); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "system_browser", + }); + break; + case "copy-url": + navigator.clipboard.writeText(href); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "copy_link", + }); + break; + } + }, + [href, taskId, openBrowserUrl, hostClient], + ); + + return ( +
void handleContextMenu(e)} + className="markdown-link inline-flex cursor-pointer items-center gap-[2px]" + > + {children} + + + + + + + ); +} + const agentComponents: Partial = { + a: ({ href, children }) => {children}, code: ({ children, className }) => { const langMatch = className?.match(/language-(\w+)/); if (langMatch) { From e9485caf37c5d1e9036fc2e3701618734a5fba80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 16:53:00 -0600 Subject: [PATCH 05/11] feat(browser): add native right-click context menu with devtools to embedded browser Right-clicking in the embedded browser now shows a native context menu: - Back / Forward / Reload for in-browser navigation - "Open in system browser" for the current page (or "Open link in system browser" + "Copy link address" when right-clicking a hyperlink) - "Inspect element" that opens Chromium DevTools at the clicked position Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../code/src/main/services/browser/service.ts | 92 ++++++++++++++++--- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/apps/code/src/main/services/browser/service.ts b/apps/code/src/main/services/browser/service.ts index d0cafb8c86..7ba0560873 100644 --- a/apps/code/src/main/services/browser/service.ts +++ b/apps/code/src/main/services/browser/service.ts @@ -7,8 +7,8 @@ import type { } from "@posthog/host-router/ports/browser"; import { MAIN_WINDOW_SERVICE } from "@posthog/platform/main-window"; import { TypedEventEmitter } from "@posthog/shared"; -// biome-ignore lint/style/noRestrictedImports: WebContentsView is Electron-only by design; see host-boundary-allowlist.json -import { WebContentsView } from "electron"; +// biome-ignore lint/style/noRestrictedImports: Electron-only by design; see host-boundary-allowlist.json +import { clipboard, Menu, MenuItem, shell, WebContentsView } from "electron"; import { inject, injectable, preDestroy } from "inversify"; import type { ElectronMainWindow } from "../../platform-adapters/electron-main-window"; import { logger } from "../../utils/logger"; @@ -74,6 +74,10 @@ export class BrowserService win.contentView.addChildView(view); } + // Guards any handler that fires in the narrow window between + // this.browsers.delete() and webContents.close() in destroy(). + const alive = () => this.browsers.has(browserId); + // Block navigation to anything other than http/https. view.webContents.on("will-navigate", (event, targetUrl) => { if (!this.isSafeUrl(targetUrl)) { @@ -93,37 +97,35 @@ export class BrowserService // Open window.open() calls as new browser tabs in the app instead of // spawning an uncontrolled native window. view.webContents.setWindowOpenHandler(({ url: targetUrl }) => { - if (this.isSafeUrl(targetUrl)) { + if (alive() && this.isSafeUrl(targetUrl)) { this.emit("openUrl", { url: targetUrl }); } return { action: "deny" }; }); view.webContents.on("did-navigate", () => { - this.emitNavigate(entry); + if (alive()) this.emitNavigate(entry); }); view.webContents.on("did-navigate-in-page", () => { - this.emitNavigate(entry); + if (alive()) this.emitNavigate(entry); }); view.webContents.on("page-title-updated", (_e, title) => { - this.emit("title", { browserId, title }); + if (alive()) this.emit("title", { browserId, title }); }); view.webContents.on("page-favicon-updated", (_e, favicons) => { - this.emit("favicon", { - browserId, - favicon: favicons[0] ?? null, - }); + if (alive()) + this.emit("favicon", { browserId, favicon: favicons[0] ?? null }); }); view.webContents.on("did-start-loading", () => { - this.emitNavigate(entry); + if (alive()) this.emitNavigate(entry); }); view.webContents.on("did-stop-loading", () => { - this.emitNavigate(entry); + if (alive()) this.emitNavigate(entry); }); // Show a branded error page when a URL fails to load (DNS errors, timeouts, etc.). @@ -135,11 +137,72 @@ export class BrowserService (_event, errorCode, _errorDescription, validatedURL, isMainFrame) => { if (!isMainFrame) return; if (errorCode === -3) return; + if (!alive()) return; const errorPage = buildErrorPage(validatedURL); view.webContents.loadURL(errorPage).catch(() => {}); }, ); + view.webContents.on("context-menu", (_event, params) => { + if (!alive()) return; + const wc = entry.view.webContents; + const items: MenuItem[] = [ + new MenuItem({ + label: "Back", + enabled: wc.canGoBack(), + click: () => wc.goBack(), + }), + new MenuItem({ + label: "Forward", + enabled: wc.canGoForward(), + click: () => wc.goForward(), + }), + new MenuItem({ label: "Reload", click: () => wc.reload() }), + new MenuItem({ type: "separator" }), + ]; + + if (params.linkURL) { + items.push( + new MenuItem({ + label: "Open link in system browser", + click: () => { + shell.openExternal(params.linkURL).catch(() => {}); + }, + }), + new MenuItem({ + label: "Copy link address", + click: () => { + clipboard.writeText(params.linkURL); + }, + }), + new MenuItem({ type: "separator" }), + ); + } else { + items.push( + new MenuItem({ + label: "Open in system browser", + click: () => { + shell.openExternal(wc.getURL()).catch(() => {}); + }, + }), + new MenuItem({ type: "separator" }), + ); + } + + items.push( + new MenuItem({ + label: "Inspect element", + click: () => { + wc.inspectElement(params.x, params.y); + }, + }), + ); + + const menu = Menu.buildFromTemplate(items); + const mainWin = this.mainWindow.getBrowserWindow(); + if (mainWin) menu.popup({ window: mainWin }); + }); + if (url && url !== "about:blank") { view.webContents.loadURL(url).catch((err) => { log.warn("Failed to load URL", url, err); @@ -151,6 +214,8 @@ export class BrowserService const entry = this.browsers.get(browserId); if (!entry) return; + // Remove from map first so any in-flight event callbacks (alive() check) + // become no-ops before we start tearing down. this.browsers.delete(browserId); const win = this.mainWindow.getBrowserWindow(); @@ -163,6 +228,9 @@ export class BrowserService } try { + // Remove all listeners before close() so closures referencing entry + // are released immediately rather than waiting for GC. + entry.view.webContents.removeAllListeners(); entry.view.webContents.close(); } catch { // already closed From 71d7a40f2409a959fe9f61fd79aca1134a67ac0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 17:27:17 -0600 Subject: [PATCH 06/11] test(context-menu): cover showLinkContextMenu with labels, each action, and dismissal Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../src/context-menu/context-menu.test.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/core/src/context-menu/context-menu.test.ts b/packages/core/src/context-menu/context-menu.test.ts index 036e4cffc4..f8f8d13030 100644 --- a/packages/core/src/context-menu/context-menu.test.ts +++ b/packages/core/src/context-menu/context-menu.test.ts @@ -186,3 +186,43 @@ describe("ContextMenuService.confirmDeleteTask", () => { ).toEqual({ confirmed: false }); }); }); + +describe("ContextMenuService.showLinkContextMenu", () => { + it("shows all three link actions", async () => { + const menu = new FakeContextMenu(); + makeService(menu).showLinkContextMenu({ url: "https://example.com" }); + await menu.shown; + expect(labels(menu.lastItems)).toEqual([ + "Open in app browser", + "Open in system browser", + "Copy link", + ]); + }); + + it.each([ + ["Open in app browser", { type: "open-embedded" }], + ["Open in system browser", { type: "open-external" }], + ["Copy link", { type: "copy-url" }], + ] as const)( + "clicking '%s' resolves to the correct action", + async (label, expected) => { + const menu = new FakeContextMenu(); + const result = makeService(menu).showLinkContextMenu({ + url: "https://example.com", + }); + await menu.shown; + findItem(menu.lastItems, label).click(); + expect(await result).toEqual({ action: expected }); + }, + ); + + it("resolves to null when dismissed without a selection", async () => { + const menu = new FakeContextMenu(); + const result = makeService(menu).showLinkContextMenu({ + url: "https://example.com", + }); + await menu.shown; + menu.lastOptions?.onDismiss?.(); + expect(await result).toEqual({ action: null }); + }); +}); From 7abb8fe8ba171f7a22f1d579f932c8894165a88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 23:07:25 -0600 Subject: [PATCH 07/11] feat(browser): embedded browser with tab management and welcome page - Add Hedge Browser welcome page (shown instead of Google on new tabs): dark-themed page with hedgehog logo, description, and footer note - Fix split panel without reload: skip destroy when tab moves to another panel; BrowserService.create() guards with browsers.has() so the WebContentsView is preserved across panel splits - Fix ghost browser view on hot-reload: setVisible(false) when skipping destroy so the native layer doesn't float over the UI - Fix address bar on error pages: track last real URL in a ref and emit synthetic navigate on create() so the toolbar is seeded immediately - Add loading animation bar at the bottom of the browser toolbar - Fix z-index: right-side tab-bar actions render above the scrollable tab list - Hide native WebContentsView when the "+" dropdown opens so it doesn't cover Radix dropdown menus (native OS layer ignores CSS z-index) - Fix silent no-op: "Open in app browser" in chat falls back to system browser when no active task is present - Freeze FALLBACK_BROWSER_STATE so mutations don't pollute the sentinel - Fix canOpenUrl regex in MentionChipView (require http/https prefix) - Add useOpenUrl hook centralising all external-link handling across the app (GithubRefChip, MarkdownRenderer, PRBadgeLink, FetchToolView, GitActionResult) - Update updateBrowserTabUrl to use typed wrappers for findTabInTree / updateTreeNode; fixes TypeScript error where core PanelNode (Tab with component: unknown) was not assignable to UI PanelNode (Tab with component: ReactNode) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../src/main/services/browser/errorPage.ts | 2 +- .../src/main/services/browser/newTabPage.ts | 59 ++++ .../code/src/main/services/browser/service.ts | 48 ++-- biome.jsonc | 3 +- .../core/src/panels/panelLayoutTransforms.ts | 2 +- .../ui/src/features/browser/BrowserPanel.tsx | 63 ++++- .../src/features/browser/BrowserToolbar.tsx | 23 +- .../ui/src/features/browser/browserStore.ts | 8 +- .../editor/components/GithubRefChip.tsx | 4 +- .../editor/components/MarkdownRenderer.tsx | 255 +++++++++--------- .../components/PRBadgeLink.tsx | 18 +- .../message-editor/tiptap/MentionChipView.tsx | 6 +- .../panels/components/PanelLayout.tsx | 6 + .../panels/components/TabbedPanel.tsx | 63 +++-- .../src/features/panels/panelLayoutStore.ts | 44 ++- .../src/features/panels/panelStoreHelpers.ts | 12 + .../sessions/components/GitActionResult.tsx | 6 +- .../session-update/AgentMessage.tsx | 44 ++- .../session-update/FetchToolView.tsx | 10 +- packages/ui/src/shell/useOpenUrl.ts | 26 ++ packages/ui/tailwind.config.js | 5 + 21 files changed, 496 insertions(+), 211 deletions(-) create mode 100644 apps/code/src/main/services/browser/newTabPage.ts create mode 100644 packages/ui/src/shell/useOpenUrl.ts diff --git a/apps/code/src/main/services/browser/errorPage.ts b/apps/code/src/main/services/browser/errorPage.ts index 755e2b70e9..6b739eecaf 100644 --- a/apps/code/src/main/services/browser/errorPage.ts +++ b/apps/code/src/main/services/browser/errorPage.ts @@ -1,7 +1,7 @@ // Error page shown when a URL fails to load in the browser panel. // The hedgehog image is embedded as base64 so this works in both dev and // the packaged app without any extra asset-serving setup. -const HOG_B64 = +export const HOG_B64 = "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"; export function buildErrorPage(url: string): string { diff --git a/apps/code/src/main/services/browser/newTabPage.ts b/apps/code/src/main/services/browser/newTabPage.ts new file mode 100644 index 0000000000..95cef86247 --- /dev/null +++ b/apps/code/src/main/services/browser/newTabPage.ts @@ -0,0 +1,59 @@ +import { HOG_B64 } from "./errorPage"; + +export function buildNewTabPage(): string { + const html = ` + + + + + + +
+ +

Hedge Browser

+

A lightweight browser built right into your workspace. Check things quickly without breaking your flow.

+ +
+ +`; + return `data:text/html;charset=utf-8,${encodeURIComponent(html)}`; +} diff --git a/apps/code/src/main/services/browser/service.ts b/apps/code/src/main/services/browser/service.ts index 7ba0560873..aeb480f242 100644 --- a/apps/code/src/main/services/browser/service.ts +++ b/apps/code/src/main/services/browser/service.ts @@ -13,6 +13,7 @@ import { inject, injectable, preDestroy } from "inversify"; import type { ElectronMainWindow } from "../../platform-adapters/electron-main-window"; import { logger } from "../../utils/logger"; import { buildErrorPage } from "./errorPage"; +import { buildNewTabPage } from "./newTabPage"; const log = logger.scope("browser-service"); @@ -56,6 +57,10 @@ export class BrowserService create(browserId: string, url: string): void { if (this.browsers.has(browserId)) return; + // Replace blank new-tab sentinel with the Hedge Browser welcome page. + const effectiveUrl = + !url || url === "about:blank" ? buildNewTabPage() : url; + const view = new WebContentsView({ webPreferences: { nodeIntegration: false, @@ -74,11 +79,20 @@ export class BrowserService win.contentView.addChildView(view); } - // Guards any handler that fires in the narrow window between - // this.browsers.delete() and webContents.close() in destroy(). + // Seed the address bar immediately so it shows the target URL before any + // navigation events fire (getURL() returns "" on a fresh WebContentsView). + this.emit("navigate", { + browserId, + url: effectiveUrl, + title: "", + canGoBack: false, + canGoForward: false, + isLoading: true, + }); + + // Guards handlers that fire between browsers.delete() and webContents.close(). const alive = () => this.browsers.has(browserId); - // Block navigation to anything other than http/https. view.webContents.on("will-navigate", (event, targetUrl) => { if (!this.isSafeUrl(targetUrl)) { event.preventDefault(); @@ -94,8 +108,7 @@ export class BrowserService } }); - // Open window.open() calls as new browser tabs in the app instead of - // spawning an uncontrolled native window. + // Route window.open() into the app as a new tab instead of a native window. view.webContents.setWindowOpenHandler(({ url: targetUrl }) => { if (alive() && this.isSafeUrl(targetUrl)) { this.emit("openUrl", { url: targetUrl }); @@ -128,10 +141,7 @@ export class BrowserService if (alive()) this.emitNavigate(entry); }); - // Show a branded error page when a URL fails to load (DNS errors, timeouts, etc.). - // Error codes < 0 are Chromium net errors; -3 is ABORTED (e.g. caused by our own - // navigation lock, or the user pressing Stop) — skip those to avoid flashing the - // error page during normal navigation. + // -3 is ABORTED (our own navigation lock or user pressing Stop) — skip to avoid flashing an error page. view.webContents.on( "did-fail-load", (_event, errorCode, _errorDescription, validatedURL, isMainFrame) => { @@ -185,6 +195,12 @@ export class BrowserService shell.openExternal(wc.getURL()).catch(() => {}); }, }), + new MenuItem({ + label: "Copy page URL", + click: () => { + clipboard.writeText(wc.getURL()); + }, + }), new MenuItem({ type: "separator" }), ); } @@ -203,19 +219,16 @@ export class BrowserService if (mainWin) menu.popup({ window: mainWin }); }); - if (url && url !== "about:blank") { - view.webContents.loadURL(url).catch((err) => { - log.warn("Failed to load URL", url, err); - }); - } + view.webContents.loadURL(effectiveUrl).catch((err) => { + log.warn("Failed to load URL", effectiveUrl, err); + }); } destroy(browserId: string): void { const entry = this.browsers.get(browserId); if (!entry) return; - // Remove from map first so any in-flight event callbacks (alive() check) - // become no-ops before we start tearing down. + // Delete first so in-flight handlers (alive() check) become no-ops before teardown. this.browsers.delete(browserId); const win = this.mainWindow.getBrowserWindow(); @@ -228,8 +241,7 @@ export class BrowserService } try { - // Remove all listeners before close() so closures referencing entry - // are released immediately rather than waiting for GC. + // removeAllListeners before close() drops closure references immediately instead of waiting for GC. entry.view.webContents.removeAllListeners(); entry.view.webContents.close(); } catch { diff --git a/biome.jsonc b/biome.jsonc index afedcd2d38..e0ee379d73 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -360,7 +360,8 @@ "!@posthog/platform", "!@posthog/platform/*", "!@posthog/quill", - "!@posthog/quill-charts" + "!@posthog/quill-charts", + "!@posthog/host-router/react" ], "message": "ui must run in any JS environment." } diff --git a/packages/core/src/panels/panelLayoutTransforms.ts b/packages/core/src/panels/panelLayoutTransforms.ts index 86da1dab05..b1bb57bd33 100644 --- a/packages/core/src/panels/panelLayoutTransforms.ts +++ b/packages/core/src/panels/panelLayoutTransforms.ts @@ -707,7 +707,7 @@ export function addTerminalTab( export function addBrowserTab( layout: TaskLayout, panelId: string, - url = "https://www.google.com", + url = "about:blank", ): Partial { const browserId = `browser-${Date.now()}`; const updatedTree = updateTreeNode(layout.panelTree, panelId, (panel) => { diff --git a/packages/ui/src/features/browser/BrowserPanel.tsx b/packages/ui/src/features/browser/BrowserPanel.tsx index 0525a8e40f..5709c1e48c 100644 --- a/packages/ui/src/features/browser/BrowserPanel.tsx +++ b/packages/ui/src/features/browser/BrowserPanel.tsx @@ -1,10 +1,14 @@ +import { findTabInTree } from "@posthog/core/panels/panelTree"; import { useHostTRPC, useHostTRPCClient } from "@posthog/host-router/react"; +import { ANALYTICS_EVENTS } from "@posthog/shared"; import { BrowserToolbar } from "@posthog/ui/features/browser/BrowserToolbar"; import { useBrowserStore } from "@posthog/ui/features/browser/browserStore"; import { usePanelLayoutState } from "@posthog/ui/features/panels/hooks/usePanelLayoutHooks"; +import { usePanelLayoutStore } from "@posthog/ui/features/panels/panelLayoutStore"; import { Flex } from "@radix-ui/themes"; import { useSubscription } from "@trpc/tanstack-react-query"; import { useCallback, useEffect, useRef, useState } from "react"; +import { track } from "../../shell/analytics"; interface BrowserPanelProps { browserId: string; @@ -25,9 +29,17 @@ export function BrowserPanel({ const setBrowserState = useBrowserStore((s) => s.setBrowserState); const removeBrowser = useBrowserStore((s) => s.removeBrowser); const { addBrowserTab, updateTabLabel } = usePanelLayoutState(taskId); + const updateBrowserTabUrl = usePanelLayoutStore((s) => s.updateBrowserTabUrl); const boundsRafRef = useRef(null); const mountedRef = useRef(false); const visibleRef = useRef(false); + const lastBoundsRef = useRef<{ + x: number; + y: number; + width: number; + height: number; + } | null>(null); + const lastVisibleRef = useRef(null); const [viewReady, setViewReady] = useState(false); // Create the WebContentsView on mount, destroy on unmount. @@ -46,8 +58,20 @@ export function BrowserPanel({ if (boundsRafRef.current !== null) { cancelAnimationFrame(boundsRafRef.current); } - client.browser.destroy.mutate({ browserId }); - removeBrowser(browserId); + // Skip destroy if the tab was moved to another panel — create() will be + // called by the new BrowserPanel but the guard (browsers.has) returns early, + // preserving the WebContentsView without a reload. + const layout = usePanelLayoutStore.getState().getLayout(taskId); + const tabMoved = layout + ? findTabInTree(layout.panelTree, browserId) !== null + : false; + if (!tabMoved) { + client.browser.destroy.mutate({ browserId }); + removeBrowser(browserId); + } else { + // Hide the native view so it doesn't float over the UI during re-renders or HMR. + client.browser.setVisible.mutate({ browserId, visible: false }); + } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -56,13 +80,21 @@ export function BrowserPanel({ if (!contentRef.current || !mountedRef.current) return; const rect = contentRef.current.getBoundingClientRect(); if (rect.width <= 0 || rect.height <= 0) return; - client.browser.setBounds.mutate({ - browserId, - x: Math.round(rect.left), - y: Math.round(rect.top), - width: Math.round(rect.width), - height: Math.round(rect.height), - }); + const x = Math.round(rect.left); + const y = Math.round(rect.top); + const width = Math.round(rect.width); + const height = Math.round(rect.height); + const prev = lastBoundsRef.current; + if ( + prev && + prev.x === x && + prev.y === y && + prev.width === width && + prev.height === height + ) + return; + lastBoundsRef.current = { x, y, width, height }; + client.browser.setBounds.mutate({ browserId, x, y, width, height }); }, [browserId, client]); const scheduleSyncBounds = useCallback(() => { @@ -77,6 +109,7 @@ export function BrowserPanel({ useEffect(() => { if (!viewReady) return; const visible = visibleRef.current; + lastVisibleRef.current = visible; client.browser.setVisible.mutate({ browserId, visible }); if (visible) syncBounds(); }, [viewReady, browserId, client, syncBounds]); @@ -90,7 +123,10 @@ export function BrowserPanel({ const visible = entry?.isIntersecting ?? false; visibleRef.current = visible; if (!viewReady) return; - client.browser.setVisible.mutate({ browserId, visible }); + if (lastVisibleRef.current !== visible) { + lastVisibleRef.current = visible; + client.browser.setVisible.mutate({ browserId, visible }); + } if (visible) scheduleSyncBounds(); }); @@ -127,6 +163,9 @@ export function BrowserPanel({ canGoForward: data.canGoForward, isLoading: data.isLoading, }); + if (!data.isLoading && data.url && !data.url.startsWith("data:")) { + updateBrowserTabUrl(taskId, browserId, data.url); + } }, }, ), @@ -160,6 +199,10 @@ export function BrowserPanel({ trpc.browser.onOpenUrl.subscriptionOptions(undefined, { onData: (data) => { addBrowserTab(taskId, panelId, data.url); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "window_open", + has_initial_url: true, + }); }, }), ); diff --git a/packages/ui/src/features/browser/BrowserToolbar.tsx b/packages/ui/src/features/browser/BrowserToolbar.tsx index 3b80728849..6cf0098029 100644 --- a/packages/ui/src/features/browser/BrowserToolbar.tsx +++ b/packages/ui/src/features/browser/BrowserToolbar.tsx @@ -35,16 +35,20 @@ export function BrowserToolbar({ browserId }: BrowserToolbarProps) { isLoading, } = useBrowserViewState(browserId); - const [inputValue, setInputValue] = useState(url); + const lastRealUrlRef = useRef(url.startsWith("data:") ? "" : url); + if (url && !url.startsWith("data:")) lastRealUrlRef.current = url; + const displayUrl = url.startsWith("data:") ? lastRealUrlRef.current : url; + + const [inputValue, setInputValue] = useState(displayUrl); const inputRef = useRef(null); const isEditingRef = useRef(false); const didNavigateRef = useRef(false); useEffect(() => { if (!isEditingRef.current) { - setInputValue(url); + setInputValue(displayUrl); } - }, [url]); + }, [displayUrl]); const handleNavigate = useCallback(() => { const target = normalizeUrl(inputValue); @@ -61,6 +65,7 @@ export function BrowserToolbar({ browserId }: BrowserToolbarProps) { gap="1" px="2" style={{ + position: "relative", height: "36px", flexShrink: 0, borderBottom: "1px solid var(--gray-4)", @@ -108,7 +113,7 @@ export function BrowserToolbar({ browserId }: BrowserToolbarProps) { onBlur={() => { isEditingRef.current = false; if (!didNavigateRef.current) { - setInputValue(url); + setInputValue(displayUrl); } didNavigateRef.current = false; }} @@ -116,11 +121,19 @@ export function BrowserToolbar({ browserId }: BrowserToolbarProps) { onKeyDown={(e) => { if (e.key === "Enter") handleNavigate(); if (e.key === "Escape") { - setInputValue(url); + setInputValue(displayUrl); inputRef.current?.blur(); } }} /> + {isLoading && ( +
+
+
+ )} ); } diff --git a/packages/ui/src/features/browser/browserStore.ts b/packages/ui/src/features/browser/browserStore.ts index c1ffe8f7ef..d001d2cefe 100644 --- a/packages/ui/src/features/browser/browserStore.ts +++ b/packages/ui/src/features/browser/browserStore.ts @@ -27,6 +27,10 @@ const defaultBrowserState = (): BrowserViewState => ({ canGoForward: false, }); +const FALLBACK_BROWSER_STATE: BrowserViewState = Object.freeze( + defaultBrowserState(), +); + export const useBrowserStore = create((set) => ({ browsers: {}, @@ -49,5 +53,7 @@ export const useBrowserStore = create((set) => ({ })); export function useBrowserViewState(browserId: string): BrowserViewState { - return useBrowserStore((s) => s.browsers[browserId] ?? defaultBrowserState()); + return useBrowserStore( + (s) => s.browsers[browserId] ?? FALLBACK_BROWSER_STATE, + ); } diff --git a/packages/ui/src/features/editor/components/GithubRefChip.tsx b/packages/ui/src/features/editor/components/GithubRefChip.tsx index a8a712f095..c91fb91a87 100644 --- a/packages/ui/src/features/editor/components/GithubRefChip.tsx +++ b/packages/ui/src/features/editor/components/GithubRefChip.tsx @@ -1,6 +1,7 @@ import { GithubLogoIcon, GitPullRequestIcon } from "@phosphor-icons/react"; import { Chip } from "@posthog/quill"; import type { ReactNode } from "react"; +import { useOpenUrl } from "../../../shell/useOpenUrl"; /** * DOM attribute carrying the chip's GitHub URL. The conversation context menu @@ -18,12 +19,13 @@ export function GithubRefChip({ kind: "issue" | "pr"; children: ReactNode; }) { + const openUrl = useOpenUrl(); const Icon = kind === "pr" ? GitPullRequestIcon : GithubLogoIcon; return ( window.open(href, "_blank")} + onClick={() => openUrl(href)} className="cli-file-mention mx-0.5 max-w-full cursor-pointer! whitespace-nowrap pl-1 align-middle active:translate-y-0" > diff --git a/packages/ui/src/features/editor/components/MarkdownRenderer.tsx b/packages/ui/src/features/editor/components/MarkdownRenderer.tsx index e024b2d08c..856623fb0b 100644 --- a/packages/ui/src/features/editor/components/MarkdownRenderer.tsx +++ b/packages/ui/src/features/editor/components/MarkdownRenderer.tsx @@ -12,6 +12,7 @@ import ReactMarkdown, { defaultUrlTransform } from "react-markdown"; import remarkGfm from "remark-gfm"; import type { PluggableList } from "unified"; import { openExternalUrl } from "../../../shell/openExternal"; +import { useOpenUrl } from "../../../shell/useOpenUrl"; interface MarkdownRendererProps { content: string; @@ -37,132 +38,138 @@ const HeadingText = ({ children }: { children: React.ReactNode }) => ( ); -export const baseComponents: Components = { - h1: ({ children }) => {children}, - h2: ({ children }) => {children}, - h3: ({ children }) => {children}, - h4: ({ children }) => {children}, - h5: ({ children }) => {children}, - h6: ({ children }) => {children}, - p: ({ children }) => ( - - {children} - - ), - blockquote: ({ children }) => ( -
- {children} -
- ), - code: ({ children, className }) => { - const match = className?.match(/language-(\w+)/); - if (!match) { - return {children}; - } - return ( - - ); - }, - pre: ({ children }) => {children}, - em: ({ children }) => {children}, - i: ({ children }) => {children}, - strong: ({ children }) => {children}, - del: ({ children }) => ( - {children} - ), - a: ({ href, children }) => { - const githubRef = href ? parseGithubIssueUrl(href) : null; - if (githubRef) { - const isAutoLink = typeof children === "string" && children === href; - const label = isAutoLink - ? `${githubRef.owner}/${githubRef.repo}#${githubRef.number}` - : children; - return ( - - {label} - - ); - } - const isDeeplink = isPostHogCodeDeeplink(href); - return ( - { - if (!isDeeplink || !href) return; - event.preventDefault(); - openExternalUrl(href); - }} - target="_blank" - rel="noopener noreferrer" - className="markdown-link inline-flex items-center gap-[2px]" - > +function makeBaseComponents(openUrl: (url: string) => void): Components { + return { + h1: ({ children }) => {children}, + h2: ({ children }) => {children}, + h3: ({ children }) => {children}, + h4: ({ children }) => {children}, + h5: ({ children }) => {children}, + h6: ({ children }) => {children}, + p: ({ children }) => ( + {children} - - - - - - - ); - }, - kbd: ({ children }) => {children}, - ul: ({ children }) => ( - - {children} - - ), - ol: ({ children }) => ( - - {children} - - ), - li: ({ children }) => {children}, - hr: () => , - // Task list checkbox - input: ({ type, checked }) => { - if (type === "checkbox") { + + ), + blockquote: ({ children }) => ( +
+ {children} +
+ ), + code: ({ children, className }) => { + const match = className?.match(/language-(\w+)/); + if (!match) { + return {children}; + } return ( - ); - } - return ; - }, - // Table components - plain HTML for size control - table: ({ children }) => {children}
, - thead: ({ children }) => {children}, - tbody: ({ children }) => {children}, - tr: ({ children }) => {children}, - th: ({ children, style }) => ( - - {children} - - ), - td: ({ children, style }) => ( - - {children} - - ), -}; + }, + pre: ({ children }) => {children}, + em: ({ children }) => {children}, + i: ({ children }) => {children}, + strong: ({ children }) => {children}, + del: ({ children }) => ( + {children} + ), + a: ({ href, children }) => { + const githubRef = href ? parseGithubIssueUrl(href) : null; + if (githubRef) { + const isAutoLink = typeof children === "string" && children === href; + const label = isAutoLink + ? `${githubRef.owner}/${githubRef.repo}#${githubRef.number}` + : children; + return ( + + {label} + + ); + } + return ( + { + if (!href) return; + event.preventDefault(); + openUrl(href); + }} + target="_blank" + rel="noopener noreferrer" + className="markdown-link inline-flex items-center gap-[2px]" + > + {children} + + + + + + + ); + }, + kbd: ({ children }) => {children}, + ul: ({ children }) => ( + + {children} + + ), + ol: ({ children }) => ( + + {children} + + ), + li: ({ children }) => {children}, + hr: () => , + // Task list checkbox + input: ({ type, checked }) => { + if (type === "checkbox") { + return ( + + ); + } + return ; + }, + // Table components - plain HTML for size control + table: ({ children }) => {children}
, + thead: ({ children }) => {children}, + tbody: ({ children }) => {children}, + tr: ({ children }) => ( + {children} + ), + th: ({ children, style }) => ( + + {children} + + ), + td: ({ children, style }) => ( + + {children} + + ), + }; +} + +// Static version for module-level use where hooks are unavailable (falls back to system browser). +export const baseComponents: Components = makeBaseComponents(openExternalUrl); export const defaultRemarkPlugins = [remarkGfm]; @@ -172,17 +179,19 @@ export const MarkdownRenderer = memo(function MarkdownRenderer({ componentsOverride, rehypePlugins, }: MarkdownRendererProps) { + const openUrl = useOpenUrl(); const processedContent = useMemo( () => preprocessMarkdown(content), [content], ); const plugins = remarkPluginsOverride ?? defaultRemarkPlugins; + const baseComponents = useMemo(() => makeBaseComponents(openUrl), [openUrl]); const components = useMemo( () => componentsOverride ? { ...baseComponents, ...componentsOverride } : baseComponents, - [componentsOverride], + [componentsOverride, baseComponents], ); return ( e.stopPropagation()} + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + openUrl(prUrl); + }} className={`inline-flex items-center gap-0.5 rounded px-1 py-0.5 text-[10px] no-underline ${COMPACT_COLOR_CLASSES[config.color]}`} > {isPrPending ? ( @@ -83,9 +87,11 @@ export function PRBadgeLink({ > e.stopPropagation()} + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + openUrl(prUrl); + }} > {isPrPending ? ( diff --git a/packages/ui/src/features/message-editor/tiptap/MentionChipView.tsx b/packages/ui/src/features/message-editor/tiptap/MentionChipView.tsx index 24f13336a2..4659c6b97a 100644 --- a/packages/ui/src/features/message-editor/tiptap/MentionChipView.tsx +++ b/packages/ui/src/features/message-editor/tiptap/MentionChipView.tsx @@ -16,6 +16,7 @@ import { Tooltip } from "@posthog/ui/primitives/Tooltip"; import type { Node as PmNode } from "@tiptap/pm/model"; import type { Editor } from "@tiptap/react"; import { type NodeViewProps, NodeViewWrapper } from "@tiptap/react"; +import { useOpenUrl } from "../../../shell/useOpenUrl"; import { readAbsoluteFile } from "../hostApi"; import type { ChipType, MentionChipAttrs } from "./MentionChipNode"; @@ -77,18 +78,19 @@ function DefaultChip({ selected: boolean; onRemove: () => void; }) { + const openUrl = useOpenUrl(); const isCommand = type === "command"; const prefix = isCommand ? "/" : "@"; const isFile = type === "file"; const isFolder = type === "folder"; const isGithubRef = type === "github_issue" || type === "github_pr"; - const canOpenUrl = isGithubRef && /^https:\/\//.test(id); + const canOpenUrl = isGithubRef && /^https?:\/\//i.test(id); const chipContent = ( window.open(id, "_blank") : undefined} + onClick={canOpenUrl ? () => openUrl(id) : undefined} className={`${chipBase} max-w-full whitespace-nowrap ${isGithubRef ? "cursor-pointer!" : "cursor-default! active:translate-y-0!"} ${isCommand ? "cli-slash-command" : "cli-file-mention"} ${selected ? selectedRing : ""}`} > diff --git a/packages/ui/src/features/panels/components/PanelLayout.tsx b/packages/ui/src/features/panels/components/PanelLayout.tsx index da6411d8aa..5264dd76c5 100644 --- a/packages/ui/src/features/panels/components/PanelLayout.tsx +++ b/packages/ui/src/features/panels/components/PanelLayout.tsx @@ -1,7 +1,9 @@ import { DragDropProvider } from "@dnd-kit/react"; +import { ANALYTICS_EVENTS } from "@posthog/shared"; import type { Task } from "@posthog/shared/domain-types"; import type React from "react"; import { useCallback, useEffect } from "react"; +import { track } from "../../../shell/analytics"; import { useDragDropHandlers } from "../hooks/useDragDropHandlers"; import { usePanelKeyboardShortcuts } from "../hooks/usePanelKeyboardShortcuts"; import { @@ -75,6 +77,10 @@ const PanelLayoutRenderer: React.FC<{ const handleAddBrowser = useCallback( (panelId: string) => { layoutState.addBrowserTab(taskId, panelId); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "user", + has_initial_url: false, + }); }, [layoutState, taskId], ); diff --git a/packages/ui/src/features/panels/components/TabbedPanel.tsx b/packages/ui/src/features/panels/components/TabbedPanel.tsx index 316b6e1a87..189f2d1a12 100644 --- a/packages/ui/src/features/panels/components/TabbedPanel.tsx +++ b/packages/ui/src/features/panels/components/TabbedPanel.tsx @@ -109,6 +109,21 @@ export const TabbedPanel: React.FC = ({ } }; + // Hide the active browser view when a dropdown opens so it doesn't cover the menu + // (WebContentsView is a native layer that ignores CSS z-index). + const handleAddDropdownOpenChange = useCallback( + (open: boolean) => { + const activeTab = content.tabs.find((t) => t.id === content.activeTabId); + if (activeTab?.data?.type === "browser") { + hostClient.browser.setVisible.mutate({ + browserId: activeTab.data.browserId, + visible: !open, + }); + } + }, + [content.tabs, content.activeTabId, hostClient], + ); + const scrollContainerRef = useRef(null); const { ref: droppableRef } = useDroppable({ id: `tab-bar-${panelId}`, @@ -171,6 +186,7 @@ export const TabbedPanel: React.FC = ({ {content.tabs.map((tab, index) => ( = ({ badge={tab.badge} /> ))} - {content.droppable && (onAddTerminal || onAddBrowser) && ( - - - - {}}> - - - - - - {onAddTerminal && ( + {content.droppable && + (onAddTerminal || onAddBrowser) && + (onAddTerminal && onAddBrowser ? ( + + + + {}}> + + + + + New terminal - )} - {onAddBrowser && ( New browser tab - )} - - - )} + + + ) : ( + + {})} + > + + + + ))} {/* Spacer to increase DND area */} {content.droppable && ( @@ -242,6 +270,7 @@ export const TabbedPanel: React.FC = ({ {rightContent} {content.droppable && onAddTerminal && ( diff --git a/packages/ui/src/features/panels/panelLayoutStore.ts b/packages/ui/src/features/panels/panelLayoutStore.ts index 530fd1656e..63349a1cea 100644 --- a/packages/ui/src/features/panels/panelLayoutStore.ts +++ b/packages/ui/src/features/panels/panelLayoutStore.ts @@ -21,12 +21,15 @@ import { splitPanelTree, } from "@posthog/core/panels/panelLayoutTransforms"; import { createFileTabId } from "@posthog/core/panels/panelStoreHelpers"; -import { findTabInTree } from "@posthog/core/panels/panelTree"; import { ANALYTICS_EVENTS, getFileExtension } from "@posthog/shared"; import { persist } from "zustand/middleware"; import { createWithEqualityFn } from "zustand/traditional"; import { track } from "../../shell/analytics"; -import { updateTaskLayout } from "./panelStoreHelpers"; +import { + findTabInTree, + updateTaskLayout, + updateTreeNode, +} from "./panelStoreHelpers"; import type { PanelNode, Tab } from "./panelTypes"; export interface TaskLayout { @@ -100,6 +103,7 @@ export interface PanelLayoutStore { addTerminalTab: (taskId: string, panelId: string) => void; addBrowserTab: (taskId: string, panelId: string, url?: string) => void; openBrowserUrl: (taskId: string, url: string) => void; + updateBrowserTabUrl: (taskId: string, browserId: string, url: string) => void; addActionTab: ( taskId: string, panelId: string, @@ -389,10 +393,6 @@ export const usePanelLayoutStore = createWithEqualityFn()( coreAddBrowserTab(layout, panelId, url) as Partial, ), ); - track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { - source: url ? "window_open" : "user", - has_initial_url: Boolean(url), - }); }, openBrowserUrl: (taskId, url) => { @@ -405,10 +405,34 @@ export const usePanelLayoutStore = createWithEqualityFn()( (l) => coreAddBrowserTab(l, panelId, url) as Partial, ), ); - track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { - source: "chat_link", - has_initial_url: true, - }); + }, + + updateBrowserTabUrl: (taskId, browserId, url) => { + set((state) => + updateTaskLayout(state, taskId, (layout) => { + const location = findTabInTree(layout.panelTree, browserId); + if (!location) return {}; + const updatedTree = updateTreeNode( + layout.panelTree, + location.panelId, + (panel) => { + if (panel.type !== "leaf") return panel; + return { + ...panel, + content: { + ...panel.content, + tabs: panel.content.tabs.map((t) => + t.id === browserId && t.data.type === "browser" + ? { ...t, data: { ...t.data, url } } + : t, + ), + }, + }; + }, + ); + return { panelTree: updatedTree }; + }), + ); }, addActionTab: (taskId, panelId, action) => { diff --git a/packages/ui/src/features/panels/panelStoreHelpers.ts b/packages/ui/src/features/panels/panelStoreHelpers.ts index d450e912d6..10bf1637d5 100644 --- a/packages/ui/src/features/panels/panelStoreHelpers.ts +++ b/packages/ui/src/features/panels/panelStoreHelpers.ts @@ -1,4 +1,5 @@ import * as core from "@posthog/core/panels/panelStoreHelpers"; +import * as coreTree from "@posthog/core/panels/panelTree"; import type { TaskLayout } from "./panelLayoutStore"; import type { GroupPanel, LeafPanel, PanelNode, Tab } from "./panelTypes"; @@ -67,6 +68,17 @@ export const isFileTabActiveInTree = core.isFileTabActiveInTree as ( filePath: string, ) => boolean; +export const findTabInTree = coreTree.findTabInTree as ( + node: PanelNode, + tabId: string, +) => { panelId: string; tab: Tab } | null; + +export const updateTreeNode = coreTree.updateTreeNode as ( + node: PanelNode, + targetId: string, + updateFn: (node: PanelNode) => PanelNode, +) => PanelNode; + export function updateTaskLayout( state: { taskLayouts: Record }, taskId: string, diff --git a/packages/ui/src/features/sessions/components/GitActionResult.tsx b/packages/ui/src/features/sessions/components/GitActionResult.tsx index f991a9a91c..3f166268df 100644 --- a/packages/ui/src/features/sessions/components/GitActionResult.tsx +++ b/packages/ui/src/features/sessions/components/GitActionResult.tsx @@ -6,7 +6,7 @@ import { } from "@phosphor-icons/react"; import { useHostTRPC } from "@posthog/host-router/react"; import type { GitActionType } from "@posthog/ui/features/sessions/components/GitActionMessage"; -import { openExternalUrl } from "@posthog/ui/shell/openExternal"; +import { useOpenUrl } from "@posthog/ui/shell/useOpenUrl"; import { Badge, Box, Button, Flex, Text } from "@radix-ui/themes"; import { useQuery } from "@tanstack/react-query"; @@ -43,9 +43,7 @@ export function GitActionResult({ ), ); - const handleOpenUrl = (url: string) => { - openExternalUrl(url); - }; + const handleOpenUrl = useOpenUrl(); const showCommit = commitInfo != null; const showPrLink = repoInfo?.compareUrl != null; diff --git a/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx b/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx index d7dd239b79..ee708e2c5e 100644 --- a/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx +++ b/packages/ui/src/features/sessions/components/session-update/AgentMessage.tsx @@ -125,10 +125,19 @@ function ChatLink({ e.preventDefault(); if (taskId) { openBrowserUrl(taskId, href); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "embedded_browser", + }); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "chat_link", + has_initial_url: true, + }); + } else { + openExternalUrl(href); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "system_browser", + }); } - track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { - destination: "embedded_browser", - }); }, [href, taskId, openBrowserUrl], ); @@ -143,10 +152,21 @@ function ChatLink({ if (!result.action) return; switch (result.action.type) { case "open-embedded": - if (taskId) openBrowserUrl(taskId, href); - track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { - destination: "embedded_browser", - }); + if (taskId) { + openBrowserUrl(taskId, href); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "chat_link", + has_initial_url: true, + }); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "embedded_browser", + }); + } else { + openExternalUrl(href); + track(ANALYTICS_EVENTS.LINK_CLICKED_IN_CHAT, { + destination: "system_browser", + }); + } break; case "open-external": openExternalUrl(href); @@ -165,7 +185,7 @@ function ChatLink({ [href, taskId, openBrowserUrl, hostClient], ); - return ( + const anchor = ( ); + + if (!href) return anchor; + + return ( + + {anchor} + + ); } const agentComponents: Partial = { diff --git a/packages/ui/src/features/sessions/components/session-update/FetchToolView.tsx b/packages/ui/src/features/sessions/components/session-update/FetchToolView.tsx index 6b4a278a5f..ff4fdb13b7 100644 --- a/packages/ui/src/features/sessions/components/session-update/FetchToolView.tsx +++ b/packages/ui/src/features/sessions/components/session-update/FetchToolView.tsx @@ -1,5 +1,6 @@ import { Globe } from "@phosphor-icons/react"; import { Link } from "@radix-ui/themes"; +import { useOpenUrl } from "../../../../shell/useOpenUrl"; import { ToolRow } from "./ToolRow"; import { ContentPre, @@ -25,6 +26,7 @@ export function FetchToolView({ turnComplete, ); + const openUrl = useOpenUrl(); const resourceLink = findResourceLink(content); const fetchedContent = getContentText(content) ?? ""; const hasContent = fetchedContent.trim().length > 0; @@ -43,10 +45,12 @@ export function FetchToolView({ > e.stopPropagation()} + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + openUrl(url); + }} > {url} diff --git a/packages/ui/src/shell/useOpenUrl.ts b/packages/ui/src/shell/useOpenUrl.ts new file mode 100644 index 0000000000..4853dae0f2 --- /dev/null +++ b/packages/ui/src/shell/useOpenUrl.ts @@ -0,0 +1,26 @@ +import { useParams } from "@tanstack/react-router"; +import { useCallback } from "react"; +import { usePanelLayoutStore } from "../features/panels/panelLayoutStore"; +import { useSessionTaskId } from "../features/sessions/useSessionTaskId"; +import { openExternalUrl } from "./openExternal"; + +const HTTP_RE = /^https?:\/\//i; + +export function useOpenUrl(): (url: string) => void { + const sessionTaskId = useSessionTaskId(); + const { taskId: routeTaskId } = useParams({ strict: false }); + const taskId = + sessionTaskId ?? (typeof routeTaskId === "string" ? routeTaskId : null); + const openBrowserUrl = usePanelLayoutStore((s) => s.openBrowserUrl); + + return useCallback( + (url: string) => { + if (HTTP_RE.test(url) && taskId) { + openBrowserUrl(taskId, url); + } else { + openExternalUrl(url); + } + }, + [taskId, openBrowserUrl], + ); +} diff --git a/packages/ui/tailwind.config.js b/packages/ui/tailwind.config.js index 6e88fa839b..63cf70f1a5 100644 --- a/packages/ui/tailwind.config.js +++ b/packages/ui/tailwind.config.js @@ -14,6 +14,7 @@ module.exports = { extend: { animation: { "sync-rotate": "sync-rotate 3s ease-in-out infinite", + "browser-loading": "browser-loading 1.4s ease-in-out infinite", }, keyframes: { "sync-rotate": { @@ -22,6 +23,10 @@ module.exports = { "66%": { transform: "rotate(360deg)" }, "100%": { transform: "rotate(360deg)" }, }, + "browser-loading": { + "0%": { transform: "translateX(-200%)" }, + "100%": { transform: "translateX(400%)" }, + }, }, colors: { posthog: { From 66a2e2ee8f4b3c3a0f406a755adc1642ed194307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Fri, 19 Jun 2026 23:53:37 -0600 Subject: [PATCH 08/11] fix(browser): remove stale analytics store tests and useParams from useOpenUrl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Analytics for BROWSER_TAB_OPENED is tracked at call sites (PanelLayout, BrowserPanel, AgentMessage) with source context — not in the store action where source is unknown. Remove the two tests that incorrectly expected the store to fire the event. useOpenUrl no longer reads taskId from TanStack Router params; useSessionTaskId() alone is sufficient since all real call sites are inside SessionTaskIdProvider, and useParams({ strict: false }) was throwing in test environments without a RouterProvider. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../features/panels/panelLayoutStore.test.ts | 23 ------------------- packages/ui/src/shell/useOpenUrl.ts | 6 +---- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/packages/ui/src/features/panels/panelLayoutStore.test.ts b/packages/ui/src/features/panels/panelLayoutStore.test.ts index f6780949e5..4dfccf6f46 100644 --- a/packages/ui/src/features/panels/panelLayoutStore.test.ts +++ b/packages/ui/src/features/panels/panelLayoutStore.test.ts @@ -5,7 +5,6 @@ vi.mock("@posthog/ui/shell/analytics", () => ({ setActiveTaskContext: vi.fn(), })); -import { ANALYTICS_EVENTS } from "@posthog/shared/analytics-events"; import { track } from "@posthog/ui/shell/analytics"; import { usePanelLayoutStore } from "./panelLayoutStore"; import { @@ -560,28 +559,6 @@ describe("panelLayoutStore", () => { vi.mocked(track).mockClear(); }); - it("tracks BROWSER_TAB_OPENED with source=user when no URL provided", () => { - usePanelLayoutStore.getState().addBrowserTab("task-1", "main-panel"); - - expect(track).toHaveBeenCalledOnce(); - expect(track).toHaveBeenCalledWith(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { - source: "user", - has_initial_url: false, - }); - }); - - it("tracks BROWSER_TAB_OPENED with source=window_open when URL provided", () => { - usePanelLayoutStore - .getState() - .addBrowserTab("task-1", "main-panel", "https://example.com"); - - expect(track).toHaveBeenCalledOnce(); - expect(track).toHaveBeenCalledWith(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { - source: "window_open", - has_initial_url: true, - }); - }); - it("adds a browser tab to the panel", () => { usePanelLayoutStore .getState() diff --git a/packages/ui/src/shell/useOpenUrl.ts b/packages/ui/src/shell/useOpenUrl.ts index 4853dae0f2..ff506cf37e 100644 --- a/packages/ui/src/shell/useOpenUrl.ts +++ b/packages/ui/src/shell/useOpenUrl.ts @@ -1,4 +1,3 @@ -import { useParams } from "@tanstack/react-router"; import { useCallback } from "react"; import { usePanelLayoutStore } from "../features/panels/panelLayoutStore"; import { useSessionTaskId } from "../features/sessions/useSessionTaskId"; @@ -7,10 +6,7 @@ import { openExternalUrl } from "./openExternal"; const HTTP_RE = /^https?:\/\//i; export function useOpenUrl(): (url: string) => void { - const sessionTaskId = useSessionTaskId(); - const { taskId: routeTaskId } = useParams({ strict: false }); - const taskId = - sessionTaskId ?? (typeof routeTaskId === "string" ? routeTaskId : null); + const taskId = useSessionTaskId(); const openBrowserUrl = usePanelLayoutStore((s) => s.openBrowserUrl); return useCallback( From fd290f654e1ffe6a9a4d507029c6297d38f2e09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Sat, 20 Jun 2026 09:34:03 -0600 Subject: [PATCH 09/11] fix(browser): match new-tab page visual style to error page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align hoglet size (72 → 160 px), font-weight (600 → 700), heading color (#f0f0f0 → #fff), body font-size (13.5 → 14 px), drop-shadow, and footer color so both pages look consistent side-by-side. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../src/main/services/browser/newTabPage.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/code/src/main/services/browser/newTabPage.ts b/apps/code/src/main/services/browser/newTabPage.ts index 95cef86247..03e5d5b778 100644 --- a/apps/code/src/main/services/browser/newTabPage.ts +++ b/apps/code/src/main/services/browser/newTabPage.ts @@ -22,27 +22,29 @@ export function buildNewTabPage(): string { max-width: 460px; } .hog { - width: 72px; - height: 72px; - margin: 0 auto 20px; - opacity: 0.85; + width: 160px; + height: auto; + margin: 0 auto 28px; + filter: drop-shadow(0 8px 32px rgba(0,0,0,.6)); } h1 { font-size: 24px; - font-weight: 600; - color: #f0f0f0; + font-weight: 700; + color: #fff; letter-spacing: -0.3px; margin-bottom: 10px; } p { - font-size: 13.5px; + font-size: 14px; line-height: 1.65; color: #888; + max-width: 400px; } .footer { margin-top: 24px; font-size: 11px; - color: #555; + color: #444; + letter-spacing: 0.5px; } From f127897858752507ec3a2668d6fad2c66c79f845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Sat, 20 Jun 2026 09:54:45 -0600 Subject: [PATCH 10/11] =?UTF-8?q?fix(browser):=20address=20Greptile=20revi?= =?UTF-8?q?ew=20=E2=80=94=20scoped=20onOpenUrl,=20unique=20IDs,=20about:bl?= =?UTF-8?q?ank=20in=20navigate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - onOpenUrl subscription now takes browserId and filters at the router level (same as onNavigate/onTitle/onFavicon), so window.open() in one tab no longer creates N new tabs across all mounted BrowserPanels - BrowserOpenUrlEvent carries browserId; service emits it from the setWindowOpenHandler closure where browserId is in scope - browserId generation adds a random suffix to eliminate collisions when two tabs open within the same millisecond - navigate() applies the same about:blank → welcome-page redirect that create() uses, so typing about:blank in the address bar shows Hedge Browser instead of a truly blank page Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01TpGjPYBD4pgZpsAHjozzsN --- .../code/src/main/services/browser/service.ts | 8 +++++--- .../core/src/panels/panelLayoutTransforms.ts | 2 +- packages/host-router/src/ports/browser.ts | 1 + .../host-router/src/routers/browser.router.ts | 19 +++++++++++-------- .../ui/src/features/browser/BrowserPanel.tsx | 19 +++++++++++-------- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/apps/code/src/main/services/browser/service.ts b/apps/code/src/main/services/browser/service.ts index aeb480f242..05fafe5e0d 100644 --- a/apps/code/src/main/services/browser/service.ts +++ b/apps/code/src/main/services/browser/service.ts @@ -111,7 +111,7 @@ export class BrowserService // Route window.open() into the app as a new tab instead of a native window. view.webContents.setWindowOpenHandler(({ url: targetUrl }) => { if (alive() && this.isSafeUrl(targetUrl)) { - this.emit("openUrl", { url: targetUrl }); + this.emit("openUrl", { browserId, url: targetUrl }); } return { action: "deny" }; }); @@ -252,8 +252,10 @@ export class BrowserService navigate(browserId: string, url: string): void { const entry = this.browsers.get(browserId); if (!entry) return; - entry.view.webContents.loadURL(url).catch((err) => { - log.warn("Failed to navigate", url, err); + const effectiveUrl = + !url || url === "about:blank" ? buildNewTabPage() : url; + entry.view.webContents.loadURL(effectiveUrl).catch((err) => { + log.warn("Failed to navigate", effectiveUrl, err); }); } diff --git a/packages/core/src/panels/panelLayoutTransforms.ts b/packages/core/src/panels/panelLayoutTransforms.ts index b1bb57bd33..0529d35d6a 100644 --- a/packages/core/src/panels/panelLayoutTransforms.ts +++ b/packages/core/src/panels/panelLayoutTransforms.ts @@ -709,7 +709,7 @@ export function addBrowserTab( panelId: string, url = "about:blank", ): Partial { - const browserId = `browser-${Date.now()}`; + const browserId = `browser-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; const updatedTree = updateTreeNode(layout.panelTree, panelId, (panel) => { if (panel.type !== "leaf") return panel; return addTabToPanel(panel, { diff --git a/packages/host-router/src/ports/browser.ts b/packages/host-router/src/ports/browser.ts index 9630654907..998fd4b271 100644 --- a/packages/host-router/src/ports/browser.ts +++ b/packages/host-router/src/ports/browser.ts @@ -20,6 +20,7 @@ export interface BrowserFaviconEvent { } export interface BrowserOpenUrlEvent { + browserId: string; url: string; } diff --git a/packages/host-router/src/routers/browser.router.ts b/packages/host-router/src/routers/browser.router.ts index 593cc5f4b0..664b15c1cc 100644 --- a/packages/host-router/src/routers/browser.router.ts +++ b/packages/host-router/src/routers/browser.router.ts @@ -164,12 +164,15 @@ export const browserRouter = router({ ); }), - onOpenUrl: publicProcedure.subscription(({ ctx, signal }) => { - const service = ctx.container.get(BROWSER_SERVICE); - return eventToAsyncIterator( - (l) => service.on("openUrl", l), - (l) => service.off("openUrl", l), - signal, - ); - }), + onOpenUrl: publicProcedure + .input(browserIdInput) + .subscription(({ ctx, input, signal }) => { + const service = ctx.container.get(BROWSER_SERVICE); + return eventToAsyncIterator( + (l) => service.on("openUrl", l), + (l) => service.off("openUrl", l), + signal, + (data) => data.browserId === input.browserId, + ); + }), }); diff --git a/packages/ui/src/features/browser/BrowserPanel.tsx b/packages/ui/src/features/browser/BrowserPanel.tsx index 5709c1e48c..68fe640b44 100644 --- a/packages/ui/src/features/browser/BrowserPanel.tsx +++ b/packages/ui/src/features/browser/BrowserPanel.tsx @@ -196,15 +196,18 @@ export function BrowserPanel({ // Open window.open() requests as new browser tabs in the same panel. useSubscription( - trpc.browser.onOpenUrl.subscriptionOptions(undefined, { - onData: (data) => { - addBrowserTab(taskId, panelId, data.url); - track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { - source: "window_open", - has_initial_url: true, - }); + trpc.browser.onOpenUrl.subscriptionOptions( + { browserId }, + { + onData: (data) => { + addBrowserTab(taskId, panelId, data.url); + track(ANALYTICS_EVENTS.BROWSER_TAB_OPENED, { + source: "window_open", + has_initial_url: true, + }); + }, }, - }), + ), ); return ( From e714a2c62302c11b292e632610f9112254a68cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Andr=C3=A9s=20Leiva=20Castillo?= Date: Mon, 22 Jun 2026 09:49:06 -0600 Subject: [PATCH 11/11] fix(browser): grant permission requests from localhost in Hedge Browser Local dev servers at http://localhost need browser APIs like clipboard-read and notifications. Without a permission handler, Electron silently denies all such requests since there is no prompt UI. Allow them for localhost / 127.0.0.1; deny everything else. Co-Authored-By: Claude Sonnet 4.6 --- .../code/src/main/services/browser/service.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/code/src/main/services/browser/service.ts b/apps/code/src/main/services/browser/service.ts index 05fafe5e0d..171abba0bb 100644 --- a/apps/code/src/main/services/browser/service.ts +++ b/apps/code/src/main/services/browser/service.ts @@ -8,7 +8,14 @@ import type { import { MAIN_WINDOW_SERVICE } from "@posthog/platform/main-window"; import { TypedEventEmitter } from "@posthog/shared"; // biome-ignore lint/style/noRestrictedImports: Electron-only by design; see host-boundary-allowlist.json -import { clipboard, Menu, MenuItem, shell, WebContentsView } from "electron"; +import { + clipboard, + Menu, + MenuItem, + session, + shell, + WebContentsView, +} from "electron"; import { inject, injectable, preDestroy } from "inversify"; import type { ElectronMainWindow } from "../../platform-adapters/electron-main-window"; import { logger } from "../../utils/logger"; @@ -41,6 +48,29 @@ export class BrowserService private readonly mainWindow: ElectronMainWindow, ) { super(); + this.setupSession(); + } + + // Grant browser permission requests (clipboard, notifications, etc.) for + // localhost origins — this is a developer tool and local dev servers need + // these APIs. All other origins are denied because we have no permission + // prompt UI. + private setupSession(): void { + const browserSession = session.fromPartition("persist:browser"); + browserSession.setPermissionRequestHandler( + (webContents, _permission, callback) => { + try { + const { hostname } = new URL(webContents.getURL()); + if (hostname === "localhost" || hostname === "127.0.0.1") { + callback(true); + return; + } + } catch { + // ignore malformed URLs + } + callback(false); + }, + ); } private static readonly SAFE_PROTOCOLS = new Set(["https:", "http:"]);