MOFF - Markdown Organization and Format Framework. A CLI tool for validating documentation structure.
Project description
MOFF CLI
Markdown Opinionated File Formatter
A command-line tool for validating and maintaining clean, organized documentation. Designed to work seamlessly with Large Language Models (LLMs) in modern IDEs like Cursor, VSCode, and Zed.
๐ฏ Purpose
MOFF helps maintain consistent documentation structure across projects by:
- Validating markdown files against configurable rules
- Enforcing location constraints for different document types
- Checking frontmatter schemas and required fields
- Ensuring headers follow specified patterns and order
- Providing visual feedback through tree visualization
Perfect for projects where documentation quality and consistency matter, especially when working with AI assistants that write markdown documentation.
โจ Features
- ๐ Smart Root Detection: Automatically finds documentation root via
project_*.mdfiles - ๐ Comprehensive Validation: Check frontmatter, headers, and file locations
- ๐ณ Tree Visualization: See your documentation structure with error highlighting
- โ๏ธ Configurable Rules: Define custom prefixes, patterns, and validation rules
- ๐พ Result Persistence: Save validation results for CI/CD integration
- ๐จ Rich Terminal Output: Beautiful, colored output using Rich library
- ๐ Verbose Mode: Shows expected file structure templates when validation fails
- ๐ง Auto-fix: Automatically fix common issues like missing frontmatter and headers
๐ฆ Installation
Using pip
pip install moff-cli
Using uv (recommended)
uv add moff-cli
๐ Quick Start
- Check your documentation (creates
settings.jsonautomatically if not present):
moff check
- Visualize documentation structure:
moff tree
๐ Usage
Commands Overview
moff --help # Show help information
moff --version # Show version
moff check # Run validation checks
moff check --verbose # Show expected structure for files with errors
moff check --fix # Automatically fix fixable issues
moff check --save # Run checks and save results to moff_results.txt
moff check --save --verbose # Save results with expected structure templates
moff check --path ./docs # Check specific directory
moff tree # Display documentation tree
moff tree --errors-only # Show only files with errors
moff tree --no-check # Skip validation (faster)
Example: Setting Up a Project
- Create a project file (
project_myapp.md):
---
project: myapp
---
# Overview
This is my application's main documentation.
## Requirements
- Python 3.12+
- Rich library
- Create feature documentation (
features/feature_auth.md):
---
project: myapp
feature: authentication
linked_features: ["users", "sessions"]
---
# Overview
Authentication system for the application.
## Requirements
- Secure password hashing
- JWT token support
- Session management
- Validate your documentation (this will create
settings.jsonif it doesn't exist):
moff check
Example Output
Check Command
Collecting documentation files...
Root directory: /Users/you/project/docs
โ All checks passed!
No validation issues found.
Or with errors:
Validation Summary:
Total issues: 2
Errors: 2
Issues found:
features/feature_broken.md:
error [feature] headers.missing: Missing required header level=2 text='Requirements' (line 10)
tech_database.md:
error [tech] location.subdirs_only: File must be in a subdirectory, not in root
Or with verbose mode to see expected structure:
features/feature_broken.md:
error [feature] frontmatter.missing: Required frontmatter is missing (line 1)
error [feature] headers.missing: Missing required header level=1 text='Overview'
error [feature] headers.missing: Missing required header level=2 text='Requirements'
Expected structure for this file type (feature):
---
project:
feature:
linked_features: []
---
# Overview
## Requirements
Fix Command
When running moff check, you can use the --fix flag to automatically fix certain issues:
moff check --fix
Fixable issues include:
- Missing frontmatter blocks
- Missing required frontmatter fields
- Missing required headers
Example output:
Applying 3 automatic fixes...
Fixed features/feature_broken.md:
โข Added missing frontmatter block
โข Added missing header: Overview
โข Added missing header: Requirements
Fixes applied successfully!
Note: Some issues cannot be automatically fixed, such as:
- File location constraints (files in wrong directories)
- Header ordering issues
- Type mismatches in frontmatter values
Tree Command
๐ docs (documentation root)
โโโ ๐ features
โ โโโ โก feature_auth.md โ
โ โโโ โก feature_users.md โ
โโโ ๐ technical
โ โโโ ๐ง tech_database.md โ
โโโ ๐ project_myapp.md โ
Summary:
Total markdown files: 4
Files with errors: 0
Files with warnings: 0
โ All files passed validation!
๐ Programmatic Usage
When installed via pip, moff-cli can also be used as a Python library. Import it as moff_cli:
Basic Validation
from pathlib import Path
from moff_cli import Settings, Collector, Checker
# Load settings and collect documentation
settings = Settings()
collector = Collector(settings, start_path=Path.cwd())
collected_data = collector.collect()
# Run validation
checker = Checker(settings)
diagnostics = checker.check(collected_data)
# Process results
if not diagnostics:
print("โ All documentation is valid!")
else:
for diag in diagnostics:
print(f"{diag.path}: {diag.message}")
Custom Configuration
from moff_cli import (
Settings,
PrefixConfig,
LocationConstraint,
HeaderRule,
HeaderMatch
)
# Create custom settings
settings = Settings()
# Add a custom prefix for API documentation
settings.prefixes["api"] = PrefixConfig(
filename_pattern="api_*.md",
location=LocationConstraint.SUBDIRS_ONLY,
frontmatter_required={
"endpoint": "string",
"method": "string",
"version": "string"
},
headers_required=[
HeaderRule(level=1, text="Endpoint"),
HeaderRule(level=2, text="Request"),
HeaderRule(level=2, text="Response"),
]
)
# Save custom settings
settings.save_to_file(Path("settings.json"))
Tree Visualization
from moff_cli import Settings, Collector, Checker, TreeVisualizer
from rich.console import Console
console = Console()
settings = Settings()
# Collect and check
collector = Collector(settings)
collected_data = collector.collect()
checker = Checker(settings)
diagnostics = checker.check(collected_data)
# Display tree with error highlighting
visualizer = TreeVisualizer(settings, console)
visualizer.show_tree(collected_data, diagnostics)
CI/CD Integration
from pathlib import Path
from moff_cli import Settings, Collector, Checker, Severity
def validate_docs(project_path: Path) -> bool:
"""Validate documentation for CI/CD pipeline."""
settings = Settings()
collector = Collector(settings, start_path=project_path)
checker = Checker(settings)
# Collect and check
collected = collector.collect()
if collected.get("error"):
print(f"ERROR: {collected['error']}")
return False
diagnostics = checker.check(collected)
# Filter to only errors (ignore warnings)
errors = [d for d in diagnostics if d.severity == Severity.ERROR]
if errors:
print(f"Validation failed with {len(errors)} errors")
for error in errors:
print(f" โ {error.path}: {error.message}")
return False
return True
# Use in CI/CD
if not validate_docs(Path(".")):
exit(1)
Available Classes and Functions
Settings: Configuration managementCollector: File discovery and parsingChecker: Validation engineTreeVisualizer: Tree visualizationDiagnostic: Validation issue representationSeverity: Error, Warning, Info levelsLocationConstraint: ROOT_ONLY, SUBDIRS_ONLY, ANYHeaderOrder: STRICT, IN_ORDER, ANYHeaderMatch: EXACT, REGEX
โ๏ธ Configuration
MOFF uses settings.json for configuration. The default configuration supports three document prefixes:
Default Prefixes
| Prefix | Pattern | Location | Purpose |
|---|---|---|---|
project |
project_*.md |
Root only | Main project documentation |
feature |
feature_*.md |
Any | Feature specifications |
tech |
tech_*.md |
Subdirs only | Technical implementation details |
Custom Configuration Example
{
"version": 1,
"root": {
"detect": {
"method": "project_file",
"pattern": "project_*.md"
},
"override_path": null,
"ignore": [
"**/.git/**",
"**/.venv/**",
"**/node_modules/**",
"**/archive/**"
]
},
"prefixes": {
"api": {
"filename": {
"pattern": "api_*.md"
},
"location": "subdirs_only",
"frontmatter": {
"required": {
"project": "string",
"endpoint": "string",
"method": "string"
},
"optional": {
"deprecated": "boolean"
}
},
"headers": {
"required": [
{
"level": 1,
"text": "Endpoint",
"match": "exact"
},
{
"level": 2,
"text": "Request",
"match": "exact"
},
{
"level": 2,
"text": "Response",
"match": "exact"
}
],
"optional": [],
"order": "in-order"
}
}
}
}
Configuration Options
Root Detection
detect.method: Currently supports"project_file"detect.pattern: Glob pattern for root detection (default:"project_*.md")override_path: Bypass auto-detection with explicit pathignore: List of glob patterns to exclude
Location Constraints
"root_only": File must be in root directory"subdirs_only": File must be in a subdirectory"any": File can be anywhere
Frontmatter Types
"string": Text values"number": Numeric values (int or float)"boolean": True/false values"list": Array values"object": Dictionary/object values
Header Order
"strict": Headers must appear in exact order"in-order": Headers must be in order but others can appear between"any": No order enforcement
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Built with Rich for beautiful terminal output
- Uses markdown-to-data for parsing
- Inspired by the need for better documentation tooling in AI-assisted development
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moff_cli-0.3.0.tar.gz.
File metadata
- Download URL: moff_cli-0.3.0.tar.gz
- Upload date:
- Size: 82.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a4b6dd7f0ece59aeb471bbdfdb71b5b3a9251948727d9442a513e5d3f4bc755
|
|
| MD5 |
a2b5b6fa49eb9a075f3c65f27b38176f
|
|
| BLAKE2b-256 |
3b63bd81f94dc335060fad8bec391712bea9f345684dbd2711c6fab29384d594
|
File details
Details for the file moff_cli-0.3.0-py3-none-any.whl.
File metadata
- Download URL: moff_cli-0.3.0-py3-none-any.whl
- Upload date:
- Size: 31.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17f6ef323c037bcf9c13d888bad4ee6e7dfb9fc5a73932d92562c5d274b45d43
|
|
| MD5 |
93490e427a8e8000c99521e5752c1ebe
|
|
| BLAKE2b-256 |
7abb8d5e3893b912313f7bdd1eafc44a122d89c70b0e3add5a408ca0d3cec106
|