feat(client): undo button on the activity screen #357
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!357
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "356-undo-button-ui"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Makes the undo backend (#354 / ADR-0031) user-facing — the last piece to fully satisfy epic #47's "undoable from the UI" exit criterion. Each reversible row of the activity history (#350) gets an undo affordance, with an inline confirmation before anything is reversed.
What's in it
@carol/api-client—useUndoAuditEvent(): mutation overPOST /api/agent/audit/{id}/undo, returns the inverseProposalDto.lib/activity/isUndoable.ts(pure, tested) — hides the undo affordance for the delete-family tools (delete_*/remove_*/merge_*), since deletes aren't reversible (ADR-0031). The server's 409not_undoablestays as the backstop for anything the heuristic misses.activity.tsx— an "undo" button (LucideRotateCcw) on each undoable row → proposes the inverse → renders an inline confirmation card (summary + diff + apply/decline). Apply commits viauseCommitProposaland invalidates the audit list (so the inverse appears in history); decline rejects; errors render inline viaformatApiError. Reuses the chat card's diff-rendering + destructive-action styling conventions.activity.undo+activity.confirm.*; updated the lede (was "nothing here can be undone").How it flows
undo button →
POST /undoreturns a pending inverse proposal → confirmation card → commit/reject (the existing #51 endpoints) → audit list refreshes. The undo is itself confirmed + audited (consistent with the write-confirmation discipline), exactly as ADR-0031 intends.Verification (local)
@carol/api-client: typecheck ✓ · lint ✓ ·check✓ (no spec change) · test ✓ 42@carol/client: typecheck ✓ · lint ✓ · test ✓ 156 (+2isUndoablecases)en.jsonvalid; semgrep (CI pack set) ✓ 0 findings on the new/changed files⚠️ Needs maintainer verification (headless limit)
Client vitest is
node-env — the visual undo button, confirmation card, and the commit→refresh interaction need a real PWA/device check.Out of scope (follow-ups)
Part of epic #47.
Closes #356
🤖 Generated with Claude Code
📊 Test coverage
Patch coverage: no testable lines changed.
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Soft thresholds per ADR-0019. Coverage is informational and does not block merge.