Skip to content

fix: prevent dirty file tracker from auto-opening chat-edited files (#298700)#302036

Open
kangarko wants to merge 3 commits intomicrosoft:mainfrom
kangarko:fix/chat-editing-dirty-file-auto-open
Open

fix: prevent dirty file tracker from auto-opening chat-edited files (#298700)#302036
kangarko wants to merge 3 commits intomicrosoft:mainfrom
kangarko:fix/chat-editing-dirty-file-auto-open

Conversation

@kangarko
Copy link

@kangarko kangarko commented Mar 16, 2026

Problem

When the chat agent edits files, those models become dirty while edits stream in. VS Code has generic dirty-model auto-open paths for both text files and notebooks:

  • TextFileEditorTracker for dirty text files
  • NotebookEditorManager for dirty notebooks

Without an explicit suppression, both can auto-open editors even when accessibility.openChatEditedFiles is false.

My original fix addressed the behavior directly from TextFileEditorTracker, but that introduced a files -> chat dependency and broke layers.

Updated fix

This PR now moves the suppression to a generic lower-level seam:

  • IFilesConfigurationService exposes a per-resource runtime override to suppress opening an editor for a dirty resource.
  • TextFileEditorTracker consults that generic override for text files.
  • NotebookEditorManager consults the same generic override for notebooks.
  • Chat editing registers the override from its modified-entry implementations while the entry is chat-owned and keeps it until the resource becomes clean, which avoids the debounce race after a fast accept/save.

Why this should fit better

  • no files -> chat dependency
  • no notebook -> chat special casing beyond consuming a generic service override
  • keeps the dirty-editor auto-open logic generic
  • follows the same disposable override pattern chat already uses with disableAutoSave(...)
  • covers both text documents and notebooks, matching the actual dirty-model entry points in the codebase

Files changed

  • src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts
  • src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts
  • src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts
  • src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedFileEntry.ts
  • src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedDocumentEntry.ts
  • src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry.ts
  • src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts
  • src/vs/workbench/test/common/workbenchTestServices.ts
  • src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts

Fixes #298700

cc @bpasero @roblourens @jrieken @meganrogge

…icrosoft#298700)

When the chat agent creates or modifies files, the text models become
dirty. The TextFileEditorTracker has a general-purpose mechanism that
auto-opens all dirty files as editor tabs after an 800ms debounce.
This bypasses the accessibility.openChatEditedFiles setting (default:
false), causing files to open in tabs even when the user has not opted
in.

The fix adds a check in ensureDirtyTextFilesAreOpened() to skip files
that are part of an active chat editing session. The chat editing
system already manages its own editor lifecycle via the
accessibility.openChatEditedFiles setting — the dirty file tracker
should not interfere with that.

Also fixes stale accessibility help text that still referenced the old
default (true) for the setting.
Copilot AI review requested due to automatic review settings March 16, 2026 10:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an accessibility/configuration regression where chat agent streaming edits mark models dirty and trigger TextFileEditorTracker to auto-open editor tabs, bypassing accessibility.openChatEditedFiles (default false). Also updates chat accessibility help text to reflect the current default behavior.

Changes:

  • Exclude chat-edit-session files from the “open dirty files automatically” tracker logic.
  • Update accessibility help copy describing the default behavior for opening chat-edited files.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts Skips resources associated with chat editing sessions when deciding which dirty models to auto-open as editors.
src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts Updates localized accessibility help text to match the current default setting behavior.

You can also share your feedback on Copilot code review. Take the survey.

// The chat editing system manages its own editor lifecycle via
// the accessibility.openChatEditedFiles setting (#298700).
for (const session of this.chatEditingService?.editingSessionsObs?.get() ?? []) {
if (session.entries.get().some(e => isEqual(e.modifiedURI, resource))) {
Comment on lines +77 to +84
// Skip files being actively modified by a chat editing session.
// The chat editing system manages its own editor lifecycle via
// the accessibility.openChatEditedFiles setting (#298700).
for (const session of this.chatEditingService?.editingSessionsObs?.get() ?? []) {
if (session.entries.get().some(e => isEqual(e.modifiedURI, resource))) {
return false;
}
}
Comment on lines +77 to +84
// Skip files being actively modified by a chat editing session.
// The chat editing system manages its own editor lifecycle via
// the accessibility.openChatEditedFiles setting (#298700).
for (const session of this.chatEditingService?.editingSessionsObs?.get() ?? []) {
if (session.entries.get().some(e => isEqual(e.modifiedURI, resource))) {
return false;
}
}
Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, breaks layers.

@kangarko
Copy link
Author

@microsoft-github-policy-service agree company="MineAcademy"

Introduce a generic per-resource override in FilesConfigurationService that
prevents TextFileEditorTracker from auto-opening dirty resources as editors.
Chat editing uses that override for text document entries while chat owns the
file and keeps it until the file reaches a clean state, which avoids both the
layer violation and the accept/debounce race.

Also add a focused TextFileEditorTracker test for the explicit suppression path.
@kangarko
Copy link
Author

Thanks — updated the PR to remove the files -> chat dependency.

The new version pushes the state into IFilesConfigurationService as a generic per-resource override, and TextFileEditorTracker only consults that lower-level service. Chat registers the override from ChatEditingModifiedDocumentEntry while the entry is modified, and keeps it until the resource becomes clean to avoid the debounce race.

I also replied to the CLA bot, so that check should unblock once it processes.

If you'd prefer this runtime override to live somewhere other than IFilesConfigurationService, I'm happy to move it, but I wanted to keep the same override/disposable pattern that chat already uses there for disableAutoSave(...).

@vs-code-engineering
Copy link

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@jrieken

Matched files:

  • src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedDocumentEntry.ts

if (isEqual(model.resource, this.modifiedURI)) {
updateOpenEditorWhenDirtyDisabled();
}
}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedNotebookEntry.ts and whatever is done here for documents should also work for notebooks

Use the same generic open-when-dirty suppression for notebook chat edits as
for text documents, and have NotebookEditorManager honor that override before
opening dirty notebook editors.
@kangarko
Copy link
Author

Thanks — that notebook point was real.

I re-traced the code paths and found there are two generic dirty-editor auto-open entry points involved here:

  • TextFileEditorTracker for dirty text files
  • NotebookEditorManager for dirty notebooks

So the suppression needed to cover both, not just document entries.

I pushed a follow-up commit that:

  • factors the dirty-editor suppression lifetime into the shared chat modified-entry base,
  • applies it to both ChatEditingModifiedDocumentEntry and ChatEditingModifiedNotebookEntry, and
  • makes NotebookEditorManager consult the same generic IFilesConfigurationService override before opening dirty notebook editors.

That keeps the fix grounded in the actual auto-open paths instead of assuming documents were the only case.

@kangarko
Copy link
Author

Hey! I know you're busy so I tried using AI on this. If you see any feasible solution we'd really appreciate this feature bc the files keep opening and breaking the width of the chat on their own. Otherwise just wanted to say you guys are doing amazing job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opening agent created/modified in the editor is overwhelming

5 participants