Problem
The main multi-tab workspace is currently notebook-centric. The tab strip in Actions.tsx is driven by NotebookContext.useNotebookList(), CurrentDocContext, and openNotebooks.map(...), and each regular tab renders NotebookTabContent.
Notebook diffs currently open as a separate route (/diff/:diffId) outside the notebook tab workspace. We want diff views to render as first-class tabs next to notebooks, and this likely applies to future non-notebook views too.
Current shape
NotebookContext owns open notebook state and exposes openNotebook, removeNotebook, and useNotebookList.
CurrentDocContext stores a single current URI that many call sites assume is a notebook URI.
Actions.tsx renders the main Radix tab strip from openNotebooks.
DRIVE_LINK_STATUS_TAB_URI is a one-off non-notebook tab special case, which proves the UI can host other views but not through a generalized model.
- App Console resolves the current notebook from
currentDoc / visible notebook DOM, so setting currentDoc to a diff URI would likely break current-notebook helpers.
Proposed direction
Introduce a generic open-document/tab model, while keeping notebook data ownership in NotebookContext.
Example shape:
type OpenDocument =
| { type: "notebook"; id: string; uri: string; title: string }
| { type: "notebook-diff"; id: string; diffId: string; title: string }
| { type: "status"; id: string; title: string };
Then update the main workspace tabs to render by document type:
notebook -> NotebookTabContent
notebook-diff -> NotebookDiffContent
status -> DriveLinkStatusTab
CurrentDocContext should either become a generic current document context, or be split so App Console can still reliably resolve the active notebook even when the selected tab is a diff.
Acceptance criteria
- Notebook diff views can open as tabs in the existing main multi-tab workspace.
- Switching between notebook tabs and diff tabs preserves notebook state and scroll/editor state as much as the current tab system does.
- App Console helpers that need a current notebook still resolve a notebook, not an arbitrary active document.
- The one-off Drive Link Status tab can either migrate to the generic model or remain clearly isolated during the transition.
- Non-notebook tabs do not get added to the Open Notebooks sidebar unless that sidebar is intentionally generalized.
Notes
A narrow V0 could add openDiffTabs state inside Actions.tsx as another special case, similar to Drive Link Status. That would validate the UX quickly, but the cleaner long-term fix is a generic document tab abstraction.
Problem
The main multi-tab workspace is currently notebook-centric. The tab strip in
Actions.tsxis driven byNotebookContext.useNotebookList(),CurrentDocContext, andopenNotebooks.map(...), and each regular tab rendersNotebookTabContent.Notebook diffs currently open as a separate route (
/diff/:diffId) outside the notebook tab workspace. We want diff views to render as first-class tabs next to notebooks, and this likely applies to future non-notebook views too.Current shape
NotebookContextowns open notebook state and exposesopenNotebook,removeNotebook, anduseNotebookList.CurrentDocContextstores a single current URI that many call sites assume is a notebook URI.Actions.tsxrenders the main Radix tab strip fromopenNotebooks.DRIVE_LINK_STATUS_TAB_URIis a one-off non-notebook tab special case, which proves the UI can host other views but not through a generalized model.currentDoc/ visible notebook DOM, so settingcurrentDocto a diff URI would likely break current-notebook helpers.Proposed direction
Introduce a generic open-document/tab model, while keeping notebook data ownership in
NotebookContext.Example shape:
Then update the main workspace tabs to render by document type:
notebook->NotebookTabContentnotebook-diff->NotebookDiffContentstatus->DriveLinkStatusTabCurrentDocContextshould either become a generic current document context, or be split so App Console can still reliably resolve the active notebook even when the selected tab is a diff.Acceptance criteria
Notes
A narrow V0 could add
openDiffTabsstate insideActions.tsxas another special case, similar to Drive Link Status. That would validate the UX quickly, but the cleaner long-term fix is a generic document tab abstraction.