Your gentle digital gravedigger
Relfa scans your inbox for old files, lets you know what's gathering dust, and helps you archive it.
) )
) )
)
) )
Motivation
In our daily digital lives, we constantly download, capture, and create small bursts of information — a PDF here, a draft note there, a temporary screenshot, today’s meeting summary. We save them quickly, intending to return later to tidy things up. But “later” rarely comes, and before long our computers fill with forgotten files and disorganized corners of digital clutter.
Relfa is the gentle gravedigger for your digital workspace. When a file begins to gather dust, it doesn't act hastily. First, it offers a quiet reminder—a chance for you to decide if the file's time has come. If it continues to sit untouched, Relfa then performs its final, gentle duty: respectfully moving the file to a well-organized graveyard. This two-step process ensures that archival is an intentional choice, not an accident, keeping your active workspace for the living, not the forgotten.
This tool isn’t about perfection. It’s about being present for what we’ve discarded and giving ourselves another chance to choose what stays.
Features
- Dual-Threshold System: Relfa uses two time limits. A "soft" threshold gently notifies you of stale files, while a "hard" threshold automatically archives them, keeping your workspace tidy without constant intervention.
- Flexible Archival: Files are stored in a highly-organized "graveyard." Using symlinks, you can browse archived files by their creation, modification, or archival date, all without duplicating a single file.
- Interactive Review: For files that need a personal touch, the
reviewcommand lets you process them one-by-one with options to archive, delete, view, open, or skip. - Epitaphs for Posterity: When archiving, you can attach an "epitaph" — a note explaining the file's context. These notes are stored alongside the file and are fully searchable.
- Powerful Search & Resurrection: Easily find archived files by searching filenames or epitaph content. The
resurrectcommand brings files back from the graveyard to your inbox. - Declarative & Automated: Full support for Nix and Home Manager allows for declarative configuration and automated execution with systemd timers.
- Desktop Integration: Get desktop notifications for scan results and open files directly in their default applications.
Usage
To see which files in your inbox have exceeded the age_threshold_days, run:
This will print a list of "stale" files and another list of files that are old enough to be auto-archived. This command is read-only and will not modify any files.
For a guided, one-by-one review of your stale files, run:
For each file, you will be prompted to choose an action:
(a)rchive: Move the file to the graveyard.(n)ote+archive: Archive the file and attach an epitaph (a descriptive note).(d)elete: Permanently delete the file (requires confirmation).(v)iew: Preview the file's content using your configured pager.(o)pen: Open the file with its default application.(s)kip: Do nothing and move to the next file.(q)uit: Exit the review session.
The archive command is flexible and has several modes.
Auto-Archiving
To automatically archive all files that have exceeded the auto_archive_threshold_days, simply run archive with no arguments:
# Archives all files older than the "hard limit" threshold.
# You can also add a note to all auto-archived files.
Archiving Specific Files or All Stale Files
# Archive a single, specific item from your inbox.
# Archive all stale files (those older than the "soft limit").
To find files you've already archived, use the search command. It searches both filenames and epitaph content.
To bring a file back from the graveyard to your inbox, use resurrect. This copies the file back, leaving the original in the graveyard.
If your search term matches multiple files, Relfa will present a list for you to choose from.
Installation
The recommended way to use Relfa is declaratively through its Home Manager module, which allows for easy configuration and automated execution. See the Home Manager Configuration section for details.
For quick trials or environments without Home Manager, you can use one of the following nix commands:
Temporary Execution
To run Relfa without installing it, use nix run:
# Example:
Persistent Installation
To install Relfa into your user profile, making it available in your shell, run:
If you have the Rust toolchain installed on your system, you can install Relfa directly from crates.io using cargo:
This command will download the source code, compile it, and place the relfa binary in your Cargo binary path (~/.cargo/bin/), which should be in your system's PATH.
At the moment, pre-compiled binaries are not officially provided. I am waiting to see if there is sufficient user interest before setting up a build pipeline for different platforms.
If you would like to see official binaries for your operating system (e.g., Linux x86_64, macOS, Windows), please open an issue on GitHub. This will help me gauge demand and prioritize which platforms to support.
Configuration
Relfa is configured via a TOML file located at ~/.config/relfa/config.toml.
You can generate a configuration file with default values by running:
This will create the file if it doesn't exist and print the current settings.
Example config.toml
# Path to the directory you want Relfa to monitor.
= "/home/user/Inbox"
# Path to the directory where archived files will be stored.
= "/home/user/Graveyard"
# (Soft limit) Files older than this (in days) are considered "stale"
# and will be shown during a `scan` or `review`.
= 3
# (Hard limit) Files older than this (in days) will be automatically
# archived when you run `relfa archive` without any arguments.
= 7
# How to deliver notifications. Can be "cli" or "desktop".
= "desktop"
# The command to use for viewing files with the `review` command.
# Defaults to your $PAGER environment variable, or "less".
= "less"
# Configuration for the graveyard's directory structure.
[]
# A template for creating date-based paths.
# Available variables: {hostname}, {year}, {month}, {day}, {month:02}, {day:02}
= "{hostname}/{year}/{month:02}/{day:02}"
# Defines a subdirectory for organizing files by their creation date.
# `type = "original"` means the actual files are stored here.
[]
= "original"
= "created"
# Defines a subdirectory for organizing files by their modification date.
# `type = "symlink"` means this directory will contain symbolic links.
# `target = "created"` means the links will point to the files in the "created" subdirectory.
[]
= "symlink"
= "modified"
= "created"
# Defines a subdirectory for organizing files by their archival date.
# In this example, this view is disabled.
[]
= "nothing"
For users of Nix and Home Manager, Relfa provides a module for declarative configuration.
-
Add the flake to your inputs:
# flake.nix { inputs = { relfa.url = "github:nilp0inter/relfa"; # ... other inputs }; } -
Import the module in your
home.nix:{ inputs, ... }: { imports = [ inputs.relfa.homeManagerModules.relfa ]; } -
Configure Relfa:
The
programs.relfa.settingsblock is required for the program to run. Note that thepath_formatsection and its sub-sections are also mandatory.# home.nix programs.relfa = { enable = true; settings = { inbox = "${config.home.homeDirectory}/Downloads"; graveyard = "${config.home.homeDirectory}/Archive"; age_threshold_days = 5; auto_archive_threshold_days = 14; notification = "desktop"; # The `path_format` block is required. path_format = { date_format = "{hostname}/{year}/{month:02}/{day:02}"; created_subdir = { type = "original"; name = "created"; }; modified_subdir = { type = "symlink"; name = "modified"; target = "created"; }; archived_subdir = { type = "symlink"; name = "archived"; target = "created"; }; }; }; # Optional: Enable a systemd timer for automated execution. timer = { enable = true; # Run `relfa scan` daily. command = "scan"; frequency = "daily"; # Add a random delay to avoid running at the exact same time as other services. randomizedDelay = "1h"; }; };
Timer Options
The timer submodule allows you to automate Relfa's execution.
command: Which command to run. Can be"scan","archive", or"scan-then-archive".frequency: How often to run the command. Acceptssystemd.timecalendar event formats (e.g.,"daily","hourly","*:0/30"for every 30 minutes).randomizedDelay: A random delay to add before execution (e.g.,"1h","30m").
Development
The official and recommended development setup for Relfa uses Nix and Direnv. While other setups are possible, they are not officially supported and are left to the user's discretion.
Prerequisites
Before you begin, ensure you have both Nix and Direnv installed on your system.
Setup
Setting up the development environment is a one-step process. Simply navigate to the project's root directory in your terminal and run:
This command will trigger the Nix flake to build the complete development environment. It automatically:
- Downloads and installs all necessary dependencies (Rust toolchain, etc.).
- Configures and installs the required Git hooks.
- Activates a
devshellwith pre-configured aliases for common tasks (build, test, format, etc.).
Workflow
Once the environment is active, you will have access to a devshell menu with commands for building, testing, and formatting the code.
The installed Git hooks will run automatically on every commit. These hooks check for correct formatting and ensure the project compiles, helping to guarantee that your changes will pass the CI pipeline.
Community
Contributing
Contributions are welcome, but please follow these guidelines to ensure a smooth process.
- Reporting Issues: If you find a bug, please open an issue. Include your OS, Relfa version, and clear steps to reproduce the problem.
- Feature Requests: If you have an idea for a new feature, please open an issue to start a discussion. Please do not submit a pull request for a new feature without prior discussion and approval in an issue.
- Code Contributions:
- Pull requests are welcome for bug fixes only.
- Your pull request must include tests that demonstrate the bug and verify your fix.
- To contribute:
- Fork the repository.
- Create a branch for your fix (
git checkout -b fix/some-bug). - Implement your changes and add corresponding tests.
- Submit a pull request that links to the relevant issue.
Legal
This project is licensed under the MIT License. See the LICENSE file for details.