Provides the CLI structure using Click, including build, serve, and tree commands.
-
-
-
-
- Notes
-
-
The build command validates requested modes before generating anything.
-
--mkdocs, --api, and --wiki each emit their own MkDocs config and
- build (docs/mkdocs.{kind}.yml into site/{kind}); --mcp generates a
- machine-readable bundle independently.
This command runs the full documentation pipeline: it loads Python
-modules, generates renderer-specific documentation sources, and
-optionally builds the final output.
-
Depending on the selected options, the build can target:
-
-
A lib MkDocs site (--mkdocs) for library reference docs
-
A swagger-enabled API MkDocs site (--api) built from an OpenAPI spec
-
A wiki MkDocs site (--wiki) built from hand-written markdown
-
MCP structured documentation resources (--mcp)
-
-
Each enabled site kind produces its own MkDocs configuration
-(docs/mkdocs.{kind}.yml) and its own build (site/{kind}).
-
-
-
- Notes
-
-
At least one of --mcp, --mkdocs, --wiki, or --api must be
- provided.
-
--mkdocs, --api, and --wiki emit independent MkDocs builds,
- while --mcp emits a machine-readable bundle.
-
Configuration files are generated only when absent; an existing
- docs/mkdocs.{kind}.yml is used as-is. Pass --refresh to
- rebaseline it from the templates.
-
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
mcp
-
- bool
-
-
-
-
Enable MCP documentation generation.
-
-
-
- required
-
-
-
-
mkdocs
-
- bool
-
-
-
-
Enable the lib MkDocs documentation generation.
-
-
-
- required
-
-
-
-
api
-
- bool
-
-
-
-
Enable API documentation generation from an OpenAPI spec.
-
-
-
- required
-
-
-
-
wiki
-
- bool
-
-
-
-
Build a hand-written wiki directory as its own MkDocs site.
-
-
-
- required
-
-
-
-
refresh
-
- bool
-
-
-
-
Regenerate docs/mkdocs.{kind}.yml from templates even when
-it already exists. By default, existing configs are used as-is.
-
-
-
- required
-
-
-
-
module_is_source
-
- bool
-
-
-
-
Treat the specified module directory as the project root.
-
-
-
- required
-
-
-
-
module
-
- str | None
-
-
-
-
Python module import path to document.
-
-
-
- required
-
-
-
-
openapi_spec
-
- Path | None
-
-
-
-
Path to the OpenAPI JSON specification used for API docs.
-
-
-
- required
-
-
-
-
project_name
-
- str | None
-
-
-
-
Optional override for the project name.
-
-
-
- required
-
-
-
-
site_name
-
- str | None
-
-
-
-
Display name for the lib and wiki MkDocs sites.
-
-
-
- required
-
-
-
-
docs_dir
-
- Path
-
-
-
-
Shared documentation root used for generated sources.
-
-
-
- required
-
-
-
-
wiki_dir
-
- Path
-
-
-
-
Directory containing hand-written wiki markdown files.
Depending on the selected mode, this command starts either:
-
-
A MkDocs development server for browsing a site, or
-
An MCP server exposing structured documentation resources
-
-
The kind flags (--lib, --api, --wiki) select the generated
-per-kind config (docs/mkdocs.{kind}.yml); --mkdocs serves the config
-passed via --mkdocs-yml.
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
mcp
-
- bool
-
-
-
-
Serve documentation using the MCP server.
-
-
-
- required
-
-
-
-
mkdocs
-
- bool
-
-
-
-
Serve the MkDocs development site from --mkdocs-yml.
Display the documentation object tree for a module.
-
This command introspects the specified module and prints a
-hierarchical representation of the discovered documentation
-objects, including modules, classes, functions, and members.
This module exposes the primary CLI entry function used by the
-doc-forge command. The actual command implementation resides in
-docforge.cli.main, while this module provides a stable import path
-for external tools and the package entry point configuration.
-
The CLI is responsible for orchestrating documentation workflows such as
-generating renderer sources, building documentation sites, exporting
-machine-readable documentation bundles, and starting development or MCP
-servers.
-
-
Typical usage
-
The CLI is normally invoked through the installed command:
This function initializes and executes the Click CLI application.
-It is used as the console entry point when invoking doc-forge
-from the command line.
Generate MCP documentation resources from a Python module.
-
The function performs project introspection, builds the internal
-documentation model, and renders MCP-compatible JSON resources
-to the specified output directory.
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
module
-
- str
-
-
-
-
Python module import path used as the entry point for
-documentation generation.
-
-
-
- required
-
-
-
-
project_name
-
- str | None
-
-
-
-
Optional override for the project name used in generated
-documentation metadata.
-
-
-
- required
-
-
-
-
out_dir
-
- Path
-
-
-
-
Directory where MCP resources (index.json, nav.json, and module data)
-will be written.
Utilities for working with MkDocs in the doc-forge CLI.
-
-
-
-
- Notes
-
-
A separate mkdocs.{kind}.yml configuration and build is emitted per
- enabled kind (lib, api, wiki), each scoped to its own docs_dir and
- written into its own site_dir (site/lib, site/api, site/wiki).
-
Navigation blocks are re-rooted per kind: the wiki navigation drops its
- leading wiki/ scope and the resolved nav spec drops its lib/ scope.
Build the re-rooted navigation block for a lib site.
-
The navigation specification is resolved against the shared documentation
-root and every resulting path is re-rooted relative to the lib
-subdirectory by stripping its leading lib/ scope component.
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
nav_file
-
- Path
-
-
-
-
Path to the docforge.nav.yml navigation specification.
-
-
-
- required
-
-
-
-
docs_root
-
- Path
-
-
-
-
Shared documentation root containing the lib sources.
Build the re-rooted navigation block for a wiki site.
-
The wiki navigation derived from the wiki file structure is re-rooted
-relative to the wiki directory itself by stripping the leading wiki/
-scope component.
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
wiki_dir
-
- Path
-
-
-
-
Path to the hand-written wiki directory, for example docs/wiki.
-
-
-
- required
-
-
-
-
-
-
-
Returns:
-
-
-
-
Type
-
Description
-
-
-
-
-
- list[dict[str, Any]]
-
-
-
-
list[dict[str, Any]]:
-Navigation entries relative to the wiki directory.
Generate a per-kind mkdocs.{kind}.yml configuration file.
-
The configuration is created by merging the shared mkdocs.common.yml
-template with the fragment contributed by the kind (lib, api, or
-wiki). Both docs_dir and site_dir are written relative to the
-configuration file's directory: the kind's sources when expressed as a
-sibling path (for example lib) and the per-kind site output (for
-example ../site/lib).
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
kind
-
- str
-
-
-
-
Documentation kind, one of lib, api, or wiki.
-
-
-
- required
-
-
-
-
kind_root
-
- Path
-
-
-
-
Directory scoped to the kind (for example docs/lib) that
-serves as the MkDocs docs_dir.
-
-
-
- required
-
-
-
-
nav_block
-
- list[dict[str, Any]]
-
-
-
-
Re-rooted navigation entries for the kind's site.
-
-
-
- required
-
-
-
-
out
-
- Path
-
-
-
-
Destination path where the generated mkdocs.{kind}.yml file
-is written.
-
-
-
- required
-
-
-
-
site_name
-
- str
-
-
-
-
Display name for the generated documentation site.
-
-
-
- required
-
-
-
-
docs_dir
-
- str
-
-
-
-
MkDocs docs_dir value, relative to the configuration
-file's directory.
-
-
-
- required
-
-
-
-
site_dir
-
- str
-
-
-
-
MkDocs site_dir value, relative to the configuration
-file's directory.
-
-
-
- required
-
-
-
-
template
-
- Path | None
-
-
-
-
Optional path to a fully custom MkDocs configuration template
-that replaces the built-in templates entirely.
-
-
-
- None
-
-
-
-
site_description
-
- str | None
-
-
-
-
Optional site description written into the configuration.
-
-
-
- None
-
-
-
-
site_author
-
- str | None
-
-
-
-
Optional site author written into the configuration.
-
-
-
- None
-
-
-
-
theme_icon
-
- dict[str, str] | None
-
-
-
-
Optional mapping of theme icon entries injected as
-theme.icon.
Generate MkDocs Markdown sources for a Python module.
-
This function introspects the specified module, builds the internal
-documentation model, and renders Markdown documentation files for
-use with MkDocs.
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
module
-
- str
-
-
-
-
Python module import path used as the entry point for
-documentation generation.
-
-
-
- required
-
-
-
-
docs_dir
-
- Path
-
-
-
-
Directory where the generated Markdown files will be written.
-
-
-
- required
-
-
-
-
project_name
-
- str | None
-
-
-
-
Optional override for the project name used in documentation metadata.
-
-
-
- None
-
-
-
-
module_is_source
-
- bool | None
-
-
-
-
If True, treat the specified module directory as the project root
-rather than a nested module.
-
-
-
- None
-
-
-
-
readme_dir
-
- Path | None
-
-
-
-
Directory where the generated README.md should be written. If not
-provided, defaults to the parent of docs_dir.
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.
doc-forgeserve--wiki# preview from docs/mkdocs.wiki.yml
-doc-forgeserve--lib
-doc-forgeserve--api
-# or any config directly:
-doc-forgeserve--mkdocs--mkdocs-ymldocs/mkdocs.wiki.yml
-
Load Python modules using Griffe and convert them into doc-forge models.
-
This loader uses the Griffe introspection engine to analyze Python source
-code and transform the extracted information into Project, Module,
-and DocObject instances used by doc-forge.
-
-
-
Attributes:
-
-
-
-
Name
-
Type
-
Description
-
-
-
-
-
_loader
-
- GriffeLoader
-
-
-
-
Internal Griffe loader with dedicated module and line collections.
-
-
-
-
-
-
-
Initialize the Griffe-backed loader.
-
Creates an internal Griffe loader instance with dedicated collections
-for modules and source lines.
A populated Project instance containing the loaded modules.
-
-
-
-
-
-
-
-
Raises:
-
-
-
-
Type
-
Description
-
-
-
-
-
- ValueError
-
-
-
-
If no module paths are provided.
-
-
-
-
-
- ImportError
-
-
-
-
If a module fails to load and skip_import_errors is False.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-MCPRenderer
-
-
-
-
-
-
-
-
-
Renderer that generates MCP-compatible documentation resources.
-
This renderer converts doc-forge project models into structured JSON
-resources suitable for consumption by systems implementing the Model
-Context Protocol (MCP).
Generate Markdown documentation files for a project.
-
This method renders a documentation structure from the provided
-project model and writes the resulting Markdown files to the
-specified output directory.
Utilities for loading and introspecting Python modules using Griffe.
-
This module provides the GriffeLoader class and helper utilities used to
-discover Python modules, introspect their structure, and convert the results
-into doc-forge documentation models.
-
-
-
-
- Notes
-
-
All analysis is static; analyzed modules are never executed.
-
Private members (names starting with _) are skipped during conversion.
Load Python modules using Griffe and convert them into doc-forge models.
-
This loader uses the Griffe introspection engine to analyze Python source
-code and transform the extracted information into Project, Module,
-and DocObject instances used by doc-forge.
-
-
-
Attributes:
-
-
-
-
Name
-
Type
-
Description
-
-
-
-
-
_loader
-
- GriffeLoader
-
-
-
-
Internal Griffe loader with dedicated module and line collections.
-
-
-
-
-
-
-
Initialize the Griffe-backed loader.
-
Creates an internal Griffe loader instance with dedicated collections
-for modules and source lines.
The docforge.loaders package is responsible for discovering Python modules
-and extracting documentation data using static analysis.
-
-
Overview
-
This layer converts Python source code into an intermediate documentation
-model used by doc-forge. It performs module discovery, introspection, and
-initial filtering before the data is passed to the core documentation models.
-
Core capabilities include:
-
-
Module discovery – Locate Python modules and packages within a project.
-
Static introspection – Parse docstrings, signatures, and object
- hierarchies using the griffe library without executing the code.
-
Public API filtering – Exclude private members (names prefixed with
- _) to produce clean public documentation structures.
Load Python modules using Griffe and convert them into doc-forge models.
-
This loader uses the Griffe introspection engine to analyze Python source
-code and transform the extracted information into Project, Module,
-and DocObject instances used by doc-forge.
-
-
-
Attributes:
-
-
-
-
Name
-
Type
-
Description
-
-
-
-
-
_loader
-
- GriffeLoader
-
-
-
-
Internal Griffe loader with dedicated module and line collections.
-
-
-
-
-
-
-
Initialize the Griffe-backed loader.
-
Creates an internal Griffe loader instance with dedicated collections
-for modules and source lines.
The docforge.models package defines the core data structures used to
-represent Python source code as a structured documentation model.
-
-
Overview
-
The model layer forms the central intermediate representation used throughout
-doc-forge. Python modules and objects discovered during introspection are
-converted into a hierarchy of documentation models that can later be rendered
-into different documentation formats.
-
Key components:
-
-
Project – Root container representing an entire documented codebase.
-
Module – Representation of a Python module or package containing
- documented members.
-
DocObject – Recursive structure representing Python objects such as
- classes, functions, methods, and attributes.
-
-
These models are intentionally renderer-agnostic, allowing the same
-documentation structure to be transformed into multiple output formats
-(e.g., MkDocs, MCP, or other renderers).
A DocObject models a single Python entity discovered during
-introspection. Objects may contain nested members, allowing the structure
-of modules, classes, and other containers to be represented recursively.
-
-
-
Attributes:
-
-
-
-
Name
-
Type
-
Description
-
-
-
-
-
name
-
- str
-
-
-
-
Local name of the object.
-
-
-
-
-
kind
-
- str
-
-
-
-
Type of object (for example class, function, method, or attribute).
-
-
-
-
-
path
-
- str
-
-
-
-
Fully qualified dotted path to the object.
-
-
-
-
-
signature
-
- str | None
-
-
-
-
Callable signature if the object represents a callable.
-
-
-
-
-
docstring
-
- str | None
-
-
-
-
Raw docstring text extracted from the source code.
Documentation model representing a Python module or package.
-
This module defines the Module class used in the doc-forge documentation
-model. A Module acts as a container for top-level documented objects
-(classes, functions, variables, and other members) discovered during
-introspection.
-
-
-
-
- Notes
-
-
Only public members are stored; private names are filtered by the loader.
Documentation model representing individual Python objects.
-
This module defines the DocObject class, the fundamental recursive unit of
-the doc-forge documentation model. Each DocObject represents a Python
-entity such as a class, function, method, or attribute, and may contain nested
-members that form a hierarchical documentation structure.
-
-
-
-
- Notes
-
-
DocObject instances form a tree mirroring the Python import hierarchy.
-
Objects are renderer-agnostic and may be consumed by any renderer.
A DocObject models a single Python entity discovered during
-introspection. Objects may contain nested members, allowing the structure
-of modules, classes, and other containers to be represented recursively.
-
-
-
Attributes:
-
-
-
-
Name
-
Type
-
Description
-
-
-
-
-
name
-
- str
-
-
-
-
Local name of the object.
-
-
-
-
-
kind
-
- str
-
-
-
-
Type of object (for example class, function, method, or attribute).
-
-
-
-
-
path
-
- str
-
-
-
-
Fully qualified dotted path to the object.
-
-
-
-
-
signature
-
- str | None
-
-
-
-
Callable signature if the object represents a callable.
-
-
-
-
-
docstring
-
- str | None
-
-
-
-
Raw docstring text extracted from the source code.
This module defines the Project class, the top-level container used by
-doc-forge to represent a documented codebase. A Project aggregates multiple
-modules and provides access to them through a unified interface.
-
-
-
-
- Notes
-
-
Modules are keyed by their dotted import path.
-
Objects are renderer-agnostic; the same model feeds every renderer.
The docforge.nav package manages the relationship between the logical
-documentation structure defined by the user and the physical documentation
-files generated on disk.
-
-
Workflow
-
-
Specification – Users define navigation intent in docforge.nav.yml.
-
Resolution – resolve_nav expands patterns and matches them against
- generated Markdown files.
-
Emission – MkDocsNavEmitter converts the resolved structure into
- the YAML navigation format required by mkdocs.yml.
-
-
This layer separates documentation organization from the underlying source
-code layout, enabling flexible grouping, ordering, and navigation structures
-independent of module hierarchy.
-
-
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-
-
-
-
-MkDocsNavEmitter
-
-
-
-
-
-
-
-
-
Emit MkDocs navigation structures from resolved navigation data.
-
The emitter transforms a ResolvedNav object into the YAML-compatible
-list structure expected by the MkDocs nav configuration field.
Resolved navigation data describing documentation groups
-and their associated Markdown files.
-
-
-
- required
-
-
-
-
-
-
-
Returns:
-
-
-
-
Type
-
Description
-
-
-
-
-
- list[dict[str, Any]]
-
-
-
-
list[dict[str, Any]]:
-A list of dictionaries representing the MkDocs navigation layout.
-Each dictionary maps a navigation label to a page or a list of
-pages.
Derive an MkDocs navigation block from a wiki directory.
-
Returned paths are relative to the parent of wiki_dir and carry the
-wiki directory name as their leading component (for example
-wiki/01_overview.md when the wiki lives at docs/wiki). This makes
-the result directly usable in an MkDocs nav block with
-
-
index.md at the wiki root becomes the Home entry.
-
Page labels are derived from filenames: numeric order prefixes such as
- 01_ or 02- are stripped, separators are replaced with spaces, and
- names are title-cased (01_overview.md becomes Overview).
-
Subdirectories become nested navigation groups. A nested index.md is
- rendered as the section root placed first inside the group.
-
Only .md files are considered; hidden entries are ignored.
-
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
wiki_dir
-
- Path
-
-
-
-
Path to the hand-written wiki directory, for example docs/wiki.
-
-
-
- required
-
-
-
-
-
-
-
Returns:
-
-
-
-
Type
-
Description
-
-
-
-
-
- list[dict[str, Any]]
-
-
-
-
list[dict[str, Any]]:
-Navigation entries compatible with the MkDocs nav configuration.
-The list is empty if the wiki contains no Markdown files.
This module provides the MkDocsNavEmitter class, which converts a
-ResolvedNav instance into the navigation structure required by the
-MkDocs nav configuration.
-
-
-
-
- Notes
-
-
The emitted structure is a list of dictionaries, one per top-level nav
- entry, matching the MkDocs nav YAML format.
-
-
-
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-
-
-
-
-MkDocsNavEmitter
-
-
-
-
-
-
-
-
-
Emit MkDocs navigation structures from resolved navigation data.
-
The emitter transforms a ResolvedNav object into the YAML-compatible
-list structure expected by the MkDocs nav configuration field.
Resolved navigation data describing documentation groups
-and their associated Markdown files.
-
-
-
- required
-
-
-
-
-
-
-
Returns:
-
-
-
-
Type
-
Description
-
-
-
-
-
- list[dict[str, Any]]
-
-
-
-
list[dict[str, Any]]:
-A list of dictionaries representing the MkDocs navigation layout.
-Each dictionary maps a navigation label to a page or a list of
-pages.
This module defines the NavSpec class, which represents the navigation
-structure defined by the user in the doc-forge navigation specification
-(typically docforge.nav.yml).
-
-
-
-
- Notes
-
-
The spec file supports an optional icon mapping for MkDocs theme
- customization.
-
All file references in groups are relative to the documentation root.
This module provides build_wiki_nav, which derives an MkDocs-ready
-navigation block from the file structure of a hand-written wiki directory
-(typically docs/wiki). wiki content is authored by hand and is never
-modified by doc-forge; only the navigation layout is inferred.
-
Notes
-
-
index.md at the wiki root becomes the Home entry.
-
Page labels are derived from filenames: numeric order prefixes such as
- 01_ or 02- are stripped, separators are replaced with spaces, and
- names are title-cased (01_overview.md becomes Overview).
-
Subdirectories become nested navigation groups. A nested index.md is
- rendered as the section root placed first inside the group.
-
Only .md files are considered; hidden entries are ignored.
Derive an MkDocs navigation block from a wiki directory.
-
Returned paths are relative to the parent of wiki_dir and carry the
-wiki directory name as their leading component (for example
-wiki/01_overview.md when the wiki lives at docs/wiki). This makes
-the result directly usable in an MkDocs nav block with
-
-
index.md at the wiki root becomes the Home entry.
-
Page labels are derived from filenames: numeric order prefixes such as
- 01_ or 02- are stripped, separators are replaced with spaces, and
- names are title-cased (01_overview.md becomes Overview).
-
Subdirectories become nested navigation groups. A nested index.md is
- rendered as the section root placed first inside the group.
-
Only .md files are considered; hidden entries are ignored.
-
-
-
-
Parameters:
-
-
-
-
Name
-
Type
-
Description
-
Default
-
-
-
-
-
wiki_dir
-
- Path
-
-
-
-
Path to the hand-written wiki directory, for example docs/wiki.
-
-
-
- required
-
-
-
-
-
-
-
Returns:
-
-
-
-
Type
-
Description
-
-
-
-
-
- list[dict[str, Any]]
-
-
-
-
list[dict[str, Any]]:
-Navigation entries compatible with the MkDocs nav configuration.
-The list is empty if the wiki contains no Markdown files.
Renderer base interfaces and configuration models.
-
This module defines the base protocol and configuration container used by
-doc-forge renderers. Concrete renderer implementations should implement the
-DocRenderer protocol.
-
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-
-
-
-
-DocRenderer
-
-
-
-
-
-
-
- Bases: Protocol
-
-
-
Protocol defining the interface for documentation renderers.
-
Implementations of this protocol are responsible for transforming a
-Project model into renderer-specific documentation sources.
The docforge.renderers package transforms the internal documentation
-models into files formatted for specific documentation systems.
-
-
Overview
-
Renderers consume the doc-forge project model and generate output suitable
-for documentation tools or machine interfaces.
-
Current implementations:
-
-
MkDocsRenderer – Produces Markdown files compatible with MkDocs and
- the mkdocstrings plugin. It automatically handles package hierarchy
- and generates index.md files for packages.
-
MCPRenderer – Emits structured JSON resources designed for consumption
- by Model Context Protocol (MCP) clients.
-
-
-
Extending
-
New renderers can be added by implementing the DocRenderer protocol
-defined in docforge.renderers.base.
-
-
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-
-
-
-
-MCPRenderer
-
-
-
-
-
-
-
-
-
Renderer that generates MCP-compatible documentation resources.
-
This renderer converts doc-forge project models into structured JSON
-resources suitable for consumption by systems implementing the Model
-Context Protocol (MCP).
Generate Markdown documentation files for a project.
-
This method renders a documentation structure from the provided
-project model and writes the resulting Markdown files to the
-specified output directory.
This module defines the MCPRenderer class, which generates documentation
-resources compatible with the Model Context Protocol (MCP).
-
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-
-
-
-
-MCPRenderer
-
-
-
-
-
-
-
-
-
Renderer that generates MCP-compatible documentation resources.
-
This renderer converts doc-forge project models into structured JSON
-resources suitable for consumption by systems implementing the Model
-Context Protocol (MCP).
This module defines the MkDocsRenderer class, which generates Markdown
-documentation sources compatible with MkDocs Material and the mkdocstrings
-plugin.
-
The renderer ensures a consistent documentation structure by:
-
-
Creating a root index.md if one does not exist
-
Generating package index pages automatically
-
Linking child modules within parent package pages
-
Optionally generating README.md from the root package docstring
-
-
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-
-
-
-
-MkDocsRenderer
-
-
-
-
-
-
-
-
-
Renderer that produces Markdown documentation for MkDocs.
-
Generated pages use mkdocstrings directives to reference Python modules,
-allowing MkDocs to render API documentation dynamically.
Generate Markdown documentation files for a project.
-
This method renders a documentation structure from the provided
-project model and writes the resulting Markdown files to the
-specified output directory.
This module exposes server implementations used to provide live access
-to generated documentation resources. Currently, it includes the MCP
-documentation server.
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.
Class docstrings define object responsibility, lifecycle, and attributes.
Recommended sections:
Attributes:\nNotes:\nExample:\nRaises:\n
Example
Simple Foo:
class Foo:\n '''\n Represents a unit of work.\n\n Attributes:\n name (str):\n Identifier of the foo instance.\n\n value (int):\n Numeric value associated with foo.\n\n Notes:\n Guarantees:\n\n - instances are immutable after creation\n\n Lifecycle:\n\n - create instance\n - pass to processing engine\n\n Example:\n Create and inspect a Foo:\n\n ```python\n foo = Foo(\"example\", value=42)\n print(foo.name)\n ```\n '''\n
Complex Bar:
class BarEngine:\n '''\n Executes Foo objects through Bar stages.\n\n Attributes:\n foos (tuple[Foo, ...]):\n Foo instances managed by the engine.\n\n Notes:\n Guarantees:\n\n - deterministic execution order\n\n Example:\n Run engine:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n
"},{"location":"#docforge--function-and-method-docstrings","title":"Function and method docstrings","text":"
def process(foo: Foo, multiplier: int) -> int:\n '''\n Process a Foo instance.\n\n Args:\n foo (Foo):\n Foo instance to process.\n\n multiplier (int):\n Value used to scale foo.\n\n Returns:\n int:\n Processed result.\n\n Raises:\n ValueError:\n If multiplier is negative.\n\n Notes:\n Guarantees:\n\n - foo is not modified\n\n Example:\n Process foo:\n\n ```python\n foo = Foo(\"example\", value=10)\n\n result = process(foo, multiplier=2)\n print(result)\n ```\n '''\n
Document attributes in class docstrings using Attributes:.
Example
Attribute Doc String:
```python\n'''\nRepresents a processing stage.\n\nAttributes:\n id (str):\n Unique identifier.\n\n enabled (bool):\n Whether the stage is active.\n'''\n```\n
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
This module exposes the primary CLI entry function used by the doc-forge command. The actual command implementation resides in docforge.cli.main, while this module provides a stable import path for external tools and the package entry point configuration.
The CLI is responsible for orchestrating documentation workflows such as generating renderer sources, building documentation sites, exporting machine-readable documentation bundles, and starting development or MCP servers.
Provides the CLI structure using Click, including build, serve, and tree commands.
Notes
The build command validates requested modes before generating anything.
--mkdocs, --api, and --wiki each emit their own MkDocs config and build (docs/mkdocs.{kind}.yml into site/{kind}); --mcp generates a machine-readable bundle independently.
This command runs the full documentation pipeline: it loads Python modules, generates renderer-specific documentation sources, and optionally builds the final output.
Depending on the selected options, the build can target:
A lib MkDocs site (--mkdocs) for library reference docs
A swagger-enabled API MkDocs site (--api) built from an OpenAPI spec
A wiki MkDocs site (--wiki) built from hand-written markdown
MCP structured documentation resources (--mcp)
Each enabled site kind produces its own MkDocs configuration (docs/mkdocs.{kind}.yml) and its own build (site/{kind}).
Notes
At least one of --mcp, --mkdocs, --wiki, or --api must be provided.
--mkdocs, --api, and --wiki emit independent MkDocs builds, while --mcp emits a machine-readable bundle.
Configuration files are generated only when absent; an existing docs/mkdocs.{kind}.yml is used as-is. Pass --refresh to rebaseline it from the templates.
Parameters:
Name Type Description Default mcpbool
Enable MCP documentation generation.
required mkdocsbool
Enable the lib MkDocs documentation generation.
required apibool
Enable API documentation generation from an OpenAPI spec.
required wikibool
Build a hand-written wiki directory as its own MkDocs site.
required refreshbool
Regenerate docs/mkdocs.{kind}.yml from templates even when it already exists. By default, existing configs are used as-is.
required module_is_sourcebool
Treat the specified module directory as the project root.
required modulestr | None
Python module import path to document.
required openapi_specPath | None
Path to the OpenAPI JSON specification used for API docs.
required project_namestr | None
Optional override for the project name.
required site_namestr | None
Display name for the lib and wiki MkDocs sites.
required docs_dirPath
Shared documentation root used for generated sources.
required wiki_dirPath
Directory containing hand-written wiki markdown files.
Depending on the selected mode, this command starts either:
A MkDocs development server for browsing a site, or
An MCP server exposing structured documentation resources
The kind flags (--lib, --api, --wiki) select the generated per-kind config (docs/mkdocs.{kind}.yml); --mkdocs serves the config passed via --mkdocs-yml.
Parameters:
Name Type Description Default mcpbool
Serve documentation using the MCP server.
required mkdocsbool
Serve the MkDocs development site from --mkdocs-yml.
Display the documentation object tree for a module.
This command introspects the specified module and prints a hierarchical representation of the discovered documentation objects, including modules, classes, functions, and members.
Generate MCP documentation resources from a Python module.
The function performs project introspection, builds the internal documentation model, and renders MCP-compatible JSON resources to the specified output directory.
Parameters:
Name Type Description Default modulestr
Python module import path used as the entry point for documentation generation.
required project_namestr | None
Optional override for the project name used in generated documentation metadata.
required out_dirPath
Directory where MCP resources (index.json, nav.json, and module data) will be written.
Utilities for working with MkDocs in the doc-forge CLI.
Notes
A separate mkdocs.{kind}.yml configuration and build is emitted per enabled kind (lib, api, wiki), each scoped to its own docs_dir and written into its own site_dir (site/lib, site/api, site/wiki).
Navigation blocks are re-rooted per kind: the wiki navigation drops its leading wiki/ scope and the resolved nav spec drops its lib/ scope.
Build the re-rooted navigation block for a lib site.
The navigation specification is resolved against the shared documentation root and every resulting path is re-rooted relative to the lib subdirectory by stripping its leading lib/ scope component.
Parameters:
Name Type Description Default nav_filePath
Path to the docforge.nav.yml navigation specification.
required docs_rootPath
Shared documentation root containing the lib sources.
required
Returns:
Type Description tuple[list[dict[str, Any]], dict[str, str] | None]
tuple[list[dict[str, Any]], dict[str, str] | None]: The re-rooted navigation block and the optional theme icon mapping from the specification.
Build the re-rooted navigation block for a wiki site.
The wiki navigation derived from the wiki file structure is re-rooted relative to the wiki directory itself by stripping the leading wiki/ scope component.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries relative to the wiki directory.
Generate a per-kind mkdocs.{kind}.yml configuration file.
The configuration is created by merging the shared mkdocs.common.yml template with the fragment contributed by the kind (lib, api, or wiki). Both docs_dir and site_dir are written relative to the configuration file's directory: the kind's sources when expressed as a sibling path (for example lib) and the per-kind site output (for example ../site/lib).
Parameters:
Name Type Description Default kindstr
Documentation kind, one of lib, api, or wiki.
required kind_rootPath
Directory scoped to the kind (for example docs/lib) that serves as the MkDocs docs_dir.
required nav_blocklist[dict[str, Any]]
Re-rooted navigation entries for the kind's site.
required outPath
Destination path where the generated mkdocs.{kind}.yml file is written.
required site_namestr
Display name for the generated documentation site.
required docs_dirstr
MkDocs docs_dir value, relative to the configuration file's directory.
required site_dirstr
MkDocs site_dir value, relative to the configuration file's directory.
required templatePath | None
Optional path to a fully custom MkDocs configuration template that replaces the built-in templates entirely.
Nonesite_descriptionstr | None
Optional site description written into the configuration.
Nonesite_authorstr | None
Optional site author written into the configuration.
Nonetheme_icondict[str, str] | None
Optional mapping of theme icon entries injected as theme.icon.
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.
Each site kind (lib, api, wiki) is built independently into site/{kind}.
"},{"location":"docforge/#docforge--build-the-library-reference-from-a-python-package","title":"Build the library reference from a Python package:","text":"
doc-forge build --mkdocs --module my_package\n
"},{"location":"docforge/#docforge--build-the-api-reference-from-an-openapi-spec","title":"Build the API reference from an OpenAPI spec:","text":"
doc-forge build --api --openapi-spec spec.json\n
"},{"location":"docforge/#docforge--build-the-hand-written-wiki","title":"Build the hand-written wiki:","text":"
Class docstrings define object responsibility, lifecycle, and attributes.
Recommended sections:
Attributes:\nNotes:\nExample:\nRaises:\n
Example
Simple Foo:
class Foo:\n '''\n Represents a unit of work.\n\n Attributes:\n name (str):\n Identifier of the foo instance.\n\n value (int):\n Numeric value associated with foo.\n\n Notes:\n Guarantees:\n\n - instances are immutable after creation\n\n Lifecycle:\n\n - create instance\n - pass to processing engine\n\n Example:\n Create and inspect a Foo:\n\n ```python\n foo = Foo(\"example\", value=42)\n print(foo.name)\n ```\n '''\n
Complex Bar:
class BarEngine:\n '''\n Executes Foo objects through Bar stages.\n\n Attributes:\n foos (tuple[Foo, ...]):\n Foo instances managed by the engine.\n\n Notes:\n Guarantees:\n\n - deterministic execution order\n\n Example:\n Run engine:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n
"},{"location":"docforge/#docforge--function-and-method-docstrings","title":"Function and method docstrings","text":"
def process(foo: Foo, multiplier: int) -> int:\n '''\n Process a Foo instance.\n\n Args:\n foo (Foo):\n Foo instance to process.\n\n multiplier (int):\n Value used to scale foo.\n\n Returns:\n int:\n Processed result.\n\n Raises:\n ValueError:\n If multiplier is negative.\n\n Notes:\n Guarantees:\n\n - foo is not modified\n\n Example:\n Process foo:\n\n ```python\n foo = Foo(\"example\", value=10)\n\n result = process(foo, multiplier=2)\n print(result)\n ```\n '''\n
Document attributes in class docstrings using Attributes:.
Example
Attribute Doc String:
```python\n'''\nRepresents a processing stage.\n\nAttributes:\n id (str):\n Unique identifier.\n\n enabled (bool):\n Whether the stage is active.\n'''\n```\n
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
This module exposes the primary CLI entry function used by the doc-forge command. The actual command implementation resides in docforge.cli.main, while this module provides a stable import path for external tools and the package entry point configuration.
The CLI is responsible for orchestrating documentation workflows such as generating renderer sources, building documentation sites, exporting machine-readable documentation bundles, and starting development or MCP servers.
Provides the CLI structure using Click, including build, serve, and tree commands.
Notes
The build command validates requested modes before generating anything.
--mkdocs, --api, and --wiki each emit their own MkDocs config and build (docs/mkdocs.{kind}.yml into site/{kind}); --mcp generates a machine-readable bundle independently.
This command runs the full documentation pipeline: it loads Python modules, generates renderer-specific documentation sources, and optionally builds the final output.
Depending on the selected options, the build can target:
A lib MkDocs site (--mkdocs) for library reference docs
A swagger-enabled API MkDocs site (--api) built from an OpenAPI spec
A wiki MkDocs site (--wiki) built from hand-written markdown
MCP structured documentation resources (--mcp)
Each enabled site kind produces its own MkDocs configuration (docs/mkdocs.{kind}.yml) and its own build (site/{kind}).
Notes
At least one of --mcp, --mkdocs, --wiki, or --api must be provided.
--mkdocs, --api, and --wiki emit independent MkDocs builds, while --mcp emits a machine-readable bundle.
Configuration files are generated only when absent; an existing docs/mkdocs.{kind}.yml is used as-is. Pass --refresh to rebaseline it from the templates.
Parameters:
Name Type Description Default mcpbool
Enable MCP documentation generation.
required mkdocsbool
Enable the lib MkDocs documentation generation.
required apibool
Enable API documentation generation from an OpenAPI spec.
required wikibool
Build a hand-written wiki directory as its own MkDocs site.
required refreshbool
Regenerate docs/mkdocs.{kind}.yml from templates even when it already exists. By default, existing configs are used as-is.
required module_is_sourcebool
Treat the specified module directory as the project root.
required modulestr | None
Python module import path to document.
required openapi_specPath | None
Path to the OpenAPI JSON specification used for API docs.
required project_namestr | None
Optional override for the project name.
required site_namestr | None
Display name for the lib and wiki MkDocs sites.
required docs_dirPath
Shared documentation root used for generated sources.
required wiki_dirPath
Directory containing hand-written wiki markdown files.
Depending on the selected mode, this command starts either:
A MkDocs development server for browsing a site, or
An MCP server exposing structured documentation resources
The kind flags (--lib, --api, --wiki) select the generated per-kind config (docs/mkdocs.{kind}.yml); --mkdocs serves the config passed via --mkdocs-yml.
Parameters:
Name Type Description Default mcpbool
Serve documentation using the MCP server.
required mkdocsbool
Serve the MkDocs development site from --mkdocs-yml.
Display the documentation object tree for a module.
This command introspects the specified module and prints a hierarchical representation of the discovered documentation objects, including modules, classes, functions, and members.
Generate MCP documentation resources from a Python module.
The function performs project introspection, builds the internal documentation model, and renders MCP-compatible JSON resources to the specified output directory.
Parameters:
Name Type Description Default modulestr
Python module import path used as the entry point for documentation generation.
required project_namestr | None
Optional override for the project name used in generated documentation metadata.
required out_dirPath
Directory where MCP resources (index.json, nav.json, and module data) will be written.
Utilities for working with MkDocs in the doc-forge CLI.
Notes
A separate mkdocs.{kind}.yml configuration and build is emitted per enabled kind (lib, api, wiki), each scoped to its own docs_dir and written into its own site_dir (site/lib, site/api, site/wiki).
Navigation blocks are re-rooted per kind: the wiki navigation drops its leading wiki/ scope and the resolved nav spec drops its lib/ scope.
Build the re-rooted navigation block for a lib site.
The navigation specification is resolved against the shared documentation root and every resulting path is re-rooted relative to the lib subdirectory by stripping its leading lib/ scope component.
Parameters:
Name Type Description Default nav_filePath
Path to the docforge.nav.yml navigation specification.
required docs_rootPath
Shared documentation root containing the lib sources.
required
Returns:
Type Description tuple[list[dict[str, Any]], dict[str, str] | None]
tuple[list[dict[str, Any]], dict[str, str] | None]: The re-rooted navigation block and the optional theme icon mapping from the specification.
Build the re-rooted navigation block for a wiki site.
The wiki navigation derived from the wiki file structure is re-rooted relative to the wiki directory itself by stripping the leading wiki/ scope component.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries relative to the wiki directory.
Generate a per-kind mkdocs.{kind}.yml configuration file.
The configuration is created by merging the shared mkdocs.common.yml template with the fragment contributed by the kind (lib, api, or wiki). Both docs_dir and site_dir are written relative to the configuration file's directory: the kind's sources when expressed as a sibling path (for example lib) and the per-kind site output (for example ../site/lib).
Parameters:
Name Type Description Default kindstr
Documentation kind, one of lib, api, or wiki.
required kind_rootPath
Directory scoped to the kind (for example docs/lib) that serves as the MkDocs docs_dir.
required nav_blocklist[dict[str, Any]]
Re-rooted navigation entries for the kind's site.
required outPath
Destination path where the generated mkdocs.{kind}.yml file is written.
required site_namestr
Display name for the generated documentation site.
required docs_dirstr
MkDocs docs_dir value, relative to the configuration file's directory.
required site_dirstr
MkDocs site_dir value, relative to the configuration file's directory.
required templatePath | None
Optional path to a fully custom MkDocs configuration template that replaces the built-in templates entirely.
Nonesite_descriptionstr | None
Optional site description written into the configuration.
Nonesite_authorstr | None
Optional site author written into the configuration.
Nonetheme_icondict[str, str] | None
Optional mapping of theme icon entries injected as theme.icon.
This layer converts Python source code into an intermediate documentation model used by doc-forge. It performs module discovery, introspection, and initial filtering before the data is passed to the core documentation models.
Core capabilities include:
Module discovery \u2013 Locate Python modules and packages within a project.
Static introspection \u2013 Parse docstrings, signatures, and object hierarchies using the griffe library without executing the code.
Public API filtering \u2013 Exclude private members (names prefixed with _) to produce clean public documentation structures.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
Utilities for loading and introspecting Python modules using Griffe.
This module provides the GriffeLoader class and helper utilities used to discover Python modules, introspect their structure, and convert the results into doc-forge documentation models.
Notes
All analysis is static; analyzed modules are never executed.
Private members (names starting with _) are skipped during conversion.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
The model layer forms the central intermediate representation used throughout doc-forge. Python modules and objects discovered during introspection are converted into a hierarchy of documentation models that can later be rendered into different documentation formats.
Key components:
Project \u2013 Root container representing an entire documented codebase.
Module \u2013 Representation of a Python module or package containing documented members.
DocObject \u2013 Recursive structure representing Python objects such as classes, functions, methods, and attributes.
These models are intentionally renderer-agnostic, allowing the same documentation structure to be transformed into multiple output formats (e.g., MkDocs, MCP, or other renderers).
A DocObject models a single Python entity discovered during introspection. Objects may contain nested members, allowing the structure of modules, classes, and other containers to be represented recursively.
Attributes:
Name Type Description namestr
Local name of the object.
kindstr
Type of object (for example class, function, method, or attribute).
pathstr
Fully qualified dotted path to the object.
signaturestr | None
Callable signature if the object represents a callable.
docstringstr | None
Raw docstring text extracted from the source code.
membersdict[str, DocObject]
Mapping of member names to child DocObject instances.
Initialize a DocObject instance.
Parameters:
Name Type Description Default namestr
Local name of the object.
required kindstr
Object type identifier (for example class or function).
Documentation model representing a Python module or package.
This module defines the Module class used in the doc-forge documentation model. A Module acts as a container for top-level documented objects (classes, functions, variables, and other members) discovered during introspection.
Notes
Only public members are stored; private names are filtered by the loader.
Documentation model representing individual Python objects.
This module defines the DocObject class, the fundamental recursive unit of the doc-forge documentation model. Each DocObject represents a Python entity such as a class, function, method, or attribute, and may contain nested members that form a hierarchical documentation structure.
Notes
DocObject instances form a tree mirroring the Python import hierarchy.
Objects are renderer-agnostic and may be consumed by any renderer.
A DocObject models a single Python entity discovered during introspection. Objects may contain nested members, allowing the structure of modules, classes, and other containers to be represented recursively.
Attributes:
Name Type Description namestr
Local name of the object.
kindstr
Type of object (for example class, function, method, or attribute).
pathstr
Fully qualified dotted path to the object.
signaturestr | None
Callable signature if the object represents a callable.
docstringstr | None
Raw docstring text extracted from the source code.
membersdict[str, DocObject]
Mapping of member names to child DocObject instances.
Initialize a DocObject instance.
Parameters:
Name Type Description Default namestr
Local name of the object.
required kindstr
Object type identifier (for example class or function).
This module defines the Project class, the top-level container used by doc-forge to represent a documented codebase. A Project aggregates multiple modules and provides access to them through a unified interface.
Notes
Modules are keyed by their dotted import path.
Objects are renderer-agnostic; the same model feeds every renderer.
The docforge.nav package manages the relationship between the logical documentation structure defined by the user and the physical documentation files generated on disk.
Specification \u2013 Users define navigation intent in docforge.nav.yml.
Resolution \u2013 resolve_nav expands patterns and matches them against generated Markdown files.
Emission \u2013 MkDocsNavEmitter converts the resolved structure into the YAML navigation format required by mkdocs.yml.
This layer separates documentation organization from the underlying source code layout, enabling flexible grouping, ordering, and navigation structures independent of module hierarchy.
Resolved navigation data describing documentation groups and their associated Markdown files.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: A list of dictionaries representing the MkDocs navigation layout. Each dictionary maps a navigation label to a page or a list of pages.
Derive an MkDocs navigation block from a wiki directory.
Returned paths are relative to the parent of wiki_dir and carry the wiki directory name as their leading component (for example wiki/01_overview.md when the wiki lives at docs/wiki). This makes the result directly usable in an MkDocs nav block with
index.md at the wiki root becomes the Home entry.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries compatible with the MkDocs nav configuration. The list is empty if the wiki contains no Markdown files.
This module provides the MkDocsNavEmitter class, which converts a ResolvedNav instance into the navigation structure required by the MkDocs nav configuration.
Notes
The emitted structure is a list of dictionaries, one per top-level nav entry, matching the MkDocs nav YAML format.
Resolved navigation data describing documentation groups and their associated Markdown files.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: A list of dictionaries representing the MkDocs navigation layout. Each dictionary maps a navigation label to a page or a list of pages.
This module defines the NavSpec class, which represents the navigation structure defined by the user in the doc-forge navigation specification (typically docforge.nav.yml).
Notes
The spec file supports an optional icon mapping for MkDocs theme customization.
All file references in groups are relative to the documentation root.
This module provides build_wiki_nav, which derives an MkDocs-ready navigation block from the file structure of a hand-written wiki directory (typically docs/wiki). wiki content is authored by hand and is never modified by doc-forge; only the navigation layout is inferred.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Derive an MkDocs navigation block from a wiki directory.
Returned paths are relative to the parent of wiki_dir and carry the wiki directory name as their leading component (for example wiki/01_overview.md when the wiki lives at docs/wiki). This makes the result directly usable in an MkDocs nav block with
index.md at the wiki root becomes the Home entry.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries compatible with the MkDocs nav configuration. The list is empty if the wiki contains no Markdown files.
Renderers consume the doc-forge project model and generate output suitable for documentation tools or machine interfaces.
Current implementations:
MkDocsRenderer \u2013 Produces Markdown files compatible with MkDocs and the mkdocstrings plugin. It automatically handles package hierarchy and generates index.md files for packages.
MCPRenderer \u2013 Emits structured JSON resources designed for consumption by Model Context Protocol (MCP) clients.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
Renderer base interfaces and configuration models.
This module defines the base protocol and configuration container used by doc-forge renderers. Concrete renderer implementations should implement the DocRenderer protocol.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
This module defines the MkDocsRenderer class, which generates Markdown documentation sources compatible with MkDocs Material and the mkdocstrings plugin.
The renderer ensures a consistent documentation structure by:
Creating a root index.md if one does not exist
Generating package index pages automatically
Linking child modules within parent package pages
Optionally generating README.md from the root package docstring
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
This module exposes server implementations used to provide live access to generated documentation resources. Currently, it includes the MCP documentation server.
This layer converts Python source code into an intermediate documentation model used by doc-forge. It performs module discovery, introspection, and initial filtering before the data is passed to the core documentation models.
Core capabilities include:
Module discovery \u2013 Locate Python modules and packages within a project.
Static introspection \u2013 Parse docstrings, signatures, and object hierarchies using the griffe library without executing the code.
Public API filtering \u2013 Exclude private members (names prefixed with _) to produce clean public documentation structures.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
Utilities for loading and introspecting Python modules using Griffe.
This module provides the GriffeLoader class and helper utilities used to discover Python modules, introspect their structure, and convert the results into doc-forge documentation models.
Notes
All analysis is static; analyzed modules are never executed.
Private members (names starting with _) are skipped during conversion.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
The model layer forms the central intermediate representation used throughout doc-forge. Python modules and objects discovered during introspection are converted into a hierarchy of documentation models that can later be rendered into different documentation formats.
Key components:
Project \u2013 Root container representing an entire documented codebase.
Module \u2013 Representation of a Python module or package containing documented members.
DocObject \u2013 Recursive structure representing Python objects such as classes, functions, methods, and attributes.
These models are intentionally renderer-agnostic, allowing the same documentation structure to be transformed into multiple output formats (e.g., MkDocs, MCP, or other renderers).
A DocObject models a single Python entity discovered during introspection. Objects may contain nested members, allowing the structure of modules, classes, and other containers to be represented recursively.
Attributes:
Name Type Description namestr
Local name of the object.
kindstr
Type of object (for example class, function, method, or attribute).
pathstr
Fully qualified dotted path to the object.
signaturestr | None
Callable signature if the object represents a callable.
docstringstr | None
Raw docstring text extracted from the source code.
membersdict[str, DocObject]
Mapping of member names to child DocObject instances.
Initialize a DocObject instance.
Parameters:
Name Type Description Default namestr
Local name of the object.
required kindstr
Object type identifier (for example class or function).
Documentation model representing a Python module or package.
This module defines the Module class used in the doc-forge documentation model. A Module acts as a container for top-level documented objects (classes, functions, variables, and other members) discovered during introspection.
Notes
Only public members are stored; private names are filtered by the loader.
Documentation model representing individual Python objects.
This module defines the DocObject class, the fundamental recursive unit of the doc-forge documentation model. Each DocObject represents a Python entity such as a class, function, method, or attribute, and may contain nested members that form a hierarchical documentation structure.
Notes
DocObject instances form a tree mirroring the Python import hierarchy.
Objects are renderer-agnostic and may be consumed by any renderer.
A DocObject models a single Python entity discovered during introspection. Objects may contain nested members, allowing the structure of modules, classes, and other containers to be represented recursively.
Attributes:
Name Type Description namestr
Local name of the object.
kindstr
Type of object (for example class, function, method, or attribute).
pathstr
Fully qualified dotted path to the object.
signaturestr | None
Callable signature if the object represents a callable.
docstringstr | None
Raw docstring text extracted from the source code.
membersdict[str, DocObject]
Mapping of member names to child DocObject instances.
Initialize a DocObject instance.
Parameters:
Name Type Description Default namestr
Local name of the object.
required kindstr
Object type identifier (for example class or function).
This module defines the Project class, the top-level container used by doc-forge to represent a documented codebase. A Project aggregates multiple modules and provides access to them through a unified interface.
Notes
Modules are keyed by their dotted import path.
Objects are renderer-agnostic; the same model feeds every renderer.
The docforge.nav package manages the relationship between the logical documentation structure defined by the user and the physical documentation files generated on disk.
Specification \u2013 Users define navigation intent in docforge.nav.yml.
Resolution \u2013 resolve_nav expands patterns and matches them against generated Markdown files.
Emission \u2013 MkDocsNavEmitter converts the resolved structure into the YAML navigation format required by mkdocs.yml.
This layer separates documentation organization from the underlying source code layout, enabling flexible grouping, ordering, and navigation structures independent of module hierarchy.
Resolved navigation data describing documentation groups and their associated Markdown files.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: A list of dictionaries representing the MkDocs navigation layout. Each dictionary maps a navigation label to a page or a list of pages.
Derive an MkDocs navigation block from a wiki directory.
Returned paths are relative to the parent of wiki_dir and carry the wiki directory name as their leading component (for example wiki/01_overview.md when the wiki lives at docs/wiki). This makes the result directly usable in an MkDocs nav block with
index.md at the wiki root becomes the Home entry.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries compatible with the MkDocs nav configuration. The list is empty if the wiki contains no Markdown files.
This module provides the MkDocsNavEmitter class, which converts a ResolvedNav instance into the navigation structure required by the MkDocs nav configuration.
Notes
The emitted structure is a list of dictionaries, one per top-level nav entry, matching the MkDocs nav YAML format.
Resolved navigation data describing documentation groups and their associated Markdown files.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: A list of dictionaries representing the MkDocs navigation layout. Each dictionary maps a navigation label to a page or a list of pages.
This module defines the NavSpec class, which represents the navigation structure defined by the user in the doc-forge navigation specification (typically docforge.nav.yml).
Notes
The spec file supports an optional icon mapping for MkDocs theme customization.
All file references in groups are relative to the documentation root.
This module provides build_wiki_nav, which derives an MkDocs-ready navigation block from the file structure of a hand-written wiki directory (typically docs/wiki). wiki content is authored by hand and is never modified by doc-forge; only the navigation layout is inferred.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Derive an MkDocs navigation block from a wiki directory.
Returned paths are relative to the parent of wiki_dir and carry the wiki directory name as their leading component (for example wiki/01_overview.md when the wiki lives at docs/wiki). This makes the result directly usable in an MkDocs nav block with
index.md at the wiki root becomes the Home entry.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries compatible with the MkDocs nav configuration. The list is empty if the wiki contains no Markdown files.
Renderers consume the doc-forge project model and generate output suitable for documentation tools or machine interfaces.
Current implementations:
MkDocsRenderer \u2013 Produces Markdown files compatible with MkDocs and the mkdocstrings plugin. It automatically handles package hierarchy and generates index.md files for packages.
MCPRenderer \u2013 Emits structured JSON resources designed for consumption by Model Context Protocol (MCP) clients.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
Renderer base interfaces and configuration models.
This module defines the base protocol and configuration container used by doc-forge renderers. Concrete renderer implementations should implement the DocRenderer protocol.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
This module defines the MkDocsRenderer class, which generates Markdown documentation sources compatible with MkDocs Material and the mkdocstrings plugin.
The renderer ensures a consistent documentation structure by:
Creating a root index.md if one does not exist
Generating package index pages automatically
Linking child modules within parent package pages
Optionally generating README.md from the root package docstring
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
This module exposes server implementations used to provide live access to generated documentation resources. Currently, it includes the MCP documentation server.
Name Type Description Default transportLiteral['stdio', 'sse', 'streamable-http']
Transport mechanism used by the MCP server. Supported options include stdio, sse, and streamable-http.
'streamable-http'"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"docforge","text":""},{"location":"#docforge","title":"docforge","text":""},{"location":"#docforge--summary","title":"Summary","text":"
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.
Class docstrings define object responsibility, lifecycle, and attributes.
Recommended sections:
Attributes:\nNotes:\nExample:\nRaises:\n
Example
Simple Foo:
class Foo:\n '''\n Represents a unit of work.\n\n Attributes:\n name (str):\n Identifier of the foo instance.\n\n value (int):\n Numeric value associated with foo.\n\n Notes:\n Guarantees:\n\n - instances are immutable after creation\n\n Lifecycle:\n\n - create instance\n - pass to processing engine\n\n Example:\n Create and inspect a Foo:\n\n ```python\n foo = Foo(\"example\", value=42)\n print(foo.name)\n ```\n '''\n
Complex Bar:
class BarEngine:\n '''\n Executes Foo objects through Bar stages.\n\n Attributes:\n foos (tuple[Foo, ...]):\n Foo instances managed by the engine.\n\n Notes:\n Guarantees:\n\n - deterministic execution order\n\n Example:\n Run engine:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n
"},{"location":"#docforge--function-and-method-docstrings","title":"Function and method docstrings","text":"
def process(foo: Foo, multiplier: int) -> int:\n '''\n Process a Foo instance.\n\n Args:\n foo (Foo):\n Foo instance to process.\n\n multiplier (int):\n Value used to scale foo.\n\n Returns:\n int:\n Processed result.\n\n Raises:\n ValueError:\n If multiplier is negative.\n\n Notes:\n Guarantees:\n\n - foo is not modified\n\n Example:\n Process foo:\n\n ```python\n foo = Foo(\"example\", value=10)\n\n result = process(foo, multiplier=2)\n print(result)\n ```\n '''\n
Document attributes in class docstrings using Attributes:.
Example
Attribute Doc String:
```python\n'''\nRepresents a processing stage.\n\nAttributes:\n id (str):\n Unique identifier.\n\n enabled (bool):\n Whether the stage is active.\n'''\n```\n
"},{"location":"#docforge--type-parity-pyi-stubs-and-pytyped","title":"Type parity (.pyi stubs and py.typed)","text":"
Documented APIs ship matching type information:
Each .py module has a synchronized .pyi stub in the same package.
Packages expose a py.typed marker so type checkers (and consumers) use the authored signatures instead of Any.
When signatures change, update the .py implementation and its .pyi stub together.
Doc-forge documents the docstrings in .py; the .pyi stub is the machine-consumable signature surface.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
This module exposes the primary CLI entry function used by the doc-forge command. The actual command implementation resides in docforge.cli.main, while this module provides a stable import path for external tools and the package entry point configuration.
The CLI is responsible for orchestrating documentation workflows such as generating renderer sources, building documentation sites, exporting machine-readable documentation bundles, and starting development or MCP servers.
Provides the CLI structure using Click, including build, serve, and tree commands.
Notes
The build command validates requested modes before generating anything.
--mkdocs, --api, and --wiki each emit their own MkDocs config and build (docs/mkdocs.{kind}.yml into site/{kind}); --mcp generates a machine-readable bundle independently.
This command runs the full documentation pipeline: it loads Python modules, generates renderer-specific documentation sources, and optionally builds the final output.
Depending on the selected options, the build can target:
A lib MkDocs site (--mkdocs) for library reference docs
A swagger-enabled API MkDocs site (--api) built from an OpenAPI spec
A wiki MkDocs site (--wiki) built from hand-written markdown
MCP structured documentation resources (--mcp)
Each enabled site kind produces its own MkDocs configuration (docs/mkdocs.{kind}.yml) and its own build (site/{kind}).
Notes
At least one of --mcp, --mkdocs, --wiki, or --api must be provided.
--mkdocs, --api, and --wiki emit independent MkDocs builds, while --mcp emits a machine-readable bundle.
Configuration files are generated only when absent; an existing docs/mkdocs.{kind}.yml is used as-is. Pass --refresh to rebaseline it from the templates.
Parameters:
Name Type Description Default mcpbool
Enable MCP documentation generation.
required mkdocsbool
Enable the lib MkDocs documentation generation.
required apibool
Enable API documentation generation from an OpenAPI spec.
required wikibool
Build a hand-written wiki directory as its own MkDocs site.
required refreshbool
Regenerate docs/mkdocs.{kind}.yml from templates even when it already exists. By default, existing configs are used as-is.
required module_is_sourcebool
Treat the specified module directory as the project root.
required modulestr | None
Python module import path to document.
required openapi_specPath | None
Path to the OpenAPI JSON specification used for API docs.
required project_namestr | None
Optional override for the project name.
required site_namestr | None
Display name for the lib and wiki MkDocs sites.
required docs_dirPath
Shared documentation root used for generated sources.
required wiki_dirPath
Directory containing hand-written wiki markdown files.
Depending on the selected mode, this command starts either:
A MkDocs development server for browsing a site, or
An MCP server exposing structured documentation resources
The kind flags (--lib, --api, --wiki) select the generated per-kind config (docs/mkdocs.{kind}.yml); --mkdocs serves the config passed via --mkdocs-yml.
Parameters:
Name Type Description Default mcpbool
Serve documentation using the MCP server.
required mkdocsbool
Serve the MkDocs development site from --mkdocs-yml.
Display the documentation object tree for a module.
This command introspects the specified module and prints a hierarchical representation of the discovered documentation objects, including modules, classes, functions, and members.
Generate MCP documentation resources from a Python module.
The function performs project introspection, builds the internal documentation model, and renders MCP-compatible JSON resources to the specified output directory.
Parameters:
Name Type Description Default modulestr
Python module import path used as the entry point for documentation generation.
required project_namestr | None
Optional override for the project name used in generated documentation metadata.
required out_dirPath
Directory where MCP resources (index.json, nav.json, and module data) will be written.
Utilities for working with MkDocs in the doc-forge CLI.
Notes
A separate mkdocs.{kind}.yml configuration and build is emitted per enabled kind (lib, api, wiki), each scoped to its own docs_dir and written into its own site_dir (site/lib, site/api, site/wiki).
Navigation blocks are re-rooted per kind: the wiki navigation drops its leading wiki/ scope and the resolved nav spec drops its lib/ scope.
Build the re-rooted navigation block for a lib site.
The navigation specification is resolved against the shared documentation root and every resulting path is re-rooted relative to the lib subdirectory by stripping its leading lib/ scope component.
Parameters:
Name Type Description Default nav_filePath
Path to the docforge.nav.yml navigation specification.
required docs_rootPath
Shared documentation root containing the lib sources.
required
Returns:
Type Description tuple[list[dict[str, Any]], dict[str, str] | None]
tuple[list[dict[str, Any]], dict[str, str] | None]: The re-rooted navigation block and the optional theme icon mapping from the specification.
Build the re-rooted navigation block for a wiki site.
The wiki navigation derived from the wiki file structure is re-rooted relative to the wiki directory itself by stripping the leading wiki/ scope component.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries relative to the wiki directory.
Generate a per-kind mkdocs.{kind}.yml configuration file.
The configuration is created by merging the shared mkdocs.common.yml template with the fragment contributed by the kind (lib, api, or wiki). Both docs_dir and site_dir are written relative to the configuration file's directory: the kind's sources when expressed as a sibling path (for example lib) and the per-kind site output (for example ../site/lib).
Parameters:
Name Type Description Default kindstr
Documentation kind, one of lib, api, or wiki.
required kind_rootPath
Directory scoped to the kind (for example docs/lib) that serves as the MkDocs docs_dir.
required nav_blocklist[dict[str, Any]]
Re-rooted navigation entries for the kind's site.
required outPath
Destination path where the generated mkdocs.{kind}.yml file is written.
required site_namestr
Display name for the generated documentation site.
required docs_dirstr
MkDocs docs_dir value, relative to the configuration file's directory.
required site_dirstr
MkDocs site_dir value, relative to the configuration file's directory.
required templatePath | None
Optional path to a fully custom MkDocs configuration template that replaces the built-in templates entirely.
Nonesite_descriptionstr | None
Optional site description written into the configuration.
Nonesite_authorstr | None
Optional site author written into the configuration.
Nonetheme_icondict[str, str] | None
Optional mapping of theme icon entries injected as theme.icon.
This layer converts Python source code into an intermediate documentation model used by doc-forge. It performs module discovery, introspection, and initial filtering before the data is passed to the core documentation models.
Core capabilities include:
Module discovery \u2013 Locate Python modules and packages within a project.
Static introspection \u2013 Parse docstrings, signatures, and object hierarchies using the griffe library without executing the code.
Public API filtering \u2013 Exclude private members (names prefixed with _) to produce clean public documentation structures.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
Utilities for loading and introspecting Python modules using Griffe.
This module provides the GriffeLoader class and helper utilities used to discover Python modules, introspect their structure, and convert the results into doc-forge documentation models.
Notes
All analysis is static; analyzed modules are never executed.
Private members (names starting with _) are skipped during conversion.
Imported aliases that cannot be resolved (stdlib/third-party names) are skipped; aliases that resolve within the documented project are kept.
Load Python modules using Griffe and convert them into doc-forge models.
This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into Project, Module, and DocObject instances used by doc-forge.
Attributes:
Name Type Description _loaderGriffeLoader
Internal Griffe loader with dedicated module and line collections.
Initialize the Griffe-backed loader.
Creates an internal Griffe loader instance with dedicated collections for modules and source lines.
The model layer forms the central intermediate representation used throughout doc-forge. Python modules and objects discovered during introspection are converted into a hierarchy of documentation models that can later be rendered into different documentation formats.
Key components:
Project \u2013 Root container representing an entire documented codebase.
Module \u2013 Representation of a Python module or package containing documented members.
DocObject \u2013 Recursive structure representing Python objects such as classes, functions, methods, and attributes.
These models are intentionally renderer-agnostic, allowing the same documentation structure to be transformed into multiple output formats (e.g., MkDocs, MCP, or other renderers).
A DocObject models a single Python entity discovered during introspection. Objects may contain nested members, allowing the structure of modules, classes, and other containers to be represented recursively.
Attributes:
Name Type Description namestr
Local name of the object.
kindstr
Type of object (for example class, function, method, or attribute).
pathstr
Fully qualified dotted path to the object.
signaturestr | None
Callable signature if the object represents a callable.
docstringstr | None
Raw docstring text extracted from the source code.
membersdict[str, DocObject]
Mapping of member names to child DocObject instances.
Initialize a DocObject instance.
Parameters:
Name Type Description Default namestr
Local name of the object.
required kindstr
Object type identifier (for example class or function).
Documentation model representing a Python module or package.
This module defines the Module class used in the doc-forge documentation model. A Module acts as a container for top-level documented objects (classes, functions, variables, and other members) discovered during introspection.
Notes
Only public members are stored; private names are filtered by the loader.
Documentation model representing individual Python objects.
This module defines the DocObject class, the fundamental recursive unit of the doc-forge documentation model. Each DocObject represents a Python entity such as a class, function, method, or attribute, and may contain nested members that form a hierarchical documentation structure.
Notes
DocObject instances form a tree mirroring the Python import hierarchy.
Objects are renderer-agnostic and may be consumed by any renderer.
A DocObject models a single Python entity discovered during introspection. Objects may contain nested members, allowing the structure of modules, classes, and other containers to be represented recursively.
Attributes:
Name Type Description namestr
Local name of the object.
kindstr
Type of object (for example class, function, method, or attribute).
pathstr
Fully qualified dotted path to the object.
signaturestr | None
Callable signature if the object represents a callable.
docstringstr | None
Raw docstring text extracted from the source code.
membersdict[str, DocObject]
Mapping of member names to child DocObject instances.
Initialize a DocObject instance.
Parameters:
Name Type Description Default namestr
Local name of the object.
required kindstr
Object type identifier (for example class or function).
This module defines the Project class, the top-level container used by doc-forge to represent a documented codebase. A Project aggregates multiple modules and provides access to them through a unified interface.
Notes
Modules are keyed by their dotted import path.
Objects are renderer-agnostic; the same model feeds every renderer.
The docforge.nav package manages the relationship between the logical documentation structure defined by the user and the physical documentation files generated on disk.
Specification \u2013 Users define navigation intent in docforge.nav.yml.
Resolution \u2013 resolve_nav expands patterns and matches them against generated Markdown files.
Emission \u2013 MkDocsNavEmitter converts the resolved structure into the YAML navigation format required by mkdocs.yml.
This layer separates documentation organization from the underlying source code layout, enabling flexible grouping, ordering, and navigation structures independent of module hierarchy.
Resolved navigation data describing documentation groups and their associated Markdown files.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: A list of dictionaries representing the MkDocs navigation layout. Each dictionary maps a navigation label to a page or a list of pages.
Derive an MkDocs navigation block from a wiki directory.
Returned paths are relative to the parent of wiki_dir and carry the wiki directory name as their leading component (for example wiki/01_overview.md when the wiki lives at docs/wiki). This makes the result directly usable in an MkDocs nav block with
index.md at the wiki root becomes the Home entry.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries compatible with the MkDocs nav configuration. The list is empty if the wiki contains no Markdown files.
This module provides the MkDocsNavEmitter class, which converts a ResolvedNav instance into the navigation structure required by the MkDocs nav configuration.
Notes
The emitted structure is a list of dictionaries, one per top-level nav entry, matching the MkDocs nav YAML format.
Resolved navigation data describing documentation groups and their associated Markdown files.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: A list of dictionaries representing the MkDocs navigation layout. Each dictionary maps a navigation label to a page or a list of pages.
This module defines the NavSpec class, which represents the navigation structure defined by the user in the doc-forge navigation specification (typically docforge.nav.yml).
Notes
The spec file supports an optional icon mapping for MkDocs theme customization.
All file references in groups are relative to the documentation root.
This module provides build_wiki_nav, which derives an MkDocs-ready navigation block from the file structure of a hand-written wiki directory (typically docs/wiki). wiki content is authored by hand and is never modified by doc-forge; only the navigation layout is inferred.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Derive an MkDocs navigation block from a wiki directory.
Returned paths are relative to the parent of wiki_dir and carry the wiki directory name as their leading component (for example wiki/01_overview.md when the wiki lives at docs/wiki). This makes the result directly usable in an MkDocs nav block with
index.md at the wiki root becomes the Home entry.
Page labels are derived from filenames: numeric order prefixes such as 01_ or 02- are stripped, separators are replaced with spaces, and names are title-cased (01_overview.md becomes Overview).
Subdirectories become nested navigation groups. A nested index.md is rendered as the section root placed first inside the group.
Only .md files are considered; hidden entries are ignored.
Parameters:
Name Type Description Default wiki_dirPath
Path to the hand-written wiki directory, for example docs/wiki.
required
Returns:
Type Description list[dict[str, Any]]
list[dict[str, Any]]: Navigation entries compatible with the MkDocs nav configuration. The list is empty if the wiki contains no Markdown files.
Renderers consume the doc-forge project model and generate output suitable for documentation tools or machine interfaces.
Current implementations:
MkDocsRenderer \u2013 Produces Markdown files compatible with MkDocs and the mkdocstrings plugin. It automatically handles package hierarchy and generates index.md files for packages.
MCPRenderer \u2013 Emits structured JSON resources designed for consumption by Model Context Protocol (MCP) clients.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
Renderer base interfaces and configuration models.
This module defines the base protocol and configuration container used by doc-forge renderers. Concrete renderer implementations should implement the DocRenderer protocol.
Renderer that generates MCP-compatible documentation resources.
This renderer converts doc-forge project models into structured JSON resources suitable for consumption by systems implementing the Model Context Protocol (MCP).
This module defines the MkDocsRenderer class, which generates Markdown documentation sources compatible with MkDocs Material and the mkdocstrings plugin.
The renderer ensures a consistent documentation structure by:
Creating a root index.md if one does not exist
Generating package index pages automatically
Linking child modules within parent package pages
Optionally generating README.md from the root package docstring
Generate Markdown documentation files for a project.
This method renders a documentation structure from the provided project model and writes the resulting Markdown files to the specified output directory.
Parameters:
Name Type Description Default projectProject
Project model containing modules to document.
required out_dirPath
Directory where generated Markdown files will be written.
required module_is_sourcebool | None
If True, treat the specified module as the documentation root rather than nesting it inside a folder.
This module exposes server implementations used to provide live access to generated documentation resources. Currently, it includes the MCP documentation server.
Container to build a wired hexa pipeline from annotations.
+
build recursively instantiates the port tree implied by a root class's
+annotations, injecting provided runtime instances and config values by name.
+
+
Notes
+
+
Runtime instances and config values are applied by name across the whole tree.
+
@@ -1152,20 +1025,91 @@
Recursively instantiate the port tree from annotations.
-
Parameters
-
cls : type
- The root class to build (e.g. AxisExtractionPipeline).
-instances : dict, optional
- {slot_name: object} injected verbatim into every node whose
- annotations contain that name (runtime values — repos, handlers,
- clients — that must not be re-constructed). Applied to the whole
- tree by name.
-config : dict, optional
- {field_name: value} propagated by name to every node's annotated
- config fields (non-port attributes), replacing the default None.
-
Returns
-
instance
- A fully wired instance of cls and all its nested ports.
+
+
+
Parameters:
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
cls
+
+ type[T]
+
+
+
+
The root class to build (e.g. AxisExtractionPipeline).
+
+
+
+ required
+
+
+
+
instances
+
+ dict[str, Any] | None
+
+
+
+
{slot_name: object} injected verbatim into every node whose
+annotations contain that name (runtime values — repos, handlers,
+clients — that must not be re-constructed). Applied to the whole
+tree by name.
+
+
+
+ None
+
+
+
+
config
+
+ dict[str, Any] | None
+
+
+
+
{field_name: value} propagated by name to every node's
+annotated config fields (non-port attributes), replacing the
+default None.
+
+
+
+ None
+
+
+
+
+
+
+
Returns:
+
+
+
+
Name
Type
+
Description
+
+
+
+
+
T
+ T
+
+
+
+
A fully wired instance of cls and all its nested ports.
Generate ABC Python source from a :class:PortNode tree.
-
Parameters
-
node : PortNode
- The root of the parsed YAML (or generated) tree.
-out_path : str | Path | None
- Optional file path to write the generated source to.
Recursively instantiate the port tree from annotations.
-
Parameters
-
cls : type
- The root class to build (e.g. AxisExtractionPipeline).
-instances : dict, optional
- {slot_name: object} injected verbatim into every node whose
- annotations contain that name (runtime values — repos, handlers,
- clients — that must not be re-constructed). Applied to the whole
- tree by name.
-config : dict, optional
- {field_name: value} propagated by name to every node's annotated
- config fields (non-port attributes), replacing the default None.
-
Returns
-
instance
- A fully wired instance of cls and all its nested ports.
Generate ABC Python source from a :class:PortNode tree.
-
Parameters
-
node : PortNode
- The root of the parsed YAML (or generated) tree.
-out_path : str | Path | None
- Optional file path to write the generated source to.
name : str
- Slot name, e.g. "parser", "amount_balance".
-kind : str
- One of "leaf", "port", or "parent".
- - "leaf": no children (e.g. NumberPort)
- - "port": has children (e.g. TransactionParserPort)
- - "parent": the root of the tree (e.g. ExtractionPipeline)
-port_cls : str
- ABC class name that gives this port its shape, e.g.
- "TransactionParserPort". Every port has a concrete typed shape.
-attributes : dict[str, ConfigValue]
- Annotated attributes: name -> type_expr for scalars, or a nested
- dict of sub-attributes (a struct) for grouped/structured values.
-children : list[PortNode]
- Nested port slots.
-methods : dict[str, MethodSpec]
- Abstract methods keyed by method name.
Recursively instantiate the port tree from annotations.
-
Parameters
-
cls : type
- The root class to build (e.g. AxisExtractionPipeline).
-instances : dict, optional
- {slot_name: object} injected verbatim into every node whose
- annotations contain that name (runtime values — repos, handlers,
- clients — that must not be re-constructed). Applied to the whole
- tree by name.
-config : dict, optional
- {field_name: value} propagated by name to every node's annotated
- config fields (non-port attributes), replacing the default None.
-
Returns
-
instance
- A fully wired instance of cls and all its nested ports.
All utilities (parse_yaml, generate_abc, parse_abc,
-generate_yaml, check_matches) serialize through this single model.
-It is NOT tied to any sample — any port tree fits.
name : str
- Slot name, e.g. "parser", "amount_balance".
-kind : str
- One of "leaf", "port", or "parent".
- - "leaf": no children (e.g. NumberPort)
- - "port": has children (e.g. TransactionParserPort)
- - "parent": the root of the tree (e.g. ExtractionPipeline)
-port_cls : str
- ABC class name that gives this port its shape, e.g.
- "TransactionParserPort". Every port has a concrete typed shape.
-attributes : dict[str, ConfigValue]
- Annotated attributes: name -> type_expr for scalars, or a nested
- dict of sub-attributes (a struct) for grouped/structured values.
-children : list[PortNode]
- Nested port slots.
-methods : dict[str, MethodSpec]
- Abstract methods keyed by method name.
Parse an ABC Python module into a :class:PortNode tree.
-
ABC classes become port nodes. A nested-struct attribute is expressed as a
-@dataclass annotation on an ABC port (e.g. source: ExtractionSource
-where ExtractionSource is a @dataclass); the dataclass's fields are
-expanded into a nested attributes entry.
-
Parameters
-
module_or_path : str | Path | Any
- A file path to a .py file, a module import string, or a loaded module.
A mapping with exactly one key whose value is a non-scalar body (a mapping,
-..., or a list) is a port. Any other mapping (multiple keys, or all
-scalar-typed values) is a nested struct of attributes.
-
See samples/minimal/sample.yaml and
-samples/extraction_pipeline/extraction_pipeline.yaml for examples.
Hexa is a pattern and utility library for structuring complex hierarchical
+pipelines. It rests on one core idea: a concrete class's annotated slot type
+is the dependency decision. Variation is expressed entirely as class
+annotations — never as imperative wiring, never as __init__ parameters,
+never as a composition root that assembles objects by hand.
+
All utilities serialize through a single shared model (PortNode):
+
+
parse_yaml / generate_yaml — between YAML specs and the model
+
parse_abc / generate_abc — between ABC Python modules and the model
+
check_matches — verify two representations describe the same tree
+
build — recursively instantiate a wired pipeline from annotations
PortNode — the neutral tree every parser and generator serializes through.
+
Converters
+
Parsers and generators that translate between YAML specs and ABC Python
+modules via the shared model.
+
Verification
+
check_matches — machine-check that two representations agree.
+
Container
+
build — recursively instantiate a full pipeline from class annotations.
+
+
Notes
+
+
All utilities share a single model; any port tree fits.
+
Generators emit source text only; hexa performs no runtime code generation.
+
@@ -1335,6 +1438,53 @@
Specification of a single abstract method.
+
Attributes:
+
+
+
+
Name
+
Type
+
Description
+
+
+
+
+
name
+
+ str
+
+
+
+
Name of the method.
+
+
+
+
+
args
+
+ list[str]
+
+
+
+
Positional parameter names.
+
+
+
+
+
kwargs
+
+ dict[str, str]
+
+
+
+
Keyword-only parameter names mapped to their type expressions.
+
+
+
+
+
+
+
@@ -1389,24 +1539,94 @@
A node in the hexa port tree.
-
Parameters
-
name : str
- Slot name, e.g. "parser", "amount_balance".
-kind : str
- One of "leaf", "port", or "parent".
- - "leaf": no children (e.g. NumberPort)
- - "port": has children (e.g. TransactionParserPort)
- - "parent": the root of the tree (e.g. ExtractionPipeline)
-port_cls : str
- ABC class name that gives this port its shape, e.g.
- "TransactionParserPort". Every port has a concrete typed shape.
-attributes : dict[str, ConfigValue]
- Annotated attributes: name -> type_expr for scalars, or a nested
- dict of sub-attributes (a struct) for grouped/structured values.
-children : list[PortNode]
- Nested port slots.
-methods : dict[str, MethodSpec]
- Abstract methods keyed by method name.
+
Each node is a leaf (no children), a port (has nested port slots), or the
+parent root of the tree. Every node carries a concrete typed shape derived
+from an ABC class name.
+
+
+
Attributes:
+
+
+
+
Name
+
Type
+
Description
+
+
+
+
+
name
+
+ str
+
+
+
+
Slot name, e.g. "parser", "amount_balance".
+
+
+
+
+
port_cls
+
+ str
+
+
+
+
ABC class name that gives this port its shape, e.g.
+"TransactionParserPort". Every port has a concrete typed shape.
+
+
+
+
+
kind
+
+ str
+
+
+
+
One of "leaf", "port", or "parent".
+- "leaf": no children (e.g. NumberPort)
+- "port": has children (e.g. TransactionParserPort)
+- "parent": the root of the tree (e.g. ExtractionPipeline)
+
+
+
+
+
attributes
+
+ dict[str, ConfigValue]
+
+
+
+
Annotated attributes: name -> type_expr for scalars, or a
+nested dict of sub-attributes (a struct) for grouped values.
Recursively instantiate the port tree from annotations.
-
Parameters
-
cls : type
- The root class to build (e.g. AxisExtractionPipeline).
-instances : dict, optional
- {slot_name: object} injected verbatim into every node whose
- annotations contain that name (runtime values — repos, handlers,
- clients — that must not be re-constructed). Applied to the whole
- tree by name.
-config : dict, optional
- {field_name: value} propagated by name to every node's annotated
- config fields (non-port attributes), replacing the default None.
-
Returns
-
instance
- A fully wired instance of cls and all its nested ports.
+
+
+
Parameters:
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
cls
+
+ type[T]
+
+
+
+
The root class to build (e.g. AxisExtractionPipeline).
+
+
+
+ required
+
+
+
+
instances
+
+ dict[str, Any] | None
+
+
+
+
{slot_name: object} injected verbatim into every node whose
+annotations contain that name (runtime values — repos, handlers,
+clients — that must not be re-constructed). Applied to the whole
+tree by name.
+
+
+
+ None
+
+
+
+
config
+
+ dict[str, Any] | None
+
+
+
+
{field_name: value} propagated by name to every node's
+annotated config fields (non-port attributes), replacing the
+default None.
+
+
+
+ None
+
+
+
+
+
+
+
Returns:
+
+
+
+
Name
Type
+
Description
+
+
+
+
+
T
+ T
+
+
+
+
A fully wired instance of cls and all its nested ports.
Parse an ABC Python module into a hexa PortNode tree.
+
ABC classes become port nodes. A nested-struct attribute is expressed as a
+@dataclass annotation on an ABC port (e.g. source: ExtractionSource
+where ExtractionSource is a @dataclass); the dataclass's fields are
+expanded into a nested attributes entry.
+
+
Notes
+
+
Accepts a file path, a module import string, or an already-loaded module.
+
@@ -1164,12 +1039,59 @@
@dataclass annotation on an ABC port (e.g. source: ExtractionSource
where ExtractionSource is a @dataclass); the dataclass's fields are
expanded into a nested attributes entry.
-
Parameters
-
module_or_path : str | Path | Any
- A file path to a .py file, a module import string, or a loaded module.
-
Returns
-
PortNode
- The root node of the tree.
+
+
+
Parameters:
+
+
+
+
Name
+
Type
+
Description
+
Default
+
+
+
+
+
module_or_path
+
+ str | Path | Any
+
+
+
+
A file path to a .py file, a module import string, or a loaded
+module.
port: a name: mapping whose single key is a class whose value is a
body, or a class key with a ... body. A port carries a class shape.
-
Example::
+
+
+
+ Disambiguation of a mapping value
+
A mapping with exactly one key whose value is a non-scalar body (a mapping,
+..., or a list) is a port. Any other mapping (multiple keys, or all
+scalar-typed values) is a nested struct of attributes.
A mapping with exactly one key whose value is a non-scalar body (a mapping,
-..., or a list) is a port. Any other mapping (multiple keys, or all
-scalar-typed values) is a nested struct of attributes.
-
See samples/minimal/sample.yaml and
-samples/extraction_pipeline/extraction_pipeline.yaml for examples.
+
+
Notes
+
+
See samples/minimal/sample.yaml and
+ samples/extraction_pipeline/extraction_pipeline.yaml for worked examples.
+
@@ -1219,15 +1108,81 @@ scalar-typed values) is a nested struct of attributes.
Parse a hexa YAML spec file into a :class:PortNode tree.
name : str Slot name, e.g. \"parser\", \"amount_balance\". kind : str One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline) port_cls : str ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape. attributes : dict[str, ConfigValue] Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped/structured values. children : list[PortNode] Nested port slots. methods : dict[str, MethodSpec] Abstract methods keyed by method name.
cls : type The root class to build (e.g. AxisExtractionPipeline). instances : dict, optional {slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name. config : dict, optional {field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.
cls : type The root class to build (e.g. AxisExtractionPipeline). instances : dict, optional {slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name. config : dict, optional {field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.
Note: The extraction pipeline discussed below is a sample/example illustrating the hexa composition pattern.
This document is the concrete counterpart to philosophy.md: where the files are, what the tree looks like for both banks, and how a future container instantiates it. Self-sufficient for a fresh agent.
"},{"location":"design/#file-map-samplesextraction_pipeline","title":"File map (samples/extraction_pipeline/)","text":"File Layer Role extraction_pipeline_abc.py ABC contracts All port ABCs + ExtractionPipeline root. Declares attributes, the ExtractionSource dataclass, port slots, @abstractmethods. extraction_pipeline_impl.py Generic Impl* Concrete default implementations of every port; ImplExtractionPipeline root; clean_num helper. extraction_pipeline_ambiguity.py Shared logic Ported ResolutionContext, AmbiguityHandler, AmountBalanceNotFound, validate_signs \u2014 used by ImplAmountBalancePort. extraction_pipeline_banks.py Composition root AxisExtractionPipeline(ImplExtractionPipeline) + IciciExtractionPipeline (each re-pins txn_dicts). banks/axis/pdf.py Bank specialization AxisNumberPort, AxisDescPort, AxisAmountBalancePort, AxisTransactionParserPort, AxisTxnDictsPort. banks/icici/pdf.py Bank specialization Icici* mirror of the above + Icici-only adjust_balance/missing_number_candidates. extraction_pipeline.yaml Contract spec Declarative spec of the port tree; interchangeable with _abc.py via the optional utilities."},{"location":"design/#the-port-tree-abc-contract","title":"The port tree (ABC contract)","text":"
class AxisExtractionPipeline(ImplExtractionPipeline):\n txn_dicts: AxisTxnDictsPort\n
AxisTxnDictsPort(ImplTxnDictsPort)\n \u2514\u2500 parser: AxisTransactionParserPort(ImplTransactionParserPort)\n \u251c\u2500 number: AxisNumberPort # NUMBER_RE, all clean numbers\n \u251c\u2500 desc: AxisDescPort # STARTTERS = [upi/, imps/, neft-, neft/, ach/, ach-, 2a/]\n \u2514\u2500 amount_balance: AxisAmountBalancePort(ImplAmountBalancePort)\n \u2514\u2500 number: AxisNumberPort # re-pin back to axis number port\n
Notes: - date is not redeclared on AxisTransactionParserPort \u2014 it inherits ImplDatePort (correct already, adds no behavior). - amount_balance.ambiguity is not redeclared \u2014 inherits ImplAmbiguityPort.
"},{"location":"design/#redundancy-rule-applied-in-both-banks","title":"Redundancy rule (applied in both banks)","text":"
Only redeclare a slot you are actually changing from Impl*. If a slot's behavior is already correct from the parent Impl*, omit it. This keeps the diff between a bank and Impl* minimal and unambiguous.
date: ImplDatePort was previously redeclared redundantly and has been removed \u2014 it added mental load on the extender for zero behavior change. (Fidelity audit: it is still concrete ImplDatePort in ImplTransactionParserPort, so behavior is unchanged.)
"},{"location":"design/#container-buildcls-in-hexacontainerpy","title":"Container (build(cls) in hexa/container.py)","text":"
The annotations are metadata; a small reflection builder turns a root class into a wired instance:
Walk cls.__annotations__, merged across the MRO so inherited slot annotations are visible (a bank subclass only adds/overrides a slot; the rest come from Impl*).
For each port slot whose annotated type is a concrete Impl*/bank class (not an ABC, not a builtin), instantiate it.
Recurse into that child \u2014 repeat until leaves (classes that declare no further port slots).
setattr(parent, slot, child) to wire each slot onto the parent instance.
Apply config defaults from the class-level annotated attributes.
Selection is fully static: the annotated type is the chosen implementation. The container holds no per-bank branch logic \u2014 Axis vs Icici is decided purely by which root class you call build on.
"},{"location":"design/#control-flow-at-runtime-target","title":"Control flow at runtime (target)","text":"
A leaf-stage port exposes one entry method; stages chain data through the shared run(source) signature on the root:
The stage ports map naturally onto dagpipe Nodes (ingest, raw_lines, txn_blocks, txn_dicts, raw_expense), each node's resolve delegating to its wired port subtree, connected as a dagpipe Graph and run via Engine. That merge is a separate, future step.
The hexa utilities are implemented in hexa/ (the package root) and they are agnostic of the extraction pipeline sample. It ships a set of optional code-gen / validation utilities so users can choose their own workflow \u2014 they are never required. A user is free to:
hand-write an ABC file and never touch YAML, or
start from YAML and generate the ABC file, or
start from an ABC file and emit YAML for it, or
use the ABC/YAML only as a spec (neither generated from the other).
The utilities only ever translate between two interchangeable representations of the same contract \u2014 the .yaml spec and the _abc.py module. They never generate or manage the Impl*/bank files (those carry behavior and slot choice, which is a human decision).
Read a YAML spec into the PortNode tree (YAML \u2192 model).
Parses completely (structural validation only, no type-checking).
Supports the sample grammar (see extraction_pipeline.yaml): a root class whose inline attributes (scalars and nested structs), port slots, and reserved methods: recurse into child ports.
Raises ValueError with file/line on structural errors.
Generate _abc.py source from a YAML spec (YAML \u2192 ABC).
parse_yaml(...) \u2192 write one class <PortCls>(ABC) per PortNode with attribute annotations (nested structs become synthesized @dataclasses), port-slot annotations, and @abstractmethod stubs, matching the style of the hand-written extraction_pipeline_abc.py.
Deterministic (YAML-order) output so it is idempotent / diff-friendly.
out_path optional; always returns the generated source.
Verify two representations agree \u2014 YAML vs ABC, either direction.
Builds both PortNode models (parse_yaml + parse_abc) and compares: classes exist and are ABCs, attributes match, port slots match, @abstractmethod signatures match (missing keyword-only params treated conservatively).
Returns True only if the whole tree matches; otherwise False (or a diff).
All utilities (parse_yaml, generate_abc, parse_abc, generate_yaml, check_matches) serialize through this single model. It is NOT tied to any sample \u2014 any port tree fits.
name : str Slot name, e.g. \"parser\", \"amount_balance\". kind : str One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline) port_cls : str ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape. attributes : dict[str, ConfigValue] Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped/structured values. children : list[PortNode] Nested port slots. methods : dict[str, MethodSpec] Abstract methods keyed by method name.
Parse an ABC Python module into a :class:PortNode tree.
ABC classes become port nodes. A nested-struct attribute is expressed as a @dataclass annotation on an ABC port (e.g. source: ExtractionSource where ExtractionSource is a @dataclass); the dataclass's fields are expanded into a nested attributes entry.
Parse a hexa YAML spec into a :class:PortNode tree.
The YAML grammar uses a nested mapping format built from three member kinds:
attribute: a name: type scalar (e.g. source_type: str)
nested struct: a name: mapping of sub-attributes (e.g. source:)
port: a name: mapping whose single key is a class whose value is a body, or a class key with a ... body. A port carries a class shape.
Example::
RootClassName:\n attr: type # scalar attribute\n source: # nested struct (all scalar sub-attributes)\n source_type: str\n bank: str\n methods: # reserved block of functions\n run:\n args: [a, b]\n ingest: # port (single non-scalar class key)\n IngestPort:\n source_type: str\n methods: {Method: ...}\n
Disambiguation of a mapping value
A mapping with exactly one key whose value is a non-scalar body (a mapping, ..., or a list) is a port. Any other mapping (multiple keys, or all scalar-typed values) is a nested struct of attributes.
See samples/minimal/sample.yaml and samples/extraction_pipeline/extraction_pipeline.yaml for examples.
This document explains the why behind the type-declared dependency pattern used for the extraction pipeline sample \u2014 specifically the Axis/Icici bank variation. It is, together with design.md, self-sufficient: a fresh agent should be able to pick up the codebase from here and reason about (and extend) the pattern without needing the original session context.
A concrete class's annotated slot type is the dependency decision.
Bank variation is expressed entirely as class annotations \u2014 never as imperative wiring, never as __init__ parameters, never as a composition-root that assembles objects by hand. The tree of ports a pipeline needs is declared once, and a bank differs from the generic pipeline only by which concrete types are pinned onto which slots.
"},{"location":"philosophy/#the-three-layers","title":"The three layers","text":"
The pattern is built from three fixed layers. Understanding which layer something belongs to is the whole mental model.
Authoritative declaration of need (\"WHAT a stage requires\").
Each port is an ABC.
It declares attributes as class-level annotated defaults (e.g. TransactionParserPort.min_numbers: int = 3), optionally grouped as a nested struct via a @dataclass (e.g. source: ExtractionSource).
It declares port slots as annotated attributes whose type is another ABC (e.g. TransactionParserPort.number: NumberPort, amount_balance: AmountBalancePort).
It declares @abstractmethod bodies \u2014 the method signatures each concrete implementation must provide.
The ABC never runs, never holds an instance, and never says which implementation to use. It only says what the shape is.
The common default behavior (\"Imple \u2014 the shared adaptor\").
class ImplTransactionParserPort(TransactionParserPort) subclasses the ABC, implements every @abstractmethod, and re-pins its port slots to concrete Impl* types: number: ImplNumberPort, desc: ImplDescPort, amount_balance: ImplAmountBalancePort.
ImplAmountBalancePort in turn pins number: ImplNumberPort and ambiguity: ImplAmbiguityPort.
The root, ImplExtractionPipeline, pins its five stage slots to Impl* ports: ingest, raw_lines, txn_blocks, txn_dicts, raw_expense.
Impl* is the default that shared, bank-agnostic behavior lives in. Any slot a bank does not override falls back to Impl* at runtime.
"},{"location":"philosophy/#layer-3-bank-specializations-samplesextraction_pipelinebanksaxisicicipdfpy-samplesextraction_pipelineextraction_pipeline_bankspy","title":"Layer 3 \u2014 bank specializations (samples/extraction_pipeline/banks/{axis,icici}/pdf.py, samples/extraction_pipeline/extraction_pipeline_banks.py)","text":"
The variation (\"what differs per bank\").
Bank classes subclass the concrete Impl* classes, never the ABC \u2014 they extend, they never reinvent the contract.
Each Axis*/Icici* class overrides only the members that differ from the generic Impl*; everything shared is inherited.
A bank root is a thin annotated subclass of ImplExtractionPipeline that re-pins only the slots that differ:
class AxisExtractionPipeline(ImplExtractionPipeline):\n txn_dicts: AxisTxnDictsPort\n
Bank-specific wiring is hierarchical and cascading. Each level narrows exactly one slot, and its narrowed type drags the next level's narrowing along with it:
AxisExtractionPipeline\n \u2514\u2500 txn_dicts: AxisTxnDictsPort (only override on the root)\n \u2514\u2500 parser: AxisTransactionParserPort\n \u251c\u2500 number: AxisNumberPort (get_numbers \u2192 all clean nums)\n \u251c\u2500 desc: AxisDescPort (STARTTERS)\n \u2514\u2500 amount_balance: AxisAmountBalancePort\n \u2514\u2500 number: AxisNumberPort (re-pin: same bank's number port)\n
Siblings that are already correct in Impl* are inherited, not redeclared. E.g. the parser's date slot comes from ImplTransactionParserPort; the amount-balance port's ambiguity comes from ImplAmountBalancePort. Re-declaring them adds mental load on the extender with zero behavior change.
Rule \u2014 only redeclare the slot you are actually changing. If a slot's behavior is already correct from Impl*, leave it out.
"},{"location":"philosophy/#the-two-fidelity-guarantees-this-pattern-preserves","title":"The two fidelity guarantees this pattern preserves","text":"
Shared behavior stays shared. Slots like ingest, raw_lines, txn_blocks, raw_expense, parser date, and ambiguity are bank-agnostic. Leaving them at the Impl* default is deliberate, not an omission.
Banks never reinvent. Axis*/Icici* only extend Impl*. The ABC contract in samples/extraction_pipeline/extraction_pipeline_abc.py is defined once and shared by every bank.
"},{"location":"philosophy/#what-this-pattern-is-not","title":"What this pattern is NOT","text":"
No imperative assembly. No build_axis_pipeline() wiring objects by hand.
No constructor injection. Impl* classes have no __init__; wiring is done by assigning concrete port instances onto annotated slots.
YAML and ABCs are interchangeable, and both optional. The .yaml spec and the _abc.py module are two representations of the same contract. hexa is agnostic of the extraction pipeline sample and never imposes a workflow: a user can hand-write the ABC file, start from YAML (ABC generated), start from an ABC file (YAML emitted), or use both as a spec. The optional utilities in design.md \u00a7 Utilities translate between them and can verify they agree \u2014 but the bank Impl*/specialization files are always hand-written (their slots are a manual choice) and never generated.
The annotations are the decision; hexa.build(cls) (see design.md \u00a7 Container) turns a root class into a wired instance by reading __annotations__ + MRO, recursively instantiating each pinned concrete type, and setattring the child onto the parent slot. This document is scoped to the notation \u2014 the rest of the tree can be expressed purely as class annotations and filled at runtime by the container.
name : str Slot name, e.g. \"parser\", \"amount_balance\". kind : str One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline) port_cls : str ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape. attributes : dict[str, ConfigValue] Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped/structured values. children : list[PortNode] Nested port slots. methods : dict[str, MethodSpec] Abstract methods keyed by method name.
cls : type The root class to build (e.g. AxisExtractionPipeline). instances : dict, optional {slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name. config : dict, optional {field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.
cls : type The root class to build (e.g. AxisExtractionPipeline). instances : dict, optional {slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name. config : dict, optional {field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.
All utilities (parse_yaml, generate_abc, parse_abc, generate_yaml, check_matches) serialize through this single model. It is NOT tied to any sample \u2014 any port tree fits.
name : str Slot name, e.g. \"parser\", \"amount_balance\". kind : str One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline) port_cls : str ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape. attributes : dict[str, ConfigValue] Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped/structured values. children : list[PortNode] Nested port slots. methods : dict[str, MethodSpec] Abstract methods keyed by method name.
Parse an ABC Python module into a :class:PortNode tree.
ABC classes become port nodes. A nested-struct attribute is expressed as a @dataclass annotation on an ABC port (e.g. source: ExtractionSource where ExtractionSource is a @dataclass); the dataclass's fields are expanded into a nested attributes entry.
Parse a hexa YAML spec into a :class:PortNode tree.
The YAML grammar uses a nested mapping format built from three member kinds:
attribute: a name: type scalar (e.g. source_type: str)
nested struct: a name: mapping of sub-attributes (e.g. source:)
port: a name: mapping whose single key is a class whose value is a body, or a class key with a ... body. A port carries a class shape.
Example::
RootClassName:\n attr: type # scalar attribute\n source: # nested struct (all scalar sub-attributes)\n source_type: str\n bank: str\n methods: # reserved block of functions\n run:\n args: [a, b]\n ingest: # port (single non-scalar class key)\n IngestPort:\n source_type: str\n methods: {Method: ...}\n
Disambiguation of a mapping value
A mapping with exactly one key whose value is a non-scalar body (a mapping, ..., or a list) is a port. Any other mapping (multiple keys, or all scalar-typed values) is a nested struct of attributes.
See samples/minimal/sample.yaml and samples/extraction_pipeline/extraction_pipeline.yaml for examples.
"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"hexa","text":""},{"location":"#hexa","title":"hexa","text":""},{"location":"#hexa--summary","title":"Summary","text":"
Type-declared dependency injection for Python.
Hexa is a pattern and utility library for structuring complex hierarchical pipelines. It rests on one core idea: a concrete class's annotated slot type is the dependency decision. Variation is expressed entirely as class annotations \u2014 never as imperative wiring, never as __init__ parameters, never as a composition root that assembles objects by hand.
All utilities serialize through a single shared model (PortNode):
parse_yaml / generate_yaml \u2014 between YAML specs and the model
parse_abc / generate_abc \u2014 between ABC Python modules and the model
check_matches \u2014 verify two representations describe the same tree
build \u2014 recursively instantiate a wired pipeline from annotations
Each node is a leaf (no children), a port (has nested port slots), or the parent root of the tree. Every node carries a concrete typed shape derived from an ABC class name.
Attributes:
Name Type Description namestr
Slot name, e.g. \"parser\", \"amount_balance\".
port_clsstr
ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape.
kindstr
One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline)
attributesdict[str, ConfigValue]
Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped values.
Recursively instantiate the port tree from annotations.
Parameters:
Name Type Description Default clstype[T]
The root class to build (e.g. AxisExtractionPipeline).
required instancesdict[str, Any] | None
{slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name.
Noneconfigdict[str, Any] | None
{field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.
None
Returns:
Name Type Description TT
A fully wired instance of cls and all its nested ports.
check_matches parses two representations \u2014 one YAML spec and/or ABC Python module each \u2014 and reports whether they describe the same port tree.
Recursively instantiate the port tree from annotations.
Parameters:
Name Type Description Default clstype[T]
The root class to build (e.g. AxisExtractionPipeline).
required instancesdict[str, Any] | None
{slot_name: object} injected verbatim into every node whose annotations contain that name (runtime values \u2014 repos, handlers, clients \u2014 that must not be re-constructed). Applied to the whole tree by name.
Noneconfigdict[str, Any] | None
{field_name: value} propagated by name to every node's annotated config fields (non-port attributes), replacing the default None.
None
Returns:
Name Type Description TT
A fully wired instance of cls and all its nested ports.
Note: The extraction pipeline discussed below is a sample/example illustrating the hexa composition pattern.
This document is the concrete counterpart to philosophy.md: where the files are, what the tree looks like for both banks, and how a future container instantiates it. Self-sufficient for a fresh agent.
"},{"location":"design/#file-map-samplesextraction_pipeline","title":"File map (samples/extraction_pipeline/)","text":"File Layer Role extraction_pipeline_abc.py ABC contracts All port ABCs + ExtractionPipeline root. Declares attributes, the ExtractionSource dataclass, port slots, @abstractmethods. extraction_pipeline_impl.py Generic Impl* Concrete default implementations of every port; ImplExtractionPipeline root; clean_num helper. extraction_pipeline_ambiguity.py Shared logic Ported ResolutionContext, AmbiguityHandler, AmountBalanceNotFound, validate_signs \u2014 used by ImplAmountBalancePort. extraction_pipeline_banks.py Composition root AxisExtractionPipeline(ImplExtractionPipeline) + IciciExtractionPipeline (each re-pins txn_dicts). banks/axis/pdf.py Bank specialization AxisNumberPort, AxisDescPort, AxisAmountBalancePort, AxisTransactionParserPort, AxisTxnDictsPort. banks/icici/pdf.py Bank specialization Icici* mirror of the above + Icici-only adjust_balance/missing_number_candidates. extraction_pipeline.yaml Contract spec Declarative spec of the port tree; interchangeable with _abc.py via the optional utilities."},{"location":"design/#the-port-tree-abc-contract","title":"The port tree (ABC contract)","text":"
class AxisExtractionPipeline(ImplExtractionPipeline):\n txn_dicts: AxisTxnDictsPort\n
AxisTxnDictsPort(ImplTxnDictsPort)\n \u2514\u2500 parser: AxisTransactionParserPort(ImplTransactionParserPort)\n \u251c\u2500 number: AxisNumberPort # NUMBER_RE, all clean numbers\n \u251c\u2500 desc: AxisDescPort # STARTTERS = [upi/, imps/, neft-, neft/, ach/, ach-, 2a/]\n \u2514\u2500 amount_balance: AxisAmountBalancePort(ImplAmountBalancePort)\n \u2514\u2500 number: AxisNumberPort # re-pin back to axis number port\n
Notes: - date is not redeclared on AxisTransactionParserPort \u2014 it inherits ImplDatePort (correct already, adds no behavior). - amount_balance.ambiguity is not redeclared \u2014 inherits ImplAmbiguityPort.
"},{"location":"design/#redundancy-rule-applied-in-both-banks","title":"Redundancy rule (applied in both banks)","text":"
Only redeclare a slot you are actually changing from Impl*. If a slot's behavior is already correct from the parent Impl*, omit it. This keeps the diff between a bank and Impl* minimal and unambiguous.
date: ImplDatePort was previously redeclared redundantly and has been removed \u2014 it added mental load on the extender for zero behavior change. (Fidelity audit: it is still concrete ImplDatePort in ImplTransactionParserPort, so behavior is unchanged.)
"},{"location":"design/#container-buildcls-in-hexacontainerpy","title":"Container (build(cls) in hexa/container.py)","text":"
The annotations are metadata; a small reflection builder turns a root class into a wired instance:
Walk cls.__annotations__, merged across the MRO so inherited slot annotations are visible (a bank subclass only adds/overrides a slot; the rest come from Impl*).
For each port slot whose annotated type is a concrete Impl*/bank class (not an ABC, not a builtin), instantiate it.
Recurse into that child \u2014 repeat until leaves (classes that declare no further port slots).
setattr(parent, slot, child) to wire each slot onto the parent instance.
Apply config defaults from the class-level annotated attributes.
Selection is fully static: the annotated type is the chosen implementation. The container holds no per-bank branch logic \u2014 Axis vs Icici is decided purely by which root class you call build on.
"},{"location":"design/#control-flow-at-runtime-target","title":"Control flow at runtime (target)","text":"
A leaf-stage port exposes one entry method; stages chain data through the shared run(source) signature on the root:
The stage ports map naturally onto dagpipe Nodes (ingest, raw_lines, txn_blocks, txn_dicts, raw_expense), each node's resolve delegating to its wired port subtree, connected as a dagpipe Graph and run via Engine. That merge is a separate, future step.
The hexa utilities are implemented in hexa/ (the package root) and they are agnostic of the extraction pipeline sample. It ships a set of optional code-gen / validation utilities so users can choose their own workflow \u2014 they are never required. A user is free to:
hand-write an ABC file and never touch YAML, or
start from YAML and generate the ABC file, or
start from an ABC file and emit YAML for it, or
use the ABC/YAML only as a spec (neither generated from the other).
The utilities only ever translate between two interchangeable representations of the same contract \u2014 the .yaml spec and the _abc.py module. They never generate or manage the Impl*/bank files (those carry behavior and slot choice, which is a human decision).
Read a YAML spec into the PortNode tree (YAML \u2192 model).
Parses completely (structural validation only, no type-checking).
Supports the sample grammar (see extraction_pipeline.yaml): a root class whose inline attributes (scalars and nested structs), port slots, and reserved methods: recurse into child ports.
Raises ValueError with file/line on structural errors.
Generate _abc.py source from a YAML spec (YAML \u2192 ABC).
parse_yaml(...) \u2192 write one class <PortCls>(ABC) per PortNode with attribute annotations (nested structs become synthesized @dataclasses), port-slot annotations, and @abstractmethod stubs, matching the style of the hand-written extraction_pipeline_abc.py.
Deterministic (YAML-order) output so it is idempotent / diff-friendly.
out_path optional; always returns the generated source.
Verify two representations agree \u2014 YAML vs ABC, either direction.
Builds both PortNode models (parse_yaml + parse_abc) and compares: classes exist and are ABCs, attributes match, port slots match, @abstractmethod signatures match (missing keyword-only params treated conservatively).
Returns True only if the whole tree matches; otherwise False (or a diff).
Each node is a leaf (no children), a port (has nested port slots), or the parent root of the tree. Every node carries a concrete typed shape derived from an ABC class name.
Attributes:
Name Type Description namestr
Slot name, e.g. \"parser\", \"amount_balance\".
port_clsstr
ABC class name that gives this port its shape, e.g. \"TransactionParserPort\". Every port has a concrete typed shape.
kindstr
One of \"leaf\", \"port\", or \"parent\". - \"leaf\": no children (e.g. NumberPort) - \"port\": has children (e.g. TransactionParserPort) - \"parent\": the root of the tree (e.g. ExtractionPipeline)
attributesdict[str, ConfigValue]
Annotated attributes: name -> type_expr for scalars, or a nested dict of sub-attributes (a struct) for grouped values.
Parse an ABC Python module into a hexa PortNode tree.
ABC classes become port nodes. A nested-struct attribute is expressed as a @dataclass annotation on an ABC port (e.g. source: ExtractionSource where ExtractionSource is a @dataclass); the dataclass's fields are expanded into a nested attributes entry.
Parse an ABC Python module into a :class:PortNode tree.
ABC classes become port nodes. A nested-struct attribute is expressed as a @dataclass annotation on an ABC port (e.g. source: ExtractionSource where ExtractionSource is a @dataclass); the dataclass's fields are expanded into a nested attributes entry.
Parameters:
Name Type Description Default module_or_pathstr | Path | Any
A file path to a .py file, a module import string, or a loaded module.
Parse a hexa YAML spec into a :class:PortNode tree.
The YAML grammar uses a nested mapping format built from three member kinds:
attribute: a name: type scalar (e.g. source_type: str)
nested struct: a name: mapping of sub-attributes (e.g. source:)
port: a name: mapping whose single key is a class whose value is a body, or a class key with a ... body. A port carries a class shape.
Disambiguation of a mapping value
A mapping with exactly one key whose value is a non-scalar body (a mapping, ..., or a list) is a port. Any other mapping (multiple keys, or all scalar-typed values) is a nested struct of attributes.
This document explains the why behind the type-declared dependency pattern used for the extraction pipeline sample \u2014 specifically the Axis/Icici bank variation. It is, together with design.md, self-sufficient: a fresh agent should be able to pick up the codebase from here and reason about (and extend) the pattern without needing the original session context.
A concrete class's annotated slot type is the dependency decision.
Bank variation is expressed entirely as class annotations \u2014 never as imperative wiring, never as __init__ parameters, never as a composition-root that assembles objects by hand. The tree of ports a pipeline needs is declared once, and a bank differs from the generic pipeline only by which concrete types are pinned onto which slots.
"},{"location":"philosophy/#the-three-layers","title":"The three layers","text":"
The pattern is built from three fixed layers. Understanding which layer something belongs to is the whole mental model.
Authoritative declaration of need (\"WHAT a stage requires\").
Each port is an ABC.
It declares attributes as class-level annotated defaults (e.g. TransactionParserPort.min_numbers: int = 3), optionally grouped as a nested struct via a @dataclass (e.g. source: ExtractionSource).
It declares port slots as annotated attributes whose type is another ABC (e.g. TransactionParserPort.number: NumberPort, amount_balance: AmountBalancePort).
It declares @abstractmethod bodies \u2014 the method signatures each concrete implementation must provide.
The ABC never runs, never holds an instance, and never says which implementation to use. It only says what the shape is.
The common default behavior (\"Imple \u2014 the shared adaptor\").
class ImplTransactionParserPort(TransactionParserPort) subclasses the ABC, implements every @abstractmethod, and re-pins its port slots to concrete Impl* types: number: ImplNumberPort, desc: ImplDescPort, amount_balance: ImplAmountBalancePort.
ImplAmountBalancePort in turn pins number: ImplNumberPort and ambiguity: ImplAmbiguityPort.
The root, ImplExtractionPipeline, pins its five stage slots to Impl* ports: ingest, raw_lines, txn_blocks, txn_dicts, raw_expense.
Impl* is the default that shared, bank-agnostic behavior lives in. Any slot a bank does not override falls back to Impl* at runtime.
"},{"location":"philosophy/#layer-3-bank-specializations-samplesextraction_pipelinebanksaxisicicipdfpy-samplesextraction_pipelineextraction_pipeline_bankspy","title":"Layer 3 \u2014 bank specializations (samples/extraction_pipeline/banks/{axis,icici}/pdf.py, samples/extraction_pipeline/extraction_pipeline_banks.py)","text":"
The variation (\"what differs per bank\").
Bank classes subclass the concrete Impl* classes, never the ABC \u2014 they extend, they never reinvent the contract.
Each Axis*/Icici* class overrides only the members that differ from the generic Impl*; everything shared is inherited.
A bank root is a thin annotated subclass of ImplExtractionPipeline that re-pins only the slots that differ:
class AxisExtractionPipeline(ImplExtractionPipeline):\n txn_dicts: AxisTxnDictsPort\n
Bank-specific wiring is hierarchical and cascading. Each level narrows exactly one slot, and its narrowed type drags the next level's narrowing along with it:
AxisExtractionPipeline\n \u2514\u2500 txn_dicts: AxisTxnDictsPort (only override on the root)\n \u2514\u2500 parser: AxisTransactionParserPort\n \u251c\u2500 number: AxisNumberPort (get_numbers \u2192 all clean nums)\n \u251c\u2500 desc: AxisDescPort (STARTTERS)\n \u2514\u2500 amount_balance: AxisAmountBalancePort\n \u2514\u2500 number: AxisNumberPort (re-pin: same bank's number port)\n
Siblings that are already correct in Impl* are inherited, not redeclared. E.g. the parser's date slot comes from ImplTransactionParserPort; the amount-balance port's ambiguity comes from ImplAmountBalancePort. Re-declaring them adds mental load on the extender with zero behavior change.
Rule \u2014 only redeclare the slot you are actually changing. If a slot's behavior is already correct from Impl*, leave it out.
"},{"location":"philosophy/#the-two-fidelity-guarantees-this-pattern-preserves","title":"The two fidelity guarantees this pattern preserves","text":"
Shared behavior stays shared. Slots like ingest, raw_lines, txn_blocks, raw_expense, parser date, and ambiguity are bank-agnostic. Leaving them at the Impl* default is deliberate, not an omission.
Banks never reinvent. Axis*/Icici* only extend Impl*. The ABC contract in samples/extraction_pipeline/extraction_pipeline_abc.py is defined once and shared by every bank.
"},{"location":"philosophy/#what-this-pattern-is-not","title":"What this pattern is NOT","text":"
No imperative assembly. No build_axis_pipeline() wiring objects by hand.
No constructor injection. Impl* classes have no __init__; wiring is done by assigning concrete port instances onto annotated slots.
YAML and ABCs are interchangeable, and both optional. The .yaml spec and the _abc.py module are two representations of the same contract. hexa is agnostic of the extraction pipeline sample and never imposes a workflow: a user can hand-write the ABC file, start from YAML (ABC generated), start from an ABC file (YAML emitted), or use both as a spec. The optional utilities in design.md \u00a7 Utilities translate between them and can verify they agree \u2014 but the bank Impl*/specialization files are always hand-written (their slots are a manual choice) and never generated.
The annotations are the decision; hexa.build(cls) (see design.md \u00a7 Container) turns a root class into a wired instance by reading __annotations__ + MRO, recursively instantiating each pinned concrete type, and setattring the child onto the parent slot. This document is scoped to the notation \u2014 the rest of the tree can be expressed purely as class annotations and filled at runtime by the container.
"}]}
\ No newline at end of file
diff --git a/hexa/lib/sitemap.xml.gz b/hexa/lib/sitemap.xml.gz
index e496a0d39e2d89445c665e87a8c93f68e7f55814..01465253604ef76b3b2b517f1166919160e58317 100644
GIT binary patch
delta 13
Ucmb=gXP58h;ArStF_FCj03F=~f&c&j
delta 13
Ucmb=gXP58h;AnWhbRv5N03V_R+yDRo
diff --git a/mcp/doc-forge/modules/docforge.cli.api_utils.json b/mcp/doc-forge/modules/docforge.cli.api_utils.json
index 1fc4060..ae164da 100644
--- a/mcp/doc-forge/modules/docforge.cli.api_utils.json
+++ b/mcp/doc-forge/modules/docforge.cli.api_utils.json
@@ -4,34 +4,6 @@
"path": "docforge.cli.api_utils",
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"objects": {
- "json": {
- "name": "json",
- "kind": "alias",
- "path": "docforge.cli.api_utils.json",
- "signature": "",
- "docstring": null
- },
- "dataclass": {
- "name": "dataclass",
- "kind": "alias",
- "path": "docforge.cli.api_utils.dataclass",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.api_utils.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.api_utils.click",
- "signature": "",
- "docstring": null
- },
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
@@ -43,7 +15,7 @@
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.api_utils.OpenAPIMetadata",
- "signature": "",
+ "signature": "OpenAPIMetadata(site_name: str, site_description: str | None, site_author: str | None)",
"docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.",
"members": {
"site_name": {
@@ -73,29 +45,22 @@
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.api_utils.load_openapi_spec",
- "signature": "",
+ "signature": "load_openapi_spec(spec_path: Path) -> dict[Any, Any]",
"docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path (Path):\n Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid."
},
"derive_metadata": {
"name": "derive_metadata",
"kind": "function",
"path": "docforge.cli.api_utils.derive_metadata",
- "signature": "",
+ "signature": "derive_metadata(spec: dict[Any, Any]) -> OpenAPIMetadata",
"docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec."
},
"generate_api_sources": {
"name": "generate_api_sources",
"kind": "function",
"path": "docforge.cli.api_utils.generate_api_sources",
- "signature": "",
+ "signature": "generate_api_sources(spec: dict[Any, Any], docs_dir: Path) -> None",
"docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n docs_dir (Path):\n Directory (for example ``docs/api``) where the swagger\n sources are written."
- },
- "Any": {
- "name": "Any",
- "kind": "alias",
- "path": "docforge.cli.api_utils.Any",
- "signature": "",
- "docstring": null
}
}
}
diff --git a/mcp/doc-forge/modules/docforge.cli.commands.json b/mcp/doc-forge/modules/docforge.cli.commands.json
index 79af154..2d73bff 100644
--- a/mcp/doc-forge/modules/docforge.cli.commands.json
+++ b/mcp/doc-forge/modules/docforge.cli.commands.json
@@ -4,95 +4,46 @@
"path": "docforge.cli.commands",
"docstring": "# Summary\n\nCommand definitions for the doc-forge CLI.\n\nProvides the CLI structure using Click, including build, serve, and tree commands.\n\n---\n\nNotes:\n - The `build` command validates requested modes before generating anything.\n - `--mkdocs`, `--api`, and `--wiki` each emit their own MkDocs config and\n build (`docs/mkdocs.{kind}.yml` into `site/{kind}`); `--mcp` generates a\n machine-readable bundle independently.\n\n---",
"objects": {
- "os": {
- "name": "os",
- "kind": "alias",
- "path": "docforge.cli.commands.os",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.click",
- "signature": "",
- "docstring": null
- },
"api_utils": {
"name": "api_utils",
"kind": "module",
"path": "docforge.cli.commands.api_utils",
- "signature": "",
+ "signature": null,
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"members": {
- "json": {
- "name": "json",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.json",
- "signature": "",
- "docstring": null
- },
- "dataclass": {
- "name": "dataclass",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.dataclass",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.click",
- "signature": "",
- "docstring": null
- },
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
- "signature": "",
+ "signature": null,
"docstring": null
},
"OpenAPIMetadata": {
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
- "signature": "",
+ "signature": "OpenAPIMetadata(site_name: str, site_description: str | None, site_author: str | None)",
"docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.",
"members": {
"site_name": {
"name": "site_name",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"site_description": {
"name": "site_description",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
- "signature": "",
+ "signature": null,
"docstring": null
},
"site_author": {
"name": "site_author",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
- "signature": "",
+ "signature": null,
"docstring": null
}
}
@@ -101,29 +52,22 @@
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.commands.api_utils.load_openapi_spec",
- "signature": "",
+ "signature": "load_openapi_spec(spec_path: Path)",
"docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path (Path):\n Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid."
},
"derive_metadata": {
"name": "derive_metadata",
"kind": "function",
"path": "docforge.cli.commands.api_utils.derive_metadata",
- "signature": "",
+ "signature": "derive_metadata(spec: dict[Any, Any])",
"docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec."
},
"generate_api_sources": {
"name": "generate_api_sources",
"kind": "function",
"path": "docforge.cli.commands.api_utils.generate_api_sources",
- "signature": "",
+ "signature": "generate_api_sources(spec: dict[Any, Any], docs_dir: Path)",
"docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n docs_dir (Path):\n Directory (for example ``docs/api``) where the swagger\n sources are written."
- },
- "Any": {
- "name": "Any",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.Any",
- "signature": "",
- "docstring": null
}
}
},
@@ -131,42 +75,28 @@
"name": "mcp_utils",
"kind": "module",
"path": "docforge.cli.commands.mcp_utils",
- "signature": "",
+ "signature": null,
"docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.\n\n---\n\nNotes:\n - `generate_resources` produces the bundle consumed by `MCPServer`:\n `index.json`, `nav.json`, and per-module resources under `modules/`.\n - Resource URIs use the `docs://` scheme: `docs://index`, `docs://nav`,\n and `docs://modules/{module}`.\n\n---",
"members": {
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.mcp_utils.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.mcp_utils.click",
- "signature": "",
- "docstring": null
- },
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader",
- "signature": "",
+ "signature": "GriffeLoader()",
"docstring": "Load Python modules using Griffe and convert them into doc-forge models.\n\nThis loader uses the Griffe introspection engine to analyze Python source\ncode and transform the extracted information into `Project`, `Module`,\nand `DocObject` instances used by doc-forge.\n\nAttributes:\n _loader (_GriffeLoader):\n Internal Griffe loader with dedicated module and line collections.",
"members": {
"load_project": {
"name": "load_project",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader.load_project",
- "signature": "",
+ "signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None)",
"docstring": "Load multiple modules and assemble them into a Project model.\n\nEach module path is introspected and converted into a `Module`\ninstance. All modules are then aggregated into a single `Project`\nobject.\n\nArgs:\n module_paths (list[str]):\n List of dotted module import paths to load.\n\n project_name (str | None):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool | None):\n If True, modules that fail to load will be skipped instead of raising an error.\n\nReturns:\n Project:\n A populated `Project` instance containing the loaded modules.\n\nRaises:\n ValueError:\n If no module paths are provided.\n\n ImportError:\n If a module fails to load and `skip_import_errors` is False."
},
"load_module": {
"name": "load_module",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader.load_module",
- "signature": "",
+ "signature": "load_module(path: str)",
"docstring": "Load and convert a single Python module.\n\nThe module is introspected using Griffe and then transformed into\na doc-forge `Module` model.\n\nArgs:\n path (str):\n Dotted import path of the module.\n\nReturns:\n Module:\n A populated `Module` instance.\n\nRaises:\n ImportError:\n If the module cannot be loaded by Griffe.\n\n KeyError:\n If the loaded module is missing from the module collection.\n\nExample:\n Load a single module:\n\n ```python\n loader = GriffeLoader()\n module = loader.load_module(\"mypackage.submodule\")\n ```"
}
}
@@ -175,28 +105,28 @@
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.discover_module_paths",
- "signature": "",
+ "signature": "discover_module_paths(module_name: str, project_root: Path | None = None)",
"docstring": "Discover Python modules within a package directory.\n\nThe function scans the filesystem for `.py` files inside the specified\npackage and converts them into dotted module import paths.\n\nDiscovery rules:\n\n- Directories containing `__init__.py` are treated as packages.\n- Each `.py` file is treated as a module.\n- Results are returned as dotted import paths.\n\nArgs:\n module_name (str):\n Top-level package name to discover modules from.\n\n project_root (Path | None):\n Root directory used to resolve module paths. If not provided, the\n current working directory is used.\n\nReturns:\n list[str]:\n A sorted list of unique dotted module import paths.\n\nRaises:\n FileNotFoundError:\n If the specified package directory does not exist."
},
"MCPRenderer": {
"name": "MCPRenderer",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer",
- "signature": "",
+ "signature": null,
"docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer.name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources",
- "signature": "",
+ "signature": "generate_sources(project: Project, out_dir: Path)",
"docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written."
}
}
@@ -205,28 +135,28 @@
"name": "MCPServer",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.MCPServer",
- "signature": "",
+ "signature": "MCPServer(mcp_root: Path, name: str)",
"docstring": "MCP server for serving a pre-generated documentation bundle.\n\nThe server exposes documentation resources and diagnostic tools through\nMCP endpoints backed by JSON files generated by the MCP renderer.\n\nAttributes:\n mcp_root (Path):\n Directory containing the generated MCP documentation bundle.\n\n app (FastMCP):\n Underlying FastMCP application instance that registers resources\n and tools.",
"members": {
"mcp_root": {
"name": "mcp_root",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPServer.mcp_root",
- "signature": "",
+ "signature": null,
"docstring": null
},
"app": {
"name": "app",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPServer.app",
- "signature": "",
+ "signature": null,
"docstring": null
},
"run": {
"name": "run",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPServer.run",
- "signature": "",
+ "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')",
"docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`."
}
}
@@ -235,14 +165,14 @@
"name": "generate_resources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.generate_resources",
- "signature": "",
+ "signature": "generate_resources(module: str, project_name: str | None, out_dir: Path)",
"docstring": "Generate MCP documentation resources from a Python module.\n\nThe function performs project introspection, builds the internal\ndocumentation model, and renders MCP-compatible JSON resources\nto the specified output directory.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n project_name (str | None):\n Optional override for the project name used in generated\n documentation metadata.\n\n out_dir (Path):\n Directory where MCP resources (index.json, nav.json, and module data)\n will be written."
},
"serve": {
"name": "serve",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.serve",
- "signature": "",
+ "signature": "serve(module: str, mcp_root: Path)",
"docstring": "Start an MCP server for a pre-generated documentation bundle.\n\nThe server exposes documentation resources such as project metadata,\nnavigation structure, and module documentation through MCP endpoints.\n\nArgs:\n module (str):\n Python module import path used to identify the served\n documentation instance.\n\n mcp_root (Path):\n Path to the directory containing the MCP documentation\n bundle (index.json, nav.json, and modules/).\n\nRaises:\n click.ClickException:\n If the MCP documentation bundle is missing required files or directories."
}
}
@@ -251,77 +181,28 @@
"name": "mkdocs_utils",
"kind": "module",
"path": "docforge.cli.commands.mkdocs_utils",
- "signature": "",
+ "signature": null,
"docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.\n\n---\n\nNotes:\n - A separate `mkdocs.{kind}.yml` configuration and build is emitted per\n enabled kind (lib, api, wiki), each scoped to its own `docs_dir` and\n written into its own `site_dir` (`site/lib`, `site/api`, `site/wiki`).\n - Navigation blocks are re-rooted per kind: the wiki navigation drops its\n leading `wiki/` scope and the resolved nav spec drops its `lib/` scope.\n\n---",
"members": {
- "Iterable": {
- "name": "Iterable",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.Iterable",
- "signature": "",
- "docstring": null
- },
- "resources": {
- "name": "resources",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.resources",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.Path",
- "signature": "",
- "docstring": null
- },
- "Any": {
- "name": "Any",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.Any",
- "signature": "",
- "docstring": null
- },
- "cast": {
- "name": "cast",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.cast",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.click",
- "signature": "",
- "docstring": null
- },
- "yaml": {
- "name": "yaml",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.yaml",
- "signature": "",
- "docstring": null
- },
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader",
- "signature": "",
+ "signature": "GriffeLoader()",
"docstring": "Load Python modules using Griffe and convert them into doc-forge models.\n\nThis loader uses the Griffe introspection engine to analyze Python source\ncode and transform the extracted information into `Project`, `Module`,\nand `DocObject` instances used by doc-forge.\n\nAttributes:\n _loader (_GriffeLoader):\n Internal Griffe loader with dedicated module and line collections.",
"members": {
"load_project": {
"name": "load_project",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_project",
- "signature": "",
+ "signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None)",
"docstring": "Load multiple modules and assemble them into a Project model.\n\nEach module path is introspected and converted into a `Module`\ninstance. All modules are then aggregated into a single `Project`\nobject.\n\nArgs:\n module_paths (list[str]):\n List of dotted module import paths to load.\n\n project_name (str | None):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool | None):\n If True, modules that fail to load will be skipped instead of raising an error.\n\nReturns:\n Project:\n A populated `Project` instance containing the loaded modules.\n\nRaises:\n ValueError:\n If no module paths are provided.\n\n ImportError:\n If a module fails to load and `skip_import_errors` is False."
},
"load_module": {
"name": "load_module",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_module",
- "signature": "",
+ "signature": "load_module(path: str)",
"docstring": "Load and convert a single Python module.\n\nThe module is introspected using Griffe and then transformed into\na doc-forge `Module` model.\n\nArgs:\n path (str):\n Dotted import path of the module.\n\nReturns:\n Module:\n A populated `Module` instance.\n\nRaises:\n ImportError:\n If the module cannot be loaded by Griffe.\n\n KeyError:\n If the loaded module is missing from the module collection.\n\nExample:\n Load a single module:\n\n ```python\n loader = GriffeLoader()\n module = loader.load_module(\"mypackage.submodule\")\n ```"
}
}
@@ -330,21 +211,21 @@
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.discover_module_paths",
- "signature": "",
+ "signature": "discover_module_paths(module_name: str, project_root: Path | None = None)",
"docstring": "Discover Python modules within a package directory.\n\nThe function scans the filesystem for `.py` files inside the specified\npackage and converts them into dotted module import paths.\n\nDiscovery rules:\n\n- Directories containing `__init__.py` are treated as packages.\n- Each `.py` file is treated as a module.\n- Results are returned as dotted import paths.\n\nArgs:\n module_name (str):\n Top-level package name to discover modules from.\n\n project_root (Path | None):\n Root directory used to resolve module paths. If not provided, the\n current working directory is used.\n\nReturns:\n list[str]:\n A sorted list of unique dotted module import paths.\n\nRaises:\n FileNotFoundError:\n If the specified package directory does not exist."
},
"MkDocsNavEmitter": {
"name": "MkDocsNavEmitter",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter",
- "signature": "",
+ "signature": null,
"docstring": "Emit MkDocs navigation structures from resolved navigation data.\n\nThe emitter transforms a ``ResolvedNav`` object into the YAML-compatible\nlist structure expected by the MkDocs ``nav`` configuration field.",
"members": {
"emit": {
"name": "emit",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter.emit",
- "signature": "",
+ "signature": "emit(nav: ResolvedNav)",
"docstring": "Generate a navigation structure for ``mkdocs.yml``.\n\nArgs:\n nav (ResolvedNav):\n Resolved navigation data describing documentation groups\n and their associated Markdown files.\n\nReturns:\n list[dict[str, Any]]:\n A list of dictionaries representing the MkDocs navigation layout.\n Each dictionary maps a navigation label to a page or a list of\n pages."
}
}
@@ -353,49 +234,49 @@
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_wiki_nav",
- "signature": "",
+ "signature": "build_wiki_nav(wiki_dir: Path)",
"docstring": "Derive an MkDocs navigation block from a wiki directory.\n\nReturned paths are relative to the parent of ``wiki_dir`` and carry the\nwiki directory name as their leading component (for example\n``wiki/01_overview.md`` when the wiki lives at ``docs/wiki``). This makes\nthe result directly usable in an MkDocs ``nav`` block with\n\n- ``index.md`` at the wiki root becomes the ``Home`` entry.\n- Page labels are derived from filenames: numeric order prefixes such as\n ``01_`` or ``02-`` are stripped, separators are replaced with spaces, and\n names are title-cased (``01_overview.md`` becomes ``Overview``).\n- Subdirectories become nested navigation groups. A nested ``index.md`` is\n rendered as the section root placed first inside the group.\n- Only ``.md`` files are considered; hidden entries are ignored.\n\nArgs:\n wiki_dir (Path):\n Path to the hand-written wiki directory, for example ``docs/wiki``.\n\nReturns:\n list[dict[str, Any]]:\n Navigation entries compatible with the MkDocs ``nav`` configuration.\n The list is empty if the wiki contains no Markdown files.\n\nRaises:\n FileNotFoundError:\n If the wiki directory does not exist."
},
"load_nav_spec": {
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.load_nav_spec",
- "signature": "",
+ "signature": "load_nav_spec(path: Path)",
"docstring": "Load a navigation specification file.\n\nThis helper function reads a YAML navigation file and constructs a\ncorresponding ``NavSpec`` instance.\n\nArgs:\n path (Path):\n Path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed specification.\n\nRaises:\n FileNotFoundError: If the specification file does not exist.\n ValueError: If the YAML structure is invalid."
},
"resolve_nav": {
"name": "resolve_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.resolve_nav",
- "signature": "",
+ "signature": "resolve_nav(spec: NavSpec, docs_root: Path)",
"docstring": "Resolve a navigation specification against the filesystem.\n\nThe function expands glob patterns defined in a ``NavSpec`` and verifies\nthat referenced documentation files exist within the documentation root.\n\nArgs:\n spec (NavSpec):\n Navigation specification describing documentation layout.\n docs_root (Path):\n Root directory containing documentation Markdown files.\n\nReturns:\n ResolvedNav:\n A `ResolvedNav` instance containing validated navigation paths.\n\nRaises:\n FileNotFoundError: If the documentation root does not exist or a\n navigation pattern does not match any files."
},
"MkDocsRenderer": {
"name": "MkDocsRenderer",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer",
- "signature": "",
+ "signature": null,
"docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources",
- "signature": "",
+ "signature": "generate_sources(project: Project, out_dir: Path, module_is_source: bool | None = None)",
"docstring": "Generate Markdown documentation files for a project.\n\nThis method renders a documentation structure from the provided\nproject model and writes the resulting Markdown files to the\nspecified output directory.\n\nArgs:\n project (Project):\n Project model containing modules to document.\n\n out_dir (Path):\n Directory where generated Markdown files will be written.\n\n module_is_source (bool | None):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder."
},
"generate_readme": {
"name": "generate_readme",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_readme",
- "signature": "",
+ "signature": "generate_readme(project: Project, docs_dir: Path, module_is_source: bool | None = None, readme_dir: Path | None = None)",
"docstring": "Generate a `README.md` file from the root module docstring.\n\nNotes:\n - If `module_is_source` is True, `README.md` is written to the\n project root directory.\n - If False, README generation is currently not implemented.\n\nArgs:\n project (Project):\n Project model containing documentation metadata.\n\n docs_dir (Path):\n Directory containing generated documentation sources.\n\n module_is_source (bool | None):\n Whether the module is treated as the project source root.\n\n readme_dir (Path | None):\n Directory where the generated README.md should be written.\n Defaults to the parent of `docs_dir`."
}
}
@@ -404,49 +285,49 @@
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.generate_sources",
- "signature": "",
+ "signature": "generate_sources(module: str, docs_dir: Path, project_name: str | None = None, module_is_source: bool | None = None, readme_dir: Path | None = None)",
"docstring": "Generate MkDocs Markdown sources for a Python module.\n\nThis function introspects the specified module, builds the internal\ndocumentation model, and renders Markdown documentation files for\nuse with MkDocs.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n docs_dir (Path):\n Directory where the generated Markdown files will be written.\n\n project_name (str | None):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (bool | None):\n If True, treat the specified module directory as the project root\n rather than a nested module.\n\n readme_dir (Path | None):\n Directory where the generated README.md should be written. If not\n provided, defaults to the parent of ``docs_dir``."
},
"build_lib_nav": {
"name": "build_lib_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_lib_nav",
- "signature": "",
+ "signature": "build_lib_nav(nav_file: Path, docs_root: Path)",
"docstring": "Build the re-rooted navigation block for a lib site.\n\nThe navigation specification is resolved against the shared documentation\nroot and every resulting path is re-rooted relative to the ``lib``\nsubdirectory by stripping its leading ``lib/`` scope component.\n\nArgs:\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n docs_root (Path):\n Shared documentation root containing the ``lib`` sources.\n\nReturns:\n tuple[list[dict[str, Any]], dict[str, str] | None]:\n The re-rooted navigation block and the optional theme icon\n mapping from the specification.\n\nRaises:\n click.FileError:\n If the navigation specification cannot be found."
},
"build_wiki_nav_block": {
"name": "build_wiki_nav_block",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_wiki_nav_block",
- "signature": "",
+ "signature": "build_wiki_nav_block(wiki_dir: Path)",
"docstring": "Build the re-rooted navigation block for a wiki site.\n\nThe wiki navigation derived from the wiki file structure is re-rooted\nrelative to the wiki directory itself by stripping the leading ``wiki/``\nscope component.\n\nArgs:\n wiki_dir (Path):\n Path to the hand-written wiki directory, for example ``docs/wiki``.\n\nReturns:\n list[dict[str, Any]]:\n Navigation entries relative to the wiki directory.\n\nRaises:\n click.FileError:\n If the wiki directory does not exist."
},
"load_spec_icon": {
"name": "load_spec_icon",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.load_spec_icon",
- "signature": "",
+ "signature": "load_spec_icon(nav_file: Path)",
"docstring": "Load the theme icon mapping from a navigation specification.\n\nArgs:\n nav_file (Path):\n Path to the navigation specification file.\n\nReturns:\n dict[str, str] | None:\n The icon mapping, or ``None`` when the specification file is\n absent or cannot be parsed."
},
"generate_site_config": {
"name": "generate_site_config",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.generate_site_config",
- "signature": "",
+ "signature": "generate_site_config(kind: str, kind_root: Path, nav_block: list[dict[str, Any]], out: Path, site_name: str, docs_dir: str, site_dir: str, template: Path | None = None, site_description: str | None = None, site_author: str | None = None, theme_icon: dict[str, str] | None = None)",
"docstring": "Generate a per-kind `mkdocs.{kind}.yml` configuration file.\n\nThe configuration is created by merging the shared ``mkdocs.common.yml``\ntemplate with the fragment contributed by the kind (``lib``, ``api``, or\n``wiki``). Both ``docs_dir`` and ``site_dir`` are written relative to the\nconfiguration file's directory: the kind's sources when expressed as a\nsibling path (for example ``lib``) and the per-kind site output (for\nexample ``../site/lib``).\n\nArgs:\n kind (str):\n Documentation kind, one of ``lib``, ``api``, or ``wiki``.\n\n kind_root (Path):\n Directory scoped to the kind (for example ``docs/lib``) that\n serves as the MkDocs ``docs_dir``.\n\n nav_block (list[dict[str, Any]]):\n Re-rooted navigation entries for the kind's site.\n\n out (Path):\n Destination path where the generated ``mkdocs.{kind}.yml`` file\n is written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n docs_dir (str):\n MkDocs ``docs_dir`` value, relative to the configuration\n file's directory.\n\n site_dir (str):\n MkDocs ``site_dir`` value, relative to the configuration\n file's directory.\n\n template (Path | None):\n Optional path to a fully custom MkDocs configuration template\n that replaces the built-in templates entirely.\n\n site_description (str | None):\n Optional site description written into the configuration.\n\n site_author (str | None):\n Optional site author written into the configuration.\n\n theme_icon (dict[str, str] | None):\n Optional mapping of theme icon entries injected as\n ``theme.icon``."
},
"build_configs": {
"name": "build_configs",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_configs",
- "signature": "",
+ "signature": "build_configs(yml_paths: Iterable[Path])",
"docstring": "Build the MkDocs documentation site for every given configuration.\n\nEach configuration file is loaded and built in turn, producing the\nper-kind static sites (``site/lib``, ``site/api``, ``site/wiki``).\n\nArgs:\n yml_paths (Iterable[Path]):\n Configuration files to build, in order.\n\nRaises:\n click.ClickException:\n If a configuration file does not exist."
},
"serve": {
"name": "serve",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.serve",
- "signature": "",
+ "signature": "serve(mkdocs_yml: Path)",
"docstring": "Start an MkDocs development server with live reload.\n\nThe server watches documentation files and automatically reloads\nthe site when changes are detected.\n\nArgs:\n mkdocs_yml (Path):\n Path to the `mkdocs.yml` configuration file.\n\nRaises:\n click.ClickException:\n If the configuration file does not exist."
}
}
@@ -455,21 +336,21 @@
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.GriffeLoader",
- "signature": "",
+ "signature": "GriffeLoader()",
"docstring": "Load Python modules using Griffe and convert them into doc-forge models.\n\nThis loader uses the Griffe introspection engine to analyze Python source\ncode and transform the extracted information into `Project`, `Module`,\nand `DocObject` instances used by doc-forge.\n\nAttributes:\n _loader (_GriffeLoader):\n Internal Griffe loader with dedicated module and line collections.",
"members": {
"load_project": {
"name": "load_project",
"kind": "function",
"path": "docforge.cli.commands.GriffeLoader.load_project",
- "signature": "",
+ "signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None)",
"docstring": "Load multiple modules and assemble them into a Project model.\n\nEach module path is introspected and converted into a `Module`\ninstance. All modules are then aggregated into a single `Project`\nobject.\n\nArgs:\n module_paths (list[str]):\n List of dotted module import paths to load.\n\n project_name (str | None):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool | None):\n If True, modules that fail to load will be skipped instead of raising an error.\n\nReturns:\n Project:\n A populated `Project` instance containing the loaded modules.\n\nRaises:\n ValueError:\n If no module paths are provided.\n\n ImportError:\n If a module fails to load and `skip_import_errors` is False."
},
"load_module": {
"name": "load_module",
"kind": "function",
"path": "docforge.cli.commands.GriffeLoader.load_module",
- "signature": "",
+ "signature": "load_module(path: str)",
"docstring": "Load and convert a single Python module.\n\nThe module is introspected using Griffe and then transformed into\na doc-forge `Module` model.\n\nArgs:\n path (str):\n Dotted import path of the module.\n\nReturns:\n Module:\n A populated `Module` instance.\n\nRaises:\n ImportError:\n If the module cannot be loaded by Griffe.\n\n KeyError:\n If the loaded module is missing from the module collection.\n\nExample:\n Load a single module:\n\n ```python\n loader = GriffeLoader()\n module = loader.load_module(\"mypackage.submodule\")\n ```"
}
}
@@ -478,70 +359,70 @@
"name": "DocObject",
"kind": "class",
"path": "docforge.cli.commands.DocObject",
- "signature": "",
+ "signature": "DocObject(name: str, kind: str, path: str, signature: str | None = None, docstring: str | None = None)",
"docstring": "Representation of a documented Python object.\n\nA `DocObject` models a single Python entity discovered during\nintrospection. Objects may contain nested members, allowing the structure\nof modules, classes, and other containers to be represented recursively.\n\nAttributes:\n name (str):\n Local name of the object.\n\n kind (str):\n Type of object (for example `class`, `function`, `method`, or `attribute`).\n\n path (str):\n Fully qualified dotted path to the object.\n\n signature (str | None):\n Callable signature if the object represents a callable.\n\n docstring (str | None):\n Raw docstring text extracted from the source code.\n\n members (dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.kind",
- "signature": "",
+ "signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.path",
- "signature": "",
+ "signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.signature",
- "signature": "",
+ "signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.docstring",
- "signature": "",
+ "signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.members",
- "signature": "",
+ "signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.cli.commands.DocObject.add_member",
- "signature": "",
+ "signature": "add_member(obj: DocObject)",
"docstring": "Add a child documentation object.\n\nThis is typically used when attaching methods to classes or\nnested objects to their parent containers.\n\nArgs:\n obj (DocObject):\n Documentation object to add as a member."
},
"get_member": {
"name": "get_member",
"kind": "function",
"path": "docforge.cli.commands.DocObject.get_member",
- "signature": "",
+ "signature": "get_member(name: str)",
"docstring": "Retrieve a member object by name.\n\nArgs:\n name (str):\n Name of the member to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If the member does not exist."
},
"get_all_members": {
"name": "get_all_members",
"kind": "function",
"path": "docforge.cli.commands.DocObject.get_all_members",
- "signature": "",
+ "signature": "get_all_members()",
"docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members."
}
}
@@ -557,29 +438,22 @@
"name": "build",
"kind": "function",
"path": "docforge.cli.commands.build",
- "signature": "",
+ "signature": "build(mcp: bool, mkdocs: bool, api: bool, wiki: bool, refresh: bool, module_is_source: bool, module: str | None, openapi_spec: Path | None, project_name: str | None, site_name: str | None, docs_dir: Path, wiki_dir: Path, nav_file: Path, template: Path | None, out_dir: Path) -> None",
"docstring": "Build documentation artifacts.\n\nThis command runs the full documentation pipeline: it loads Python\nmodules, generates renderer-specific documentation sources, and\noptionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- A lib MkDocs site (`--mkdocs`) for library reference docs\n- A swagger-enabled API MkDocs site (`--api`) built from an OpenAPI spec\n- A wiki MkDocs site (`--wiki`) built from hand-written markdown\n- MCP structured documentation resources (`--mcp`)\n\nEach enabled site kind produces its own MkDocs configuration\n(`docs/mkdocs.{kind}.yml`) and its own build (`site/{kind}`).\n\nNotes:\n - At least one of `--mcp`, `--mkdocs`, `--wiki`, or `--api` must be\n provided.\n - `--mkdocs`, `--api`, and `--wiki` emit independent MkDocs builds,\n while `--mcp` emits a machine-readable bundle.\n - Configuration files are generated only when absent; an existing\n `docs/mkdocs.{kind}.yml` is used as-is. Pass `--refresh` to\n rebaseline it from the templates.\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable the lib MkDocs documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\n\n wiki (bool):\n Build a hand-written wiki directory as its own MkDocs site.\n\n refresh (bool):\n Regenerate ``docs/mkdocs.{kind}.yml`` from templates even when\n it already exists. By default, existing configs are used as-is.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (str | None):\n Python module import path to document.\n\n openapi_spec (Path | None):\n Path to the OpenAPI JSON specification used for API docs.\n\n project_name (str | None):\n Optional override for the project name.\n\n site_name (str | None):\n Display name for the lib and wiki MkDocs sites.\n\n docs_dir (Path):\n Shared documentation root used for generated sources.\n wiki_dir (Path):\n Directory containing hand-written wiki markdown files.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Path | None):\n Optional custom MkDocs configuration template.\n\n out_dir (Path):\n Output directory for generated MCP resources.\n\nRaises:\n click.UsageError:\n If required options are missing or conflicting."
},
"serve": {
"name": "serve",
"kind": "function",
"path": "docforge.cli.commands.serve",
- "signature": "",
+ "signature": "serve(mcp: bool, mkdocs: bool, lib: bool, api: bool, wiki: bool, module: str | None, mkdocs_yml: Path, out_dir: Path) -> None",
"docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing a site, or\n- An MCP server exposing structured documentation resources\n\nThe kind flags (`--lib`, `--api`, `--wiki`) select the generated\nper-kind config (`docs/mkdocs.{kind}.yml`); `--mkdocs` serves the config\npassed via `--mkdocs-yml`.\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site from ``--mkdocs-yml``.\n\n lib (bool):\n Serve the lib MkDocs site.\n\n api (bool):\n Serve the API MkDocs site.\n\n wiki (bool):\n Serve the wiki MkDocs site.\n\n module (str | None):\n Python module import path to serve via MCP.\n\n mkdocs_yml (Path):\n Path to the MkDocs configuration file.\n\n out_dir (Path):\n Root directory containing MCP documentation resources.\n\nRaises:\n click.UsageError:\n If invalid or conflicting options are provided."
},
"tree": {
"name": "tree",
"kind": "function",
"path": "docforge.cli.commands.tree",
- "signature": "",
+ "signature": "tree(module: str, project_name: str | None) -> None",
"docstring": "Display the documentation object tree for a module.\n\nThis command introspects the specified module and prints a\nhierarchical representation of the discovered documentation\nobjects, including modules, classes, functions, and members.\n\nArgs:\n module (str):\n Python module import path to introspect.\n\n project_name (str | None):\n Optional name to display as the project root."
- },
- "Group": {
- "name": "Group",
- "kind": "alias",
- "path": "docforge.cli.commands.Group",
- "signature": "",
- "docstring": null
}
}
}
diff --git a/mcp/doc-forge/modules/docforge.cli.json b/mcp/doc-forge/modules/docforge.cli.json
index be6964a..b1b7190 100644
--- a/mcp/doc-forge/modules/docforge.cli.json
+++ b/mcp/doc-forge/modules/docforge.cli.json
@@ -15,14 +15,14 @@
"name": "cli",
"kind": "attribute",
"path": "docforge.cli.main.cli",
- "signature": "",
+ "signature": null,
"docstring": null
},
"main": {
"name": "main",
"kind": "function",
"path": "docforge.cli.main.main",
- "signature": "",
+ "signature": "main() -> None",
"docstring": "Run the doc-forge command-line interface.\n\nThis function initializes and executes the Click CLI application.\nIt is used as the console entry point when invoking `doc-forge`\nfrom the command line."
}
}
@@ -34,34 +34,6 @@
"signature": null,
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"members": {
- "json": {
- "name": "json",
- "kind": "alias",
- "path": "docforge.cli.api_utils.json",
- "signature": "",
- "docstring": null
- },
- "dataclass": {
- "name": "dataclass",
- "kind": "alias",
- "path": "docforge.cli.api_utils.dataclass",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.api_utils.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.api_utils.click",
- "signature": "",
- "docstring": null
- },
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
@@ -73,7 +45,7 @@
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.api_utils.OpenAPIMetadata",
- "signature": "",
+ "signature": "OpenAPIMetadata(site_name: str, site_description: str | None, site_author: str | None)",
"docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.",
"members": {
"site_name": {
@@ -103,29 +75,22 @@
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.api_utils.load_openapi_spec",
- "signature": "",
+ "signature": "load_openapi_spec(spec_path: Path) -> dict[Any, Any]",
"docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path (Path):\n Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid."
},
"derive_metadata": {
"name": "derive_metadata",
"kind": "function",
"path": "docforge.cli.api_utils.derive_metadata",
- "signature": "",
+ "signature": "derive_metadata(spec: dict[Any, Any]) -> OpenAPIMetadata",
"docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec."
},
"generate_api_sources": {
"name": "generate_api_sources",
"kind": "function",
"path": "docforge.cli.api_utils.generate_api_sources",
- "signature": "",
+ "signature": "generate_api_sources(spec: dict[Any, Any], docs_dir: Path) -> None",
"docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n docs_dir (Path):\n Directory (for example ``docs/api``) where the swagger\n sources are written."
- },
- "Any": {
- "name": "Any",
- "kind": "alias",
- "path": "docforge.cli.api_utils.Any",
- "signature": "",
- "docstring": null
}
}
},
@@ -136,95 +101,46 @@
"signature": null,
"docstring": "# Summary\n\nCommand definitions for the doc-forge CLI.\n\nProvides the CLI structure using Click, including build, serve, and tree commands.\n\n---\n\nNotes:\n - The `build` command validates requested modes before generating anything.\n - `--mkdocs`, `--api`, and `--wiki` each emit their own MkDocs config and\n build (`docs/mkdocs.{kind}.yml` into `site/{kind}`); `--mcp` generates a\n machine-readable bundle independently.\n\n---",
"members": {
- "os": {
- "name": "os",
- "kind": "alias",
- "path": "docforge.cli.commands.os",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.click",
- "signature": "",
- "docstring": null
- },
"api_utils": {
"name": "api_utils",
"kind": "module",
"path": "docforge.cli.commands.api_utils",
- "signature": "",
+ "signature": null,
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"members": {
- "json": {
- "name": "json",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.json",
- "signature": "",
- "docstring": null
- },
- "dataclass": {
- "name": "dataclass",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.dataclass",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.click",
- "signature": "",
- "docstring": null
- },
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
- "signature": "",
+ "signature": null,
"docstring": null
},
"OpenAPIMetadata": {
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
- "signature": "",
+ "signature": "OpenAPIMetadata(site_name: str, site_description: str | None, site_author: str | None)",
"docstring": "Metadata derived from the ``info`` block of an OpenAPI specification.\n\nAttributes:\n site_name: Spec title, used as the MkDocs site name.\n site_description: Spec description, used as the site description.\n site_author: Contact name (fallback: contact email), used as the\n site author.",
"members": {
"site_name": {
"name": "site_name",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"site_description": {
"name": "site_description",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
- "signature": "",
+ "signature": null,
"docstring": null
},
"site_author": {
"name": "site_author",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
- "signature": "",
+ "signature": null,
"docstring": null
}
}
@@ -233,29 +149,22 @@
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.commands.api_utils.load_openapi_spec",
- "signature": "",
+ "signature": "load_openapi_spec(spec_path: Path)",
"docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path (Path):\n Path to the OpenAPI JSON specification file.\n\nReturns:\n dict:\n The parsed OpenAPI specification.\n\nRaises:\n click.ClickException:\n If the file cannot be read or the ``info`` block is invalid."
},
"derive_metadata": {
"name": "derive_metadata",
"kind": "function",
"path": "docforge.cli.commands.api_utils.derive_metadata",
- "signature": "",
+ "signature": "derive_metadata(spec: dict[Any, Any])",
"docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n\nReturns:\n OpenAPIMetadata:\n Site name, description, and author derived from the spec."
},
"generate_api_sources": {
"name": "generate_api_sources",
"kind": "function",
"path": "docforge.cli.commands.api_utils.generate_api_sources",
- "signature": "",
+ "signature": "generate_api_sources(spec: dict[Any, Any], docs_dir: Path)",
"docstring": "Generate swagger-enabled Markdown sources and the spec copy.\n\nThe specification is written as ``openapi.json`` inside ``docs_dir`` and\nan ``index.md`` embedding the swagger UI is generated alongside it.\n\nArgs:\n spec (dict):\n Parsed OpenAPI specification.\n docs_dir (Path):\n Directory (for example ``docs/api``) where the swagger\n sources are written."
- },
- "Any": {
- "name": "Any",
- "kind": "alias",
- "path": "docforge.cli.commands.api_utils.Any",
- "signature": "",
- "docstring": null
}
}
},
@@ -263,42 +172,28 @@
"name": "mcp_utils",
"kind": "module",
"path": "docforge.cli.commands.mcp_utils",
- "signature": "",
+ "signature": null,
"docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.\n\n---\n\nNotes:\n - `generate_resources` produces the bundle consumed by `MCPServer`:\n `index.json`, `nav.json`, and per-module resources under `modules/`.\n - Resource URIs use the `docs://` scheme: `docs://index`, `docs://nav`,\n and `docs://modules/{module}`.\n\n---",
"members": {
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.mcp_utils.Path",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.mcp_utils.click",
- "signature": "",
- "docstring": null
- },
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader",
- "signature": "",
+ "signature": "GriffeLoader()",
"docstring": "Load Python modules using Griffe and convert them into doc-forge models.\n\nThis loader uses the Griffe introspection engine to analyze Python source\ncode and transform the extracted information into `Project`, `Module`,\nand `DocObject` instances used by doc-forge.\n\nAttributes:\n _loader (_GriffeLoader):\n Internal Griffe loader with dedicated module and line collections.",
"members": {
"load_project": {
"name": "load_project",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader.load_project",
- "signature": "",
+ "signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None)",
"docstring": "Load multiple modules and assemble them into a Project model.\n\nEach module path is introspected and converted into a `Module`\ninstance. All modules are then aggregated into a single `Project`\nobject.\n\nArgs:\n module_paths (list[str]):\n List of dotted module import paths to load.\n\n project_name (str | None):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool | None):\n If True, modules that fail to load will be skipped instead of raising an error.\n\nReturns:\n Project:\n A populated `Project` instance containing the loaded modules.\n\nRaises:\n ValueError:\n If no module paths are provided.\n\n ImportError:\n If a module fails to load and `skip_import_errors` is False."
},
"load_module": {
"name": "load_module",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader.load_module",
- "signature": "",
+ "signature": "load_module(path: str)",
"docstring": "Load and convert a single Python module.\n\nThe module is introspected using Griffe and then transformed into\na doc-forge `Module` model.\n\nArgs:\n path (str):\n Dotted import path of the module.\n\nReturns:\n Module:\n A populated `Module` instance.\n\nRaises:\n ImportError:\n If the module cannot be loaded by Griffe.\n\n KeyError:\n If the loaded module is missing from the module collection.\n\nExample:\n Load a single module:\n\n ```python\n loader = GriffeLoader()\n module = loader.load_module(\"mypackage.submodule\")\n ```"
}
}
@@ -307,28 +202,28 @@
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.discover_module_paths",
- "signature": "",
+ "signature": "discover_module_paths(module_name: str, project_root: Path | None = None)",
"docstring": "Discover Python modules within a package directory.\n\nThe function scans the filesystem for `.py` files inside the specified\npackage and converts them into dotted module import paths.\n\nDiscovery rules:\n\n- Directories containing `__init__.py` are treated as packages.\n- Each `.py` file is treated as a module.\n- Results are returned as dotted import paths.\n\nArgs:\n module_name (str):\n Top-level package name to discover modules from.\n\n project_root (Path | None):\n Root directory used to resolve module paths. If not provided, the\n current working directory is used.\n\nReturns:\n list[str]:\n A sorted list of unique dotted module import paths.\n\nRaises:\n FileNotFoundError:\n If the specified package directory does not exist."
},
"MCPRenderer": {
"name": "MCPRenderer",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer",
- "signature": "",
+ "signature": null,
"docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer.name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources",
- "signature": "",
+ "signature": "generate_sources(project: Project, out_dir: Path)",
"docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written."
}
}
@@ -337,28 +232,28 @@
"name": "MCPServer",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.MCPServer",
- "signature": "",
+ "signature": "MCPServer(mcp_root: Path, name: str)",
"docstring": "MCP server for serving a pre-generated documentation bundle.\n\nThe server exposes documentation resources and diagnostic tools through\nMCP endpoints backed by JSON files generated by the MCP renderer.\n\nAttributes:\n mcp_root (Path):\n Directory containing the generated MCP documentation bundle.\n\n app (FastMCP):\n Underlying FastMCP application instance that registers resources\n and tools.",
"members": {
"mcp_root": {
"name": "mcp_root",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPServer.mcp_root",
- "signature": "",
+ "signature": null,
"docstring": null
},
"app": {
"name": "app",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPServer.app",
- "signature": "",
+ "signature": null,
"docstring": null
},
"run": {
"name": "run",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPServer.run",
- "signature": "",
+ "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')",
"docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`."
}
}
@@ -367,14 +262,14 @@
"name": "generate_resources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.generate_resources",
- "signature": "",
+ "signature": "generate_resources(module: str, project_name: str | None, out_dir: Path)",
"docstring": "Generate MCP documentation resources from a Python module.\n\nThe function performs project introspection, builds the internal\ndocumentation model, and renders MCP-compatible JSON resources\nto the specified output directory.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n project_name (str | None):\n Optional override for the project name used in generated\n documentation metadata.\n\n out_dir (Path):\n Directory where MCP resources (index.json, nav.json, and module data)\n will be written."
},
"serve": {
"name": "serve",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.serve",
- "signature": "",
+ "signature": "serve(module: str, mcp_root: Path)",
"docstring": "Start an MCP server for a pre-generated documentation bundle.\n\nThe server exposes documentation resources such as project metadata,\nnavigation structure, and module documentation through MCP endpoints.\n\nArgs:\n module (str):\n Python module import path used to identify the served\n documentation instance.\n\n mcp_root (Path):\n Path to the directory containing the MCP documentation\n bundle (index.json, nav.json, and modules/).\n\nRaises:\n click.ClickException:\n If the MCP documentation bundle is missing required files or directories."
}
}
@@ -383,77 +278,28 @@
"name": "mkdocs_utils",
"kind": "module",
"path": "docforge.cli.commands.mkdocs_utils",
- "signature": "",
+ "signature": null,
"docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.\n\n---\n\nNotes:\n - A separate `mkdocs.{kind}.yml` configuration and build is emitted per\n enabled kind (lib, api, wiki), each scoped to its own `docs_dir` and\n written into its own `site_dir` (`site/lib`, `site/api`, `site/wiki`).\n - Navigation blocks are re-rooted per kind: the wiki navigation drops its\n leading `wiki/` scope and the resolved nav spec drops its `lib/` scope.\n\n---",
"members": {
- "Iterable": {
- "name": "Iterable",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.Iterable",
- "signature": "",
- "docstring": null
- },
- "resources": {
- "name": "resources",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.resources",
- "signature": "",
- "docstring": null
- },
- "Path": {
- "name": "Path",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.Path",
- "signature": "",
- "docstring": null
- },
- "Any": {
- "name": "Any",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.Any",
- "signature": "",
- "docstring": null
- },
- "cast": {
- "name": "cast",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.cast",
- "signature": "",
- "docstring": null
- },
- "click": {
- "name": "click",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.click",
- "signature": "",
- "docstring": null
- },
- "yaml": {
- "name": "yaml",
- "kind": "alias",
- "path": "docforge.cli.commands.mkdocs_utils.yaml",
- "signature": "",
- "docstring": null
- },
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader",
- "signature": "",
+ "signature": "GriffeLoader()",
"docstring": "Load Python modules using Griffe and convert them into doc-forge models.\n\nThis loader uses the Griffe introspection engine to analyze Python source\ncode and transform the extracted information into `Project`, `Module`,\nand `DocObject` instances used by doc-forge.\n\nAttributes:\n _loader (_GriffeLoader):\n Internal Griffe loader with dedicated module and line collections.",
"members": {
"load_project": {
"name": "load_project",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_project",
- "signature": "",
+ "signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None)",
"docstring": "Load multiple modules and assemble them into a Project model.\n\nEach module path is introspected and converted into a `Module`\ninstance. All modules are then aggregated into a single `Project`\nobject.\n\nArgs:\n module_paths (list[str]):\n List of dotted module import paths to load.\n\n project_name (str | None):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool | None):\n If True, modules that fail to load will be skipped instead of raising an error.\n\nReturns:\n Project:\n A populated `Project` instance containing the loaded modules.\n\nRaises:\n ValueError:\n If no module paths are provided.\n\n ImportError:\n If a module fails to load and `skip_import_errors` is False."
},
"load_module": {
"name": "load_module",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_module",
- "signature": "",
+ "signature": "load_module(path: str)",
"docstring": "Load and convert a single Python module.\n\nThe module is introspected using Griffe and then transformed into\na doc-forge `Module` model.\n\nArgs:\n path (str):\n Dotted import path of the module.\n\nReturns:\n Module:\n A populated `Module` instance.\n\nRaises:\n ImportError:\n If the module cannot be loaded by Griffe.\n\n KeyError:\n If the loaded module is missing from the module collection.\n\nExample:\n Load a single module:\n\n ```python\n loader = GriffeLoader()\n module = loader.load_module(\"mypackage.submodule\")\n ```"
}
}
@@ -462,21 +308,21 @@
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.discover_module_paths",
- "signature": "",
+ "signature": "discover_module_paths(module_name: str, project_root: Path | None = None)",
"docstring": "Discover Python modules within a package directory.\n\nThe function scans the filesystem for `.py` files inside the specified\npackage and converts them into dotted module import paths.\n\nDiscovery rules:\n\n- Directories containing `__init__.py` are treated as packages.\n- Each `.py` file is treated as a module.\n- Results are returned as dotted import paths.\n\nArgs:\n module_name (str):\n Top-level package name to discover modules from.\n\n project_root (Path | None):\n Root directory used to resolve module paths. If not provided, the\n current working directory is used.\n\nReturns:\n list[str]:\n A sorted list of unique dotted module import paths.\n\nRaises:\n FileNotFoundError:\n If the specified package directory does not exist."
},
"MkDocsNavEmitter": {
"name": "MkDocsNavEmitter",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter",
- "signature": "",
+ "signature": null,
"docstring": "Emit MkDocs navigation structures from resolved navigation data.\n\nThe emitter transforms a ``ResolvedNav`` object into the YAML-compatible\nlist structure expected by the MkDocs ``nav`` configuration field.",
"members": {
"emit": {
"name": "emit",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter.emit",
- "signature": "",
+ "signature": "emit(nav: ResolvedNav)",
"docstring": "Generate a navigation structure for ``mkdocs.yml``.\n\nArgs:\n nav (ResolvedNav):\n Resolved navigation data describing documentation groups\n and their associated Markdown files.\n\nReturns:\n list[dict[str, Any]]:\n A list of dictionaries representing the MkDocs navigation layout.\n Each dictionary maps a navigation label to a page or a list of\n pages."
}
}
@@ -485,49 +331,49 @@
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_wiki_nav",
- "signature": "",
+ "signature": "build_wiki_nav(wiki_dir: Path)",
"docstring": "Derive an MkDocs navigation block from a wiki directory.\n\nReturned paths are relative to the parent of ``wiki_dir`` and carry the\nwiki directory name as their leading component (for example\n``wiki/01_overview.md`` when the wiki lives at ``docs/wiki``). This makes\nthe result directly usable in an MkDocs ``nav`` block with\n\n- ``index.md`` at the wiki root becomes the ``Home`` entry.\n- Page labels are derived from filenames: numeric order prefixes such as\n ``01_`` or ``02-`` are stripped, separators are replaced with spaces, and\n names are title-cased (``01_overview.md`` becomes ``Overview``).\n- Subdirectories become nested navigation groups. A nested ``index.md`` is\n rendered as the section root placed first inside the group.\n- Only ``.md`` files are considered; hidden entries are ignored.\n\nArgs:\n wiki_dir (Path):\n Path to the hand-written wiki directory, for example ``docs/wiki``.\n\nReturns:\n list[dict[str, Any]]:\n Navigation entries compatible with the MkDocs ``nav`` configuration.\n The list is empty if the wiki contains no Markdown files.\n\nRaises:\n FileNotFoundError:\n If the wiki directory does not exist."
},
"load_nav_spec": {
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.load_nav_spec",
- "signature": "",
+ "signature": "load_nav_spec(path: Path)",
"docstring": "Load a navigation specification file.\n\nThis helper function reads a YAML navigation file and constructs a\ncorresponding ``NavSpec`` instance.\n\nArgs:\n path (Path):\n Path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed specification.\n\nRaises:\n FileNotFoundError: If the specification file does not exist.\n ValueError: If the YAML structure is invalid."
},
"resolve_nav": {
"name": "resolve_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.resolve_nav",
- "signature": "",
+ "signature": "resolve_nav(spec: NavSpec, docs_root: Path)",
"docstring": "Resolve a navigation specification against the filesystem.\n\nThe function expands glob patterns defined in a ``NavSpec`` and verifies\nthat referenced documentation files exist within the documentation root.\n\nArgs:\n spec (NavSpec):\n Navigation specification describing documentation layout.\n docs_root (Path):\n Root directory containing documentation Markdown files.\n\nReturns:\n ResolvedNav:\n A `ResolvedNav` instance containing validated navigation paths.\n\nRaises:\n FileNotFoundError: If the documentation root does not exist or a\n navigation pattern does not match any files."
},
"MkDocsRenderer": {
"name": "MkDocsRenderer",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer",
- "signature": "",
+ "signature": null,
"docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.name",
- "signature": "",
+ "signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources",
- "signature": "",
+ "signature": "generate_sources(project: Project, out_dir: Path, module_is_source: bool | None = None)",
"docstring": "Generate Markdown documentation files for a project.\n\nThis method renders a documentation structure from the provided\nproject model and writes the resulting Markdown files to the\nspecified output directory.\n\nArgs:\n project (Project):\n Project model containing modules to document.\n\n out_dir (Path):\n Directory where generated Markdown files will be written.\n\n module_is_source (bool | None):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder."
},
"generate_readme": {
"name": "generate_readme",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_readme",
- "signature": "",
+ "signature": "generate_readme(project: Project, docs_dir: Path, module_is_source: bool | None = None, readme_dir: Path | None = None)",
"docstring": "Generate a `README.md` file from the root module docstring.\n\nNotes:\n - If `module_is_source` is True, `README.md` is written to the\n project root directory.\n - If False, README generation is currently not implemented.\n\nArgs:\n project (Project):\n Project model containing documentation metadata.\n\n docs_dir (Path):\n Directory containing generated documentation sources.\n\n module_is_source (bool | None):\n Whether the module is treated as the project source root.\n\n readme_dir (Path | None):\n Directory where the generated README.md should be written.\n Defaults to the parent of `docs_dir`."
}
}
@@ -536,49 +382,49 @@
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.generate_sources",
- "signature": "",
+ "signature": "generate_sources(module: str, docs_dir: Path, project_name: str | None = None, module_is_source: bool | None = None, readme_dir: Path | None = None)",
"docstring": "Generate MkDocs Markdown sources for a Python module.\n\nThis function introspects the specified module, builds the internal\ndocumentation model, and renders Markdown documentation files for\nuse with MkDocs.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n docs_dir (Path):\n Directory where the generated Markdown files will be written.\n\n project_name (str | None):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (bool | None):\n If True, treat the specified module directory as the project root\n rather than a nested module.\n\n readme_dir (Path | None):\n Directory where the generated README.md should be written. If not\n provided, defaults to the parent of ``docs_dir``."
},
"build_lib_nav": {
"name": "build_lib_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_lib_nav",
- "signature": "",
+ "signature": "build_lib_nav(nav_file: Path, docs_root: Path)",
"docstring": "Build the re-rooted navigation block for a lib site.\n\nThe navigation specification is resolved against the shared documentation\nroot and every resulting path is re-rooted relative to the ``lib``\nsubdirectory by stripping its leading ``lib/`` scope component.\n\nArgs:\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n docs_root (Path):\n Shared documentation root containing the ``lib`` sources.\n\nReturns:\n tuple[list[dict[str, Any]], dict[str, str] | None]:\n The re-rooted navigation block and the optional theme icon\n mapping from the specification.\n\nRaises:\n click.FileError:\n If the navigation specification cannot be found."
},
"build_wiki_nav_block": {
"name": "build_wiki_nav_block",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_wiki_nav_block",
- "signature": "",
+ "signature": "build_wiki_nav_block(wiki_dir: Path)",
"docstring": "Build the re-rooted navigation block for a wiki site.\n\nThe wiki navigation derived from the wiki file structure is re-rooted\nrelative to the wiki directory itself by stripping the leading ``wiki/``\nscope component.\n\nArgs:\n wiki_dir (Path):\n Path to the hand-written wiki directory, for example ``docs/wiki``.\n\nReturns:\n list[dict[str, Any]]:\n Navigation entries relative to the wiki directory.\n\nRaises:\n click.FileError:\n If the wiki directory does not exist."
},
"load_spec_icon": {
"name": "load_spec_icon",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.load_spec_icon",
- "signature": "",
+ "signature": "load_spec_icon(nav_file: Path)",
"docstring": "Load the theme icon mapping from a navigation specification.\n\nArgs:\n nav_file (Path):\n Path to the navigation specification file.\n\nReturns:\n dict[str, str] | None:\n The icon mapping, or ``None`` when the specification file is\n absent or cannot be parsed."
},
"generate_site_config": {
"name": "generate_site_config",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.generate_site_config",
- "signature": "",
+ "signature": "generate_site_config(kind: str, kind_root: Path, nav_block: list[dict[str, Any]], out: Path, site_name: str, docs_dir: str, site_dir: str, template: Path | None = None, site_description: str | None = None, site_author: str | None = None, theme_icon: dict[str, str] | None = None)",
"docstring": "Generate a per-kind `mkdocs.{kind}.yml` configuration file.\n\nThe configuration is created by merging the shared ``mkdocs.common.yml``\ntemplate with the fragment contributed by the kind (``lib``, ``api``, or\n``wiki``). Both ``docs_dir`` and ``site_dir`` are written relative to the\nconfiguration file's directory: the kind's sources when expressed as a\nsibling path (for example ``lib``) and the per-kind site output (for\nexample ``../site/lib``).\n\nArgs:\n kind (str):\n Documentation kind, one of ``lib``, ``api``, or ``wiki``.\n\n kind_root (Path):\n Directory scoped to the kind (for example ``docs/lib``) that\n serves as the MkDocs ``docs_dir``.\n\n nav_block (list[dict[str, Any]]):\n Re-rooted navigation entries for the kind's site.\n\n out (Path):\n Destination path where the generated ``mkdocs.{kind}.yml`` file\n is written.\n\n site_name (str):\n Display name for the generated documentation site.\n\n docs_dir (str):\n MkDocs ``docs_dir`` value, relative to the configuration\n file's directory.\n\n site_dir (str):\n MkDocs ``site_dir`` value, relative to the configuration\n file's directory.\n\n template (Path | None):\n Optional path to a fully custom MkDocs configuration template\n that replaces the built-in templates entirely.\n\n site_description (str | None):\n Optional site description written into the configuration.\n\n site_author (str | None):\n Optional site author written into the configuration.\n\n theme_icon (dict[str, str] | None):\n Optional mapping of theme icon entries injected as\n ``theme.icon``."
},
"build_configs": {
"name": "build_configs",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_configs",
- "signature": "",
+ "signature": "build_configs(yml_paths: Iterable[Path])",
"docstring": "Build the MkDocs documentation site for every given configuration.\n\nEach configuration file is loaded and built in turn, producing the\nper-kind static sites (``site/lib``, ``site/api``, ``site/wiki``).\n\nArgs:\n yml_paths (Iterable[Path]):\n Configuration files to build, in order.\n\nRaises:\n click.ClickException:\n If a configuration file does not exist."
},
"serve": {
"name": "serve",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.serve",
- "signature": "