Repository navigation
feat(sdk): Expose snapshot.track() and session.addPart() for plugin undo integration #7553
Copy link
Copy link
Closed
Description
Problem
The native task tool blocks synchronously, limiting multi-agent orchestration patterns. Community plugins like opencode-background-agents enable async delegation, but changes made by background agents cannot be reverted with /undo because:
PatchParts are only created during LLM stream processing atfinish-step- No SDK API exists to create patches programmatically
- No plugin hooks for snapshot/patch integration
This forces an impossible choice: either block the parent session (defeating async), or lose undo capability.
Proposed Solution
Expose two primitives that already exist internally, allowing plugins to integrate async operations with the native undo system.
API
// 1. Expose existing Snapshot.track()
// Captures current file state, returns git tree hash
client.snapshot.track(): Promise<string | undefined>
// 2. Expose Session.updatePart() pattern
// Adds a PatchPart to an existing message so /undo can find it
client.session.addPart(
sessionId: string,
messageId: string,
part: { type: 'patch', hash: string, files: string[] }
): Promise<void>Usage
// Before async delegation starts
const beforeHash = await client.snapshot.track()
if (!beforeHash) throw new Error("Failed to capture snapshot")
// Fire async delegation (non-blocking)
const delegation = await startDelegation(prompt, agent)
// ... parent continues working ...
// When delegation completes (via session.idle listener)
const changedFiles = getFilesChangedByDelegation(delegation)
if (changedFiles.length === 0) return // Nothing to register
// Register changes with parent's undo history
await client.session.addPart(parentSessionId, parentMessageId, {
type: 'patch',
hash: beforeHash,
files: changedFiles
})
// Now /undo will find this patch and revert the async agent's changes!Why This Design
- Minimal surface area - Just two methods, both exposing existing internals
- Matches existing patterns -
addPartmirrorsSession.updatePart(), validation follows "trust caller, validate structure" philosophy - No architectural changes - Uses existing
PatchPartstructure and undo scanning - Enables ecosystem innovation - Plugins can build async orchestration with native undo
Prior Art
| Tool/Framework | Approach |
|---|---|
| VS Code | Extensions push custom undo handlers via workspace.applyEdit() |
| Cline | Shadow Git repo for checkpoints, message-timestamp association |
| Aider | Session-scoped commit tracking, per-file git checkout for undo |
| Crystal | Git worktrees for isolation, commit-based undo |
Internal Consistency
This proposal exposes existing internals without modification:
Snapshot.track()returnsstring | undefined→ expose asclient.snapshot.track()Session.updatePart()pattern → expose asclient.session.addPart()PatchPart { type, hash, files }→ same structure- Undo scans for
type === 'patch'→ works automatically
References
- [feat] True Async/Background Sub-Agent Delegation #5887 - Async background sub-agent delegation (primary request)
- [Tracking] Edit tool reliability: "modified since last read" errors (Undo/Redo & Persistence) #5840 - Undo system architecture
- Task Tool Timeouts & Early Termination in Multi-Agent Conductor Pattern #6792 - Task tool blocks synchronously
- [FEATURE]: Expose the ability to modify the chat messages thread via a plugin #7034 - Chat message modification via plugin
- feat(cli): add snapshot management commands #7263 - Snapshot management commands
Implementation Notes
The implementation would:
- Add
track()method to SDK's snapshot namespace (wraps existingSnapshot.track()) - Add
addPart()method to SDK's session namespace (wraps existingSession.updatePart()pattern) - Use Zod for structure validation (matching existing patterns)
- Trust caller for sessionId/messageId (matching existing patterns)
Happy to contribute a PR if this direction is acceptable.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
github-actions commentedon Jan 10, 2026
This issue is closely related to existing feature requests:
This appears to be a specific SDK API proposal to enable the broader async delegation feature. These issues complement each other rather than duplicate.
mathe00 commentedon Feb 6, 2026
Up
This is a workaround for #1286. I would really like to see #1286 or your idea implemented so that we can finally have a more granular checkpoint system.
github-actions commentedon Apr 8, 2026
To stay organized issues are automatically closed after 90 days of no activity. If the issue is still relevant please open a new one.