Skip to content

Files Workbench v2: data-loss parity blockers, dirty-state tracking bugs, and recents/diff/empty-state polish #459

@arul28

Description

@arul28

Summary: Files Workbench v2 (FILES_WORKBENCH_V2, default OFF) has multiple data-loss regressions vs v1 plus dirty-state leaks and polish gaps — all Phase-9 default-flip blockers. Relates to the Files tab v2 work shipped in #449. (The agent file-read 'File not found' for brand-new unsaved files is tracked separately as ADE-62.)

Data-loss parity blockers (high):

  • Switching workspace disposes all Monaco models (incl. dirty buffers) with no save/confirm and no beforeunload. The shared registry's workspace-change cleanup calls disposeAll(); dirty window.confirm guards exist only on close-tab/delete; v2 has no beforeunload (v1 has both). FilesWorkbench.tsx:184,:193; WorkspacePicker.tsx:35; FilesPage.tsx:1010,:1794. Fix: intercept WorkspacePicker.onChange to confirm/save when dirty; add beforeunload; guard disposeAll().
  • Failed file rename still closes/disposes the tab and reports success (swallowed rejection). renamePath does await window.ade.files.rename(...).catch(setError) then always runs closeOpenTabsUnder+refreshRoot. FilesWorkbench.tsx:435; FilesExplorer.tsx:247. Fix: rethrow on failure; only run cleanup in the success path.
  • Open editor never refreshes when a file changes on disk — agent edits invisible, Cmd+S clobbers them (reloadToken dead-wired). File-watch effect only invalidates the LRU + tree; CodeViewer reuses one model via getOrCreate; ViewerHost's reloadToken is never threaded by EditorGroups/EditorGroup (defaults 0). FilesWorkbench.tsx:297; ViewerHost.tsx:33; EditorGroups.tsx:74; viewers/CodeViewer.tsx:155. Fix: on files.onChange for an open non-dirty tab, bump a per-path reloadToken through the chain and reset the model; for dirty tabs surface non-destructive 'Reload / Keep mine'.

dirtyPaths lifecycle (medium):

  • dirtyPaths is global (path-only) and never reset on workspace switch — stale 'unsaved' dots/counts leak across workspaces. FilesWorkbench.tsx:97,:184; EditorGroup.tsx:104; StatusBar.tsx:32. Fix: reset on workspace change or key by ${workspaceId}::${path}.
  • Deleting/renaming a dirty file leaves a permanent phantom 'unsaved' count (closeOpenTabsUnder never prunes dirtyPaths). FilesWorkbench.tsx:419; StatusBar.tsx:30. Fix: prune closed paths from dirtyPaths in closeOpenTabsUnder.

Polish (low):

  • Warm-start 'recent files' can list deleted/renamed paths and 404 on click (forgetRecentFile never wired). recentFiles.ts:16; FilesWorkbench.tsx:447,:435; WarmEmptyState.tsx:86.
  • Recents are in-memory only, wiped on every restart — the moment the warm empty state matters most it's always empty. recentFiles.ts:1; WarmEmptyState.tsx:85. Fix: persist per session key (bounded) pruning on rename/delete.
  • Cannot save while reviewing a diff — Save hidden and Cmd+S unbound in diff mode. EditorGroup.tsx:139; viewers/DiffViewer.tsx:26. Fix: keep Save routed to the editor's save() or bind a workbench-level Cmd+S.
  • History: disabled git actions on an off-lane commit show no inline reason (only a per-button title). CommitDetailPanel.tsx:262; historyGitActions.ts:199. Fix: one inline notice explaining the lane mismatch.
  • Files v2 empty/loading states use grayscale logo + faded monochrome copy + font-mono previews — the generic-AI aesthetic the user dislikes. WarmEmptyState.tsx:49; FilesWorkbench.tsx:520; overlays.tsx:237. Fix: accent-tinted mark, higher-contrast copy, concrete next actions; avoid font-mono for non-code previews.

Verification confidence: High for functional items; medium for the aesthetic finding. Flag defaults OFF so not yet hitting users, but these are default-flip blockers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions