""" Renderer-agnostic Python documentation compiler that converts Python docstrings into structured documentation for both humans (MkDocs) and machines (MCP / AI agents). `doc-forge` statically analyzes source code, builds a semantic model of modules, classes, functions, and attributes, and renders that model into documentation outputs without executing user code. --- # Installation Install using pip: ```bash pip install doc-forge ``` --- # CLI usage ## Generate an MkDocs site from a Python package: ```bash doc-forge build --mkdocs --module my_package ``` ## Generate MCP JSON documentation: ```bash doc-forge build --mcp --module my_package ``` ## Generate MkDocs site and MCP JSON documentation: ```bash doc-forge build --mcp --mkdocs --module my_package ``` ## Serve MkDocs locally: ```bash doc-forge serve --mkdocs --module my_package ``` ## Serve MCP locally: ```bash doc-forge serve --mcp --module my_package ``` --- # Core concepts ## Loader Extracts symbols, signatures, and docstrings using static analysis. ## Semantic model Structured, renderer-agnostic representation of the API. ## Renderer Converts the semantic model into output formats such as MkDocs or MCP JSON. ## Symbol Any documentable object - module - class - function - method - property - attribute --- # Architecture `doc-forge` follows a compiler architecture: ## Front-end: Static analysis of modules, classes, functions, type hints, and docstrings. ## Middle-end: Builds a semantic model describing symbols and relationships. ## Back-end: Renders documentation using interchangeable renderers. This architecture ensures deterministic documentation generation. --- # Rendering pipeline Typical flow: Python package ↓ Loader (static analysis) ↓ Semantic model ↓ Renderer ↓ MkDocs site or MCP JSON --- # Google-Styled Doc-Forge Convention (GSDFC) GSDFC defines how docstrings must be written so they render correctly in MkDocs and remain machine-parsable by doc-forge and AI tooling. - Docstrings are the single source of truth. - doc-forge compiles docstrings but does not generate documentation content. - Documentation follows the Python import hierarchy. - Every public symbol should have a complete and accurate docstring. --- ## General rules - Use **Markdown headings** at package and module level. - Use **Google-style structured sections** at class, function, and method level. - Use type hints in signatures instead of duplicating types in prose. - Write summaries in imperative form. - Sections are separated by ```---``` --- ## Notes subsection grouping - Group related information using labeled subsections. Example: Notes Example: Notes: **Guarantees:** - deterministic behavior **Lifecycle:** - created during initialization - reused across executions **Thread safety:** - safe for concurrent reads --- ## Example formatting - Use indentation for examples. - Indent section contents using four spaces. - Use code blocks for example code. Example: Single example: Example: ```python foo = Foo("example") process(foo, multiplier=2) ``` Multiple examples: Example: Create foo: ```python foo = Foo("example") ``` Run engine: ```python engine = BarEngine([foo]) engine.run() ``` Avoid fenced code blocks inside structured sections. --- ## Separator rules Use horizontal separators only at docstring root level to separate sections: ```markdown --- ``` Allowed locations: - package docstrings - module docstrings - major documentation sections Do not use separators inside code sections. --- ## Package docstrings - Package docstrings act as the documentation home page. Recommended sections: # Summary # Installation # Quick start # CLI usage # Core concepts # Architecture # Rendering pipeline # Examples # Notes Example: Package Doc String: ''' Foo-bar processing framework. Provides tools for defining Foo objects and executing Bar pipelines. --- # Installation ```bash pip install foo-bar ``` --- # Quick start ```python from foobar import Foo, BarEngine foo = Foo("example") engine = BarEngine([foo]) result = engine.run() ``` --- ''' --- ## Module docstrings - Module docstrings describe a subsystem. Recommended sections: # Summary # Examples # Notes Example: Module Doc String: ''' Foo execution subsystem. Provides utilities for executing Foo objects through Bar stages. --- Example: ```python from foobar.engine import BarEngine from foobar.foo import Foo foo = Foo("example") engine = BarEngine([foo]) engine.run() ``` --- ''' --- ## Class docstrings - Class docstrings define object responsibility, lifecycle, and attributes. Recommended sections: Attributes: Notes: Example: Raises: Example: Simple Foo: ```python class Foo: ''' Represents a unit of work. Attributes: name (str): Identifier of the foo instance. value (int): Numeric value associated with foo. Notes: Guarantees: - instances are immutable after creation Lifecycle: - create instance - pass to processing engine Example: Create and inspect a Foo: ```python foo = Foo("example", value=42) print(foo.name) ``` ''' ``` Complex Bar: ```python class BarEngine: ''' Executes Foo objects through Bar stages. Attributes: foos (tuple[Foo, ...]): Foo instances managed by the engine. Notes: Guarantees: - deterministic execution order Example: Run engine: ```python foo1 = Foo("a") foo2 = Foo("b") engine = BarEngine([foo1, foo2]) engine.run() ``` ''' ``` --- ## Function and method docstrings - Function docstrings define API contracts. Recommended sections: Args: Returns: Raises: Yields: Notes: Example: Example: Simple process method: ```python def process(foo: Foo, multiplier: int) -> int: ''' Process a Foo instance. Args: foo (Foo): Foo instance to process. multiplier (int): Value used to scale foo. Returns: int: Processed result. Raises: ValueError: If multiplier is negative. Notes: Guarantees: - foo is not modified Example: Process foo: ```python foo = Foo("example", value=10) result = process(foo, multiplier=2) print(result) ``` ''' ``` Multiple Examples: ```python def combine(foo_a: Foo, foo_b: Foo) -> Foo: ''' Combine two Foo instances. Args: foo_a (Foo): First foo. foo_b (Foo): Second foo. Returns: Foo: Combined foo. Example: Basic usage: ```python foo1 = Foo("a") foo2 = Foo("b") combined = combine(foo1, foo2) ``` Pipeline usage: ```python engine = BarEngine([foo1, foo2]) engine.run() ``` ''' ``` --- ## Property docstrings - Properties must document return values. Example: Property Doc String: ```python @property def foos(self) -> tuple[Foo, ...]: ''' Return contained Foo instances. Returns: tuple[Foo, ...]: Stored foo objects. Example: ```python container = FooContainer() foos = container.foos ``` ''' ``` --- ## Attribute documentation - Document attributes in class docstrings using Attributes:. Example: Attribute Doc String: ```python ''' Represents a processing stage. Attributes: id (str): Unique identifier. enabled (bool): Whether the stage is active. ''' ``` --- ## Parsing guarantees GSDFC ensures doc-forge can deterministically extract: - symbol kind (module, class, function, property, attribute) - symbol name - parameters - return values - attributes - examples - structured Notes subsections This enables: - reliable MkDocs rendering - deterministic MCP export - accurate AI semantic interpretation --- Notes: - doc-forge never executes analyzed modules. - Documentation is generated entirely through static analysis. """ from .loaders import GriffeLoader, discover_module_paths from .renderers import MkDocsRenderer, MCPRenderer from .cli import main from . import models __all__ = [ "GriffeLoader", "discover_module_paths", "MkDocsRenderer", "MCPRenderer", "models", "main", ]