π Table of Contents
- β¨ Features
- π Quick Start
- βοΈ Configuration
- π Rules
- β¨οΈ Keybindings
- π¨ Themes
- ποΈ Architecture
- π§ Building from Source
- π€ Contributing
- π License
β¨ Features
π Smart File Watching
Watch any folder for new and changed files with configurable debouncing and recursive monitoring.
π― Flexible Rules Engine
Define powerful rules with conditions based on name, extension, size, age, and more.
β‘ Powerful Actions
Move, copy, rename, delete, archive files, or run custom scripts β all automated.
π₯οΈ Beautiful TUI
A gorgeous terminal interface for managing rules and monitoring activity in real-time.
π§ Background Daemon
Set it and forget it β the daemon runs quietly and applies rules 24/7.
π Simple Configuration
Human-readable TOML config that's easy to write and maintain.
Feature Highlights
| Feature | Description |
|---|---|
| π Pattern Matching | Glob patterns and regex for precise file matching |
| π Size Conditions | Filter files by size (greater than, less than) |
| π Age Conditions | Match files by modification date |
| π·οΈ Multiple Extensions | Match any of multiple file types |
| π Recursive Watching | Monitor subdirectories automatically |
| π¨ 15 Built-in Themes | From Dracula to Cyberpunk |
| π Dry Run Mode | Preview what would happen before applying |
| π Activity Log | Full history of all file operations |
π Quick Start
Installation
Homebrew (Recommended)
Cargo
From Source
First Run
Hazelnut needs two things to work:
- Watch folders β which directories to monitor
- Rules β what to do with files in those folders
β οΈ Important: Rules alone won't do anything! You must also configure at least one watch folder.
- Create a config file at
~/.config/hazelnut/config.toml:
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# STEP 1: Define which folders to watch
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[[]]
= "/home/youruser/Downloads" # Use full path (~ not expanded)
= false # Set true to include subfolders
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# STEP 2: Define rules for what to do with files
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[[]]
= "Organize PDFs"
[]
= "pdf"
[]
= "move"
= "/home/youruser/Documents/PDFs"
- Launch the TUI to manage and monitor:
- Or start the daemon to run in the background:
βοΈ Configuration
Hazelnut uses TOML for configuration. The default location is:
~/.config/hazelnut/config.toml
Full Configuration Example
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# General Settings
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[]
# Logging level: trace, debug, info, warn, error
= "info"
# Optional log file path
= "~/.local/share/hazelnut/hazelnut.log"
# Preview actions without executing (great for testing)
= false
# Wait time (seconds) before processing a file after change detected
= 2
# Theme for the TUI
= "catppuccin-mocha"
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Watch Folders
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[[]]
= "~/Downloads"
= false
[[]]
= "~/Desktop"
= false
# Only apply specific rules to this folder
= ["screenshots", "temp-files"]
[[]]
= "~/Documents/Inbox"
= true # Watch subdirectories too
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Rules
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[[]]
= "Organize PDFs"
= true
= false # Continue checking other rules
[]
= "pdf"
[]
= "move"
= "~/Documents/PDFs"
= true
= false
[[]]
= "Screenshots"
= true
[]
= "Screenshot*.png"
[]
= "move"
= "~/Pictures/Screenshots"
[[]]
= "Clean Old Downloads"
= true
[]
= 30
= ["tmp", "log", "bak"]
[]
= "trash"
See docs/configuration.md for the complete reference.
Watch Editor (TUI)
You can manage watch folders directly in the TUI:
- Add a new watch: Press
aornin the Watches view - Edit an existing watch: Select a watch and press
e - Delete a watch: Select a watch and press
d
The watch editor dialog allows you to configure:
- Path - Full path to the folder to watch (use absolute paths,
~is not expanded) - Recursive - Whether to include subdirectories
Use Tab to move between fields, Enter to save, and Esc to cancel.
π Rules
Rules are the heart of Hazelnut. Each rule has a condition (what files to match) and an action (what to do with them).
Conditions
All conditions in a rule must match for the rule to apply.
File Name
[]
# Glob pattern matching
= "Screenshot*.png"
# Regex pattern matching
= "^invoice_\\d{4}\\.pdf$"
File Extension
[]
# Single extension
= "pdf"
# Multiple extensions (match any)
= ["jpg", "jpeg", "png", "gif", "webp"]
File Size
[]
# Size in bytes
= 10485760 # > 10 MB
= 1048576 # < 1 MB
File Age
[]
# Age in days (based on modification time)
= 30 # Older than 30 days
= 7 # Newer than 7 days
File Type
[]
= false # Match only files
= true # Match hidden files (starting with .)
Actions
Move
[]
= "move"
= "~/Documents/Archive"
= true # Create folder if missing
= false # Don't overwrite existing files
Copy
[]
= "copy"
= "~/Backup"
= true
= false
Rename
[]
= "rename"
= "{date}_{name}.{ext}"
Available variables:
| Variable | Description | Example |
|---|---|---|
{name} |
Filename without extension | document |
{filename} |
Full filename | document.pdf |
{ext} |
Extension | pdf |
{path} |
Full path | /home/user/document.pdf |
{dir} |
Parent directory | /home/user |
{date} |
Current date | 2024-01-15 |
{datetime} |
Current datetime | 2024-01-15_14-30-00 |
{date:FORMAT} |
Custom format | {date:%Y%m%d} β 20240115 |
Trash
[]
= "trash"
Moves files to the system trash (recoverable).
Delete
[]
= "delete"
β οΈ Warning: This permanently deletes files!
Run Command
[]
= "run"
= "convert"
= ["{path}", "-resize", "50%", "{dir}/{name}_small.{ext}"]
Archive
[]
= "archive"
= "~/Archives"
= false
Rule Editor (TUI)
You can create and edit rules directly in the TUI without editing the config file:
- Create a new rule: Press
nin the Rules view - Edit an existing rule: Select a rule and press
e - Delete a rule: Select a rule and press
d
The rule editor dialog allows you to configure:
- Name - A descriptive name for your rule
- Enabled - Toggle the rule on/off
- Conditions - Extension, name patterns (glob/regex), size limits, age limits, is_directory, is_hidden
- Action - Move, Copy, Rename, Trash, Delete, Run Command, or Archive
Use Tab to move between fields, Enter to save, and Esc to cancel.
π‘ Remember: Rules only apply to files in watched folders. Make sure you've configured at least one
[[watch]]entry in your config, or add one via the Watches view.
Example Rules
[[]]
= "Screenshots to folder"
[]
= "Screenshot*.png"
[]
= "move"
= "~/Pictures/Screenshots"
[[]]
= "PDFs to Documents"
[]
= "pdf"
[]
= "move"
= "~/Documents/PDFs"
[[]]
= "Spreadsheets to Documents"
[]
= ["xlsx", "xls", "csv"]
[]
= "move"
= "~/Documents/Spreadsheets"
[[]]
= "Delete old temp files"
[]
= 30
= ["tmp", "log", "bak"]
[]
= "trash"
[[]]
= "Prefix invoices with date"
[]
= "^invoice.*\\.pdf$"
[]
= "rename"
= "{date:YYYY-MM-DD}_{filename}"
[[]]
= "Compress large images"
[]
= ["jpg", "png"]
= 5242880 # > 5 MB
[]
= "run"
= "convert"
= ["{path}", "-quality", "80", "{path}"]
β¨οΈ Keybindings
Global
| Key | Action |
|---|---|
Tab |
Next view |
Shift+Tab |
Previous view |
1 2 3 4 |
Jump to view (Dashboard, Rules, Watches, Log) |
s |
Open settings |
t |
Open theme picker |
A |
About Hazelnut |
? / F1 |
Show help |
q |
Quit (from Dashboard) |
Ctrl+c / Ctrl+q |
Force quit |
Navigation
| Key | Action |
|---|---|
β / k |
Move up |
β / j |
Move down |
g / Home |
Go to first item |
G / End |
Go to last item |
PageUp |
Page up |
PageDown |
Page down |
Rules View
| Key | Action |
|---|---|
Enter / Space |
Toggle rule enabled/disabled |
e |
Edit selected rule |
n |
Create new rule |
d / Delete |
Delete selected rule |
Watches View
| Key | Action |
|---|---|
a / n |
Add new watch folder |
e |
Edit selected watch |
d / Delete |
Delete selected watch |
o / Enter |
Open folder |
Log View
| Key | Action |
|---|---|
c |
Clear log |
Theme Picker
| Key | Action |
|---|---|
β / k |
Previous theme (with live preview) |
β / j |
Next theme (with live preview) |
Enter |
Apply selected theme |
Esc |
Cancel |
π¨ Themes
Hazelnut includes 15 beautiful themes based on popular terminal and editor color schemes.
Press t in the TUI to open the theme picker with live preview.
Available Themes
| Theme | Description |
|---|---|
| π¦ Dracula | Dark purple aesthetic (default) |
| π One Dark Pro | Atom's iconic dark theme |
| βοΈ Nord | Arctic, bluish color palette |
| π± Catppuccin Mocha | Warm pastel dark theme |
| β Catppuccin Latte | Warm pastel light theme |
| πΈ Gruvbox Dark | Retro groove colors |
| π Gruvbox Light | Retro groove, light variant |
| π Tokyo Night | Futuristic dark blue |
| π Solarized Dark | Precision colors, dark |
| π Solarized Light | Precision colors, light |
| π¨ Monokai Pro | Classic syntax highlighting |
| πΉ RosΓ© Pine | All natural pine with soho vibes |
| π Kanagawa | Inspired by Katsushika Hokusai |
| π² Everforest | Comfortable green forest theme |
| π Cyberpunk | Neon-soaked futuristic theme |
ποΈ Architecture
Hazelnut consists of two binaries that work together:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β hazelnut (TUI) β
β β’ Manage rules β
β β’ Monitor activity β
β β’ Change themes β
β β’ View logs β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
Unix Socket
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β hazelnutd (Daemon) β
β β’ Watch folders β
β β’ Evaluate rules β
β β’ Execute actions β
β β’ Run 24/7 in background β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β File System β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
hazelnut β The TUI
Interactive terminal interface for:
- Viewing and managing rules
- Monitoring watch folders
- Viewing activity logs
- Changing themes
- Sending commands to the daemon
hazelnutd β The Daemon
Background service that does the actual work:
Daemon Commands
| Command | Description |
|---|---|
start |
Start daemon in background, detached from terminal |
stop |
Gracefully stop the daemon (SIGTERM) |
restart |
Stop and start the daemon |
status |
Show running state, PID, uptime, and log location |
reload |
Hot-reload config via SIGHUP (no restart needed) |
run |
Run in foreground with live logging (for debugging) |
Status Output
File Locations
| File | Path | Purpose |
|---|---|---|
| PID file | $XDG_RUNTIME_DIR/hazelnutd.pid |
Tracks running daemon |
| Log file | ~/.local/state/hazelnut/hazelnutd.log |
Daemon activity log |
| Config | ~/.config/hazelnut/config.toml |
Rules and settings |
Typical Workflow
# 1. Edit your rules in the TUI or config file
# 2. Start the daemon
# 3. Check it's running
# 4. After editing rules, reload without restart
# 5. View logs if needed
π§ Building from Source
Requirements
- Rust 1.93+ (uses Edition 2024 features)
- Linux or macOS
Build
# Clone the repository
# Build release binary
# The binaries will be at:
# - target/release/hazelnut
# - target/release/hazelnutd
# Or install directly
Development
# Run TUI in development
# Run daemon in foreground
# Run with sample config
# Run tests
# Run linter
# Format code
π€ Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Quick Start for Contributors
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
cargo test - Run clippy:
cargo clippy - Format:
cargo fmt - Commit:
git commit -m "Add amazing feature" - Push:
git push origin feature/amazing-feature - Open a Pull Request
Project Structure
hazelnut/
βββ src/
β βββ main.rs # TUI entry point
β βββ daemon.rs # Daemon entry point
β βββ lib.rs # Library root
β βββ theme.rs # Color themes
β βββ app/ # TUI application
β β βββ events.rs # Key event handling
β β βββ state.rs # Application state
β β βββ ui.rs # UI rendering
β βββ config/ # Configuration loading
β βββ rules/ # Rule engine
β β βββ action.rs # Rule actions
β β βββ condition.rs # Rule conditions
β β βββ engine.rs # Rule evaluation
β βββ watcher/ # File system watcher
β βββ ipc/ # TUI-daemon communication
βββ docs/
β βββ configuration.md # Full config reference
βββ screenshots/ # Screenshots for docs
βββ tests/ # Integration tests
π License
This project is licensed under the MIT License β see the LICENSE file for details.