#!/usr/bin/env nu # Clean file watcher with signal-based exit use utils.nu # Clean file watcher that handles Ctrl+C gracefully def main [config_file: string = "config/build.config.toml"] { # Load configuration let config = (open $config_file) let watch_files = [ "src/index.html", "src/assets/css/modules/base.css", "src/assets/css/modules/components.css", "src/assets/css/modules/animations.css", "src/assets/css/modules/patterns.css", "src/assets/css/svg-data.css" ] print "👁️ Clean file watcher starting..." print "📝 Press Ctrl+C for clean exit" # Create stop signal file let stop_file = "/tmp/dev_watcher_stop" # Register signal handler using external process ^bash -c "trap 'touch /tmp/dev_watcher_stop' INT; while [ ! -f /tmp/dev_watcher_stop ]; do sleep 0.1; done" & mut initial_times = ($watch_files | each { |file| if ($file | path exists) { { file: $file, mtime: (ls $file | get modified | first) } } } | where ($it != null)) # Main watch loop while not ($stop_file | path exists) { sleep 1sec let current_times = ($watch_files | each { |file| if ($file | path exists) { { file: $file, mtime: (ls $file | get modified | first) } } } | where ($it != null)) let changed_pairs = ($current_times | zip $initial_times | where { |pair| $pair.0.mtime != $pair.1.mtime }) if ($changed_pairs | length) > 0 { let changed_files = ($changed_pairs | each { |pair| $pair.0.file }) print $"📝 Changed files: ($changed_files | str join ', ')" # Rebuild print "🔨 Rebuilding..." ^nu scripts/build.nu dev # Update times $initial_times = $current_times } } # Clean exit rm -f $stop_file print "" print "🛑 File watcher stopped cleanly" }