See docs/architecture.md for a full architecture diagram.
A command-line tool for organizing and renaming media files according to platform-specific conventions (e.g., Plex, Jellyfin).
- Architecture Overview: High-level design and component diagram.
- Filesystem Operations: Atomic, cross-platform file moves and guarantees.
- Apply & Undo Engines: Transactional renaming, rollback, and CLI/Python usage.
- Hashing & Integrity: SHA-256 utility, integrity checks, and skip-identical logic.
- Progress Bars & Logging: Rich CLI UX, progress bars, spinners, and audit logging.
- Integration Testing: End-to-end test philosophy, structure, and guarantees.
- CLI Command Reference: All commands, flags, usage, exit codes, and advanced options.
- LLM Features & Usage Guide: Model install, selection, troubleshooting.
- Provider Setup & API Keys: How to configure API keys for metadata/artwork providers.
- Quickstart Guide: First-time setup and usage for beginners.
- Scan directories for media files
- Support for TV shows, movies, and music (album/track)
- Platform-specific naming conventions
- Multi-segment episode handling
- Explicit media information control
- JSON output support
- File integrity verification (SHA-256)
- Apply & Undo engine: Transactional, reversible renames. Undo now also removes any empty directories created by apply, restoring your directory structure to its pre-apply state (default and safe).
- Rich progress bars & logging: CLI feedback and audit trail
- Integration tests: End-to-end, cross-platform
- Pluggable metadata/artwork providers: TMDB, TVDB, MusicBrainz, Fanart.tv, TheAudioDB (API compliant)
- Metadata cache: SQLite-backed cache for provider lookups, reducing API calls and enabling offline scans
- Metadata-aware rule engine: Naming rules now use provider metadata (e.g., movie year, TV episode title) for more accurate and platform-compliant renaming
- Async Ollama wrapper: Provides a robust async interface to a local Ollama server for streaming LLM inference, error handling, and future AI-powered features.
- Prompt template system: Reusable Jinja2-based prompt template system for LLM workflows (strict loader, editable templates, orchestrator, 100% TDD)
- Anthology episode splitting: Robust, user-driven LLM-based splitting of multi-episode TV files. Supports S01E01E02, E01-E02, 1x01-1x02, and real-world anthology filenames. Only triggers with --anthology flag.
- LLM confidence/manual flag: Prevents low-confidence AI guesses from auto-renaming. Items below threshold are flagged manual, highlighted in bright red, and require user review. CLI exits with code 2 if manual items are present.
- LLM model selection: Supports Llama 3 8B (Meta) as default, Mistral 7B as lightweight fallback. See LLM Features & Usage Guide for install, usage, and troubleshooting.
- Rich CLI UX: Colorful tables, progress bars, and spinners powered by Rich (disable with
--no-richorNAMEGNOME_NO_RICH)
namegnome/ # Project root
├── src/ # Source code directory
│ └── namegnome/ # Package directory
│ ├── cli/ # CLI commands and UI
│ ├── core/ # Core renaming engine
│ ├── rules/ # Platform-specific rules
│ ├── metadata/ # Metadata providers
│ ├── fs/ # Filesystem operations
│ └── prompts/ # LLM prompt templates and orchestrator (Jinja2-based)
├── tests/ # Test directory (mirrors src structure)
├── docs/ # Documentation
│ ├── fs-operations.md
│ ├── apply-undo.md
│ ├── hashing.md
│ ├── progress-logging.md
│ ├── integration-testing.md
│ ├── cli-commands.md
│ └── architecture.md
├── config/ # Configuration files and scripts
│ └── scripts/ # Development and utility scripts
├── README.md # Project overview
├── PLANNING.md # Project planning and vision
└── TASK.md # Current tasks and sprints
The namegnome scan command is the entry point for analyzing media files, extracting metadata, and planning renames. For TV shows—especially anthologies and multi-segment episodes—the logic is now highly modular, with each part handling a specific responsibility. This design enables robust handling of edge cases, platform-specific rules, and future extensibility.
- Maintainability: Each module has a single responsibility, making it easier to test, debug, and extend.
- Testability: Fine-grained modules allow for targeted regression and edge-case tests.
- Extensibility: New platforms, naming rules, or episode-matching strategies can be added without monolithic rewrites.
- Reliability: Isolating logic reduces the risk of regressions and makes the scan pipeline more robust.
graph TD;
A[CLI: scan command] --> B[scanner.py: scan_directory];
B --> C[tv_planner.py: TV orchestration];
C --> D[segment_splitter.py: segment splitting];
D --> E[episode_parser.py: episode matching];
E --> F[anthology/TV modules: advanced logic];
F --> G[plan_builders.py: plan item assembly];
G --> H[plan_conflicts.py: conflict detection];
H --> I[CLI: render plan, save, output];
- A: User runs the scan command from the CLI.
- B:
scanner.pyfinds and classifies media files. - C:
tv_planner.pyorchestrates the TV scan/plan process. - D:
segment_splitter.pysplits filename stems into segments. - E:
episode_parser.pyand anthology modules match segments to canonical episode titles. - F: Anthology-specific modules handle complex multi-segment and edge cases.
- G:
plan_builders.pyassembles the final rename plan. - H:
plan_conflicts.pydetects and resolves conflicts. - I: CLI presents the plan to the user.
- scanner.py: Recursively scans directories, classifies files, and builds the initial list of media files for planning.
- tv_planner.py: Orchestrates the TV scan/plan pipeline. Delegates to segment splitting, episode matching, and anthology logic as needed.
- segment_splitter.py: Splits filename stems into episode segments using delimiters, moniker patterns, and fuzzy heuristics.
- episode_parser.py: Matches segments to canonical episode titles using fuzzy matching, token overlap, and rare noun analysis.
- anthology/tv_anthology_match.py: Specialized matching logic for anthology/multi-segment files. Ensures strict span-matching.
- anthology/tv_anthology_split.py: Advanced splitting logic for anthology files, including fallback strategies.
- anthology/tv_anthology_orchestration.py: Orchestrates the creation of plan items for anthology matches.
- plan_builders.py: Assembles plan items from matched episodes and segments.
- plan_conflicts.py: Detects and resolves conflicts in the planned renames.
- fuzzy_matcher.py: Provides fuzzy matching utilities for episode title matching.
- utils.py: Shared utilities for title sanitization, normalization, and other common TV logic.
- The scan command starts in
scanner.py, which finds files and classifies them. - For TV files,
tv_planner.pytakes over, orchestrating the process. - Filenames are split into segments by
segment_splitter.py(and, for anthologies, bytv_anthology_split.py). - Each segment is matched to canonical episode titles by
episode_parser.pyand, for anthologies, bytv_anthology_match.py. - Anthology-specific orchestration and fallback logic live in
core/tv/anthology/. - Plan items are built and checked for conflicts before being presented to the user.
For further details, see SCAN.md for a comprehensive, always-current breakdown of the scan pipeline, edge cases, and design rationale.
- Python: 3.12 or higher
- Supported OS: Windows, macOS, Linux (cross-platform tested)
- Recommended: pipx for isolated CLI installs
pip install namegnomepipx install namegnomenamegnome --help
# Enable tab-completion (bash example)
namegnome init bash
# or just print the script:
namegnome completion bash > ~/namegnome.bash-completionSome features (metadata/artwork lookups) require free API keys from third-party providers.
To get started:
- Copy
.env.exampleto.envin your project root:cp .env.example .env
- Fill in your API keys for the providers you wish to use.
See docs/providers.md for a full list of supported providers and setup links.
- If a key is missing, only the related feature will be skipped (e.g., no artwork if
FANARTTV_API_KEYis missing). - Never commit your real
.envfile or API keys to version control.
NameGnome reads configuration from four layers, in this exact order of precedence (highest first):
- Command-line flags – e.g.
--llm-model,--no-rich,--verify. - Environment variables – each setting maps to a
NAMEGNOME_*env-var (e.g.NAMEGNOME_LLM_DEFAULT_MODEL). - User config file –
${XDG_CONFIG_HOME:-~/.config}/namegnome/config.toml. - Built-in defaults – sane values baked into the codebase.
You can inspect the final resolved values with:
namegnome config showTo see every supported setting, its env-var counterpart, default value, and description, run:
namegnome config docsTip: Disable Rich formatting for scripting/CI by adding
--no-richor exportingNAMEGNOME_NO_RICH=1.
[llm]
default_model = "codellama:34b"
[ui]
no_rich = true # disable spinners/progress bars globally
[scan]
verify_hash = true # always compute SHA-256 checksums during scan
[tv]
max_duration = 60 # anthology pairing threshold (minutes)NameGnome is a CLI tool. All commands and options are available via namegnome --help.
Scan a directory for media files and preview the proposed renames (at least one media type is required):
namegnome scan /path/to/media/files --media-type tvYou can specify multiple types:
namegnome scan /path/to/media/files --media-type tv --media-type movieApply a previously generated plan (by plan ID or by specifying the full path to a plan file in ~/.namegnome/plans/):
namegnome apply <plan-id> --yes
namegnome apply ~/.namegnome/plans/<plan-id>.json --yes- Use
--yesto skip confirmation. - Plan files are stored in
~/.namegnome/plans/(in your home directory) by default.
Rollback a previously applied plan (by plan ID or by specifying the full path to a plan file in ~/.namegnome/plans/):
namegnome undo <plan-id> --yes
namegnome undo ~/.namegnome/plans/<plan-id>.json --yes- Restores all files to their original locations if possible.
- Updates plan status and prints a summary table.
- After restoring files, undo will also remove any empty directories created by apply, so your library is left exactly as it was before the rename (including removing hidden files like .DS_Store).
- If the original source file already exists, undo will fail and not overwrite.
- If the destination file is missing (already undone), undo will fail for that item.
Example:
namegnome undo 123e4567-e89b-12d3-a456-426614174000You will be prompted for confirmation unless you pass --yes:
Are you sure you want to undo the plan 123e4567-e89b-12d3-a456-426614174000? [y/N]: y
Restoring /path/to/moved1.txt -> /path/to/original1.txt
Restoring /path/to/moved2.txt -> /path/to/original2.txt
[green]Undo completed for plan: 123e4567-e89b-12d3-a456-426614174000[/green]Choose a target platform to apply its naming conventions:
namegnome scan /path/to/media/files --media-type tv --platform plex
namegnome scan /path/to/media/files --media-type tv --platform jellyfinChoose which metadata provider to use for lookups (TV, movie, or music):
# Use TVDB for TV shows (default)
namegnome scan /path/to/media/files --media-type tv --provider tvdb
# Use TMDB for movies
namegnome scan /path/to/media/files --media-type movie --provider tmdb
# Use OMDb as a fallback
namegnome scan /path/to/media/files --media-type movie --provider omdb
# Use MusicBrainz for music (default for music)
namegnome scan /path/to/media/files --media-type music --provider musicbrainz
# Use TheAudioDB as a fallback for music
namegnome scan /path/to/media/files --media-type music --provider theaudiodbAvailable provider options: tvdb, tmdb, omdb, musicbrainz, theaudiodb.
If not specified, the default provider is tvdb for TV, tmdb for movies, and musicbrainz for music. The CLI will fall back to other providers automatically if the primary provider fails or is missing data.
Limit scan to specific media types (required):
# TV only
namegnome scan /path/to/media/files --media-type tv
# Movies only
namegnome scan /path/to/media/files --media-type movie
# Both
namegnome scan /path/to/media/files --media-type tv --media-type movie--show-name "Show Title": Override detected show name--anthology: Handle multi-segment episodes (e.g., Paw Patrol)--adjust-episodes: Fix episode numbering if files are in correct order but misnumbered--media-type tv: Required for all TV show scans
--movie-year 2023: Specify release year for movie files--artwork: Download and cache high-quality poster artwork for each movie using Fanart.tv (requires FANARTTV_API_KEY in your .env)
--media-type music: Scan and organize music files (albums/tracks)
--json: Output results as JSON--no-color: Disable colored output (for logs/CI)--verify: Compute and store SHA-256 checksums for file integrity--llm-model "model-name": Use a specific LLM for fuzzy matching--no-cache: Bypass the metadata cache and force fresh API calls (useful for debugging or when you want the latest data)- Low-confidence LLM results are flagged manual and require user review.
- Manual items are highlighted in bright red in the diff table.
- CLI exits with code 2 if any manual items are present in the plan.
- Music files are matched using MusicBrainz (API compliant: 1 req/sec, custom User-Agent)
- Example:
namegnome scan /media/Music --media-type musicDelete old rename plans from the NameGnome plan store:
namegnome clean-plans [--keep N] [--yes]- By default, deletes all plans in
~/.namegnome/plans/(home directory). - Use
--keep Nto keep the N most recent plans. - Use
--yesto skip the confirmation prompt.
Examples:
# Delete all plans:
namegnome clean-plans
# Keep the 5 most recent plans:
namegnome clean-plans --keep 5
# Delete all plans without confirmation:
namegnome clean-plans --yesYou can list all available plan files and inspect their details:
namegnome plans # List all plans
namegnome plans --status # Show status summary for each plan
namegnome plans --show-paths # Show full file paths
namegnome plans <PLAN_ID> # Show details for a specific plan
namegnome plans --json # Output as JSON for scripting
namegnome plans --latest # Show the most recent plan- Python 3.12+: Modern language features and performance
- Typer: Declarative CLI framework
- Rich: Beautiful CLI output (tables, spinners, progress bars)
- Pydantic v2: Data validation and serialization
- httpx + asyncio: Async HTTP for metadata providers
- pytest: Testing framework (80%+ coverage enforced)
- ruff-format (Black-compatible), ruff, mypy: Formatting, linting, and static typing
- Ollama: Local LLM server for fuzzy matching and edge-case handling
- Jinja2: Prompt template system for LLM workflows
- SQLite: Local cache for metadata and LLM responses
- TMDB, TVDB, MusicBrainz, OMDb, Fanart.tv, AniList, TheAudioDB: Pluggable metadata/artwork providers (API compliant)
- pipx: Recommended for isolated CLI installs
NameGnome supports pluggable metadata providers:
- TMDB: Movies and TV metadata
- TVDB: TV episode and series metadata
- MusicBrainz: Music album/track/artist metadata
- Fully compliant with MusicBrainz API:
- 1 request/sec rate limiting
- Custom User-Agent header
- Fully compliant with MusicBrainz API:
- OMDb: Supplements TMDB with IMDb rating and full plot. Requires a free or patron API key (see OMDb API). Free keys are limited to 1,000 requests/day. OMDb fields are only used if missing from TMDB, and TMDB always takes priority.
- Fanart.tv: High-quality poster artwork for movies (by TMDB ID). Requires a free
API key (see Fanart.tv API). Artwork is downloaded
and cached locally when the
--artworkflag is used. - AniList: Anime metadata with absolute episode numbering support. Uses AniList's GraphQL API which does not require authentication.
- Register for a free OMDb API key at omdbapi.com.
- Add
OMDB_API_KEYto your.envfile (never hard-code keys). - If the key is missing, OMDb supplementation will be skipped.
- Register for a free Fanart.tv API key at fanart.tv/api.
- Add
FANARTTV_API_KEYto your.envfile (never hard-code keys). - If the key is missing, the
--artworkflag will be ignored and no artwork will be downloaded.

Metadata provided by TheTVDB.
Please consider adding missing information or subscribing.

This product uses the TMDB API but is not endorsed or certified by TMDB.
TMDB API Terms of Use
Music metadata provided by MusicBrainz.
Movie metadata supplemented by OMDb API.
OMDb API Terms of Use
Artwork provided by Fanart.tv.
Fanart.tv API Terms of Use
Anime metadata provided by AniList.
AniList GraphQL API
namegnome scan /media/TV/PawPatrol \
--show-name "Paw Patrol" \
--anthology \
--adjust-episodesnamegnome scan /media/Movies \
--media-type movie \
--movie-year 2023namegnome scan /media/Library \
--platform plex \
--media-type tv \
--media-type movie \
--show-name "Paw Patrol" \
--anthology \
--adjust-episodes \
--verify \
--json0: Success (all files processed or nothing to do)1: Error (general failure)2: Manual intervention needed (conflicts or manual review required)
- All rename operations require manual review by default
- The tool will detect and report conflicts in target paths
- File integrity verification is optional but recommended
- JSON output is useful for programmatic processing
- The
--anthologyflag enables robust, LLM-powered splitting of multi-segment TV files (e.g., anthology episodes, dual-episode files, or real-world cases like Paw Patrol). This feature supports both pattern-based and real-world filenames, but only triggers when the flag is set. - The
--adjust-episodesflag helps correct episode numbering when files are in the right order but numbered incorrectly
NameGnome uses a robust, cross-platform atomic move engine for all file renaming and reorganization. This ensures:
- Safe, auditable, and reversible moves—even across devices or on Windows with long paths.
- Overwrite protection, dry-run support, and byte-for-byte duplicate detection.
See the full API, advanced usage, and guarantees in
docs/fs-operations.md.
- Project scaffolding, pre-commit, and CI setup
- Core package skeleton and CLI
- Domain models with Pydantic
- Rule engine prototype (Plex naming)
- Metadata provider stubs (TMDB, TVDB)
- Directory scanner for media files
- Rename planner with conflict detection
- Rich diff renderer and CLI UX
- CLI
scancommand - Rollback plan store
- Test harness and baseline coverage
- Contributor and user documentation
- Atomic, cross-platform file move helper
- SHA-256 hash utility for file integrity
- Apply engine for transactional renames
- Undo engine and CLI command
- Progress bars and logging
- Integration tests across OSes
- Expanded documentation
- Provider abstraction interface
- TMDB client (movies/TV)
- TVDB client (TV)
- MusicBrainz client (music, API compliant)
- Metadata integration and tests
- Coverage and compliance improvements
- OMDb client (supplemental movie metadata)
- Fanart.tv client (high-quality poster artwork, CLI --artwork flag, caching)
- Rule engine integration: Naming rules now use provider metadata (e.g., movie year, TV episode title) for more accurate and platform-compliant renaming
- Parametrized, fixture-based tests for all metadata providers (TMDB, TVDB, MusicBrainz, OMDb, Fanart.tv, TheAudioDB, AniList)
- Coverage for expected, 404 (not found), and 429 (rate-limit) error cases
- All tests pass and coverage ≥85% for metadata package
- Implementation updated to raise on 429 and handle 404 consistently across all providers
- Fully compliant with project TDD and coverage requirements
- Settings class, config CLI, and error handling for missing API keys.
- Async Ollama wrapper module: async interface to local Ollama server, streaming, error handling, and TDD. Foundation for LLM fuzzy matching and future AI features.
- Async Ollama model discovery (
list_models) - CLI
llmcommand group:listandset-default - Config persistence and selection logic for default LLM model
- Subprocess-based CLI tests for Typer global options
- All requirements and tests pass as of 2025-07-27
- All LLM unit and integration tests implemented and passing. Mock Ollama responses using respx and monkeypatching. Coverage for llm/ package ≥90%. Integration tests for anthology splitting, confidence/manual flag, and error handling are present and deterministic. No further work required.
- Implemented prompt size guard for LLM prompts
- Added SQLite-backed cache for LLM responses (SHA-1 keying)
- Decorated ollama_client.generate with cache logic (honoring --no-cache flag)
- Wrote TDD tests for prompt size, cache hit, and cache bypass
- All code, tests, and documentation are compliant with project rules (E501, type annotations, docstrings, etc.)
- Comprehensive, E501-compliant LLM documentation, onboarding, CLI UX, and tests
- All CLI and onboarding docs require explicit --media-type
- Tests and code enforce 'llama3:8b' as the default LLM model
- All major docs are linked and up to date
- Outstanding technical debt (test failure, mypy/deptry) resolved
- All tests and pre-commit hooks pass as of this save state
- Python 3.12+: Modern language features and performance
- Typer: Declarative CLI framework
- Rich: Beautiful CLI output (tables, spinners, progress bars)
- Pydantic v2: Data validation and serialization
- httpx + asyncio: Async HTTP for metadata providers
- pytest: Testing framework (80%+ coverage enforced)
- ruff-format (Black-compatible), ruff, mypy: Formatting, linting, and static typing
- Ollama: Local LLM server for fuzzy matching and edge-case handling
- Jinja2: Prompt template system for LLM workflows
- SQLite: Local cache for metadata and LLM responses
- TMDB, TVDB, MusicBrainz, OMDb, Fanart.tv, AniList, TheAudioDB: Pluggable metadata/artwork providers (API compliant)
- pipx: Recommended for isolated CLI installs
NameGnome supports pluggable metadata providers:
- TMDB: Movies and TV metadata
- TVDB: TV episode and series metadata
- MusicBrainz: Music album/track/artist metadata
- Fully compliant with MusicBrainz API:
- 1 request/sec rate limiting
- Custom User-Agent header
- Fully compliant with MusicBrainz API:
- OMDb: Supplements TMDB with IMDb rating and full plot. Requires a free or patron API key (see OMDb API). Free keys are limited to 1,000 requests/day. OMDb fields are only used if missing from TMDB, and TMDB always takes priority.
- Fanart.tv: High-quality poster artwork for movies (by TMDB ID). Requires a free
API key (see Fanart.tv API). Artwork is downloaded
and cached locally when the
--artworkflag is used. - AniList: Anime metadata with absolute episode numbering support. Uses AniList's GraphQL API which does not require authentication.
- Register for a free OMDb API key at omdbapi.com.
- Add
OMDB_API_KEYto your.envfile (never hard-code keys). - If the key is missing, OMDb supplementation will be skipped.
- Register for a free Fanart.tv API key at fanart.tv/api.
- Add
FANARTTV_API_KEYto your.envfile (never hard-code keys). - If the key is missing, the
--artworkflag will be ignored and no artwork will be downloaded.

Metadata provided by TheTVDB.
Please consider adding missing information or subscribing.

This product uses the TMDB API but is not endorsed or certified by TMDB.
TMDB API Terms of Use
Music metadata provided by MusicBrainz.
Movie metadata supplemented by OMDb API.
OMDb API Terms of Use
Artwork provided by Fanart.tv.
Fanart.tv API Terms of Use
Anime metadata provided by AniList.
AniList GraphQL API
namegnome scan /media/TV/PawPatrol \
--show-name "Paw Patrol" \
--anthology \
--adjust-episodesnamegnome scan /media/Movies \
--media-type movie \
--movie-year 2023namegnome scan /media/Library \
--platform plex \
--media-type tv \
--media-type movie \
--show-name "Paw Patrol" \
--anthology \
--adjust-episodes \
--verify \
--json0: Success (all files processed or nothing to do)1: Error (general failure)2: Manual intervention needed (conflicts or manual review required)
- All rename operations require manual review by default
- The tool will detect and report conflicts in target paths
- File integrity verification is optional but recommended
- JSON output is useful for programmatic processing
- The
--anthologyflag enables robust, LLM-powered splitting of multi-segment TV files (e.g., anthology episodes, dual-episode files, or real-world cases like Paw Patrol). This feature supports both pattern-based and real-world filenames, but only triggers when the flag is set. - The
--adjust-episodesflag helps correct episode numbering when files are in the right order but numbered incorrectly
NameGnome uses a robust, cross-platform atomic move engine for all file renaming and reorganization. This ensures:
- Safe, auditable, and reversible moves—even across devices or on Windows with long paths.
- Overwrite protection, dry-run support, and byte-for-byte duplicate detection.
See the full API, advanced usage, and guarantees in
docs/fs-operations.md.
NameGnome is designed to work best with local LLMs via Ollama. We recommend:
- Default:
llama3:8b(Meta) - Lightweight fallback:
mistral:7b - Code-focused fallback:
deepseek-coder-v2:16b-lite-instruct-q4_K_M
Why DeepSeek-Coder-V2-Instruct?
- Lightweight (~10GB quantized), suitable for laptops and resource-limited systems
- Strong code and reasoning performance, open weights, privacy-friendly
- Easy to deploy with Ollama, supports commercial use
- See Medium deployment guide and HuggingFace model card
Install with Ollama:
ollama pull llama3:8b
ollama pull mistral:7b
ollama pull deepseek-coder-v2:16b-lite-instruct-q4_K_MSet your preferred default model:
namegnome llm set-default llama3:8b
# or for lightweight/code workflows:
namegnome llm set-default mistral:7b
namegnome llm set-default deepseek-coder-v2:16b-lite-instruct-q4_K_MSee docs/llm.md for full installation, configuration, CLI usage, and troubleshooting instructions for LLM-powered features.
All debug output in NameGnome must use the universal debug utility in src/namegnome/utils/debug.py.
- Use
debug(msg),info(msg),warn(msg), anderror(msg)for all logging. - Do not use
print()or custom log files for debug output. - Debug output is enabled by setting the environment variable
NAMEGNOME_DEBUG=1. - See the module docstring in
src/namegnome/utils/debug.pyfor usage examples.
This rule is enforced in code review and CI. See docs/project-cursorrules.mdc for details.
