Adds a "Select to Delete" toggle that enables batch deletion mode.
When active, clicking graph nodes or checking linear log checkboxes
selects them (highlighted in red), and a "Delete N Nodes" button
performs batch deletion with backup, branch tip cleanup, and HEAD
reassignment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Delete sequence: add ui_reset_token increment to prevent shifted
sequences from inheriting deleted sequence's widget state
- Promote: update data_cache with single_data so UI reflects the
file format change without requiring a manual refresh
- Mass update & clone: use copy.deepcopy to avoid shared mutable
references between sequences
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Explicitly reassign st.session_state.data_cache after mass update
to ensure Streamlit picks up in-place mutations to the batch data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Increment ui_reset_token after mass update save so Streamlit
widgets re-read their values, matching all other save operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use brighter node colors (yellow, green, light blue) and white font
for better visibility on dark backgrounds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Uses streamlit-agraph for interactive node selection. Clicking a node
restores that version. Falls back to static graphviz if not installed.
Requires: pip install streamlit-agraph
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Vertical graphs now render at natural size instead of stretching to
fill container width, which was making nodes appear giant.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reduces font sizes, padding, spacing, and note truncation length
specifically for vertical (TB) mode to improve usability.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows propagating field values from one sequence to multiple/all other
sequences. Includes source selector, field multi-select, target checkboxes
with Select All toggle, preview, and history snapshot on apply.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Combine stable and WIP timeline tabs into one with all features:
view switcher, restore/rename/delete, and data preview panel.
Add adaptive graph spacing based on node count, show full dates
and branch names on node labels, increase label truncation to 25
chars, and drop streamlit-agraph dependency.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
st.radio was called with an empty list when no JSON files existed,
causing Streamlit to error and only render the sidebar.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These fields were previously gated behind filename checks ("vace"/"i2v"
in filename), hiding them when the filename didn't match. Since DEFAULTS
includes all these keys, always render them.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Batch creation now seeds one item from DEFAULTS (which includes all
VACE/I2V keys) instead of creating an empty batch_data list.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Set nav_path_input before the widget renders and use on_change callbacks
instead of modifying widget state after instantiation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- save_json() now writes to a temp file then uses os.replace() for atomic writes
- Replace hardcoded "batch_data", "history_tree", "prompt_history", "sequence_number"
strings with constants (KEY_BATCH_DATA, etc.) across all modules
- Add 29 unit tests for history_tree, utils, and json_loader
- Add type hints to public functions in utils.py, json_loader.py, history_tree.py
- Remove ALLOWED_BASE_DIR restriction that blocked navigating outside app CWD
- Fix path text input not updating on navigation by using session state key
- Add unpin button (❌) for removing pinned folders
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace bare except clauses with specific exceptions (JSONDecodeError, IOError, ValueError, TypeError)
- Add path traversal protection restricting navigation to ALLOWED_BASE_DIR
- Sanitize iframe URLs with scheme validation and html.escape to prevent XSS
- Extract duplicate to_float/to_int to module-level helpers in json_loader.py
- Replace silent modulo wrapping with clamped bounds checking via get_batch_item()
- Remove hardcoded IP 192.168.1.51:5800, default to empty string
- Add try/except around fragile batch history string parsing
- Add JSON schema validation (dict type check) in read_json_data()
- Add Python logging framework, replace print() calls
- Consolidate session state initialization into loop with defaults dict
- Guard streamlit_agraph import with try/except ImportError
- Add backup snapshot before history node deletion
- Add cycle detection in HistoryTree.commit()
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>