automations: capture and retain client customizations for runs - #338777
Closed
Connor Peet (connor4312) wants to merge 1 commit into
Closed
Connor Peet (connor4312) wants to merge 1 commit into
Connor Peet (connor4312) wants to merge 1 commit into
Conversation
Reuse workspace-scoped client synchronization to capture enabled plugins for offline automation runs across Copilot, Claude, and Codex. Preserve snapshots on ordinary edits and recapture when retargeting. Persist revision holders in the plugin cache with write-ahead registration and authoritative reconciliation so definitions and retained run sessions survive restart and garbage collection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Connor Peet (connor4312)
September 29, 2026 21:25
View session
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Production capability advertisement and several snapshot, deduplication, mapping, and holder-lifecycle paths remain incorrect.
Review effort: Balanced
Findings: 5
Open (5)
Canceled pending session leaks run inputs on creation failure · New Captured plugins are not suppressed from live client plugins · New Selected agent changes skip snapshot acquisition · New Host capabilities omit customizations support · New Reuse path fails to update source-to-destination mapping · New
What changed in this PR
Adds durable client-customization snapshots so automation runs can execute independently of the originating client.
Changes:
- Captures active-client plugins and selected-agent mappings.
- Retains captures through automation/run holder lifecycles.
- Integrates captures across providers, protocol state, tests, and documentation.
| File | Description |
|---|---|
syncedCustomizationBundler.test.ts |
Tests immutable bundle snapshots. |
agentHostUntitledProvisionalSessionService.test.ts |
Updates scope test fixture. |
agentHostClientTools.test.ts |
Tests snapshot resolution races and recovery. |
agentHostChatContribution.test.ts |
Updates customization scope fixture. |
syncedCustomizationBundler.ts |
Adds immutable virtual-plugin snapshots. |
agentHostActiveClientService.ts |
Exposes resolved customization snapshots. |
AgentService.ts |
Adds capture and holder RPC methods. |
protocolServerHandler.ts |
Handles new customization RPCs. |
agentPluginManager.ts |
Implements capture storage and retention. |
agentHostAutomationService.ts |
Manages automation/run capture lifecycles. |
agentService.ts |
Prepares captured customizations before runs. |
copilotAgent.ts |
Supplies captures to Copilot sessions. |
copilotSdkSession.ts |
Applies captured custom-agent mappings. |
claudeAgentSession.ts |
Supplies captures to Claude sessions. |
codexClientCustomizations.ts |
Supplies captures to Codex sessions. |
automation.d.ts |
Adds customization capture API types. |
state.ts |
Extends automation protocol state. |
commands.ts |
Adds capture and holder commands. |
clientState.ts |
Registers new command handlers. |
channels-changeset/reducer.ts |
Updates generated protocol reducer. |
channels-root/reducer.ts |
Updates generated protocol reducer. |
agentHostAutomationStore.ts |
Captures client state during mutations. |
AUTOMATIONS.md |
Documents capture and retention semantics. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| this._armRunTimeout(running.resource); | ||
| const configuration = this._configurationTelemetry(definition.session); | ||
| const session = await this._execution.createSession(template, running); | ||
| const session = await this._execution.createSession(resolveCapturedAutomationAgentSelection(template, customizations), running, customizations); |
Comment on lines
+6704
to
6708
| const sessionHostCustomizations = this._hostCustomizations().filter((customization): customization is PluginCustomization => | ||
| customization.type === CustomizationType.Plugin | ||
| && this._parent.pluginManager.getCapturedPluginDir(customization.uri) !== undefined | ||
| ); | ||
| const clientCustomizations = this._flattenClientCustomizations(); |
Comment on lines
+430
to
+432
| const capture = this._targetChanged(currentDescriptor.target, descriptor.target) | ||
| ? await this._captureCustomizations(descriptor) | ||
| : undefined; |
Comment on lines
+532
to
+533
| if (!this._connection.initializeResult.get()?.automations?.customizations) { | ||
| return undefined; |
Comment on lines
+359
to
+362
| const destinationBySource = new ResourceMap<URI>(); | ||
| const addEntry = (file: ISyncableFile, sourceUri: URI, destUri: URI, hashKey: string): void => { | ||
| entries.push({ sourceUri, destUri, hashKey }); | ||
| destinationBySource.set(sourceUri, destUri); |
Member
|
I'm thinking we should display some kind of label letting users know customizations are going to be copied over, or have some checkbox / switch showing whether to copy all customizations over. Also, how might a user delete these remote copies? |
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Adopt the imported AHP automation-customization contract so scheduled runs can use enabled client plugins without requiring the originating client to remain connected.
Includes the imported AHP update to
0d9ec389and documentation of capture and retention semantics.Validation
npm run compile-clientnpm run typecheck-clientgit diff --check, and repository pre-commit hygieneRegression coverage includes startup GC before automation recovery, independent holders, failed persistence, unavailable automation storage, write-ahead ordering, overlapping registrations, and cache-loss adoption.