package main import ( "fmt" "verstak/internal/core/config" "verstak/internal/core/watcher" ) // WatcherStatus returns whether the real-time file watcher is active. func (a *App) WatcherStatus() (bool, error) { if err := a.requireVault(); err != nil { return false, err } return a.fileWatcher.IsWatching(), nil } // RunSnapshotScan performs a one-shot scan and returns results. func (a *App) RunSnapshotScan() (*watcher.SnapshotResult, error) { if err := a.requireVault(); err != nil { return nil, err } return a.fileWatcher.RunScanner() } // ToggleFileWatcher enables or disables the real-time file watcher. // Changing this persists to app config (~/.config/verstak/config.json → vault.file_watcher). // // При включении: запускает snapshot scan (сверка диска с БД), затем включает real-time watcher. // При отключении: останавливает fsnotify, watcher_state в БД сохраняется. // // Отключить watcher НАВСЕГДА (независимо от галки): // export VERSTAK_NO_WATCHER=1 // // Отключить на один запуск: // verstak-gui --no-watcher // // Snapshot scan запускается ВСЕГДА при открытии vault, даже при FileWatcher=false. func (a *App) ToggleFileWatcher(enable bool) error { if err := a.requireVault(); err != nil { return err } cfg, err := config.LoadAppConfig() if err != nil || cfg == nil { return fmt.Errorf("config: %w", err) } cfg.Vault.FileWatcher = config.BoolPtr(enable) if err := config.SaveAppConfig(cfg); err != nil { return fmt.Errorf("save config: %w", err) } if enable { _, err := a.fileWatcher.RunScanner() if err != nil { return fmt.Errorf("scan: %w", err) } if _, err := a.fileWatcher.Start(true); err != nil { return fmt.Errorf("start watcher: %w", err) } } else { a.fileWatcher.Stop() } return nil }