Depends on: #425
Coordinate with: #487 so both docked sides share one centre-width policy and shell resize lifecycle.
Goal
Replace the current collection of unrelated right-side overlays/panes with one shell-owned, foldable desktop right inspector.
The inspector is the single desktop host for contextual content such as:
- cell detail;
- rows/detail viewer content currently using the cell-drawer scaffold;
- function, aggregate-function, data-type and other Reference documentation;
- future contextual diagnostic/detail tools that genuinely belong in the same right-side surface.
On desktop, the inspector is docked beside the main Query/Dashboard surface. It consumes normal layout width and pushes the centre surface left. It must not cover the editor or Dashboard with a backdrop.
The user opens/closes it through one vertical chevron handle at its left edge. Contextual actions such as clicking a result cell or invoking Reference/F1 still open the appropriate inspector tool automatically.
Mobile keeps its existing mobile/modal presentation and is not redesigned by this issue.
Current problem
The repository already shares some low-level drawer chrome, but the user experience remains split:
- cell detail and rows viewer compose the drawer with modal backdrop/focus behaviour;
- documentation is a separate persistent non-modal pane;
- cell and documentation widths are stored independently;
- each consumer owns its own DOM insertion, lifecycle, close control and Escape handling;
- more contextual tools would create more independent right-side panels or overlays.
The result is inconsistent on desktop and wastes ultra-wide screen space: useful contextual information covers the editor instead of living beside it.
Final desktop shell geometry
The full-width application header remains above the shell.
Below it:
[right inspector closed]
[left navigation] [main Query/Dashboard surface] [chevron handle]
[right inspector open]
[left navigation] [main Query/Dashboard surface] [chevron] [right inspector]
When #487's left focused drawer is also open:
[rail] [left focused drawer] [main surface] [chevron] [right inspector]
The inspector begins below the header and uses the complete remaining vertical height.
On desktop:
- no inspector tool creates a backdrop;
- no inspector tool covers the centre surface;
- no inspector tool traps focus;
- exactly one right inspector host exists per application shell/document;
- only one inspector tool is visible at a time.
Fold control
Use one narrow vertical chevron handle attached to the inspector's left boundary.
States:
closed: chevron points left, meaning open
open: chevron points right, meaning fold closed
Requirements:
- the handle remains visible at the right edge when the inspector is closed;
- when open, the handle moves with the inspector's left edge;
- clicking it toggles the inspector without changing the active tool/content;
- folding closed preserves valid tool state in memory for the session;
- reopening restores the most recently active still-valid tool;
- do not add separate top-bar
Open inspector or Function help buttons merely to control panel visibility;
- remove redundant per-tool
X close buttons from desktop inspector chrome;
- existing contextual triggers remain: cell click, rows action, F1/reference actions, completion/hover links, schema type-reference links and similar feature-specific entry points.
The handle must have an accessible name reflecting its state, such as Open details panel or Close details panel.
Inspector tools
Define a narrow tool registry rather than allowing each feature to append an arbitrary panel to document.body.
Suggested initial IDs:
type RightInspectorToolId =
| 'cell'
| 'rows'
| 'reference';
Suggested shell-facing API:
interface OpenRightInspectorRequest<T = unknown> {
tool: RightInspectorToolId;
payload: T;
initiator?: Element | null;
}
openRightInspector(request: OpenRightInspectorRequest): void;
activateRightInspectorTool(tool: RightInspectorToolId): void;
foldRightInspector(): void;
unfoldRightInspector(): void;
closeRightInspectorTool(tool: RightInspectorToolId): void;
The shell owns geometry and active-tool selection. Each tool owns only its content model, rendering and validity lifecycle.
Do not expose inspector DOM internals to result, documentation or Dashboard application code.
Tool navigation
The inspector header displays the active tool title.
When more than one valid tool currently has session content, provide compact tabs or an equivalent accessible selector:
Rules:
- only tools with live/available content need to appear;
- opening a new tool activates it and unfolds the inspector;
- opening another cell replaces the current Cell content rather than creating another Cell tab;
- opening another documentation target replaces the current Reference entry while preserving Reference's existing back stack;
- switching tools must not destroy valid inactive tool state;
- closing one tool activates the most recently used remaining tool;
- if no tool remains, fold the inspector closed;
- the fold chevron is panel-level chrome, not a tool tab.
Cell detail tool
Migrate current single-cell detail into the inspector.
Requirements:
- clicking a supported result cell opens/unfolds the inspector and activates Cell;
- preserve current formatting, copy and structured-value rendering behaviour;
- identify the originating result through a stable result-generation token plus tab/query identity;
- replacing/rerunning the originating result invalidates the Cell tool;
- closing the originating tab invalidates it;
- switching workspaces or signing out invalidates it;
- stale asynchronous formatting/render work cannot repaint a newer Cell payload;
- no modal backdrop or focus trap on desktop;
- opening Cell does not steal editor selection unnecessarily;
- folding/reopening preserves Cell only while its origin remains valid.
A stale cell must never continue to appear as though it belongs to the current result.
Rows/detail viewer tool
Migrate every existing rows/detail consumer that currently shares the cell-drawer chrome.
Requirements:
- opening a rows/detail view unfolds the inspector and activates Rows;
- preserve current table/detail rendering, paging/copy actions and result semantics;
- tie validity to the originating result generation;
- result replacement, tab closure, workspace switch or sign-out invalidates the tool;
- no desktop modal backdrop;
- one Rows tool instance per shell; a new request replaces its payload.
If a current consumer truly requires a modal decision rather than passive inspection, leave that decision dialog modal and move only its passive result/detail content into the inspector.
Reference documentation tool
Move the existing persistent documentation pane into the shared inspector host without losing its mature behaviour.
Preserve:
- one Reference session per document/shell;
- loading, found, missing and unavailable states;
- Retry;
- related/alias navigation;
- disambiguation lists;
- bounded back stack;
- safe Markdown rendering;
- embedded code-viewer lifecycle;
- stale lookup token/generation protection;
- existing catalog capability semantics;
- contextual opening from F1, hover, completion, schema type-reference and future Reference actions.
Reference lifecycle differs from result-bound tools:
- switching Query tabs does not invalidate Reference;
- switching Query/Dashboard surfaces may preserve Reference;
- changing workspace may preserve it only when the connection/catalog identity is unchanged and the current target remains meaningful;
- connection change, catalog invalidation or sign-out closes/invalidates Reference and destroys embedded viewers;
- a fresh external Reference open starts a new browsing session according to current semantics.
Reference back-stack state remains owned by the Reference tool, not the inspector shell.
Width and resizing
The inspector is resized from its left edge.
Suggested bounds:
const RIGHT_INSPECTOR_DEFAULT_PX = 480;
const RIGHT_INSPECTOR_MIN_PX = 320;
const RIGHT_INSPECTOR_MAX_VIEWPORT_RATIO = 0.55;
const MAIN_SURFACE_MIN_PX = 640;
Final clamping must account for:
The inspector must never force the main surface to negative or unusable width. When the viewport cannot fit the saved inspector width, clamp the effective width without destroying the saved preferred width.
The left-edge resize separator must support pointer and keyboard operation and use the repository's shared splitter controller.
Do not use arbitrary delayed window-resize events. Notify centre content through ResizeObserver or established explicit layout hooks.
Preference migration
Current state has separate persisted widths:
Replace them with one browser preference:
Use a deterministic compatibility read:
- use a valid
rightInspectorPx when present;
- otherwise use valid
docPanePx;
- otherwise use valid
cellDrawerPx;
- otherwise use the default.
Write only rightInspectorPx after this feature lands. Keep legacy keys readable for the compatibility period required by repository conventions; do not write them independently again.
Inspector open/closed state and active payload are session state, not workspace persistence. Width is a browser preference and must never enter StoredWorkspaceV3, portable bundles or share links.
Suggested state
interface RightInspectorState {
folded: boolean;
preferredWidthPx: number;
activeTool: RightInspectorToolId | null;
availableTools: RightInspectorToolId[];
}
Tool payloads and lifecycle tokens remain in their tool controllers, not in one untyped shell object.
folded means hidden while valid content may remain cached. activeTool === null means there is no valid inspector content.
Surface and workspace behaviour
Query -> Dashboard
- preserve Reference when valid;
- invalidate or hide Cell/Rows when their result origin is no longer valid under existing result ownership;
- never destroy the Query surface merely to show/hide the inspector;
- resize the Dashboard layout when the inspector opens/closes.
Dashboard -> Query
- preserve Reference;
- restore a valid folded Cell/Rows session only when the same originating result still exists;
- resize CodeMirror/results immediately through normal layout hooks.
Workspace switch
- invalidate all result-bound tools;
- clear initiators from the old shell/workspace;
- preserve only connection-scoped Reference content when explicitly safe; otherwise close it;
- late async callbacks from the previous workspace cannot repaint the inspector.
Sign-out / auth loss
- invalidate every tool;
- destroy embedded viewers/listeners;
- cancel active resize;
- remove/fold inspector content before showing Login;
- late writes or lookups cannot remount it.
Escape and focus behaviour
Desktop inspector is non-modal.
- focus is allowed to move between inspector and editor/results normally;
- no focus trap;
- Escape while focus is inside the inspector folds it closed;
- that Escape must call
preventDefault/stopPropagation through the existing topmost-overlay/shortcut contract so it does not also cancel a running query;
- Escape outside the inspector follows existing global shortcut semantics;
- folding through the chevron restores focus to the most recent connected initiator when appropriate;
- switching tools moves focus only when initiated through keyboard navigation or required for accessibility;
- the resize separator and chevron are keyboard reachable with visible focus.
Keyboard/accessibility
Inspector host:
role="complementary"
aria-label="Details and reference"
Tool selector:
- proper tabs/tablist semantics when rendered as tabs;
- active state announced;
- unavailable tools are absent rather than disabled placeholders.
Resize separator:
role="separator"
aria-orientation="vertical"
aria-valuemin / aria-valuemax / aria-valuenow
Keys:
- Left/Right Arrow resize by a small step;
- Shift+Left/Right resize by a larger step;
- Home uses minimum width;
- End uses current maximum width.
The chevron's visible direction and accessible label must stay in sync.
Mobile
At the existing mobile breakpoint:
- do not force the desktop docked inspector geometry;
- retain current mobile/full-screen/modal cell and detail experiences where needed;
- Reference may use the established mobile pane pattern;
- reuse the same tool content/controllers when practical;
- desktop width/fold preferences remain stored but do not control mobile layout.
This issue must not make the mobile centre surface permanently narrower.
Main-surface reflow
Opening, folding or resizing the inspector must correctly reflow:
- CodeMirror/editor measurement;
- result table columns and virtualised rows;
- editor/results split layout;
- Dashboard grids, flow layouts and charts;
- sticky toolbars/filter bars;
- detached or fullscreen views where applicable.
A presentation change must not cancel a running editor query or Dashboard execution.
Implementation boundaries
App shell
Owns:
- inspector host and chevron;
- open/fold geometry;
- active tool selection;
- width preference and resize separator;
- interaction with left navigation and main minimum width;
- high-level teardown on workspace/sign-out.
Tool controllers
Own:
- typed payload;
- content rendering;
- result/catalog validity;
- async generation tokens;
- tool-specific back stacks/viewers/actions;
- initiator focus restoration metadata.
Existing feature call sites
Call openRightInspector() with typed payloads. They must not append panels/backdrops directly or set shell widths.
Shared drawer module
Refactor or retire buildDrawerChrome/attachDrawerResize only as needed. Preserve reusable content/chrome helpers, but the shell becomes the owner of desktop panel geometry.
Migration plan
- Add shell inspector host, state, chevron and unified width preference.
- Move Reference into the host while preserving all tests and behaviour.
- Move Cell into the host and remove its desktop backdrop/focus trap.
- Move Rows/detail consumers.
- Remove obsolete independent desktop pane insertion, close buttons and width writes.
- Keep mobile-specific composition behind the existing breakpoint.
- Verify simultaneous left/right docking and both Query/Dashboard surfaces.
Do not leave two desktop inspector implementations active behind different entry points.
Tests
Shell and fold state
- one inspector host per shell/document;
- closed state leaves only the chevron and consumes no panel width;
- open state reduces centre width;
- chevron direction/label is correct;
- folding preserves valid tool state;
- no desktop backdrop or focus trap exists;
- left and right docked panels coexist within centre-width limits.
Tool selection
- opening Cell/Rows/Reference unfolds and activates it;
- opening another payload replaces only that tool's payload;
- switching tools preserves valid inactive state;
- closing one activates the most recent remaining tool;
- no valid tools folds the inspector;
- duplicate independent panels cannot be created.
Cell and Rows validity
- result rerun invalidates stale content;
- result/tab/workspace removal invalidates it;
- stale async work cannot repaint;
- copy/format/detail behaviour remains intact;
- desktop no longer uses a modal backdrop;
- mobile behaviour remains intact.
Reference
- loading/found/missing/unavailable/Retry remain;
- back stack, aliases, related links and disambiguation remain;
- embedded viewers are destroyed on retarget/close;
- stale lookups are ignored;
- surface switching preserves valid Reference;
- sign-out/catalog invalidation tears it down.
Width and preference migration
rightInspectorPx restores and clamps;
- fallback reads
docPanePx, then cellDrawerPx;
- only the unified key is written;
- effective viewport clamping does not overwrite preferred width;
- resize cancellation/window blur leave no listeners;
- keyboard resizing matches pointer resizing.
Escape/focus/accessibility
- Escape inside folds inspector only;
- it does not also cancel a query;
- Escape outside retains current shortcuts;
- initiator focus restoration is safe;
- complementary, tabs, separator and chevron semantics are correct.
Reflow and regression
- editor/results/Dashboard resize correctly;
- opening/folding never cancels execution;
- Query surface state survives Dashboard round trips;
- existing cell, rows and Reference triggers still work;
- no detached/fullscreen regression;
- no mobile regression.
Acceptance criteria
- Desktop has one foldable right inspector for cell, rows/detail and Reference content.
- The inspector is docked, consumes layout width and never overlays the desktop editor/Dashboard.
- One chevron handle opens/folds the whole inspector; redundant desktop open/close controls are removed.
- Contextual triggers automatically open the correct tool.
- Result-bound tools cannot show stale content.
- Reference retains its existing navigation and async safety.
- Width is unified into one browser preference with deterministic migration.
- Left navigation, Query surface and Dashboard surface all reflow correctly.
- Mobile behaviour is unchanged.
Non-goals
- Moving unrelated modal confirmations into the inspector.
- Making several inspector tools visible side by side.
- Persisting inspector payloads in workspace data.
- Redesigning cell/reference content itself beyond required host integration.
- Replacing detached/fullscreen views that serve a different use case.
- Changing mobile navigation or mobile screen structure.
Depends on: #425
Coordinate with: #487 so both docked sides share one centre-width policy and shell resize lifecycle.
Goal
Replace the current collection of unrelated right-side overlays/panes with one shell-owned, foldable desktop right inspector.
The inspector is the single desktop host for contextual content such as:
On desktop, the inspector is docked beside the main Query/Dashboard surface. It consumes normal layout width and pushes the centre surface left. It must not cover the editor or Dashboard with a backdrop.
The user opens/closes it through one vertical chevron handle at its left edge. Contextual actions such as clicking a result cell or invoking Reference/F1 still open the appropriate inspector tool automatically.
Mobile keeps its existing mobile/modal presentation and is not redesigned by this issue.
Current problem
The repository already shares some low-level drawer chrome, but the user experience remains split:
The result is inconsistent on desktop and wastes ultra-wide screen space: useful contextual information covers the editor instead of living beside it.
Final desktop shell geometry
The full-width application header remains above the shell.
Below it:
When #487's left focused drawer is also open:
The inspector begins below the header and uses the complete remaining vertical height.
On desktop:
Fold control
Use one narrow vertical chevron handle attached to the inspector's left boundary.
States:
Requirements:
Open inspectororFunction helpbuttons merely to control panel visibility;Xclose buttons from desktop inspector chrome;The handle must have an accessible name reflecting its state, such as
Open details panelorClose details panel.Inspector tools
Define a narrow tool registry rather than allowing each feature to append an arbitrary panel to
document.body.Suggested initial IDs:
Suggested shell-facing API:
The shell owns geometry and active-tool selection. Each tool owns only its content model, rendering and validity lifecycle.
Do not expose inspector DOM internals to result, documentation or Dashboard application code.
Tool navigation
The inspector header displays the active tool title.
When more than one valid tool currently has session content, provide compact tabs or an equivalent accessible selector:
Rules:
Cell detail tool
Migrate current single-cell detail into the inspector.
Requirements:
A stale cell must never continue to appear as though it belongs to the current result.
Rows/detail viewer tool
Migrate every existing rows/detail consumer that currently shares the cell-drawer chrome.
Requirements:
If a current consumer truly requires a modal decision rather than passive inspection, leave that decision dialog modal and move only its passive result/detail content into the inspector.
Reference documentation tool
Move the existing persistent documentation pane into the shared inspector host without losing its mature behaviour.
Preserve:
Reference lifecycle differs from result-bound tools:
Reference back-stack state remains owned by the Reference tool, not the inspector shell.
Width and resizing
The inspector is resized from its left edge.
Suggested bounds:
Final clamping must account for:
The inspector must never force the main surface to negative or unusable width. When the viewport cannot fit the saved inspector width, clamp the effective width without destroying the saved preferred width.
The left-edge resize separator must support pointer and keyboard operation and use the repository's shared splitter controller.
Do not use arbitrary delayed window-resize events. Notify centre content through ResizeObserver or established explicit layout hooks.
Preference migration
Current state has separate persisted widths:
Replace them with one browser preference:
Use a deterministic compatibility read:
rightInspectorPxwhen present;docPanePx;cellDrawerPx;Write only
rightInspectorPxafter this feature lands. Keep legacy keys readable for the compatibility period required by repository conventions; do not write them independently again.Inspector open/closed state and active payload are session state, not workspace persistence. Width is a browser preference and must never enter
StoredWorkspaceV3, portable bundles or share links.Suggested state
Tool payloads and lifecycle tokens remain in their tool controllers, not in one untyped shell object.
foldedmeans hidden while valid content may remain cached.activeTool === nullmeans there is no valid inspector content.Surface and workspace behaviour
Query -> Dashboard
Dashboard -> Query
Workspace switch
Sign-out / auth loss
Escape and focus behaviour
Desktop inspector is non-modal.
preventDefault/stopPropagationthrough the existing topmost-overlay/shortcut contract so it does not also cancel a running query;Keyboard/accessibility
Inspector host:
Tool selector:
Resize separator:
Keys:
The chevron's visible direction and accessible label must stay in sync.
Mobile
At the existing mobile breakpoint:
This issue must not make the mobile centre surface permanently narrower.
Main-surface reflow
Opening, folding or resizing the inspector must correctly reflow:
A presentation change must not cancel a running editor query or Dashboard execution.
Implementation boundaries
App shell
Owns:
Tool controllers
Own:
Existing feature call sites
Call
openRightInspector()with typed payloads. They must not append panels/backdrops directly or set shell widths.Shared drawer module
Refactor or retire
buildDrawerChrome/attachDrawerResizeonly as needed. Preserve reusable content/chrome helpers, but the shell becomes the owner of desktop panel geometry.Migration plan
Do not leave two desktop inspector implementations active behind different entry points.
Tests
Shell and fold state
Tool selection
Cell and Rows validity
Reference
Width and preference migration
rightInspectorPxrestores and clamps;docPanePx, thencellDrawerPx;Escape/focus/accessibility
Reflow and regression
Acceptance criteria
Non-goals