Repository navigation
implement keep/undo in copilot harness - #342469
Conversation
Agent Host (Copilot SDK) chats lost the local harness's Keep and Undo when their editing session was reduced to checkpoints. The host already snapshots every edit tool call, so the client builds a review from those snapshots with the same per-file entries local chat uses. The chat's editing session exposes them, so the existing editor overlay, hunk actions, keybindings, and working sets light up unchanged. Behind chat.editor.keepUndo.enabled (experimental, off by default), for chats in the chat view or an editor on the local agent host. Keep only moves the review baseline. Undo reverts the change on disk as a user edit, which the host does not record yet, so Session Changes keeps showing undone edits until the agent edits that file again. The session working set shows changes waiting for review in a To Review tab next to Session Changes, with the local working set's actions. The host now reports created files without a before state, as restored history already did. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Base:
|
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved Undo safety and review lifecycle issues can lose user content or leave incorrect disk state.
6 open issues
Overlapping user edits can be lost during Undo · New File Undo can delete user content from agent-created files · New Deleted or renamed files can retain stale reviews · New Revalidate dirty state and review ownership after async reads · New Undo baseline corrupts non-UTF-8 documents · New Single-hunk Undo can lose save during entry cleanup · New
What changed in this PR
Adds an opt-in prototype restoring per-file and per-hunk Keep/Undo for local Agent Host chats, reusing the existing chat editing infrastructure.
Changes:
- Builds review entries from host snapshots and live documents.
- Adds a To Review tab, review actions, and accessibility guidance.
- Updates created-file reporting and adds tests and fixtures.
| File | Description |
|---|---|
| src/vs/workbench/test/browser/componentFixtures/chat/renderChatInput.ts | Supplies review actions to fixtures. |
| src/vs/workbench/test/browser/componentFixtures/chat/chatInput.fixture.ts | Adds review layouts. |
| src/vs/workbench/contrib/chat/test/browser/widget/input/chatSessionWorkingSet.test.ts | Tests review tabs and actions. |
| src/vs/workbench/contrib/chat/test/browser/widget/input/chatInputPart.test.ts | Tests pending-review visibility. |
| src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts | Tests review eligibility. |
| src/vs/workbench/contrib/chat/test/browser/agentHost/agentHostSnapshotController.test.ts | Tests delegation and checkpoint cleanup. |
| src/vs/workbench/contrib/chat/test/browser/agentHost/agentHostEditReview.test.ts | Adds review behavior tests. |
| src/vs/workbench/contrib/chat/test/browser/accessibility/chatAccessibilityHelp.test.ts | Tests review help visibility. |
| src/vs/workbench/contrib/chat/common/editing/chatEditingService.ts | Passes session scope to providers. |
| src/vs/workbench/contrib/chat/common/constants.ts | Defines the experimental setting. |
| src/vs/workbench/contrib/chat/browser/widget/media/chat.css | Styles review tabs and headings. |
| src/vs/workbench/contrib/chat/browser/widget/input/chatSessionWorkingSet.ts | Implements review tabs and controls. |
| src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts | Connects review state to working sets. |
| src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.ts | Supports row menus and custom opening. |
| src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelChangeService.ts | Passes events to attribution checks. |
| src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingServiceImpl.ts | Updates provider creation and persistence filtering. |
| src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingModifiedDocumentEntry.ts | Exposes review attribution hooks. |
| src/vs/workbench/contrib/chat/browser/chat.shared.contribution.ts | Registers the disabled-by-default setting. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts | Delegates review operations. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts | Connects turns and edits to review. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostEditReview.ts | Implements client-side review lifecycle. |
| src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts | Documents review navigation. |
| src/vs/platform/agentHost/test/node/fileEditTracker.test.ts | Tests created-file payloads. |
| src/vs/platform/agentHost/node/shared/fileEditTracker.ts | Omits before-state for created files. |
Review effort: Balanced
- Editing an agent change keeps it, so undoing never discards the user's text. The local harness and notebooks keep composing user edits into the agent change. - Undoing a created file deletes it only when its baseline is empty, and otherwise restores the baseline. - Drop the review of files the agent deletes or renames, or that are gone, so that undo never writes a stale copy back. - Check again for unsaved changes and other reviewers after reading an edit. - Review only UTF-8 documents, because the agent host decodes its snapshots as UTF-8. - Undoing a single change keeps the entry alive until it is saved, even when the review ends meanwhile. - Stop reviewing a file once the user's edits leave nothing to decide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Keep the session working set's tab and focus while the chat widget re-renders without its editing session before each update. - Stop attributing reloads to the agent after a turn even when a file leaves the review while the turn ends, and never touch a dropped entry. - Do not review files whose content before the edit was not UTF-8 text, since the agent host decodes snapshots as UTF-8. - Do not review notebooks, check unsaved changes in every editor, and only reveal changes in place in editors that can show them. - Review files under their canonical URIs, so differently cased paths can't bypass the unsaved-changes check or break lookups. - Review the edits of subagents that run on after their parent's turn, while their own turn runs. - Keep the whole change a user edits part of, as the editor shows it, so that undoing never mixes the agent's text with the user's. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The working set on main now lists the host's Working Set changeset and keeps or undoes its files through the agent host, so the Session Changes | To Review tabs, the To Review list and its row menu are no longer needed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-research-prototype # Conflicts: # src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts # src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts
The agent host now records what the user keeps: its Working Set changeset lists the tool edits that haven't been kept, and its Accept Changes and Discard Changes operations keep or undo a file's changes or a hunk's. The editor working set on main uses them for files. The editor review now follows the same Working Set, so the editor and the working set always show the same changes, like local chat edits: - Each review entry is a file of the Working Set, compared with its baseline. Changes the session hasn't recorded, like the user's typing, are moved into the baseline as the host does, and line endings follow the document. - Keep and Undo for a file, and for a hunk in the editor, ask the host to accept or discard them. A hunk's lines are mapped from the document to the content the host recorded. A created file is kept or undone whole. Undo saves unsaved text first, since the host reverts on disk. - The review no longer brackets turns, reads tool snapshots, or attributes reloads, and the shared change service no longer keeps agent changes the user edits: the host keeps undo from discarding the user's text. - Until the first diff, the change service maps all differences as one change, so that typing meanwhile can't corrupt the baseline. - Local sessions no longer adopt the entries of provider sessions. The fileEditTracker change for created files is reverted; the review no longer reads tool-call edits. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The agent host disables Working Set operations while a turn runs. Tell the user to retry once the agent has finished, and report a missing operation separately. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved correctness issues can make Keep/Undo affect changes the user did not intend.
4 open issues
6 resolved since last review
Single-hunk Undo can lose save during entry cleanup Undo baseline corrupts non-UTF-8 documents Revalidate dirty state and review ownership after async reads Deleted or renamed files can retain stale reviews File Undo can delete user content from agent-created files Overlapping user edits can be lost during Undo
Review effort: Max
The autorun that closes a chat edit's diff editors once its changes are kept or undone was only disposed by that decision, so it leaked whenever its entry was disposed undecided. The Agent Host review disposes an entry as soon as the host settles its file, which made this common. The review now also closes the diff editors that compare with a leaving entry, like local chat does once the last change is kept or undone, and disposes the entry only after they let go of its original. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- The Working Set refreshes after each edit tool call instead of 5 seconds after edits pause, so its changes show while a turn runs. - Each Working Set file publishes the version of its changes, and whether an agent's edit tool call is writing it, in namespaced _meta. - Accept Changes stays available while a turn runs: it only covers the version the client showed, or the one last published. - Discard Changes stays available while a turn runs for providers whose edit tool calls wait for it. Copilot's do, through the new file edit coordinator: a discard waits for the edits of its file in progress, and the next ones wait for the discard, so each is recorded in order. - The agent is told about changes the user undid, once, as additionalContext on its next tool result or prompt. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Keep and Undo name the version of the changes the editor and the working set showed, so the agent host refuses changes made since. - A file the agent is writing is read-only and can't be kept or undone, as while local chat edits stream into it. - The editor reloads a document from disk before comparing it with the Working Set, unless it has unsaved changes, and counts the reload as the agent's, as local chat does once an agent's edits on disk end. The Working Set can now update before the editor reloads the agent's write, which the review otherwise took for the user's typing and showed no changes for. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Addresses review feedback on the editor's Keep and Undo for Agent Host chats: - An operation waits behind earlier ones and Working Set updates, which can update the entry meanwhile. It now captures the changes shown when the user decided, refuses if they changed, and names their version, so it no longer covers an edit the agent made after the click. - Keeping or undoing changes plays the editsKept and editsUndone signals, once for several files, as local chat edits do, and not for changes the agent host refused. - Undo stops when the document's unsaved changes can't be saved, as on a write conflict, instead of reverting the disk under them. - A hunk whose lines can't be matched with the recorded content, as when their diff times out, is no longer kept or undone at its unmapped lines. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the per-file review gate through Working Set refreshes and editor diffs. Preserve background edit leases until snapshots are recorded, and deny hooks whose turns ended while they waited. Initialize Agent Host edit mappings without changing local-chat defaults. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve the chat test helper by preserving upstream steering-message handoff options and the editor review provider tracking. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
The following commit, 56542957ed0, adds dirty-file reconciliation to the existing Agent Host editor Keep/Undo review. Previously, an SDK edit could update the file on disk while an open editor still held unsaved user changes. Reloading would risk losing those changes, so the editor stayed stale: the agent's hunks were missing, and the next save could produce the "file is newer" warning. Changes to text-file modelDisplaying the combined text is only half the fix. The editor also needs to know which disk version it incorporated, whether the buffer is still dirty, and which undo-stack version represents saved content. Those responsibilities belong to the file model, not the chat review component. The merge needs three versions: For example:
The editor now shows the agent's change with Keep/Undo while the user's independent change remains unsaved. Disk still contains What changed in the text-file layer
Updating only the text would leave stale save metadata and the overwrite warning. Merely refreshing the ETag could hide an unincorporated disk change. The file-model operation coordinates both rather than having chat manipulate private save-state fields. What stays in the chat layeragentHostEditReview.ts selects the recorded Working Set version, attributes the incorporated edit to the agent, updates the existing review UI, and handles gating, notifications, and recovery. The text-file model itself does not know about Copilot, Working Sets, or Keep/Undo. Overlaps or unsafe comparisons preserve the user's buffer and warn instead of guessing a winner. Editor review resumes after resolution and save/revert, or a later Working Set update that can be reconciled safely. Scope and safeguardsThe SDK still writes to disk, and the host's Working Set still owns Keep/Undo decisions. Only the opt-in Agent Host editor review requests automatic reconciliation; ordinary dirty files do not start auto-merging. There is a shared-model cost: retaining one additional immutable text copy for eligible models. Models too large for synchronization are excluded; restored dirty documents without a known ancestor cannot be automatically reconciled. Reconciliation does not implicitly save user changes. Keep leaves them unsaved; existing send-time saving and host Undo's save-first behavior remain unchanged. The SDK still does not automatically see unsaved editor text when deciding what to edit. The commit includes regression coverage and accessibility guidance, plus the council-review fixes: immutable ancestors across EOL changes, recovery from clean reload failures without leaving the editor read-only, and preserved undo-to-saved tracking when reconciliation is a no-op. |
Incorporate non-conflicting SDK disk edits into dirty editor buffers using an immutable synchronized baseline. Preserve unsaved user text and undo history while retaining save-conflict protection for later disk changes. Recover editor review after synchronization failures and include real file-model regressions for stale updates, EOL changes, save behavior, and undo-to-saved tracking. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Combine upstream generated-image result handling with pending Undo context and failure hooks, preserving the SDK's post-tool plugin ordering. Cover both outputs together and register the text-file events required by the editor review test harness. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep review originals alive until their diff editors close, release editing restrictions on teardown, and scope saved-content retention to opted-in review owners. Run review diffs and hunk mapping through the editor worker with stale-result guards. Require client-supplied versions for active-turn Keep/Undo while preserving versionless idle behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The generic file-service mock creates a new ETag on every read, so reconciliation can correctly report stale input when the retention test crosses a clock tick. Use an in-memory filesystem with write-based versions and deliberately delayed reads instead, settling initialization events before constructing the model manager. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| * ones wait for it, so each edit's snapshots and the host's change are | ||
| * recorded in the order they were made. | ||
| */ | ||
| export interface IAgentHostFileEditCoordinator { |
There was a problem hiding this comment.
Should the FileEditTracker logic be folded into here? We use that for Claude and Codex and then they should be able to get the tracking for 'free' here.
There was a problem hiding this comment.
Moved edit-lifetime ownership into the shared FileEditTracker in 483ab4f, so its callers get editing state and snapshot-lifetime cleanup without a separate provider-owned lease map. Copilot awaits coordinated acquisition; Claude marks its observed writes synchronously and holds the mark through persistence. I kept the coordinator separate from snapshot/database/diff/telemetry responsibilities rather than moving the entire tracker into that service.
One distinction in the current code: Codex uses its native turn-diff pipeline (CodexTurnDiffTracker), not FileEditTracker. That authoritative path is unchanged, and the editor now accepts an advertised Working Set regardless of provider. Claude message-stream observation cannot actually pause SDK writes, so it deliberately does not register as a coordinated provider or enable unsafe in-turn Undo. Shared-tracker and Claude observer regressions cover these boundaries.
Bind deferred Keep/Undo settlement to the displayed revision, make review capabilities reactive, and dispose replaced reviews. Follow advertised Working Sets and chat origins across providers and connections. Move snapshot-owned edit lifetimes into the shared tracker, preserve SDK work across root-turn transitions, and avoid claiming a pre-write barrier for observational providers. Revalidate dirty-file synchronization with stat instead of a second content read. Add revision-race, provider/remote, ownership, and late-completion regressions. Protocol field proposal: microsoft/agent-host-protocol#538. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve the chat contribution test helper by retaining main's editing-session factory alongside the review-provider and text-file retention stubs. Preserve current SDK updates and the scoped review fixes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: TylerLeonhardtMatched files:
|
Sync the protocol to AHP 53f84cd0 and replace private Working Set version metadata with optional file/target nonces. Preserve the displayed nonce across editor and working-set operations, reject stale supplied nonces with Conflict, and retain omission compatibility during active turns. Includes stale-write, deferred-settlement, nonce forwarding and omitted-nonce regressions. Assumes microsoft/agent-host-protocol#539 will land; no negotiated protocol version or SDK bump. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve both the Keep/Undo file edit coordinator and upstream state-manager dependency in the Copilot session constructor. Retain upstream changeset and hook updates alongside the optional AHP nonce adoption. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sync the vendored protocol to 4ad8caa6 after microsoft/agent-host-protocol#539 merged. Carry over the agreed nonce wording without changing protocol declarations or the negotiated version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Combine upstream Computer Use setup callbacks and service dependencies with edit tracking, dirty-buffer retention, and their test registrations. Preserve the AHP nonce adoption while taking the current Copilot SDK and runtime. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adopt the optional ChangesetFile.isEditing field merged in microsoft/agent-host-protocol#540 and remove the private Working Set metadata helpers. Preserve fresh-publication review gating and cover explicit false and omitted editing state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the upstream cloud default-chat title tests alongside the editor-review and file-retention fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>


What this does
This PR adopts the merged optional nonce contract from microsoft/agent-host-protocol#539 and optional
ChangesetFile.isEditingfield from microsoft/agent-host-protocol#540, with the vendored protocol synced to merge commit1d639930. No negotiated protocol-version or Copilot SDK bump is required.Agent Host chats lost the local harness's per-change review when their editing session was reduced to checkpoints (fe781b7, 5bb2223). Since then, the agent host gained its own review state: a Working Set changeset with the tool edits the user hasn't kept, whose
accept-changesanddiscard-changesoperations keep or undo a file or a single hunk (#342812, #342614, #342841, #342899). The working set above the chat input uses them. This PR shows the same Working Set in the editor with the local harness's Keep/Undo UX, using optional AHP file/operation nonces and per-file editing state rather than private metadata, with no new SDK surface:AgentHostEditReviewsubscribes to the chat session's Working Set and reads each file's baseline and the content the host last recorded.ChatEditingModifiedDocumentEntrylocal chat uses. The original side is the file's Working Set baseline with independent user edits incorporated, and the modified side is the live document. Clean documents reload the agent's recorded write; dirty documents reconcile non-conflicting disk edits with their unsaved text before the review updates.AgentHostSnapshotController, the chat'sIChatEditingSession, used to be always empty and now exposes those entries. The existing UI reads from it unchanged: the editor overlay (Keep / Undo / n of m), hunk Keep/Undo, keybindings, the legacy working set and the "Suggested Edits" multi-diff.accept-changesanddiscard-changeson the file, and hunk Keep and Undo invoke them on the hunk's lines. The host records the decision, and the editor and the working set both follow its updated Working Set.The scope is the editor-to-Working-Set bridge, the host coordination needed for review during a turn, and synchronization of incoming agent edits with dirty documents. It reuses the existing editor UI and host review operations rather than introducing a second review ledger or replacing the SDK's edit tools.
Behavior:
chat.editor.keepUndo.enabled(experimental, default off, read-only off in the Agents window). Chats in the chat view or an editor can review any provider/connection that advertises a Working Set; there is no Copilot-only or local-host-only gate. Existing connection URI mapping keeps remote files and operations on their owning host. Inline chat keeps its own review, and subagent chats are identified from their advertised catalog origin rather than URI structure.Working set
This PR does not redesign the working set above the chat input. Its earlier Session Changes | To Review tabs are gone: main's working set already lists the Working Set with Keep and Undo, and the editor now shows the same changes. Working-set actions retain and echo the nonce associated with the displayed diff, never substituting a newer nonce while an operation or confirmation is pending.
Session Changes now reflect Undo
Earlier versions of this PR reverted files from the workbench, and the host didn't record that, so Session Changes kept showing undone edits. Undo now goes through the Working Set's
discard-changes, which the host records as an edit. Session Changes, This Turn and the working set update after an Undo, and the agent host stays the only place that decides what was kept. Uncommitted and Branch changes read git and update as before.Keep and Undo while the agent works
As in local chat, changes can be kept or undone while the agent works, except in a file the agent is writing. The host side:
ChangesetFile.nonce; Keep and Undo echo it inChangesetOperationTarget.nonce. AHP recommends updating published nonces when file contents change; VS Code derives its nonce from the latest recorded edit, accept, or discard. This host checks supplied nonces against the authoritative recorded change, including revalidation at the mutation boundary, and rejects stale ones withConflict(-32011). The privatevscode.workingSetVersionmetadata and active-turn missing-version rejection are removed. Clients may omit nonces, including during a turn, subject to the existing operation/provider safety gates. No capability or protocol-version negotiation is added.IAgentHostFileEditCoordinatorand sharedFileEditTracker:onPreToolUsewaits for an Undo of the file in progress, and an Undo waits for the edits of its file in progress, so each edit and each Undo is recorded in order. The tracker also publishes Claude's observed editing state, but does not claim that Claude's message stream can pause tool execution. Codex retains its native turn-diff pipeline. Host-advertised operation availability remains authoritative for every provider.ChangesetFile.isEditingflag. The host clears it with a freshly computed Working Set, not an older in-flight result. The editor applies the flag even while the Working Set is recomputing and even without a chat response, and keeps the file read-only and Keep/Undo disabled until its reload or dirty-buffer reconciliation and diff finish. A newer update cancels stale reconciliation work; an earlier update cannot unlock a later edit. The field is optional and advisory: false or omission clears the indication but is not a guarantee that modifying the file is safe; host-side coordination and operation checks remain authoritative. Both private Working Set metadata helpers are removed.additionalContext), naming the file and lines and asking it not to make those changes again unless asked. Following the prompt-text rules in the agent host'sAGENTS.md, it's per-turn text, byte-stable apart from the path and lines.The editor synchronizes a document before comparing it with the Working Set and attributes the incorporated write to the agent. Without that ordering, a Working Set update could arrive before the document reload, and the later reload was mistaken for user typing, leaving no highlighted changes. Clean files still reload from disk; dirty files use the explicit reconciliation path below.
User edits and dirty files
Local's model-based tools edit the same buffer as the user. The Copilot SDK instead writes to disk, so a dirty editor can otherwise miss the agent's edit and produce a "file is newer" warning on Save. This PR reconciles those recorded disk edits into the editor; it does not redirect SDK writes or automatically save before a tool.
TextFileEditorModelretains immutable text from its last synchronized disk version, including successful saves, only while an explicit consumer needs it. Opted-in session handlers enable retention before the first review, and active reviews hold their own references; the final release drops the shared saved-text copies. This is not the Working Set baseline, which can span several agent edits and Keep decisions. A document that becomes dirty while retention is enabled can use its known ancestor even before its first reviewed edit. Enabling retention after a document is already dirty does not invent an ancestor.For example, if the user changes a comment without saving and the agent changes an unrelated function, the editor shows both changes, highlights the agent's function change with Keep/Undo, and keeps the user's comment unsaved. Keep does not save it. Undo still saves first before asking the host to discard the agent's change.
Only the opt-in Agent Host editor review invokes automatic reconciliation. Normal dirty-file reload behavior is unchanged. Existing send-time saving is also unchanged, and the SDK still does not automatically read unsaved editor text when deciding what to edit.
Research findings
changeset/working-set) offersaccept-changesanddiscard-changeson a file (Resource) or on zero-based lines (Range), without confirmation. A Range target picks the hunks it touches. A discard reverts the changes since the last Keep with a 3-way merge and records the revert. Before this PR's in-turn changes, the host disabled both while a turn ran and updated the Working Set 5 seconds after edits paused.CopilotAgentSessiondrivesFileEditTrackerfromonPreToolUse/onPostToolUse. The Working Set is derived from those records rather than git; Session Changes and This Turn retain their existing host aggregation. The success hook provides completed-edit snapshots; the failure hook can still deliver pending Undo context. The hooks are async, so the host can hold an edit tool call back, which Undo during a turn relies on.ignoreTrimWhitespace: false, no moves). Its "after" side is the content it last recorded, not the live document, so the editor maps a hunk's lines across typing the host hasn't recorded.ChatServiceImpl._startSessioncreates a chat's editing session before it registers the chat model, so the provider couldn't look the chat up and never attached the review.IChatEditingSessionProvider.createEditingSessionnow receivesisGlobalEditingSession.Limitations
Open questions
chat.editor.workingSet.enabledinstead of its own setting?Changes
agentHostEditReview.ts(Working Set entries, displayed-nonce operations, range mapping, synchronization gating, cancellation, conflict notification and save/revert recovery)agentHostSnapshotController.ts(delegation, reactive capabilities, replacement-safe review ownership),agentHostSessionHandler.ts(attach to eligible chat-view/editor sessions using catalog roles, without local/provider gates),chatEditingService.ts/chatEditingServiceImpl.ts(observable review/global-session capabilities and their editor/inline-chat consumers;storeStateand entry lookup only useChatEditingSessions)chatEditingModifiedDocumentEntry.ts(_resetOriginalContent, an opt-in edit-mapping hook, and overridablediffInfo),chatEditingTextModelChangeService.ts(accepts the review's initial mapping without changing local-chat defaults),chatEditingModifiedFileEntry.ts/chatEditingService.ts/chatMarkdownContentPart.ts(being-modified state can omit a response),chatEditingCodeEditorIntegration.ts(the Toggle Diff autorun ends with its integration, so it no longer leaks when an entry is disposed undecided)textFileEditorModel.ts/textFileEditorModelManager.ts/textfiles.ts(reference-counted ancestor retention, explicit reconciliation API, worker diff/rebase, stale-operation guards, dirty/undo tracking and exact-version save metadata);agentHostSessionHandler.tsandagentHostEditReview.tsown the scoped retention lifetimesconstants.ts,chat.shared.contribution.tsagentHostSessionInputPills.ts(Keep and Undo echo the optional nonce retained with the displayed diff, including when only a nonce changes).ahp-versionsynced to merged AHP1d639930; optionalnonceandisEditingfields, no new capability or protocol-version bumpagentHostChangesetService.ts(refreshes after each edit; publishes standard nonces and editing state, clears editing state with current changes and skips superseded computations),sessionDiffAggregator.ts(computeWorkingSetFilesand file nonces),agentHostChangesetOperationService.ts(Working Set operations while a turn runs),agentHostAcceptChangesOperationHandler.ts/agentHostDiscardChangesOperationHandler.ts/workingSetNonce.ts(optional nonce checks, standard Conflict errors, and discards while a turn runs)agentHostFileEditCoordinator.ts(new), sharedfileEditTracker.ts(observed/coordinated edits and snapshot-owned lifetimes),claudeFileEditObserver.ts(shared observed tracking),copilotAgentSession.ts/copilotSessionLauncher.ts/copilotPluginConverters.ts(SDK hooks await coordinated snapshots; the agent is told about Undos),agentHostServices.tsagentHostEditReview.test.tsandagentHostFileEditCoordinator.test.ts(new); changeset-service and editor-review tests cover standard editing state, false/omitted compatibility and fresh-publication ordering;textFileEditorModel.test.ts(real file-model merge/save/undo, conflicts, stale computations, one-read metadata validation, EOL/BOM and saved-version regressions);fileEditTracker, Claude observer/router, Copilot lifecycle, remote/provider eligibility, opaque chat roles, revision-bound deferred completion, reactive capabilities/replacement disposal, accessibility, Accept and Discard Changes handler, changeset services and plugin converter testsHow to test
"chat.editor.keepUndo.enabled": trueand"chat.editor.workingSet.enabled": true, then open a new chat or reopen an existing one so the editor-review setting takes effect.sleep 30command. Each change is highlighted as soon as the host records it. Keep or Undo a hunk before the turn ends: it applies, and the agent is told about the Undo with its next tool result. While the agent writes a file, that file's editor is read-only and its Keep and Undo stay disabled until the latest synchronization and diff finish. Other files remain reviewable.chat.editor.workingSet.enabledoff, the legacy working set lists the files with Keep/Undo.