#48 makes every change revertible; this makes that reachable. The bar to clear: after the agent rearranges a bed, undoing it should take one obvious click, not a hunt through a menu.
Scope
History panel in the garden editor: change sets newest-first — who, when, summary, a count of what moved ("3 plops added, 1 bed moved"), and a badge distinguishing agent changes from hand edits. Paginate or lazy-load; a season of edits is a long list.
Undo on each entry → POST /change-sets/:id/revert, then invalidate the /full query so the canvas redraws. A reverted change set is marked as such in the list, and the revert appears as its own entry (it is one) rather than making the original disappear.
Conflict handling: a 409 names the entities that couldn't be cleanly reverted because they changed afterwards. Say which ones and what happened to the rest — "2 of 3 changes undone; the north bed was edited since and was left alone" — not a generic failure toast.
Inline undo on the agent turn itself (see #57): the result of a turn carries an Undo affordance so the common case never involves opening the panel at all. One implementation shared between here and #57, not two.
Note honestly in the panel that deleting a garden is not covered by history (see #48).
Layout note
The editor's right rail is already the inspector; #53 wants journal access and #57 wants a chat panel. Four things competing for one rail is the actual design problem, and this issue is where it gets settled — the later issues follow whatever is decided here rather than each bolting on its own chrome. A tabbed rail (Inspector / History / Journal / Chat) is the obvious candidate; a bottom drawer for history is the other.
Constraints to hold whatever wins: selecting an object still lands you in the inspector without a click, and the canvas keeps enough width to be worth watching while the agent edits it.
Out of scope
Diff visualisation (showing before/after geometry on the canvas). Nice, not necessary.
Restoring a deleted garden.
Key files
web/src/pages/GardenEditorPage.tsx · web/src/editor/ · web/src/lib/ (a new history.ts data layer alongside gardens.ts/objects.ts)
Dependencies
Blocked by #48. Owns the rail-layout decision that #53 and #57 depend on.
Acceptance criteria
Move a bed, open History, undo it: the bed returns to its previous position and the canvas reflects it without a manual refresh.
The undo itself appears in the list and can be undone.
Edit an object, then try to undo an older change set that touched it: the partial result and the reason are both stated in the UI.
The panel is usable on a phone (the editor is expected to work there).
Design: [DESIGN.md](https://gitea.stevedudenhoeffer.com/steve/pansy/src/branch/main/DESIGN.md)
## Context
#48 makes every change revertible; this makes that reachable. The bar to clear: after the agent rearranges a bed, undoing it should take one obvious click, not a hunt through a menu.
## Scope
- [ ] History panel in the garden editor: change sets newest-first — who, when, summary, a count of what moved ("3 plops added, 1 bed moved"), and a badge distinguishing **agent** changes from hand edits. Paginate or lazy-load; a season of edits is a long list.
- [ ] **Undo** on each entry → `POST /change-sets/:id/revert`, then invalidate the `/full` query so the canvas redraws. A reverted change set is marked as such in the list, and the revert appears as its own entry (it is one) rather than making the original disappear.
- [ ] Conflict handling: a `409` names the entities that couldn't be cleanly reverted because they changed afterwards. Say which ones and what happened to the rest — "2 of 3 changes undone; the north bed was edited since and was left alone" — not a generic failure toast.
- [ ] Inline undo on the agent turn itself (see #57): the result of a turn carries an Undo affordance so the common case never involves opening the panel at all. One implementation shared between here and #57, not two.
- [ ] Note honestly in the panel that deleting a garden is not covered by history (see #48).
## Layout note
The editor's right rail is already the inspector; #53 wants journal access and #57 wants a chat panel. **Four things competing for one rail is the actual design problem, and this issue is where it gets settled** — the later issues follow whatever is decided here rather than each bolting on its own chrome. A tabbed rail (Inspector / History / Journal / Chat) is the obvious candidate; a bottom drawer for history is the other.
Constraints to hold whatever wins: selecting an object still lands you in the inspector without a click, and the canvas keeps enough width to be worth watching while the agent edits it.
## Out of scope
- Diff visualisation (showing before/after geometry on the canvas). Nice, not necessary.
- Restoring a deleted garden.
## Key files
`web/src/pages/GardenEditorPage.tsx` · `web/src/editor/` · `web/src/lib/` (a new `history.ts` data layer alongside `gardens.ts`/`objects.ts`)
## Dependencies
Blocked by #48. Owns the rail-layout decision that #53 and #57 depend on.
## Acceptance criteria
- Move a bed, open History, undo it: the bed returns to its previous position and the canvas reflects it without a manual refresh.
- The undo itself appears in the list and can be undone.
- Edit an object, then try to undo an older change set that touched it: the partial result and the reason are both stated in the UI.
- The panel is usable on a phone (the editor is expected to work there).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Design: DESIGN.md
Context
#48 makes every change revertible; this makes that reachable. The bar to clear: after the agent rearranges a bed, undoing it should take one obvious click, not a hunt through a menu.
Scope
POST /change-sets/:id/revert, then invalidate the/fullquery so the canvas redraws. A reverted change set is marked as such in the list, and the revert appears as its own entry (it is one) rather than making the original disappear.409names the entities that couldn't be cleanly reverted because they changed afterwards. Say which ones and what happened to the rest — "2 of 3 changes undone; the north bed was edited since and was left alone" — not a generic failure toast.Layout note
The editor's right rail is already the inspector; #53 wants journal access and #57 wants a chat panel. Four things competing for one rail is the actual design problem, and this issue is where it gets settled — the later issues follow whatever is decided here rather than each bolting on its own chrome. A tabbed rail (Inspector / History / Journal / Chat) is the obvious candidate; a bottom drawer for history is the other.
Constraints to hold whatever wins: selecting an object still lands you in the inspector without a click, and the canvas keeps enough width to be worth watching while the agent edits it.
Out of scope
Key files
web/src/pages/GardenEditorPage.tsx·web/src/editor/·web/src/lib/(a newhistory.tsdata layer alongsidegardens.ts/objects.ts)Dependencies
Blocked by #48. Owns the rail-layout decision that #53 and #57 depend on.
Acceptance criteria