π 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. Paths support ~, $VAR, and ${VAR} expansion.
π― Flexible Rules Engine
Define powerful rules with conditions based on name, extension, size, age, and more. Multiple rules can match the same file β all matching rules execute in order.
β‘ Powerful Actions
Move, copy, rename, delete, archive files or directories, send to trash, or run custom scripts β all automated. Cross-filesystem moves are handled transparently.
π₯οΈ 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 |
| π Desktop Notifications | Get alerted on errors (cross-platform) |
| π Activity Log | Full history of all file operations |
π Quick Start
Installation
macOS
# Homebrew (recommended - fast, pre-built binary)
Linux
# Homebrew
# Or via Cargo
Arch Linux (pacman)
Windows
# Via Cargo (requires Rust toolchain)
# Or download pre-built binary from GitHub Releases:
# https://github.com/ricardodantas/hazelnut/releases
From Source
Note: The daemon (
hazelnutd) is only available on macOS and Linux. On Windows, only the TUI (hazelnut) is available.
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" # Full path, ~, $HOME all work
= 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 config file is always located at:
~/.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"
# Wait time (seconds) before processing a file after change detected
= 2
# How often to check for file changes (seconds)
= 5
# Desktop notifications on errors (cross-platform)
= true
# 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 - Path to the folder to watch (supports
~,$VAR,${VAR}, or absolute paths) - 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 (empty if none) |
{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
All files use consistent paths across Linux and macOS:
| File | Path | Purpose |
|---|---|---|
| Config | ~/.config/hazelnut/config.toml |
Rules and settings |
| PID file | ~/.local/state/hazelnut/hazelnutd.pid |
Tracks running daemon |
| Log file | ~/.local/state/hazelnut/hazelnutd.log |
Daemon activity log |
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 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 GPL-3.0-or-later license β see the LICENSE file for details.