tfrere's picture
tfrere HF Staff
chore(release): prep v0.1.0 with LICENSE, env example and agent undo test
d63dcfe
import type { UndoManager } from "yjs";
/**
* Helpers that bracket a sequence of AI-agent edits so they collapse into a
* single undo step.
*
* Yjs UndoManager merges successive transactions that happen within the
* `captureTimeout` window (500ms by default). `stopCapturing()` forces the
* next transaction to start a fresh undo item, which we use as a *boundary
* marker*:
*
* - `startAgentBatch()` is called once at the first tool call of a turn.
* It separates the previous user edit from the agent batch.
* - `endAgentBatch()` is called when the model finishes streaming.
* It separates the agent batch from the user's next edits.
*
* Between the two markers, every Yjs-backed mutation issued by the agent
* (replaceSelection, applyDiff, updateFrontmatter, ...) merges into one
* undo item so a single `Cmd+Z` reverts the entire turn.
*
* The functions are no-ops when the manager is unavailable (early in the
* editor lifecycle) or when the batch is already (in)active, which keeps
* call sites trivial.
*/
export interface AgentBatchHandle {
startAgentBatch(): void;
endAgentBatch(): void;
isActive(): boolean;
}
export function createAgentBatch(
undoManager: UndoManager | null | undefined,
): AgentBatchHandle {
let active = false;
return {
startAgentBatch() {
if (undoManager && !active) {
undoManager.stopCapturing();
active = true;
}
},
endAgentBatch() {
if (undoManager && active) {
undoManager.stopCapturing();
active = false;
}
},
isActive() {
return active;
},
};
}