0d1415fca4
Comprehensive audit pass across the JS frontend and Python backend. Bugs / correctness: - Swap & restore now pre-save current state (hash-deduped) so unsaved edits aren't lost when swapping/restoring, incl. rapid double-swap - Unify captureSnapshot/captureNodeSnapshot into _captureCore; node captures now update the dedup hash (no duplicate auto-snapshot after) - Cycle guard in getDisplayPath; Ctrl+S ignores text fields and the other-workflow view; tolerant API error parsing; prompt default pre-fill Security / robustness (backend): - Validate workflowKey against path traversal (reject ./.. + containment) - Generic 500 messages (no exception-string leak), logged server-side - Request body-size cap + migrate record cap - Atomic writes (temp file + os.replace) on all write paths Performance / memory: - /list omits base64 thumbnails (hasThumbnail flag, lazy-loaded client-side) - LRU-bounded previous-graph cache; persistent (prune+LRU) SVG cache - Incremental in-place updates for lock/note instead of full list rebuild UX / docs: - Busy-op feedback, named-delete confirm, relative timestamps - README: remove disabled branching feature, fix version badge & storage paths Features: - Export / Import snapshots (export route + reuse migrate) - Storage-usage display (usage route + footer label) - Pause auto-capture toggle - Age-based retention (maxAgeDays setting + prune param) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>