feat: Add auto-snapshot feature with git commit every N words

- Add new module src/app/auto_snapshot.rs for auto-snapshot functionality
- Add configuration options: auto_snapshot_enabled (default: false) and
  auto_snapshot_threshold (default: 250 words)
- Automatically create git commits when word count crosses threshold boundaries
- Add 'Edit -> Snapshots' menu option to open snapshots window
- Snapshots window shows: enable/disable toggle, threshold setting, current
  word count, next snapshot target, list of all snapshots with rollback buttons
- Manual snapshot creation via button in snapshots window
- Rollback to any previous snapshot with one click
- Snapshot info includes: word count, timestamp, commit message, commit hash
- Make run_git in gitsync.rs public for use by auto_snapshot module
- Update README.md with Auto-Snapshots documentation

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
landon
2026-09-16 12:11:35 -05:00
parent dcb97da518
commit aafe1786b5
6 changed files with 378 additions and 1 deletions
+14
View File
@@ -17,6 +17,7 @@ use std::thread;
use std::time::{Duration, Instant};
mod autocomplete;
mod auto_snapshot;
mod beats;
mod characters;
mod diff;
@@ -388,6 +389,12 @@ pub struct App {
story_bible_editor_content: String,
/// The workspace-relative path of the file being edited in the Story Bible editor.
story_bible_editor_path: Option<String>,
/// List of auto-snapshots for rollback.
snapshots: Vec<crate::app::auto_snapshot::SnapshotInfo>,
/// Word count at the last auto-snapshot.
last_snapshot_word_count: usize,
/// Whether the snapshots window is open.
show_snapshots: bool,
}
impl App {
@@ -495,6 +502,9 @@ impl App {
show_story_bible_editor: false,
story_bible_editor_content: String::new(),
story_bible_editor_path: None,
snapshots: Vec::new(),
last_snapshot_word_count: 0,
show_snapshots: false,
};
app.load_spell_dict();
app.open_workspace();
@@ -625,6 +635,10 @@ impl eframe::App for App {
self.story_bible_editor_window(ctx);
}
if self.show_snapshots {
self.snapshots_window(ctx);
}
if self.show_manuscript_settings {
self.manuscript_settings_window(ctx);
}