nomnom
nomnom is an extensible file watcher for local automation. The core detects file changes and fires events. Plugins do the actual work: moving files, enriching them, or kicking off downstream workflows.
Install
With uv:
uv tool install nomnom-py
With pip:
pip install nomnom-py
Quick Start
Initialize
Generates a default config.toml in your project root.
If you use the built-in rules plugin, keep rules.toml in that same directory so nomnom can read both files together.
nomnom setup
Watch
Starts watching your directories based on the configuration.
nomnom watch
Use nomnom watch --once <group> to process a single watch group one time, or nomnom watch --dry to inspect behavior without applying file effects.
Example Configuration
nomnom reads config.toml from the current project by default, or a custom path passed with --config.
When the built-in rules plugin is enabled, nomnom also reads rules.toml from that same directory.
[[watch]]
name = "inbox"
paths = ["./fixtures/inbox"]
include = ["*.pdf", "*.txt"]
[[watch]]
name = "archive"
paths = ["./fixtures/archive"]
[[plugins]]
name = "rules"
priority = 10
enabled = true
For a fuller starter file, see config.example.toml.
Plugins
The Built-in Rules Plugin
A rules plugin for declarative file automation driven by rules.toml.
It ships with the main nomnom-py install and is configured as rules.
Keep config.toml and rules.toml side by side. If you run nomnom --config /path/to/config.toml, the built-in plugin will read /path/to/rules.toml automatically.
See RULES.md for the rule format and supported actions, and
rules.example.toml for a starter example.
Installing Community Plugins
Plugins can be installed from PyPI or directly from a Git repository:
nomnom plugin add <package-name-or-git-url>
Example:
nomnom plugin add git+https://github.com/<owner>/nomnom-plugin-example
Creating a Plugin
Scaffold a local plugin package inside plugins/:
nomnom plugin create <name>
The generated package includes a pyproject.toml entry point and a stub plugin module. Local plugins are automatically discoverable, no need to configure them.
If you'd like to publish your plugin, move it to its own repo and publish it to GitHub or PyPI. There is no system for discovering plugins yet but shoot me an email if interested.
Plugin API
Plugins implement two methods:
def matches(self, event: FileEvent) -> bool: ...
def handle(self, event: FileEvent) -> list[Effect]: ...
FileEvent
| Field | Type | Description |
|---|---|---|
event_type |
EventType |
EventType.CREATED, MODIFIED, or DELETED |
path |
Path |
Absolute path to the changed file |
watch_group |
str |
Name of the watch group that triggered this event |
created_at |
datetime |
UTC timestamp when the event was created |
Effects
handle() returns a list of zero or more Effect values. The dispatcher executes them in order.
| Effect | Fields | Description |
|---|---|---|
MoveFile |
source: Path, destination: Path, overwrite: bool = True |
Moves a file. Creates parent directories as needed. Skipped if source is missing; skipped (or overwrites) if destination exists based on overwrite. |
DeleteFile |
path: Path |
Deletes a file. Skipped if the file does not exist. |
CreateFile |
path: Path, content: bytes |
Creates a file with the given content, creating parent directories as needed. |
EditFile |
path: Path, action: EditAction, content: bytes |
Prepends or appends content to an existing file. action is EditAction.PREPEND or EditAction.APPEND. |
EmitEvent |
event: FileEvent |
Injects a new FileEvent back into the dispatcher. Useful for chaining logic across plugins. Depth is capped at 10 to prevent infinite loops. |
Development
uv sync --dev
uv run pytest
uv run ruff check
uv run mypy nomnom
Contributor guidance lives in CONTRIBUTING.md.
Dependencies
nomnom is built with these open-source libraries:
- rich — MIT License
- typer — MIT License
- watchfiles — MIT License
- tomli-w — BSD-3-Clause License
Dev dependencies:
- pytest — MIT License
- pytest-cov — MIT License
- ruff — MIT License
- mypy — MIT License
CLI Reference
Core Commands:
nomnom watch [WATCH_GROUP] [OPTS] Start watching (Opts: -c/--config, -V/--verbose, --dry-run, --once)
nomnom setup [OPTS] Create or update the config file
nomnom --version / -v Print installed version
Plugin Management:
nomnom plugin add PACKAGE Install and register a plugin
nomnom plugin remove PACKAGE Remove a plugin
nomnom plugin enable NAME Enable a plugin in config
nomnom plugin disable NAME Disable a plugin in config
nomnom plugin list List active plugins
nomnom plugin setup Run setup for specific/all plugins
nomnom plugin create NAME Scaffold a new local plugin
Metadata
Release files for nomnom-py 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nomnom_py-1.1.1.tar.gz | 78.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nomnom_py-1.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 105.4 kB
Release files / nomnom_py-1.1.1.tar.gz
| Download URL | nomnom_py-1.1.1.tar.gz |
|---|---|
| Size | 78.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9ea16d9ce24ddfbdf00efd0c35c91ed2b967360516b6f090b6113e40b89e00a8
|
|
BLAKE2b-256 checksum How to use checksums |
30c6a666371fed057a926d88b8ae918d5090f2d8cd4ec161fd7c72715edc974f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.
Transparency logRelease files / nomnom_py-1.1.1-py3-none-any.whl
| Download URL | nomnom_py-1.1.1-py3-none-any.whl |
|---|---|
| Size | 27.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5c1264886d5e72a3c4717d7edba7de13b92f51d83e8f560d525dae58a3dc98e8
|
|
BLAKE2b-256 checksum How to use checksums |
a2713154a14e231be695fdc2d49150418556506ad78d4888cd5b5d73189dca70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.
Transparency log