gum-tool-undo
Reference guide for Gum's undo/redo system. Load this when working on undo/redo behavior, the History tab, UndoManager, UndoPlugin, UndoSnapshot, or stale reference issues after undo.
Best use case
gum-tool-undo is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Reference guide for Gum's undo/redo system. Load this when working on undo/redo behavior, the History tab, UndoManager, UndoPlugin, UndoSnapshot, or stale reference issues after undo.
Teams using gum-tool-undo should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/gum-tool-undo/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How gum-tool-undo Compares
| Feature / Agent | gum-tool-undo | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Reference guide for Gum's undo/redo system. Load this when working on undo/redo behavior, the History tab, UndoManager, UndoPlugin, UndoSnapshot, or stale reference issues after undo.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Gum Undo/Redo System Reference ## Overview Gum has a snapshot-based undo/redo system scoped per-element. Undo history is displayed in the **History tab** in the Gum UI tool. ## Key Characteristics ### Per-Element Scoping Undo history is stored separately for each open element (Screen, Component, or StandardElement). Switching between elements does not share or merge history — each element maintains its own independent undo stack. ### No Selection Tracking Undos do not record or restore the user's selection state. After undoing or redoing an operation, the selected object in the tree view or canvas may not match what was selected when the change was originally made. ### No Persistence Undo history is entirely in-memory and is cleared when the project is loaded or Gum is closed. There is no way to undo changes made in a previous session. ### Element Deletion Is Not Undoable When an element (Screen, Component, or StandardElement) is deleted, its entire undo history is discarded along with it. Deleting an element cannot be undone. ### Behaviors Are Not Currently Supported Undo/redo does not currently work for behavior-related changes. Changes to behaviors (adding, removing, or modifying) on an element may not be correctly undoable. ## History Tab The **History tab** in the Gum UI tool displays a human-readable list of all recorded undo actions for the currently selected element. Each entry shows a description of what changed, such as: - `Modify element variables: X=10` - `Add instances: MySprite` - `Remove instances: MySprite` - `Add behaviors: MyBehavior` - `Exposed variables: MyVar` The list is built by working backwards through undo snapshots and diffing consecutive states, so descriptions reflect the actual change rather than raw data. ## What Is Tracked The undo system records changes to: - Element-level variable values (position, size, color, etc.) - Instance additions and removals - Instance reordering (tracked as index changes) - State additions, removals, and variable changes within states - Category additions and removals - Variable exposure and unexposure ## How Recording Works The system uses a two-phase record approach: 1. **`RecordState()`** — Captures a snapshot of the element's current state before a change begins. Called automatically by `UndoPlugin` on element selection, state selection, etc. Do NOT call this manually from feature code. 2. **`RecordUndo()`** — Compares the current state against the recorded snapshot; if anything changed, saves an undo action. Called automatically when an `UndoLock` is disposed. ## Correct Pattern for Recording Undos Always use `RequestLock()` — never call `RecordState()` or `RecordUndo()` manually: ```csharp using var undoLock = _undoManager.RequestLock(); // make your changes here // lock disposal fires RecordUndo() automatically ``` `RequestLock()` adds an `UndoLock` to `UndoLocks`. When the lock is disposed (end of `using` block), it removes itself; when `UndoLocks` reaches 0, `HandleUndoLockChanged` fires `RecordUndo()`. The `RecordState()` baseline is already set by the framework when the user selected the element. **Why not `RecordState()` manually?** `RecordState()` is a no-op when any locks are held, and calling it outside of that flow risks overwriting the correct baseline snapshot. ## Snapshots Are Deep Copies Both element and behavior snapshots use `CloneElement`/`CloneBehavior`, so every saved snapshot contains **new object instances** with different references than the live data. When undo is applied, the restored instances replace the live ones — meaning any code holding a reference to the pre-undo instance now has a **stale reference** that no longer exists in the element or behavior. Consequence: after an undo, `_selectedState.SelectedInstance` may point to a stale object. Reference-based lookups (e.g. tree node searches using `==`) will fail. Name-based fallback is required to re-locate the logically equivalent node. If undo also changes the instance's name, selection cannot be restored and is silently dropped — this is considered acceptable. ## Implementation Files | File | Purpose | |------|---------| | `Gum/Undo/UndoManager.cs` | Core undo/redo logic; per-element history with `Dictionary<ElementSave, ElementHistory>` | | `Gum/Undo/UndoPlugin.cs` | Event handlers that call `RecordState()` / `RecordUndo()` | | `Gum/Undo/UndoSnapshot.cs` | Snapshot structure and diff/comparison logic (`UndoComparison`) | | `Gum/Plugins/InternalPlugins/Undos/UndosViewModel.cs` | History tab display and description generation | | `Gum/Plugins/InternalPlugins/Undos/UndoDisplay.xaml` | WPF ListBox UI for the History tab | | `Gum/Plugins/InternalPlugins/Undos/UndoItemViewModel.cs` | Individual history item (display text + undo/redo direction) | | `Tool/Tests/GumToolUnitTests/Managers/UndoManagerTests.cs` | Unit tests for undo behavior | ## Known Limitations Summary | Limitation | Details | |------------|---------| | No global undo | Each element has its own undo stack; cross-element changes are not grouped | | No selection restore | Selection state is not captured or restored on undo/redo | | No persistence | History is cleared on project load or app close | | No element-deletion undo | Deleting an element removes its history permanently | | Behaviors not supported | Behavior changes are not reliably undoable |
Related Skills
gum-tool-viewmodels
Reference guide for Gum tool ViewModel conventions. Load this when working on ViewModels, XAML views, data binding, DependsOn, or visibility properties in the Gum tool.
gum-tool-variable-references
Reference guide for Gum's variable reference system — Excel-like cross-instance/cross-element variable binding using Roslyn-parsed assignment syntax. Load this when working on VariableReferenceLogic, EvaluatedSyntax, ApplyVariableReferences, VariableChangedThroughReference, or the VariableReferences VariableListSave.
gum-tool-variable-grid
Reference guide for Gum's Variables tab and DataUiGrid system. Load this when working on the Variables tab, DataUiGrid control, MemberCategory, InstanceMember, category population, property grid refresh, or category expansion state persistence.
gum-tool-selection
Reference guide for Gum's editor selection system. Load this when working on click/drag selection, the rectangle/marquee selector, input handlers (move, resize, rotate, polygon points), the IsActive flag, locked instance behavior, SelectionManager coordination, or the selection event cascade (plugin events, forced default state, tree view sync).
gum-tool-save-classes
Reference guide for Gum's save/load data model. Load this when working with GumProjectSave, ScreenSave, ComponentSave, StandardElementSave, ElementSave, StateSave, VariableSave, InstanceSave, BehaviorSave, or any serialization/deserialization of Gum project files.
gum-tool-plugins
Reference guide for the Gum tool's plugin system, including visualization plugins (EditorTabPlugin_XNA, TextureCoordinateSelectionPlugin). Load this when working on plugin registration, PluginBase, InternalPlugin, PluginManager, plugin events, visualization/rendering concerns, or finding which internal plugin owns a feature.
gum-tool-output
Reference guide for Gum's Output tab system. Load this when working on the Output tab, IOutputManager, MainOutputViewModel, GuiCommands.PrintOutput, or adding output/error messages to the tool.
gum-tool-font-generation
Reference guide for Gum's bitmap font generation pipeline — how the tool converts font properties into .fnt/.png files via bmfont.exe. Load this when working on BmfcSave, HeadlessFontGenerationService, FontManager, BmfcTemplate.bmfc, font cache naming, texture size estimation, or the GumProjectFontGenerator CLI.
gum-tool-file-watch
Reference guide for Gum's FileWatch system. Load this when working on file watching, external file change detection, IgnoreNextChangeUntil, FileWatchManager, FileWatchLogic, FileChangeReactionLogic, or reloading assets/elements when files change on disk.
gum-tool-errors
Reference guide for Gum's error detection and display system. Load this when working on the Errors tab, error icons ("!" mark) in the tree view, ErrorChecker, ErrorViewModel, IErrorChecker, AllErrorsViewModel, MainErrorsPlugin, RequestErrorRefreshMessage, or adding new error checks.
gum-tool-dialogs
Reference guide for Gum's dialog/popup systems. Load this when working on dialog windows, DialogService, DialogWindow, DeleteOptionsWindow, dialog scrolling, dialog layout, or adding new dialog types.
gum-tool-delete-logic
Reference guide for Gum's delete architecture. Load this when working on delete commands, IEditCommands delete methods, IDeleteLogic, DeleteLogic, DeleteOptionsWindow, HandleDeleteCommand, AskToDeleteState, AskToDeleteStateCategory, or DeleteSelection.