Skip to main content

Filemindr

Declarative local file automation using profiles.

Filemindr lets you describe what should happen to your files, not how.

You define rule pipelines in YAML, group them into profiles, and run them safely through a clean CLI.

Built as a learning and portfolio project with strong focus on:

  • predictable behavior
  • safety by default
  • excellent CLI DX

Features

  • Profile-based configuration in ~/.filemindr
  • Declarative YAML rules
  • Rule engine with priority, where the highest match wins
  • Match by:
    • file extension
    • filename regex
    • file age with older_than_days
  • Actions:
    • move_to
    • copy_to
    • rename_template
    • stem_safe placeholder support
  • Global and per-rule conflict policies:
    • rename
    • skip
    • overwrite
    • trash
  • Dry-run mode
  • JSON execution reports
  • Explain mode
  • Watch mode
  • Run history with list, show, prune, and clear
  • Final summary report
  • Structured logging with INFO and DEBUG
  • Cross-platform support for Windows, macOS, and Linux

Installation

pipx install filemindr

or

pip install filemindr

Development setup:

uv sync --extra dev

Profiles

Instead of a single global YAML, Filemindr uses profiles.

Each profile lives in:

~/.filemindr/rules/<profile>/rules.yaml

And all profiles are registered in:

~/.filemindr/profiles.yaml

This allows:

  • multiple setups such as home, work, or media
  • explicit selection via CLI
  • zero ambiguity about which config is running

Quick Start

Create your first profile:

filemindr profile init home

This creates:

~/.filemindr/
|-- profiles.yaml
`-- rules/
    `-- home/
        `-- rules.yaml

Open and edit the rules:

filemindr profile open home

Example rules.yaml:

source: ~/Downloads
default_target: ~/Downloads/others
conflict_policy: rename

rules:
  - name: invoices
    priority: 100
    match:
      extensions: ["pdf"]
      regex: "(?i)invoice|nota|nf"
    action:
      move_to: ~/Downloads/finance/invoices

  - name: dated-pdfs
    priority: 70
    match:
      extensions: ["pdf"]
    action:
      move_to: ~/Downloads/archive/{yyyy}/{mm}
      rename_template: "{stem}_{yyyy}-{mm}{suffix}"

  - name: images
    priority: 40
    match:
      extensions: ["jpg", "png", "webp"]
    action:
      move_to: ~/Downloads/images

Important notes:

  • Rule priority matters. If two rules match the same file, the higher priority wins.
  • rename_template only defines the final file name, not folders.
  • move_to and copy_to can use templates in the destination path.
  • ignore accepts glob-style patterns and skips matching files in run, watch, and explain.

Example ignore rules:

ignore:
  - "*.tmp"
  - "*.crdownload"
  - "~$*"

Example with ignore plus a rule:

source: ~/Downloads
default_target: ~/Downloads/others
ignore:
  - "*.tmp"
  - "*.crdownload"

rules:
  - name: documents
    priority: 50
    match:
      extensions: ["pdf"]
    action:
      move_to: ~/Downloads/documents

Supported template fields:

  • {name}
  • {stem}
  • {stem_safe}
  • {suffix}
  • {ext}
  • {parent}
  • {yyyy}
  • {mm}
  • {dd}

Preview:

filemindr run -p home --dry-run

Verbose preview:

filemindr run -p home --dry-run --log-level DEBUG

Run:

filemindr run -p home

Write a JSON report:

filemindr run -p home --report report.json

Example report payload:

{
  "profile": "home",
  "command": "run",
  "dry_run": false,
  "summary": {
    "files_scanned": 55,
    "moved": 55,
    "copied": 0,
    "errors": 0
  },
  "by_rule": {
    "dated-pdfs": 22,
    "images": 12
  },
  "events": [
    {
      "event": "moved",
      "rule": "dated-pdfs",
      "source": "C:/Users/you/Downloads/Day Trade-2025.pdf",
      "destination": "C:/Users/you/Downloads/archive/2026/03/day-trade-2025_2026-03.pdf"
    }
  ]
}

Profile Commands

Create:

filemindr profile init home

List:

filemindr profile list

Show path:

filemindr profile show home

Open in editor:

filemindr profile open home

Remove completely:

filemindr profile remove home

Watch Mode

Continuous:

filemindr watch -p home

Single batch:

filemindr watch -p home --once

Explain Mode

Explain a directory:

filemindr explain -p home ~/Downloads

Explain a single file with spaces in the path:

filemindr explain -p home "C:\Users\you\Downloads\Day Trade-2025.pdf"

Explain with more detail about matched rules, templates, and rendered names:

filemindr explain -p home "C:\Users\you\Downloads\Day Trade-2025.pdf" --verbose

Example output:

Day Trade-2025.pdf -> C:\Users\you\Downloads\archive\2026\03\day-trade-2025_2026-03.pdf [MOVE] rule=dated-pdfs prio=70 policy=rename (source=C:\Users\you\Downloads ext=.pdf matched_rule=dated-pdfs matched_candidates=dated-pdfs(prio=70) target_template=~/Downloads/archive/{yyyy}/{mm} rename_template={stem_safe}_{yyyy}-{mm}{suffix} rendered_name=day-trade-2025_2026-03.pdf dest_exists=NO conflict=none)

Example of a normalized file name:

rename_template: "{stem_safe}_{yyyy}-{mm}{suffix}"

Validate

filemindr validate -p home

Doctor

filemindr doctor

History

List recent runs:

filemindr history list

Include legacy/internal entries too:

filemindr history list --all

Inspect one run:

filemindr history show <run_id>

Example output:

run_id:      5ffb71382410
command:     run
profile:     home
status:      completed
dry_run:     True
started_at:  2026-03-13T16:54:18.073692+00:00
finished_at: 2026-03-13T16:54:18.115000+00:00
source:      C:\Users\you\Downloads
config_path: C:\Users\you\.filemindr\rules\home\rules.yaml

counts:
  planned_move: 55

events:
  - planned_move: C:\Users\you\Downloads\Day Trade-2025.pdf -> C:\Users\you\Downloads\archive\2026\03\day-trade-2025_2026-03.pdf

Prune old history entries:

filemindr history prune --days 7

Clear all stored history:

filemindr history clear --yes

Filemindr also prunes old history automatically on pipeline runs, keeping the last 7 days by default.


Undo

Undo one recorded run:

filemindr undo <run_id>

Undo v1 only reverts recorded move operations. It does not restore trash, overwrite, or copy events.

Example workflow:

filemindr run -p home
filemindr history list
filemindr undo <run_id>

Conflict Policy

Supported values:

  • rename
  • skip
  • overwrite
  • trash

Development

Install development dependencies:

uv sync --extra dev

Run tests:

uv run pytest -q

Release notes are versioned in the repository under release-notes/ and consumed automatically by the publish workflow.


Status

Current release line: 1.4.x


License

MIT

Metadata

Release files for filemindr 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for filemindr 1.4.0
File Size Uploaded
filemindr-1.4.0.tar.gz 52.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for filemindr 1.4.0
File Interpreter ABI Platform
filemindr-1.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 75.7 kB

Release files / filemindr-1.4.0.tar.gz

Download URL filemindr-1.4.0.tar.gz
Size 52.4 kB
Tags Source
SHA-256 checksum
How to use checksums
878ab781ea0429ded1d198c9ff7dae5971c3638c06bd09460d32a56e1886f2f3
BLAKE2b-256 checksum
How to use checksums
5af448943fbf99782669976689aae9dd929c1a8bf06b0292f642fc02b9ca2a34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / filemindr-1.4.0-py3-none-any.whl

Download URL filemindr-1.4.0-py3-none-any.whl
Size 23.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2302b18aafb9bac56632b7e5963ea18e6cd369066c9a08b810c55671b54e4a93
BLAKE2b-256 checksum
How to use checksums
99a7aa7dfa53d16cfd737f7ca4be33c7a14db4e72e725b8e13589dd975b1ac51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.4

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page