- Remove unused `random` import and `KEY_PROMPT_HISTORY` from app.py
- Remove dead session state keys: edit_history_idx, append_prompt, rand_seed
- Clean up extra blank lines in json_loader.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Walks each path component and matches against actual directory entries
when an exact match fails on Linux. Widget resyncs to the corrected
canonical path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Templates now generate batch_prompt_i2v.json and
batch_prompt_vace_extend.json as batch files. Create New JSON
always creates batch files since single mode is deprecated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes leftover file_selector and loaded_file state when the current
directory has no JSON files, preventing stale data from persisting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The inline check caused mismatches between typed and resolved paths.
Now uses on_change callback that always sets _sync_nav_path flag,
so the widget is synced to the canonical current_dir path on the
next rerun before the widget renders.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use _sync_nav_path flag to defer the revert to the next rerun, before
the widget is instantiated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The on_change callback had timing issues with Streamlit's session state,
causing user input to be discarded. Now checks the widget value inline
after render and triggers rerun on valid directory change.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The nav_path_input was force-overwritten on every rerun, causing
Streamlit to discard user edits before the on_change callback could
process them. Now only syncs on first load or external changes
(favorites). Also resets loaded_file on dir change and reverts
widget on invalid paths.
Co-Authored-By: Claude Opus 4.6 <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>
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>