diff --git a/clients/web/src/components/views/InspectorView/InspectorView.test.tsx b/clients/web/src/components/views/InspectorView/InspectorView.test.tsx
index ec979431..99197eaf 100644
--- a/clients/web/src/components/views/InspectorView/InspectorView.test.tsx
+++ b/clients/web/src/components/views/InspectorView/InspectorView.test.tsx
@@ -1343,6 +1343,39 @@ describe("InspectorView", () => {
).toBeInTheDocument();
});
+ it("opens the monitoring column when a connection is established", async () => {
+ monitorWide.value = true;
+ const { rerender } = renderWithMantine(
+ ,
+ );
+ // Disconnected: the column is closed.
+ expect(
+ screen.queryByRole("button", { name: "Close monitoring column" }),
+ ).toBeNull();
+
+ // Connecting opens it (the disconnected → connected transition).
+ rerender();
+ expect(
+ await screen.findByRole("button", { name: "Close monitoring column" }),
+ ).toBeInTheDocument();
+ });
+
+ it("does not auto-open on a mount that starts already connected", () => {
+ // No disconnected → connected transition, and no stored preference, so the
+ // column stays closed (a user who closed it isn't fought on remount).
+ monitorWide.value = true;
+ renderWithMantine();
+ expect(
+ screen.queryByRole("button", { name: "Close monitoring column" }),
+ ).toBeNull();
+ });
+
it("pins the monitor group into the column and removes it from the header", async () => {
monitorWide.value = true;
renderWithMantine();
diff --git a/clients/web/src/components/views/InspectorView/InspectorView.tsx b/clients/web/src/components/views/InspectorView/InspectorView.tsx
index bd520298..b61f1ed3 100644
--- a/clients/web/src/components/views/InspectorView/InspectorView.tsx
+++ b/clients/web/src/components/views/InspectorView/InspectorView.tsx
@@ -1,4 +1,11 @@
-import { useMemo, useState, type ReactNode, type Ref } from "react";
+import {
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+ type ReactNode,
+ type Ref,
+} from "react";
import {
AppShell,
Box,
@@ -647,6 +654,23 @@ export function InspectorView({
getInitialValueInEffect: false,
});
+ // Open the monitoring column when a connection is established (#1616). Gated on
+ // the disconnected → connected *transition* (via the ref) rather than the
+ // "connected" state itself, so it fires on an actual connect — not on every
+ // render while connected, and not on a mount that starts already-connected
+ // (which would fight a user who closed it). The column still only *appears*
+ // when wide + a monitor tab is available (`effectivePinned`); this just sets
+ // the preference. Closing it stays closed until the next connect, since this
+ // effect only re-runs when `connectionStatus` changes.
+ const wasConnectedRef = useRef(connectionStatus === "connected");
+ useEffect(() => {
+ const isConnected = connectionStatus === "connected";
+ if (isConnected && !wasConnectedRef.current) {
+ setMonitorPinned(true);
+ }
+ wasConnectedRef.current = isConnected;
+ }, [connectionStatus, setMonitorPinned]);
+
const appTools = useMemo(() => {
return tools.filter((tool) => {
try {