6 Commits
0.0.6 ... 0.0.7

Author SHA1 Message Date
c9e6945c26 fix(packaging): make mcp an optional backend and install doc backends in dev
All checks were successful
continuous-integration/drone/tag Build is passing
Defer the mcp import in MCPServer.__init__ so 'import docforge' no longer requires the optional mcp dependency (matching the lazy MkDocs import). Add doc-forge[mkdocs,mcp] to the dev extra so the standard quality gate installs the backends the test suite needs.
2026-10-17 04:53:37 +05:30
85243c418d fix(drone): use AUTH_URL and private index in quality gate
Some checks failed
continuous-integration/drone/tag Build is failing
2026-10-17 04:24:26 +05:30
06ffd2febd chore(release): 0.0.7
Squash-merge lib-standardisation: adopt repo standards across packaging,
tooling, docs, and CI.

- standardize pyproject.toml (canonical packaging, lint config, extras, GSDFC pydoclint)
- add py.typed marker, modernize type hints and Google-style docstrings
- nest generated docs under docs/lib and docs/mcp; add hand-written wiki
- adopt standard Type A PyPI CI pipeline (tag==version guard + quality gate)
- promote generated CHANGELOG.md; bump version to 0.0.7
2026-10-17 02:16:44 +05:30
8253c25928 updated docs strings and added README.md 2026-03-08 17:59:55 +05:30
e8e16f3996 code blocks with backticks for more control on formatting 2026-03-08 15:32:46 +05:30
f73282b997 formatting for examples and header sections 2026-03-08 15:05:38 +05:30
165 changed files with 11078 additions and 8278 deletions

View File

@@ -23,20 +23,50 @@ steps:
commands:
- PACKAGE_NAME=$(grep -E '^name\s*=' pyproject.toml | head -1 | cut -d'"' -f2)
- VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | cut -d'"' -f2)
- echo "🔍 Checking if $PACKAGE_NAME==$VERSION exists on $PIP_REPO_URL ..."
- |
if curl -fsSL -u "$PIP_USERNAME:$PIP_PASSWORD" "$PIP_REPO_URL/simple/$PACKAGE_NAME/" | grep -q "$VERSION"; then
echo "✅ $PACKAGE_NAME==$VERSION already exists — skipping build."
if [ "$DRONE_TAG" != "$VERSION" ]; then
echo "Tag '$DRONE_TAG' does not match pyproject version '$VERSION'; refusing to publish."
exit 1
fi
- echo "Checking if $PACKAGE_NAME==$VERSION exists on $PIP_REPO_URL ..."
- |
if curl -fsSL -u "$PIP_USERNAME:$PIP_PASSWORD" "$PIP_REPO_URL/simple/$PACKAGE_NAME/" | grep -qE "${PACKAGE_NAME}-${VERSION}(-|\.tar\.gz|\.whl)"; then
echo "$PACKAGE_NAME==$VERSION already exists; skipping build."
exit 78
else
echo "🆕 New version detected: $PACKAGE_NAME==$VERSION"
echo "New version detected: $PACKAGE_NAME==$VERSION"
fi
- name: quality-gate
image: python:3.13-slim
environment:
PIP_REPO_URL:
from_secret: PIP_REPO_URL
PIP_USERNAME:
from_secret: PIP_USERNAME
PIP_PASSWORD:
from_secret: PIP_PASSWORD
commands:
- pip install --upgrade pip build
- |
if [ -z "$PIP_REPO_URL" ] || [ -z "$PIP_USERNAME" ] || [ -z "$PIP_PASSWORD" ]; then
echo "PIP_REPO_URL / PIP_USERNAME / PIP_PASSWORD are not set" >&2
exit 1
fi
- AUTH_URL="https://$PIP_USERNAME:$PIP_PASSWORD@$(echo "$PIP_REPO_URL" | sed -E 's|^[a-zA-Z]+://||; s|/*$||')/simple"
- pip install --index-url "$AUTH_URL" --extra-index-url https://pypi.org/simple/ -U ".[dev]" "pydoclint>=0.9.1"
- echo "Running quality gate..."
- python -m black --check .
- python -m ruff check .
- python -m mypy
- pydoclint .
- python -m pytest
- name: build-package
image: python:3.13-slim
commands:
- pip install --upgrade pip build
- echo "📦 Building Python package..."
- echo "Building Python package..."
- python -m build
- ls -l dist
@@ -51,7 +81,7 @@ steps:
from_secret: PIP_PASSWORD
commands:
- pip install --upgrade twine
- echo "🚀 Uploading to private PyPI at $PIP_REPO_URL ..."
- echo "Uploading to private PyPI at $PIP_REPO_URL ..."
- |
twine upload \
--repository-url "$PIP_REPO_URL" \
@@ -98,25 +128,31 @@ steps:
set -e
PACKAGE_NAME=$(grep -E '^name\s*=' pyproject.toml | cut -d'"' -f2)
echo "📦 Package: $PACKAGE_NAME"
echo "Package: $PACKAGE_NAME"
for TAG in $(git tag --sort=version:refname); do
VERSION="$TAG"
echo "🔁 Version: $VERSION"
echo "Version: $VERSION"
if curl -fsSL -u "$PIP_USERNAME:$PIP_PASSWORD" \
"$PIP_REPO_URL/simple/$PACKAGE_NAME/" | grep -q "$VERSION"; then
echo "⏭️ Exists, skipping"
"$PIP_REPO_URL/simple/$PACKAGE_NAME/" | grep -qE "${PACKAGE_NAME}-${VERSION}(-|\.tar\.gz|\.whl)"; then
echo "Exists, skipping"
continue
fi
git checkout --force "$TAG"
echo "🏗️ Building $VERSION"
TAG_VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | cut -d'"' -f2)
if [ "$TAG" != "$TAG_VERSION" ]; then
echo "Tag $TAG != pyproject version $TAG_VERSION at that commit; skipping"
continue
fi
echo "Building $VERSION"
rm -rf dist
python -m build
echo "⬆️ Uploading $VERSION"
echo "Uploading $VERSION"
twine upload \
--repository-url "$PIP_REPO_URL" \
-u "$PIP_USERNAME" \

6
.gitignore vendored
View File

@@ -53,6 +53,7 @@ test-results/
site/
docs/_site/
docs/build/
mkdocs.yml
# =========================
# MkDocs / Sphinx output
@@ -87,3 +88,8 @@ Thumbs.db
# =========================
.env
.env.*
# =========================
# Testing artifacts
# =========================
coverage.xml

47
CHANGELOG.md Normal file
View File

@@ -0,0 +1,47 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.0.7] - 2026-10-17
### Added
- `py.typed` marker for PEP 561 type information.
- `build --refresh` flag to rebaseline an existing `docs/mkdocs.{kind}.yml`
from the packaged templates.
- `wiki` build kind with navigation derived from the source file structure.
- `--api` build mode rendering an OpenAPI reference under `docs/api` with
lib-prefixed navigation.
- Hand-written wiki, plus doc-forge-generated API reference under `docs/lib`
and MCP bundle under `docs/mcp` (per-kind MkDocs configs).
- MIT `LICENSE`.
### Changed
- Adopted the standard Type A PyPI CI pipeline: a `tag == version` guard and a
quality gate (black, ruff, mypy, pydoclint, pytest).
- Standardized `pyproject.toml` (canonical packaging, lint tool config, extras).
- Pinned the `mcp` extra to `mcp>=1.0.0,<2.0.0` to restore compatibility with
the current MCP server API used by doc-forge.
- Per-kind MkDocs configs (`docs/mkdocs.{lib,api,wiki}.yml`) are generated only
when absent; an existing config is used verbatim (the file wins). Pass
`--refresh` to regenerate it from the templates.
- The wiki template now uses the mongo-ops look: horizontal `navigation.tabs`
header, blue grey/teal palette, Roboto font, and additional material feature
flags. The lib and api templates are unchanged.
- Docstrings and wiki brought to the GSDFC (Google-style) standard.
- The `dev` extra now includes the `mkdocs` and `mcp` extras so the
quality-gate environment can install and run the full test suite.
### Fixed
- Loader-generated signatures render cleanly and unresolvable aliases are
dropped from generated models.
- Stub fixes for typed API surfaces.
- `import docforge` no longer requires the optional `mcp` dependency; the
MCP server imports `mcp` lazily, matching the MkDocs backend.
[Unreleased]: https://git.aetoskia.com/aetos/doc-forge/compare/0.0.7...HEAD
[0.0.7]: https://git.aetoskia.com/aetos/doc-forge/compare/0.0.6...0.0.7

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Aetoskia Platform
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

570
README.md
View File

@@ -1,5 +1,7 @@
# docforge
# Summary
Renderer-agnostic Python documentation compiler that converts Python docstrings
into structured documentation for both humans (MkDocs) and machines (MCP / AI agents).
@@ -9,137 +11,136 @@ outputs without executing user code.
---
## Installation
# Installation
Install using pip:
pip install doc-forge
```bash
pip install doc-forge
```
---
## Quick start
# CLI usage
Generate a MkDocs site from a Python package:
Each site kind (`lib`, `api`, `wiki`) is built independently into `site/{kind}`.
doc-forge build --mkdocs --module my_package
## Build the library reference from a Python package:
Generate MCP JSON documentation:
```bash
doc-forge build --mkdocs --module my_package
```
doc-forge build --mcp --module my_package
## Build the API reference from an OpenAPI spec:
Serve documentation locally:
```bash
doc-forge build --api --openapi-spec spec.json
```
doc-forge serve --mkdocs --module my_package
## Build the hand-written wiki:
```bash
doc-forge build --wiki --site-name my_package
```
## Generate MCP JSON documentation:
```bash
doc-forge build --mcp --module my_package
```
## Build several kinds in one pass:
```bash
doc-forge build --mcp --mkdocs --wiki --module my_package
```
Each enabled kind gets its own MkDocs config (`docs/mkdocs.{lib,api,wiki}.yml`)
and its own site under `site/`.
## Serve a site locally:
```bash
doc-forge serve --wiki # preview from docs/mkdocs.wiki.yml
doc-forge serve --lib
doc-forge serve --api
# or any config directly:
doc-forge serve --mkdocs --mkdocs-yml docs/mkdocs.wiki.yml
```
## Serve MCP locally:
```bash
doc-forge serve --mcp --module my_package
```
---
## Core concepts
**Loader**
# Core concepts
## Loader
Extracts symbols, signatures, and docstrings using static analysis.
**Semantic model**
## Semantic model
Structured, renderer-agnostic representation of the API.
**Renderer**
## Renderer
Converts the semantic model into output formats such as MkDocs or MCP JSON.
**Symbol**
## Symbol
Any documentable object
Any documentable object:
- module
- class
- function
- method
- property
- attribute
- module
- class
- function
- method
- property
- attribute
---
## Architecture
# Architecture
`doc-forge` follows a compiler architecture:
Front-end:
## Front-end:
Static analysis of modules, classes, functions, type hints, and docstrings.
Static analysis of modules, classes, functions, type hints, and docstrings.
Middle-end:
## Middle-end:
Builds a semantic model describing symbols and relationships.
Builds a semantic model describing symbols and relationships.
Back-end:
## Back-end:
Renders documentation using interchangeable renderers.
Renders documentation using interchangeable renderers.
This architecture ensures deterministic documentation generation.
---
## Rendering pipeline
# Rendering pipeline
Typical flow:
Python package
↓
|
Loader (static analysis)
↓
|
Semantic model
↓
|
Renderer
↓
|
MkDocs site or MCP JSON
---
## CLI usage
Build MkDocs documentation:
doc-forge build --mkdocs --module my_package
Build MCP documentation:
doc-forge build --mcp --module my_package
Serve MkDocs locally:
doc-forge serve --module my_package
---
## Public API
Loaders:
GriffeLoader
discover_module_paths
Renderers:
MkDocsRenderer
MCPRenderer
CLI:
main
Models:
models
---
# Google-Styled Doc-Forge Convention (GSDFC)
GSDFC defines how docstrings must be written so they render correctly in MkDocs and remain machine-parsable by doc-forge and AI tooling.
- Docstrings are the single source of truth.
- doc-forge compiles docstrings but does not generate documentation content.
- `doc-forge` compiles docstrings but does not generate documentation content.
- Documentation follows the Python import hierarchy.
- Every public symbol should have a complete and accurate docstring.
@@ -149,34 +150,115 @@ GSDFC defines how docstrings must be written so they render correctly in MkDocs
- Use **Markdown headings** at package and module level.
- Use **Google-style structured sections** at class, function, and method level.
- Indent section contents using four spaces.
- Use type hints in signatures instead of duplicating types in prose.
- Use type hints in signatures.
- Use parenthesized types in prose entries (`name (Type):`) that match the
signature types. This keeps docstrings self-contained and machine-parseable.
- Write summaries in imperative form.
- Sections are separated by ```---```
- Sections are separated by `---`
---
## Package docstrings
# Notes subsection grouping
- Package docstrings act as the documentation home page.
Group related information using labeled subsections.
Example:
Notes:
**Guarantees:**
- deterministic behavior
**Lifecycle:**
- created during initialization
- reused across executions
**Thread safety:**
- safe for concurrent reads
---
# Example formatting
- Use indentation for examples.
- Indent section contents using four spaces.
- Use code blocks for example code.
Example:
Single example:
Example:
```python
foo = Foo("example")
process(foo, multiplier=2)
```
Multiple examples:
Example:
Create foo:
```python
foo = Foo("example")
```
Run engine:
```python
engine = BarEngine([foo])
engine.run()
```
Avoid fenced code blocks inside argument descriptions and other prose lines.
Inside `Example:` sections, fenced `python` code blocks are allowed and must be
indented four spaces, matching the examples below.
---
# Separator rules
Use horizontal separators only at docstring root level to separate sections:
```markdown
---
```
Allowed locations:
- package docstrings
- module docstrings
- major documentation sections
Do not use separators inside code sections.
---
# Package docstrings
Package docstrings act as the documentation home page.
Recommended sections:
## Summary
## Installation
## Quick start
## Core concepts
## Architecture
## Rendering pipeline
## CLI usage
## Public API
## Examples
## Notes
# Summary
# Installation
# Quick start
# CLI usage
# Core concepts
# Architecture
# Rendering pipeline
# Examples
# Notes
Example:
Package Doc String:
'''
# Summary
Foo-bar processing framework.
Provides tools for defining Foo objects and executing Bar pipelines.
@@ -185,47 +267,44 @@ Example:
# Installation
pip install foo-bar
```bash
pip install foo-bar
```
---
# Quick start
from foobar import Foo, BarEngine
```python
from foobar import Foo, BarEngine
foo = Foo("example")
engine = BarEngine([foo])
foo = Foo("example")
engine = BarEngine([foo])
result = engine.run()
---
# Public API
Foo
Bar
BarEngine
result = engine.run()
```
---
'''
---
## Module docstrings
# Module docstrings
- Module docstrings describe a subsystem.
Module docstrings describe a subsystem.
Recommended sections:
## Summary
## Examples
## Notes
## Public API
# Summary
# Examples
# Notes
Example:
Module Doc String:
'''
# Summary
Foo execution subsystem.
Provides utilities for executing Foo objects through Bar stages.
@@ -234,6 +313,7 @@ Example:
Example:
```python
from foobar.engine import BarEngine
from foobar.foo import Foo
@@ -241,15 +321,16 @@ Example:
engine = BarEngine([foo])
engine.run()
```
---
'''
---
## Class docstrings
# Class docstrings
- Class docstrings define object responsibility, lifecycle, and attributes.
Class docstrings define object responsibility, lifecycle, and attributes.
Recommended sections:
@@ -261,64 +342,72 @@ Recommended sections:
Example:
Simple Foo:
class Foo:
'''
Represents a unit of work.
```python
class Foo:
'''
Represents a unit of work.
Attributes:
name (str):
Identifier of the foo instance.
Attributes:
name (str):
Identifier of the foo instance.
value (int):
Numeric value associated with foo.
value (int):
Numeric value associated with foo.
Notes:
Guarantees:
Notes:
Guarantees:
- instances are immutable after creation
- instances are immutable after creation
Lifecycle:
Lifecycle:
- create instance
- pass to processing engine
- create instance
- pass to processing engine
Example:
Create and inspect a Foo:
Example:
Create and inspect a Foo:
foo = Foo("example", value=42)
print(foo.name)
'''
```python
foo = Foo("example", value=42)
print(foo.name)
```
'''
```
Complex Bar:
class BarEngine:
'''
Executes Foo objects through Bar stages.
```python
class BarEngine:
'''
Executes Foo objects through Bar stages.
Attributes:
foos (tuple[Foo, ...]):
Foo instances managed by the engine.
Attributes:
foos (tuple[Foo, ...]):
Foo instances managed by the engine.
Notes:
Guarantees:
Notes:
Guarantees:
- deterministic execution order
- deterministic execution order
Example:
Run engine:
Example:
Run engine:
foo1 = Foo("a")
foo2 = Foo("b")
```python
foo1 = Foo("a")
foo2 = Foo("b")
engine = BarEngine([foo1, foo2])
engine.run()
'''
engine = BarEngine([foo1, foo2])
engine.run()
```
'''
```
---
## Function and method docstrings
# Function and method docstrings
- Function docstrings define API contracts.
Function docstrings define API contracts.
Recommended sections:
@@ -332,79 +421,90 @@ Recommended sections:
Example:
Simple process method:
def process(foo: Foo, multiplier: int) -> int:
'''
Process a Foo instance.
```python
def process(foo: Foo, multiplier: int) -> int:
'''
Process a Foo instance.
Args:
foo (Foo):
Foo instance to process.
Args:
foo (Foo):
Foo instance to process.
multiplier (int):
Value used to scale foo.
multiplier (int):
Value used to scale foo.
Returns:
int:
Processed result.
Returns:
int:
Processed result.
Raises:
ValueError:
If multiplier is negative.
Raises:
ValueError:
If multiplier is negative.
Notes:
Guarantees:
Notes:
Guarantees:
- foo is not modified
- foo is not modified
Example:
Process foo:
Example:
Process foo:
foo = Foo("example", value=10)
```python
foo = Foo("example", value=10)
result = process(foo, multiplier=2)
print(result)
'''
result = process(foo, multiplier=2)
print(result)
```
'''
```
Multiple Examples:
def combine(foo_a: Foo, foo_b: Foo) -> Foo:
'''
Combine two Foo instances.
```python
def combine(foo_a: Foo, foo_b: Foo) -> Foo:
'''
Combine two Foo instances.
Args:
foo_a (Foo):
First foo.
Args:
foo_a (Foo):
First foo.
foo_b (Foo):
Second foo.
foo_b (Foo):
Second foo.
Returns:
Foo:
Combined foo.
Returns:
Foo:
Combined foo.
Example:
Basic usage:
Example:
Basic usage:
foo1 = Foo("a")
foo2 = Foo("b")
```python
foo1 = Foo("a")
foo2 = Foo("b")
combined = combine(foo1, foo2)
combined = combine(foo1, foo2)
```
Pipeline usage:
Pipeline usage:
engine = BarEngine([foo1, foo2])
engine.run()
'''
```python
engine = BarEngine([foo1, foo2])
engine.run()
```
'''
```
---
## Property docstrings
# Property docstrings
- Properties must document return values.
Properties must document return values.
Example:
Property Doc String:
```python
@property
def foos(self) -> tuple[Foo, ...]:
'''
@@ -415,20 +515,24 @@ Example:
Stored foo objects.
Example:
```python
container = FooContainer()
foos = container.foos
```
'''
```
---
## Attribute documentation
# Attribute documentation
- Document attributes in class docstrings using Attributes:.
Document attributes in class docstrings using `Attributes:`.
Example:
Attribute Doc String:
```python
'''
Represents a processing stage.
@@ -439,77 +543,25 @@ Example:
enabled (bool):
Whether the stage is active.
'''
```
---
## Notes subsection grouping
# Type parity (`.pyi` stubs and `py.typed`)
- Group related information using labeled subsections.
Documented APIs ship matching type information:
Example:
Notes Example:
Notes:
**Guarantees:**
- deterministic behavior
**Lifecycle:**
- created during initialization
- reused across executions
**Thread safety:**
- safe for concurrent reads
- 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.
---
## Example formatting
- Use indentation for examples.
Example:
Single example:
Example:
foo = Foo("example")
process(foo, multiplier=2)
Multiple examples:
Example:
Create foo:
foo = Foo("example")
Run engine:
engine = BarEngine([foo])
engine.run()
Avoid fenced code blocks inside structured sections.
---
## Separator rules
Use horizontal separators only at docstring root level to separate sections:
---
Allowed locations:
- package docstrings
- module docstrings
- major documentation sections
Do not use separators inside code sections.
---
## Parsing guarantees
# Parsing guarantees
GSDFC ensures doc-forge can deterministically extract:

View File

@@ -1,26 +1,30 @@
home: index.md
home: lib/index.md
groups:
Loaders:
- loaders/index.md
- loaders/griffe_loader.md
- lib/loaders/index.md
- lib/loaders/griffe_loader.md
Models:
- models/index.md
- models/module.md
- models/object.md
- models/project.md
- lib/models/index.md
- lib/models/module.md
- lib/models/object.md
- lib/models/project.md
Navigation:
- nav/index.md
- nav/spec.md
- nav/resolver.md
- nav/mkdocs.md
- lib/nav/index.md
- lib/nav/spec.md
- lib/nav/resolver.md
- lib/nav/mkdocs.md
Renderers:
- renderers/index.md
- renderers/base.md
- renderers/mkdocs_renderer.md
- renderers/mcp_renderer.md
- lib/renderers/index.md
- lib/renderers/base.md
- lib/renderers/mkdocs_renderer.md
- lib/renderers/mcp_renderer.md
CLI:
- cli/index.md
- cli/main.md
- cli/commands.md
- cli/mcp_utils.md
- cli/mkdocs_utils.md
- lib/cli/index.md
- lib/cli/main.md
- lib/cli/commands.md
- lib/cli/api_utils.md
- lib/cli/mcp_utils.md
- lib/cli/mkdocs_utils.md
icon:
logo: material/file-document-multiple
repo: fontawesome/brands/github

View File

@@ -1,4 +1,6 @@
"""
# Summary
Renderer-agnostic Python documentation compiler that converts Python docstrings
into structured documentation for both humans (MkDocs) and machines (MCP / AI agents).
@@ -8,137 +10,136 @@ outputs without executing user code.
---
## Installation
# Installation
Install using pip:
pip install doc-forge
```bash
pip install doc-forge
```
---
## Quick start
# CLI usage
Generate a MkDocs site from a Python package:
Each site kind (`lib`, `api`, `wiki`) is built independently into `site/{kind}`.
doc-forge build --mkdocs --module my_package
## Build the library reference from a Python package:
Generate MCP JSON documentation:
```bash
doc-forge build --mkdocs --module my_package
```
doc-forge build --mcp --module my_package
## Build the API reference from an OpenAPI spec:
Serve documentation locally:
```bash
doc-forge build --api --openapi-spec spec.json
```
doc-forge serve --mkdocs --module my_package
## Build the hand-written wiki:
```bash
doc-forge build --wiki --site-name my_package
```
## Generate MCP JSON documentation:
```bash
doc-forge build --mcp --module my_package
```
## Build several kinds in one pass:
```bash
doc-forge build --mcp --mkdocs --wiki --module my_package
```
Each enabled kind gets its own MkDocs config (`docs/mkdocs.{lib,api,wiki}.yml`)
and its own site under `site/`.
## Serve a site locally:
```bash
doc-forge serve --wiki # preview from docs/mkdocs.wiki.yml
doc-forge serve --lib
doc-forge serve --api
# or any config directly:
doc-forge serve --mkdocs --mkdocs-yml docs/mkdocs.wiki.yml
```
## Serve MCP locally:
```bash
doc-forge serve --mcp --module my_package
```
---
## Core concepts
**Loader**
# Core concepts
## Loader
Extracts symbols, signatures, and docstrings using static analysis.
**Semantic model**
## Semantic model
Structured, renderer-agnostic representation of the API.
**Renderer**
## Renderer
Converts the semantic model into output formats such as MkDocs or MCP JSON.
**Symbol**
## Symbol
Any documentable object
Any documentable object:
- module
- class
- function
- method
- property
- attribute
- module
- class
- function
- method
- property
- attribute
---
## Architecture
# Architecture
`doc-forge` follows a compiler architecture:
Front-end:
## Front-end:
Static analysis of modules, classes, functions, type hints, and docstrings.
Static analysis of modules, classes, functions, type hints, and docstrings.
Middle-end:
## Middle-end:
Builds a semantic model describing symbols and relationships.
Builds a semantic model describing symbols and relationships.
Back-end:
## Back-end:
Renders documentation using interchangeable renderers.
Renders documentation using interchangeable renderers.
This architecture ensures deterministic documentation generation.
---
## Rendering pipeline
# Rendering pipeline
Typical flow:
Python package
↓
|
Loader (static analysis)
↓
|
Semantic model
↓
|
Renderer
↓
|
MkDocs site or MCP JSON
---
## CLI usage
Build MkDocs documentation:
doc-forge build --mkdocs --module my_package
Build MCP documentation:
doc-forge build --mcp --module my_package
Serve MkDocs locally:
doc-forge serve --module my_package
---
## Public API
Loaders:
GriffeLoader
discover_module_paths
Renderers:
MkDocsRenderer
MCPRenderer
CLI:
main
Models:
models
---
# Google-Styled Doc-Forge Convention (GSDFC)
GSDFC defines how docstrings must be written so they render correctly in MkDocs and remain machine-parsable by doc-forge and AI tooling.
- Docstrings are the single source of truth.
- doc-forge compiles docstrings but does not generate documentation content.
- `doc-forge` compiles docstrings but does not generate documentation content.
- Documentation follows the Python import hierarchy.
- Every public symbol should have a complete and accurate docstring.
@@ -148,34 +149,115 @@ GSDFC defines how docstrings must be written so they render correctly in MkDocs
- Use **Markdown headings** at package and module level.
- Use **Google-style structured sections** at class, function, and method level.
- Indent section contents using four spaces.
- Use type hints in signatures instead of duplicating types in prose.
- Use type hints in signatures.
- Use parenthesized types in prose entries (`name (Type):`) that match the
signature types. This keeps docstrings self-contained and machine-parseable.
- Write summaries in imperative form.
- Sections are separated by ```---```
- Sections are separated by `---`
---
## Package docstrings
# Notes subsection grouping
- Package docstrings act as the documentation home page.
Group related information using labeled subsections.
Example:
Notes:
**Guarantees:**
- deterministic behavior
**Lifecycle:**
- created during initialization
- reused across executions
**Thread safety:**
- safe for concurrent reads
---
# Example formatting
- Use indentation for examples.
- Indent section contents using four spaces.
- Use code blocks for example code.
Example:
Single example:
Example:
```python
foo = Foo("example")
process(foo, multiplier=2)
```
Multiple examples:
Example:
Create foo:
```python
foo = Foo("example")
```
Run engine:
```python
engine = BarEngine([foo])
engine.run()
```
Avoid fenced code blocks inside argument descriptions and other prose lines.
Inside `Example:` sections, fenced `python` code blocks are allowed and must be
indented four spaces, matching the examples below.
---
# Separator rules
Use horizontal separators only at docstring root level to separate sections:
```markdown
---
```
Allowed locations:
- package docstrings
- module docstrings
- major documentation sections
Do not use separators inside code sections.
---
# Package docstrings
Package docstrings act as the documentation home page.
Recommended sections:
## Summary
## Installation
## Quick start
## Core concepts
## Architecture
## Rendering pipeline
## CLI usage
## Public API
## Examples
## Notes
# Summary
# Installation
# Quick start
# CLI usage
# Core concepts
# Architecture
# Rendering pipeline
# Examples
# Notes
Example:
Package Doc String:
'''
# Summary
Foo-bar processing framework.
Provides tools for defining Foo objects and executing Bar pipelines.
@@ -184,47 +266,44 @@ Example:
# Installation
pip install foo-bar
```bash
pip install foo-bar
```
---
# Quick start
from foobar import Foo, BarEngine
```python
from foobar import Foo, BarEngine
foo = Foo("example")
engine = BarEngine([foo])
foo = Foo("example")
engine = BarEngine([foo])
result = engine.run()
---
# Public API
Foo
Bar
BarEngine
result = engine.run()
```
---
'''
---
## Module docstrings
# Module docstrings
- Module docstrings describe a subsystem.
Module docstrings describe a subsystem.
Recommended sections:
## Summary
## Examples
## Notes
## Public API
# Summary
# Examples
# Notes
Example:
Module Doc String:
'''
# Summary
Foo execution subsystem.
Provides utilities for executing Foo objects through Bar stages.
@@ -233,6 +312,7 @@ Example:
Example:
```python
from foobar.engine import BarEngine
from foobar.foo import Foo
@@ -240,15 +320,16 @@ Example:
engine = BarEngine([foo])
engine.run()
```
---
'''
---
## Class docstrings
# Class docstrings
- Class docstrings define object responsibility, lifecycle, and attributes.
Class docstrings define object responsibility, lifecycle, and attributes.
Recommended sections:
@@ -260,64 +341,72 @@ Recommended sections:
Example:
Simple Foo:
class Foo:
'''
Represents a unit of work.
```python
class Foo:
'''
Represents a unit of work.
Attributes:
name (str):
Identifier of the foo instance.
Attributes:
name (str):
Identifier of the foo instance.
value (int):
Numeric value associated with foo.
value (int):
Numeric value associated with foo.
Notes:
Guarantees:
Notes:
Guarantees:
- instances are immutable after creation
- instances are immutable after creation
Lifecycle:
Lifecycle:
- create instance
- pass to processing engine
- create instance
- pass to processing engine
Example:
Create and inspect a Foo:
Example:
Create and inspect a Foo:
foo = Foo("example", value=42)
print(foo.name)
'''
```python
foo = Foo("example", value=42)
print(foo.name)
```
'''
```
Complex Bar:
class BarEngine:
'''
Executes Foo objects through Bar stages.
```python
class BarEngine:
'''
Executes Foo objects through Bar stages.
Attributes:
foos (tuple[Foo, ...]):
Foo instances managed by the engine.
Attributes:
foos (tuple[Foo, ...]):
Foo instances managed by the engine.
Notes:
Guarantees:
Notes:
Guarantees:
- deterministic execution order
- deterministic execution order
Example:
Run engine:
Example:
Run engine:
foo1 = Foo("a")
foo2 = Foo("b")
```python
foo1 = Foo("a")
foo2 = Foo("b")
engine = BarEngine([foo1, foo2])
engine.run()
'''
engine = BarEngine([foo1, foo2])
engine.run()
```
'''
```
---
## Function and method docstrings
# Function and method docstrings
- Function docstrings define API contracts.
Function docstrings define API contracts.
Recommended sections:
@@ -331,79 +420,90 @@ Recommended sections:
Example:
Simple process method:
def process(foo: Foo, multiplier: int) -> int:
'''
Process a Foo instance.
```python
def process(foo: Foo, multiplier: int) -> int:
'''
Process a Foo instance.
Args:
foo (Foo):
Foo instance to process.
Args:
foo (Foo):
Foo instance to process.
multiplier (int):
Value used to scale foo.
multiplier (int):
Value used to scale foo.
Returns:
int:
Processed result.
Returns:
int:
Processed result.
Raises:
ValueError:
If multiplier is negative.
Raises:
ValueError:
If multiplier is negative.
Notes:
Guarantees:
Notes:
Guarantees:
- foo is not modified
- foo is not modified
Example:
Process foo:
Example:
Process foo:
foo = Foo("example", value=10)
```python
foo = Foo("example", value=10)
result = process(foo, multiplier=2)
print(result)
'''
result = process(foo, multiplier=2)
print(result)
```
'''
```
Multiple Examples:
def combine(foo_a: Foo, foo_b: Foo) -> Foo:
'''
Combine two Foo instances.
```python
def combine(foo_a: Foo, foo_b: Foo) -> Foo:
'''
Combine two Foo instances.
Args:
foo_a (Foo):
First foo.
Args:
foo_a (Foo):
First foo.
foo_b (Foo):
Second foo.
foo_b (Foo):
Second foo.
Returns:
Foo:
Combined foo.
Returns:
Foo:
Combined foo.
Example:
Basic usage:
Example:
Basic usage:
foo1 = Foo("a")
foo2 = Foo("b")
```python
foo1 = Foo("a")
foo2 = Foo("b")
combined = combine(foo1, foo2)
combined = combine(foo1, foo2)
```
Pipeline usage:
Pipeline usage:
engine = BarEngine([foo1, foo2])
engine.run()
'''
```python
engine = BarEngine([foo1, foo2])
engine.run()
```
'''
```
---
## Property docstrings
# Property docstrings
- Properties must document return values.
Properties must document return values.
Example:
Property Doc String:
```python
@property
def foos(self) -> tuple[Foo, ...]:
'''
@@ -414,20 +514,24 @@ Example:
Stored foo objects.
Example:
```python
container = FooContainer()
foos = container.foos
```
'''
```
---
## Attribute documentation
# Attribute documentation
- Document attributes in class docstrings using Attributes:.
Document attributes in class docstrings using `Attributes:`.
Example:
Attribute Doc String:
```python
'''
Represents a processing stage.
@@ -438,77 +542,25 @@ Example:
enabled (bool):
Whether the stage is active.
'''
```
---
## Notes subsection grouping
# Type parity (`.pyi` stubs and `py.typed`)
- Group related information using labeled subsections.
Documented APIs ship matching type information:
Example:
Notes Example:
Notes:
**Guarantees:**
- deterministic behavior
**Lifecycle:**
- created during initialization
- reused across executions
**Thread safety:**
- safe for concurrent reads
- 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.
---
## Example formatting
- Use indentation for examples.
Example:
Single example:
Example:
foo = Foo("example")
process(foo, multiplier=2)
Multiple examples:
Example:
Create foo:
foo = Foo("example")
Run engine:
engine = BarEngine([foo])
engine.run()
Avoid fenced code blocks inside structured sections.
---
## Separator rules
Use horizontal separators only at docstring root level to separate sections:
---
Allowed locations:
- package docstrings
- module docstrings
- major documentation sections
Do not use separators inside code sections.
---
## Parsing guarantees
# Parsing guarantees
GSDFC ensures doc-forge can deterministically extract:

View File

@@ -1,7 +1,7 @@
from .loaders import GriffeLoader, discover_module_paths
from .renderers import MkDocsRenderer, MCPRenderer
from .cli import main
from . import models
from .cli import main
from .loaders import GriffeLoader, discover_module_paths
from .renderers import MCPRenderer, MkDocsRenderer
__all__ = [
"GriffeLoader",

View File

@@ -1,9 +1,11 @@
"""
# Summary
Command line interface entry point for doc-forge.
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
`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
@@ -13,23 +15,26 @@ servers.
---
Typical usage
-------------
# Typical usage
The CLI is normally invoked through the installed command:
doc-forge <command> [options]
```bash
doc-forge <command> [options]
```
Programmatic invocation is also possible:
Example:
```python
from docforge.cli import main
main()
```
---
"""
from .main import main
__all__ = [
"main"
]
__all__ = ["main"]

View File

@@ -1,5 +1,3 @@
from .main import main
__all__ = [
"main"
]
__all__ = ["main"]

118
docforge/cli/api_utils.py Normal file
View File

@@ -0,0 +1,118 @@
"""
# Summary
Utilities for building API documentation from an OpenAPI specification.
"""
import json
from dataclasses import dataclass
from pathlib import Path
import click
SWAGGER_SPEC_FILENAME = "openapi.json"
@dataclass
class OpenAPIMetadata:
"""
Metadata derived from the ``info`` block of an OpenAPI specification.
Attributes:
site_name: Spec title, used as the MkDocs site name.
site_description: Spec description, used as the site description.
site_author: Contact name (fallback: contact email), used as the
site author.
"""
site_name: str
site_description: str | None
site_author: str | None
def load_openapi_spec(spec_path: Path) -> dict:
"""
Load and validate an OpenAPI specification from a JSON file.
Args:
spec_path (Path):
Path to the OpenAPI JSON specification file.
Returns:
dict:
The parsed OpenAPI specification.
Raises:
click.ClickException:
If the file cannot be read or the ``info`` block is invalid.
"""
if not spec_path.exists():
raise click.ClickException(f"OpenAPI spec not found: {spec_path}")
try:
data = json.loads(spec_path.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError) as exc:
raise click.ClickException(f"Unable to read OpenAPI spec: {exc}") from exc
if not isinstance(data, dict):
raise click.ClickException("OpenAPI spec must be a JSON mapping")
info = data.get("info")
if not isinstance(info, dict) or not isinstance(info.get("title"), str):
raise click.ClickException("OpenAPI spec missing 'info.title'")
return data
def derive_metadata(spec: dict) -> OpenAPIMetadata:
"""
Derive MkDocs site metadata from an OpenAPI spec ``info`` block.
Args:
spec (dict):
Parsed OpenAPI specification.
Returns:
OpenAPIMetadata:
Site name, description, and author derived from the spec.
"""
info = spec["info"]
contact = info.get("contact")
if isinstance(contact, dict):
author = contact.get("name") or contact.get("email")
else:
author = None
return OpenAPIMetadata(
site_name=info.get("title", ""),
site_description=info.get("description"),
site_author=author,
)
def generate_api_sources(spec: dict, docs_dir: Path) -> None:
"""
Generate swagger-enabled Markdown sources and the spec copy.
The specification is written as ``openapi.json`` inside ``docs_dir`` and
an ``index.md`` embedding the swagger UI is generated alongside it.
Args:
spec (dict):
Parsed OpenAPI specification.
docs_dir (Path):
Directory (for example ``docs/api``) where the swagger
sources are written.
"""
docs_dir.mkdir(parents=True, exist_ok=True)
spec_path = docs_dir / SWAGGER_SPEC_FILENAME
spec_json = json.dumps(spec, indent=2)
if not spec_path.exists() or spec_path.read_text(encoding="utf-8") != spec_json:
spec_path.write_text(spec_json, encoding="utf-8")
index_path = docs_dir / "index.md"
content = "# API Reference\n\n" f'<swagger-ui src="{SWAGGER_SPEC_FILENAME}"/>\n'
if not index_path.exists() or index_path.read_text(encoding="utf-8") != content:
index_path.write_text(content, encoding="utf-8")

View File

@@ -0,0 +1,13 @@
from dataclasses import dataclass
from pathlib import Path
from typing import Any
@dataclass
class OpenAPIMetadata:
site_name: str
site_description: str | None
site_author: str | None
def load_openapi_spec(spec_path: Path) -> dict[Any, Any]: ...
def derive_metadata(spec: dict[Any, Any]) -> OpenAPIMetadata: ...
def generate_api_sources(spec: dict[Any, Any], docs_dir: Path) -> None: ...

View File

@@ -1,9 +1,29 @@
import click
"""
# Summary
Command definitions for the doc-forge CLI.
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.
---
"""
import os
from pathlib import Path
from typing import Sequence, Optional
import click
from docforge.cli import api_utils, mcp_utils, mkdocs_utils
from docforge.loaders import GriffeLoader
from docforge.cli import mkdocs_utils
from docforge.cli import mcp_utils
from docforge.models import DocObject
@click.group()
@@ -19,90 +39,246 @@ def cli() -> None:
@cli.command()
@click.option("--mcp", is_flag=True, help="Build MCP resources")
@click.option("--mkdocs", is_flag=True, help="Build MkDocs site")
@click.option("--module-is-source", is_flag=True, help="Module is source folder and to be treated as root folder")
@click.option("--mkdocs", is_flag=True, help="Build the lib MkDocs site")
@click.option("--api", is_flag=True, help="Build API docs from an OpenAPI spec")
@click.option(
"--wiki", is_flag=True, help="Build a hand-written wiki as its own MkDocs site"
)
@click.option(
"--refresh",
is_flag=True,
help="Regenerate existing docs/mkdocs.{kind}.yml configs from templates",
)
@click.option(
"--module-is-source",
is_flag=True,
help="Module is source folder and to be treated as root folder",
)
@click.option("--module", help="Python module to document")
@click.option(
"--openapi-spec",
type=click.Path(path_type=Path),
help="Path to the OpenAPI JSON specification",
)
@click.option("--project-name", help="Project name override")
@click.option("--site-name", help="MkDocs site name")
@click.option("--docs-dir", type=click.Path(path_type=Path), default=Path("docs"), help="Directory for MD sources")
@click.option("--nav", "nav_file", type=click.Path(path_type=Path), default=Path("docforge.nav.yml"),
help="Nav spec path")
@click.option("--template", type=click.Path(path_type=Path), help="MkDocs template path")
@click.option("--mkdocs-yml", type=click.Path(path_type=Path), default=Path("mkdocs.yml"), help="Output config path")
@click.option("--out-dir", type=click.Path(path_type=Path), default=Path("mcp_docs"), help="MCP output directory")
@click.option("--site-name", help="MkDocs site name for lib and wiki sites")
@click.option(
"--docs-dir",
type=click.Path(path_type=Path),
default=Path("docs"),
help="MkDocs documentation root",
)
@click.option(
"--wiki-dir",
type=click.Path(path_type=Path),
default=Path("docs/wiki"),
help="Hand-written wiki directory built as its own MkDocs site",
)
@click.option(
"--nav",
"nav_file",
type=click.Path(path_type=Path),
default=Path("docforge.nav.yml"),
help="Nav spec path",
)
@click.option(
"--template", type=click.Path(path_type=Path), help="MkDocs template path"
)
@click.option(
"--out-dir",
type=click.Path(path_type=Path),
default=Path("docs/mcp"),
help="MCP output directory",
)
def build(
mcp: bool,
mkdocs: bool,
api: bool,
wiki: bool,
refresh: bool,
module_is_source: bool,
module: Optional[str],
project_name: Optional[str],
site_name: Optional[str],
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: Optional[Path],
mkdocs_yml: Path,
template: Path | None,
out_dir: Path,
) -> None:
"""
Build documentation artifacts.
This command performs the full documentation build pipeline:
1. Introspects the Python project using Griffe
2. Generates renderer-specific documentation sources
3. Optionally builds the final documentation output
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:
- MkDocs static documentation sites
- MCP structured documentation resources
- 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.
Args:
mcp: Enable MCP documentation generation.
mkdocs: Enable MkDocs documentation generation.
module_is_source: Treat the specified module directory as the
project root.
module: Python module import path to document.
project_name: Optional override for the project name.
site_name: Display name for the MkDocs site.
docs_dir: Directory where Markdown documentation sources
will be generated.
nav_file: Path to the navigation specification file.
template: Optional custom MkDocs configuration template.
mkdocs_yml: Output path for the generated MkDocs configuration.
out_dir: Output directory for generated MCP resources.
mcp (bool):
Enable MCP documentation generation.
mkdocs (bool):
Enable the lib MkDocs documentation generation.
api (bool):
Enable API documentation generation from an OpenAPI spec.
wiki (bool):
Build a hand-written wiki directory as its own MkDocs site.
refresh (bool):
Regenerate ``docs/mkdocs.{kind}.yml`` from templates even when
it already exists. By default, existing configs are used as-is.
module_is_source (bool):
Treat the specified module directory as the project root.
module (str | None):
Python module import path to document.
openapi_spec (Path | None):
Path to the OpenAPI JSON specification used for API docs.
project_name (str | None):
Optional override for the project name.
site_name (str | None):
Display name for the lib and wiki MkDocs sites.
docs_dir (Path):
Shared documentation root used for generated sources.
wiki_dir (Path):
Directory containing hand-written wiki markdown files.
nav_file (Path):
Path to the navigation specification file.
template (Path | None):
Optional custom MkDocs configuration template.
out_dir (Path):
Output directory for generated MCP resources.
Raises:
click.UsageError: If required options are missing or conflicting.
click.UsageError:
If required options are missing or conflicting.
"""
if not mcp and not mkdocs:
raise click.UsageError("Must specify either --mcp or --mkdocs")
if not mcp and not mkdocs and not api and not wiki:
raise click.UsageError("Must specify either --mcp, --mkdocs, --wiki, or --api")
if api:
if not openapi_spec:
raise click.UsageError("--openapi-spec is required for API build")
if site_name and not mkdocs and not wiki:
raise click.UsageError(
"--site-name cannot be overridden for API build; "
"the OpenAPI spec provides the site name"
)
if mkdocs and not module:
raise click.UsageError("--module is required for MkDocs build")
if mcp and not module:
raise click.UsageError("--module is required for MCP build")
spec: dict | None = None
if api:
spec = api_utils.load_openapi_spec(openapi_spec)
kinds: list[str] = []
if mkdocs:
if not module:
raise click.UsageError("--module is required for MkDocs build")
if not site_name:
site_name = module
click.echo(f"Generating MkDocs sources in {docs_dir}...")
kinds.append("lib")
lib_dir = docs_dir / "lib"
click.echo(f"Generating MkDocs sources in {lib_dir}...")
mkdocs_utils.generate_sources(
module,
docs_dir,
lib_dir,
project_name,
module_is_source,
readme_dir=Path(".").resolve(),
)
click.echo(f"Generating MkDocs config {mkdocs_yml}...")
mkdocs_utils.generate_config(docs_dir, nav_file, template, mkdocs_yml, site_name)
if api:
kinds.append("api")
api_dir = docs_dir / "api"
click.echo(f"Generating API sources in {api_dir}...")
api_utils.generate_api_sources(spec, api_dir)
click.echo("Running MkDocs build...")
mkdocs_utils.build(mkdocs_yml)
click.echo("MkDocs build completed.")
if wiki:
kinds.append("wiki")
if kinds:
api_metadata: api_utils.OpenAPIMetadata | None = None
if api:
api_metadata = api_utils.derive_metadata(spec)
theme_icon = mkdocs_utils.load_spec_icon(nav_file)
config_paths: list[Path] = []
for kind in kinds:
out = docs_dir / f"mkdocs.{kind}.yml"
if out.exists() and not refresh:
click.echo(
f"Using existing MkDocs config {out} (run --refresh to rebaseline)..."
)
config_paths.append(out)
continue
kind_root = wiki_dir if kind == "wiki" else docs_dir / kind
site_name_kind = site_name or module or Path.cwd().name
site_description: str | None = None
site_author: str | None = None
if kind == "api" and api_metadata:
site_name_kind = api_metadata.site_name
site_description = api_metadata.site_description
site_author = api_metadata.site_author
if kind == "lib":
nav_block, _kind_icon = mkdocs_utils.build_lib_nav(nav_file, docs_dir)
elif kind == "wiki":
nav_block = mkdocs_utils.build_wiki_nav_block(wiki_dir)
else:
nav_block = [{"API Reference": "index.md"}]
click.echo(f"Generating MkDocs config {out}...")
mkdocs_utils.generate_site_config(
kind,
kind_root,
nav_block,
out,
site_name_kind,
Path(os.path.relpath(kind_root, docs_dir)).as_posix(),
Path(os.path.relpath(Path.cwd() / "site" / kind, docs_dir)).as_posix(),
template=template,
site_description=site_description,
site_author=site_author,
theme_icon=theme_icon,
)
config_paths.append(out)
click.echo("Running MkDocs builds...")
mkdocs_utils.build_configs(config_paths)
if mcp:
if not module:
raise click.UsageError("--module is required for MCP build")
click.echo(f"Generating MCP resources in {out_dir}...")
mcp_utils.generate_resources(module, project_name, out_dir)
click.echo("MCP build completed.")
@@ -110,14 +286,30 @@ def build(
@cli.command()
@click.option("--mcp", is_flag=True, help="Serve MCP documentation")
@click.option("--mkdocs", is_flag=True, help="Serve MkDocs site")
@click.option("--mkdocs", is_flag=True, help="Serve an MkDocs site from --mkdocs-yml")
@click.option("--lib", is_flag=True, help="Serve the lib MkDocs site")
@click.option("--api", is_flag=True, help="Serve the API MkDocs site")
@click.option("--wiki", is_flag=True, help="Serve the wiki MkDocs site")
@click.option("--module", help="Python module to serve")
@click.option("--mkdocs-yml", type=click.Path(path_type=Path), default=Path("mkdocs.yml"), help="MkDocs config path")
@click.option("--out-dir", type=click.Path(path_type=Path), default=Path("mcp_docs"), help="MCP root directory")
@click.option(
"--mkdocs-yml",
type=click.Path(path_type=Path),
default=Path("docs/mkdocs.wiki.yml"),
help="MkDocs config path",
)
@click.option(
"--out-dir",
type=click.Path(path_type=Path),
default=Path("docs/mcp"),
help="MCP root directory",
)
def serve(
mcp: bool,
mkdocs: bool,
module: Optional[str],
lib: bool,
api: bool,
wiki: bool,
module: str | None,
mkdocs_yml: Path,
out_dir: Path,
) -> None:
@@ -126,30 +318,73 @@ def serve(
Depending on the selected mode, this command starts either:
- A MkDocs development server for browsing documentation
- 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`.
Args:
mcp: Serve documentation using the MCP server.
mkdocs: Serve the MkDocs development site.
module: Python module import path to serve via MCP.
mkdocs_yml: Path to the MkDocs configuration file.
out_dir: Root directory containing MCP documentation resources.
mcp (bool):
Serve documentation using the MCP server.
mkdocs (bool):
Serve the MkDocs development site from ``--mkdocs-yml``.
lib (bool):
Serve the lib MkDocs site.
api (bool):
Serve the API MkDocs site.
wiki (bool):
Serve the wiki MkDocs site.
module (str | None):
Python module import path to serve via MCP.
mkdocs_yml (Path):
Path to the MkDocs configuration file.
out_dir (Path):
Root directory containing MCP documentation resources.
Raises:
click.UsageError: If invalid or conflicting options are provided.
click.UsageError:
If invalid or conflicting options are provided.
"""
if mcp and mkdocs:
raise click.UsageError("Cannot specify both --mcp and --mkdocs")
if not mcp and not mkdocs:
raise click.UsageError("Must specify either --mcp or --mkdocs")
if mcp and not module:
raise click.UsageError("--module is required for MCP serve")
selected = [
name
for name, enabled in (
("mcp", mcp),
("mkdocs", mkdocs),
("lib", lib),
("api", api),
("wiki", wiki),
)
if enabled
]
if len(selected) != 1:
raise click.UsageError(
"Must specify exactly one of --mcp, --mkdocs, --lib, --api, --wiki"
)
if mkdocs:
mkdocs_utils.serve(mkdocs_yml)
elif mcp:
if mcp:
if not module:
raise click.UsageError("--module is required for MCP serve")
mcp_utils.serve(module, out_dir)
return
config = mkdocs_yml
if lib:
config = Path("docs/mkdocs.lib.yml")
elif api:
config = Path("docs/mkdocs.api.yml")
elif wiki:
config = Path("docs/mkdocs.wiki.yml")
mkdocs_utils.serve(config)
@cli.command()
@@ -164,7 +399,7 @@ def serve(
)
def tree(
module: str,
project_name: Optional[str],
project_name: str | None,
) -> None:
"""
Display the documentation object tree for a module.
@@ -174,8 +409,11 @@ def tree(
objects, including modules, classes, functions, and members.
Args:
module: Python module import path to introspect.
project_name: Optional name to display as the project root.
module (str):
Python module import path to introspect.
project_name (str | None):
Optional name to display as the project root.
"""
loader = GriffeLoader()
project = loader.load_project([module], project_name)
@@ -188,7 +426,7 @@ def tree(
_print_object(obj, indent="│ ")
def _print_object(obj, indent: str) -> None:
def _print_object(obj: DocObject, indent: str) -> None:
"""
Recursively print a documentation object and its members.
@@ -196,8 +434,11 @@ def _print_object(obj, indent: str) -> None:
and prints each object with indentation to represent hierarchy.
Args:
obj: Documentation object to print.
indent: Current indentation prefix used for nested members.
obj (DocObject):
Documentation object to print.
indent (str):
Current indentation prefix used for nested members.
"""
click.echo(f"{indent}├── {obj.name}")
for member in obj.get_all_members():

View File

@@ -1,34 +1,39 @@
from click.core import Group
from pathlib import Path
from typing import Sequence, Optional, Any
from click.core import Group
from docforge.models import DocObject
cli: Group
def build(
mcp: bool,
mkdocs: bool,
api: bool,
wiki: bool,
module_is_source: bool,
module: Optional[str],
project_name: Optional[str],
site_name: Optional[str],
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: Optional[Path],
mkdocs_yml: Path,
template: Path | None,
out_dir: Path,
) -> None: ...
def serve(
mcp: bool,
mkdocs: bool,
module: Optional[str],
lib: bool,
api: bool,
wiki: bool,
module: str | None,
mkdocs_yml: Path,
out_dir: Path,
) -> None: ...
def tree(
module: str,
project_name: Optional[str],
project_name: str | None,
) -> None: ...
def _print_object(obj: Any, indent: str) -> None: ...
def _print_object(obj: DocObject, indent: str) -> None: ...

View File

@@ -1,8 +1,10 @@
"""
# Summary
Command-line entry point for the doc-forge CLI.
This module exposes the executable entry point that initializes the
Click command group defined in ``docforge.cli.commands``.
Click command group defined in `docforge.cli.commands`.
"""
from docforge.cli.commands import cli
@@ -13,11 +15,11 @@ def main() -> None:
Run the doc-forge command-line interface.
This function initializes and executes the Click CLI application.
It is used as the console entry point when invoking ``doc-forge``
It is used as the console entry point when invoking `doc-forge`
from the command line.
"""
cli()
if __name__ == "__main__":
main()
main()

View File

@@ -1,5 +1,23 @@
"""
# Summary
Utilities for working with MCP in the doc-forge CLI.
---
Notes:
- `generate_resources` produces the bundle consumed by `MCPServer`:
`index.json`, `nav.json`, and per-module resources under `modules/`.
- Resource URIs use the `docs://` scheme: `docs://index`, `docs://nav`,
and `docs://modules/{module}`.
---
"""
from pathlib import Path
import click
from docforge.loaders import GriffeLoader, discover_module_paths
from docforge.renderers import MCPRenderer
from docforge.servers import MCPServer
@@ -14,12 +32,17 @@ def generate_resources(module: str, project_name: str | None, out_dir: Path) ->
to the specified output directory.
Args:
module: Python module import path used as the entry point for
module (str):
Python module import path used as the entry point for
documentation generation.
project_name: Optional override for the project name used in
generated documentation metadata.
out_dir: Directory where MCP resources (index.json, nav.json,
and module data) will be written.
project_name (str | None):
Optional override for the project name used in generated
documentation metadata.
out_dir (Path):
Directory where MCP resources (index.json, nav.json, and module data)
will be written.
"""
loader = GriffeLoader()
discovered_paths = discover_module_paths(module)
@@ -37,17 +60,20 @@ def serve(module: str, mcp_root: Path) -> None:
navigation structure, and module documentation through MCP endpoints.
Args:
module: Python module import path used to identify the served
module (str):
Python module import path used to identify the served
documentation instance.
mcp_root: Path to the directory containing the MCP documentation
mcp_root (Path):
Path to the directory containing the MCP documentation
bundle (index.json, nav.json, and modules/).
Raises:
click.ClickException: If the MCP documentation bundle is missing
required files or directories.
click.ClickException:
If the MCP documentation bundle is missing required files or directories.
"""
if not mcp_root.exists():
raise click.ClickException(f"mcp_docs directory not found: {mcp_root}")
raise click.ClickException(f"MCP docs directory not found: {mcp_root}")
required = [
mcp_root / "index.json",

View File

@@ -1,4 +1,6 @@
from pathlib import Path
def generate_resources(module: str, project_name: str | None, out_dir: Path) -> None: ...
def generate_resources(
module: str, project_name: str | None, out_dir: Path
) -> None: ...
def serve(module: str, mcp_root: Path) -> None: ...

View File

@@ -1,10 +1,36 @@
from pathlib import Path
"""
# Summary
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.
---
"""
from collections.abc import Iterable
from importlib import resources
from pathlib import Path
from typing import Any, cast
import click
import yaml
from docforge.loaders import GriffeLoader, discover_module_paths
from docforge.nav import (
MkDocsNavEmitter,
build_wiki_nav,
load_nav_spec,
resolve_nav,
)
from docforge.renderers import MkDocsRenderer
from docforge.nav import load_nav_spec, resolve_nav, MkDocsNavEmitter
def generate_sources(
@@ -12,6 +38,7 @@ def generate_sources(
docs_dir: Path,
project_name: str | None = None,
module_is_source: bool | None = None,
readme_dir: Path | None = None,
) -> None:
"""
Generate MkDocs Markdown sources for a Python module.
@@ -21,13 +48,23 @@ def generate_sources(
use with MkDocs.
Args:
module: Python module import path used as the entry point for
module (str):
Python module import path used as the entry point for
documentation generation.
docs_dir: Directory where the generated Markdown files will be written.
project_name: Optional override for the project name used in
documentation metadata.
module_is_source: If True, treat the specified module directory as
the project root rather than a nested module.
docs_dir (Path):
Directory where the generated Markdown files will be written.
project_name (str | None):
Optional override for the project name used in documentation metadata.
module_is_source (bool | None):
If True, treat the specified module directory as the project root
rather than a nested module.
readme_dir (Path | None):
Directory where the generated README.md should be written. If not
provided, defaults to the parent of ``docs_dir``.
"""
loader = GriffeLoader()
discovered_paths = discover_module_paths(module)
@@ -44,82 +81,353 @@ def generate_sources(
project,
docs_dir,
module_is_source,
readme_dir,
)
def generate_config(
docs_dir: Path,
def build_lib_nav(
nav_file: Path,
template: Path | None,
out: Path,
site_name: str,
) -> None:
docs_root: Path,
) -> tuple[list[dict[str, Any]], dict[str, str] | None]:
"""
Generate an ``mkdocs.yml`` configuration file.
Build the re-rooted navigation block for a lib site.
The configuration is created by combining a template configuration
with a navigation structure derived from the docforge navigation
specification.
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.
Args:
docs_dir: Directory containing generated documentation Markdown files.
nav_file: Path to the ``docforge.nav.yml`` navigation specification.
template: Optional path to a custom MkDocs configuration template.
If not provided, a built-in template will be used.
out: Destination path where the generated ``mkdocs.yml`` file
will be written.
site_name: Display name for the generated documentation site.
nav_file (Path):
Path to the `docforge.nav.yml` navigation specification.
docs_root (Path):
Shared documentation root containing the ``lib`` sources.
Returns:
tuple[list[dict[str, Any]], dict[str, str] | None]:
The re-rooted navigation block and the optional theme icon
mapping from the specification.
Raises:
click.FileError: If the navigation specification or template
file cannot be found.
click.FileError:
If the navigation specification cannot be found.
"""
if not nav_file.exists():
raise click.FileError(str(nav_file), hint="Nav spec not found")
spec = load_nav_spec(nav_file)
resolved = resolve_nav(spec, docs_dir)
nav_block = MkDocsNavEmitter().emit(resolved)
resolved = resolve_nav(spec, docs_root)
block = MkDocsNavEmitter().emit(resolved)
return cast(list[dict[str, Any]], _strip_scope(block, "lib")), spec.icon
# Load template
if template is not None:
if not template.exists():
raise click.FileError(str(template), hint="Template not found")
data = yaml.safe_load(template.read_text(encoding="utf-8"))
else:
text = (
resources.files("docforge.templates")
.joinpath("mkdocs.sample.yml")
.read_text(encoding="utf-8")
)
data = yaml.safe_load(text)
def build_wiki_nav_block(wiki_dir: Path) -> list[dict[str, Any]]:
"""
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.
Args:
wiki_dir (Path):
Path to the hand-written wiki directory, for example ``docs/wiki``.
Returns:
list[dict[str, Any]]:
Navigation entries relative to the wiki directory.
Raises:
click.FileError:
If the wiki directory does not exist.
"""
if not wiki_dir.exists():
raise click.FileError(str(wiki_dir), hint="Wiki dir not found")
return cast(list[dict[str, Any]], _strip_scope(build_wiki_nav(wiki_dir), "wiki"))
def load_spec_icon(nav_file: Path) -> dict[str, str] | None:
"""
Load the theme icon mapping from a navigation specification.
Args:
nav_file (Path):
Path to the navigation specification file.
Returns:
dict[str, str] | None:
The icon mapping, or ``None`` when the specification file is
absent or cannot be parsed.
"""
if not nav_file.exists():
return None
try:
return load_nav_spec(nav_file).icon
except (ValueError, yaml.YAMLError):
return None
def _strip_scope(value: object, scope: str) -> object:
"""
Re-root navigation paths by removing a leading scope component.
The navigation block is walked recursively and every relative path
string that starts with ``{scope}/`` has that prefix removed, so a lib
or wiki site scoped to its own ``docs_dir`` can reuse paths that were
originally written relative to the shared documentation root.
Args:
value (object):
Navigation block, group list, path string, or scalar value.
scope (str):
Leading path component to strip, for example ``lib`` or ``wiki``.
Returns:
object:
The navigation structure with re-rooted paths.
"""
if isinstance(value, str):
prefix = f"{scope}/"
return value[len(prefix) :] if value.startswith(prefix) else value
if isinstance(value, list):
return [_strip_scope(item, scope) for item in value]
if isinstance(value, dict):
return {key: _strip_scope(val, scope) for key, val in value.items()}
return value
def 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,
) -> None:
"""
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``).
Args:
kind (str):
Documentation kind, one of ``lib``, ``api``, or ``wiki``.
kind_root (Path):
Directory scoped to the kind (for example ``docs/lib``) that
serves as the MkDocs ``docs_dir``.
nav_block (list[dict[str, Any]]):
Re-rooted navigation entries for the kind's site.
out (Path):
Destination path where the generated ``mkdocs.{kind}.yml`` file
is written.
site_name (str):
Display name for the generated documentation site.
docs_dir (str):
MkDocs ``docs_dir`` value, relative to the configuration
file's directory.
site_dir (str):
MkDocs ``site_dir`` value, relative to the configuration
file's directory.
template (Path | None):
Optional path to a fully custom MkDocs configuration template
that replaces the built-in templates entirely.
site_description (str | None):
Optional site description written into the configuration.
site_author (str | None):
Optional site author written into the configuration.
theme_icon (dict[str, str] | None):
Optional mapping of theme icon entries injected as
``theme.icon``.
"""
data = _load_template(template, [kind])
data["site_name"] = site_name
if site_description:
data["site_description"] = site_description
if site_author:
data["site_author"] = site_author
data["docs_dir"] = docs_dir
data["site_dir"] = site_dir
data["nav"] = nav_block
if theme_icon:
theme = data.setdefault("theme", {})
if not isinstance(theme, dict):
theme = {}
theme["icon"] = theme_icon
data["theme"] = theme
out.write_text(yaml.safe_dump(data, sort_keys=False), encoding="utf-8")
def build(mkdocs_yml: Path) -> None:
def _load_template(
template: Path | None,
modes: Iterable[str] | None,
) -> dict:
"""
Build the MkDocs documentation site.
Load the MkDocs configuration template.
This function loads the MkDocs configuration and runs the MkDocs
build command to generate the final static documentation site.
When a custom template path is provided, it is used as-is. Otherwise the
shared ``mkdocs.common.yml`` template is deep-merged with the fragments
contributed by each enabled mode (``lib``, ``api``, or ``wiki``).
Args:
mkdocs_yml: Path to the ``mkdocs.yml`` configuration file.
template (Path | None):
Optional fully custom template that replaces the built-ins.
modes (Iterable[str] | None):
Documentation modes whose template fragments should be merged.
Returns:
dict:
Merged MkDocs configuration mapping.
Raises:
click.ClickException: If the configuration file does not exist.
click.FileError:
If a referenced template file cannot be found.
"""
if not mkdocs_yml.exists():
raise click.ClickException(f"mkdocs.yml not found: {mkdocs_yml}")
if template is not None:
if not template.exists():
raise click.FileError(str(template), hint="Template not found")
return yaml.safe_load(template.read_text(encoding="utf-8"))
from mkdocs.config import load_config
data: dict = {}
active_modes = list(modes) if modes else ["lib"]
parts = ["common", *active_modes]
seen: set[str] = set()
for part_name in parts:
if part_name in seen:
continue
seen.add(part_name)
text = (
resources.files("docforge.templates")
.joinpath(f"mkdocs.{part_name}.yml")
.read_text(encoding="utf-8")
)
part: dict = yaml.safe_load(text)
data = _deep_merge(data, part)
return data
def _item_name(item: object) -> str:
"""
Return the identifying name of a list entry.
String entries identify as themselves; mapping entries identify by their
first key. This is used to deduplicate plugin and extension lists.
Args:
item (object):
List entry, either a string or a single-key mapping.
Returns:
str:
The identifying name of the entry.
"""
if isinstance(item, dict):
return next(iter(item.keys()), "")
return str(item)
def _merge_list(base: list, added: list) -> list:
"""
Merge two lists, preserving order and dropping duplicates by name.
Args:
base (list):
Existing list entries.
added (list):
Entries to append when not already present.
Returns:
list:
Merged list with duplicates removed.
"""
result = list(base)
names = {_item_name(item) for item in result}
for item in added:
name = _item_name(item)
if name not in names:
result.append(item)
names.add(name)
return result
def _deep_merge(base: dict, part: dict) -> dict:
"""
Deep merge a template fragment into a base configuration.
Mappings are merged recursively, while lists are combined by
deduplicating entries by their identifying name. Non-container values in
the fragment override the base.
Args:
base (dict):
Configuration being built up.
part (dict):
Template fragment to merge into the base.
Returns:
dict:
The merged configuration.
"""
for key, value in part.items():
if isinstance(value, dict) and isinstance(base.get(key), dict):
base[key] = _deep_merge(base[key], value)
elif isinstance(value, list) and isinstance(base.get(key), list):
base[key] = _merge_list(base[key], value)
else:
base[key] = value
return base
def build_configs(yml_paths: Iterable[Path]) -> None:
"""
Build the MkDocs documentation site for every given configuration.
Each configuration file is loaded and built in turn, producing the
per-kind static sites (``site/lib``, ``site/api``, ``site/wiki``).
Args:
yml_paths (Iterable[Path]):
Configuration files to build, in order.
Raises:
click.ClickException:
If a configuration file does not exist.
"""
from mkdocs.commands.build import build as mkdocs_build
from mkdocs.config import load_config
mkdocs_build(load_config(str(mkdocs_yml)))
for yml in yml_paths:
if not yml.exists():
raise click.ClickException(f"mkdocs.yml not found: {yml}")
mkdocs_build(load_config(str(yml)))
def serve(mkdocs_yml: Path) -> None:
@@ -130,13 +438,16 @@ def serve(mkdocs_yml: Path) -> None:
the site when changes are detected.
Args:
mkdocs_yml: Path to the ``mkdocs.yml`` configuration file.
mkdocs_yml (Path):
Path to the `mkdocs.yml` configuration file.
Raises:
click.ClickException: If the configuration file does not exist.
click.ClickException:
If the configuration file does not exist.
"""
if not mkdocs_yml.exists():
raise click.ClickException(f"mkdocs.yml not found: {mkdocs_yml}")
from mkdocs.commands.serve import serve as mkdocs_serve
mkdocs_serve(config_file=str(mkdocs_yml))

View File

@@ -1,11 +1,33 @@
from collections.abc import Iterable
from pathlib import Path
from typing import Any
def generate_sources(
module: str,
docs_dir: Path,
project_name: str | None = None,
module_is_source: bool | None = None,
readme_dir: Path | None = None,
) -> None: ...
def generate_config(docs_dir: Path, nav_file: Path, template: Path | None, out: Path, site_name: str) -> None: ...
def build(mkdocs_yml: Path) -> None: ...
def build_lib_nav(
nav_file: Path,
docs_root: Path,
) -> tuple[list[dict[str, Any]], dict[str, str] | None]: ...
def build_wiki_nav_block(wiki_dir: Path) -> list[dict[str, Any]]: ...
def load_spec_icon(nav_file: Path) -> dict[str, str] | None: ...
def _strip_scope(value: object, scope: str) -> object: ...
def 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,
) -> None: ...
def build_configs(yml_paths: Iterable[Path]) -> None: ...
def serve(mkdocs_yml: Path) -> None: ...

View File

@@ -1,13 +1,14 @@
"""
# Summary
Loader layer for doc-forge.
The ``docforge.loaders`` package is responsible for discovering Python modules
The `docforge.loaders` package is responsible for discovering Python modules
and extracting documentation data using static analysis.
---
Overview
--------
# Overview
This layer converts Python source code into an intermediate documentation
model used by doc-forge. It performs module discovery, introspection, and
@@ -17,9 +18,9 @@ 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.
hierarchies using the `griffe` library without executing the code.
- **Public API filtering** – Exclude private members (names prefixed with
``_``) to produce clean public documentation structures.
`_`) to produce clean public documentation structures.
---
"""

View File

@@ -1,24 +1,37 @@
"""
# Summary
Utilities for loading and introspecting Python modules using Griffe.
This module provides the ``GriffeLoader`` class and helper utilities used to
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.
---
"""
import logging
from pathlib import Path
from typing import List, Optional
from griffe import (
GriffeLoader as _GriffeLoader,
ModulesCollection,
LinesCollection,
Object,
AliasResolutionError,
LinesCollection,
ModulesCollection,
Object,
)
from griffe import (
GriffeLoader as _GriffeLoader,
)
from docforge.models import Module, Project, DocObject
from docforge.models import DocObject, Module, Project
logger = logging.getLogger(__name__)
@@ -26,29 +39,34 @@ logger = logging.getLogger(__name__)
def discover_module_paths(
module_name: str,
project_root: Path | None = None,
) -> List[str]:
) -> list[str]:
"""
Discover Python modules within a package directory.
The function scans the filesystem for ``.py`` files inside the specified
The function scans the filesystem for `.py` files inside the specified
package and converts them into dotted module import paths.
Discovery rules:
- Directories containing ``__init__.py`` are treated as packages.
- Each ``.py`` file is treated as a module.
- Directories containing `__init__.py` are treated as packages.
- Each `.py` file is treated as a module.
- Results are returned as dotted import paths.
Args:
module_name: Top-level package name to discover modules from.
project_root: Root directory used to resolve module paths. If not
provided, the current working directory is used.
module_name (str):
Top-level package name to discover modules from.
project_root (Path | None):
Root directory used to resolve module paths. If not provided, the
current working directory is used.
Returns:
A sorted list of unique dotted module import paths.
list[str]:
A sorted list of unique dotted module import paths.
Raises:
FileNotFoundError: If the specified package directory does not exist.
FileNotFoundError:
If the specified package directory does not exist.
"""
if project_root is None:
@@ -58,7 +76,7 @@ def discover_module_paths(
if not pkg_dir.exists():
raise FileNotFoundError(f"Package not found: {pkg_dir}")
module_paths: List[str] = []
module_paths: list[str] = []
for path in pkg_dir.rglob("*.py"):
if path.name == "__init__.py":
@@ -78,8 +96,12 @@ class GriffeLoader:
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.
code and transform the extracted information into `Project`, `Module`,
and `DocObject` instances used by doc-forge.
Attributes:
_loader (_GriffeLoader):
Internal Griffe loader with dedicated module and line collections.
"""
def __init__(self) -> None:
@@ -95,32 +117,39 @@ class GriffeLoader:
)
def load_project(
self,
module_paths: List[str],
project_name: Optional[str] = None,
skip_import_errors: bool = None,
self,
module_paths: list[str],
project_name: str | None = None,
skip_import_errors: bool | None = None,
) -> Project:
"""
Load multiple modules and assemble them into a Project model.
Each module path is introspected and converted into a ``Module``
instance. All modules are then aggregated into a single ``Project``
Each module path is introspected and converted into a `Module`
instance. All modules are then aggregated into a single `Project`
object.
Args:
module_paths: List of dotted module import paths to load.
project_name: Optional override for the project name. Defaults
to the top-level name of the first module.
skip_import_errors: If True, modules that fail to load will be
skipped instead of raising an error.
module_paths (list[str]):
List of dotted module import paths to load.
project_name (str | None):
Optional override for the project name. Defaults to the top-level
name of the first module.
skip_import_errors (bool | None):
If True, modules that fail to load will be skipped instead of raising an error.
Returns:
A populated ``Project`` instance containing the loaded modules.
Project:
A populated `Project` instance containing the loaded modules.
Raises:
ValueError: If no module paths are provided.
ImportError: If a module fails to load and
``skip_import_errors`` is False.
ValueError:
If no module paths are provided.
ImportError:
If a module fails to load and `skip_import_errors` is False.
"""
if not module_paths:
raise ValueError("At least one module path must be provided")
@@ -148,13 +177,30 @@ class GriffeLoader:
Load and convert a single Python module.
The module is introspected using Griffe and then transformed into
a doc-forge ``Module`` model.
a doc-forge `Module` model.
Args:
path: Dotted import path of the module.
path (str):
Dotted import path of the module.
Returns:
A populated ``Module`` instance.
Module:
A populated `Module` instance.
Raises:
ImportError:
If the module cannot be loaded by Griffe.
KeyError:
If the loaded module is missing from the module collection.
Example:
Load a single module:
```python
loader = GriffeLoader()
module = loader.load_module("mypackage.submodule")
```
"""
self._loader.load(path)
griffe_module = self._loader.modules_collection[path]
@@ -170,13 +216,15 @@ class GriffeLoader:
Convert a Griffe module object into a doc-forge Module.
All public members of the module are recursively converted into
``DocObject`` instances.
`DocObject` instances.
Args:
obj: Griffe object representing the module.
obj (Object):
Griffe object representing the module.
Returns:
A populated ``Module`` model.
Module:
A populated `Module` model.
"""
module = Module(
path=obj.path,
@@ -186,6 +234,8 @@ class GriffeLoader:
for name, member in obj.members.items():
if name.startswith("_"):
continue
if not self._is_resolvable_alias(member):
continue
module.add_object(self._convert_object(member))
@@ -200,10 +250,12 @@ class GriffeLoader:
recursively.
Args:
obj: Griffe object representing a documented Python object.
obj (Object):
Griffe object representing a documented Python object.
Returns:
A ``DocObject`` instance representing the converted object.
DocObject:
A `DocObject` instance representing the converted object.
"""
kind = obj.kind.value
signature = self._safe_signature(obj)
@@ -220,6 +272,8 @@ class GriffeLoader:
for name, member in obj.members.items():
if name.startswith("_"):
continue
if not self._is_resolvable_alias(member):
continue
doc_obj.add_member(self._convert_object(member))
except AliasResolutionError:
pass
@@ -230,35 +284,74 @@ class GriffeLoader:
# Safe extractors
# -------------------------
def _safe_docstring(self, obj: Object) -> Optional[str]:
def _safe_docstring(self, obj: Object) -> str | None:
"""
Safely extract a docstring from a Griffe object.
Args:
obj: Griffe object to inspect.
obj (Object):
Griffe object to inspect.
Returns:
The raw docstring text if available, otherwise ``None``.
str | None:
The raw docstring text if available, otherwise `None`.
"""
try:
return obj.docstring.value if obj.docstring else None
except AliasResolutionError:
return None
def _safe_signature(self, obj: Object) -> Optional[str]:
def _safe_signature(self, obj: Object) -> str | None:
"""
Safely extract the signature of a Griffe object.
Griffe exposes signatures as callables (``Object.signature``); the
method is invoked and stringified to produce a clean, stable signature.
Aliases that point outside the loaded project fail resolution and are
reported as `None`.
Args:
obj: Griffe object to inspect.
obj (Object):
Griffe object to inspect.
Returns:
String representation of the object's signature if available,
otherwise ``None``.
str | None:
Clean string representation of the object's signature if
available, otherwise `None`.
"""
try:
if hasattr(obj, "signature") and obj.signature:
return str(obj.signature)
except AliasResolutionError:
signature = getattr(obj, "signature", None)
if signature is None:
return None
if callable(signature):
signature = signature()
if not signature:
return None
return str(signature).strip() or None
except Exception:
return None
return None
def _is_resolvable_alias(self, obj: Object) -> bool:
"""
Report whether an object is a resolvable part of the documented API.
Aliases that cannot be resolved (stdlib or third-party imports) are
treated as noise and excluded from the model. Non-alias objects are
always resolvable.
Args:
obj (Object):
Griffe object to test.
Returns:
bool:
True if the object should be kept, False if it is an
unresolvable alias.
"""
if obj.kind.value != "alias":
return True
try:
_ = obj.canonical_path
except AliasResolutionError:
return False
return True

View File

@@ -1,29 +1,25 @@
from typing import List, Optional
from pathlib import Path
from docforge.models import Module, Project
def discover_module_paths(
module_name: str,
project_root: Path | None = None,
) -> List[str]:
...
) -> list[str]: ...
class GriffeLoader:
"""Griffe-based introspection loaders.
This is the only supported introspection backend in doc-forge.
Converts Griffe results into `Project`, `Module`, and `DocObject` models.
"""
def __init__(self) -> None: ...
def load_project(
self,
module_paths: List[str],
project_name: Optional[str] = ...,
skip_import_errors: bool = ...,
module_paths: list[str],
project_name: str | None = ...,
skip_import_errors: bool | None = ...,
) -> Project:
"""Load a documentation project from Python modules."""

View File

@@ -1,13 +1,14 @@
"""
# Summary
Model layer for doc-forge.
The ``docforge.models`` package defines the core data structures used to
The `docforge.models` package defines the core data structures used to
represent Python source code as a structured documentation model.
---
Overview
--------
# Overview
The model layer forms the central intermediate representation used throughout
doc-forge. Python modules and objects discovered during introspection are

View File

@@ -1,6 +1,6 @@
from .project import Project
from .module import Module
from .object import DocObject
from .project import Project
__all__ = [
"Project",

View File

@@ -1,13 +1,22 @@
"""
# Summary
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
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.
---
"""
from typing import Dict, Iterable, Optional
from collections.abc import Iterable
from docforge.models.object import DocObject
@@ -16,40 +25,47 @@ class Module:
"""
Representation of a documented Python module or package.
A ``Module`` stores metadata about the module itself and maintains a
A `Module` stores metadata about the module itself and maintains a
collection of top-level documentation objects discovered during
introspection.
Attributes:
path: Dotted import path of the module.
docstring: Module-level documentation string, if present.
members: Mapping of object names to their corresponding
``DocObject`` representations.
path (str):
Dotted import path of the module.
docstring (str | None):
Module-level documentation string, if present.
members (dict[str, DocObject]):
Mapping of object names to their corresponding `DocObject` representations.
"""
def __init__(
self,
path: str,
docstring: Optional[str] = None,
docstring: str | None = None,
) -> None:
"""
Initialize a Module instance.
Args:
path: Dotted import path identifying the module.
docstring: Module-level documentation text, if available.
path (str):
Dotted import path identifying the module.
docstring (str | None):
Module-level documentation text, if available.
"""
self.path = path
self.docstring = docstring
self.members: Dict[str, DocObject] = {}
self.members: dict[str, DocObject] = {}
def add_object(self, obj: DocObject) -> None:
"""
Add a documented object to the module.
Args:
obj: Documentation object to register as a top-level
member of the module.
obj (DocObject):
Documentation object to register as a top-level member of the module.
"""
self.members[obj.name] = obj
@@ -58,13 +74,16 @@ class Module:
Retrieve a documented object by name.
Args:
name: Name of the object to retrieve.
name (str):
Name of the object to retrieve.
Returns:
The corresponding ``DocObject`` instance.
DocObject:
The corresponding `DocObject` instance.
Raises:
KeyError: If no object with the given name exists.
KeyError:
If no object with the given name exists.
"""
return self.members[name]
@@ -73,7 +92,7 @@ class Module:
Return all top-level documentation objects in the module.
Returns:
An iterable of ``DocObject`` instances representing the
module's public members.
Iterable[DocObject]:
An iterable of `DocObject` instances representing the module's public members.
"""
return self.members.values()

View File

@@ -1,23 +1,19 @@
from typing import Dict, Iterable, Optional
from collections.abc import Iterable
from docforge.models.object import DocObject
class Module:
"""Represents a documented Python module."""
path: str
docstring: Optional[str]
members: Dict[str, DocObject]
docstring: str | None
members: dict[str, DocObject]
def __init__(
self,
path: str,
docstring: Optional[str] = ...,
docstring: str | None = ...,
) -> None: ...
def add_object(self, obj: DocObject) -> None: ...
def get_object(self, name: str) -> DocObject: ...
def get_all_objects(self) -> Iterable[DocObject]: ...

View File

@@ -1,31 +1,51 @@
"""
# Summary
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
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.
---
"""
from typing import Dict, Iterable, Optional
from collections.abc import Iterable
class DocObject:
"""
Representation of a documented Python object.
A ``DocObject`` models a single Python entity discovered during
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: Local name of the object.
kind: Type of object (for example ``class``, ``function``,
``method``, or ``attribute``).
path: Fully qualified dotted path to the object.
signature: Callable signature if the object represents a callable.
docstring: Raw docstring text extracted from the source code.
members: Mapping of member names to child ``DocObject`` instances.
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.
members (dict[str, DocObject]):
Mapping of member names to child `DocObject` instances.
"""
def __init__(
@@ -33,25 +53,34 @@ class DocObject:
name: str,
kind: str,
path: str,
signature: Optional[str] = None,
docstring: Optional[str] = None,
signature: str | None = None,
docstring: str | None = None,
) -> None:
"""
Initialize a DocObject instance.
Args:
name: Local name of the object.
kind: Object type identifier (for example ``class`` or ``function``).
path: Fully qualified dotted path of the object.
signature: Callable signature if applicable.
docstring: Documentation string associated with the object.
name (str):
Local name of the object.
kind (str):
Object type identifier (for example `class` or `function`).
path (str):
Fully qualified dotted path of the object.
signature (str | None):
Callable signature if applicable.
docstring (str | None):
Documentation string associated with the object.
"""
self.name = name
self.kind = kind
self.path = path
self.signature = signature
self.docstring = docstring
self.members: Dict[str, "DocObject"] = {}
self.members: dict[str, DocObject] = {}
def add_member(self, obj: "DocObject") -> None:
"""
@@ -61,7 +90,8 @@ class DocObject:
nested objects to their parent containers.
Args:
obj: Documentation object to add as a member.
obj (DocObject):
Documentation object to add as a member.
"""
self.members[obj.name] = obj
@@ -70,13 +100,16 @@ class DocObject:
Retrieve a member object by name.
Args:
name: Name of the member to retrieve.
name (str):
Name of the member to retrieve.
Returns:
The corresponding ``DocObject`` instance.
DocObject:
The corresponding `DocObject` instance.
Raises:
KeyError: If the member does not exist.
KeyError:
If the member does not exist.
"""
return self.members[name]
@@ -85,6 +118,7 @@ class DocObject:
Return all child members of the object.
Returns:
An iterable of ``DocObject`` instances representing nested members.
Iterable[DocObject]:
An iterable of `DocObject` instances representing nested members.
"""
return self.members.values()

View File

@@ -1,5 +1,4 @@
from typing import Dict, Iterable, Optional
from collections.abc import Iterable
class DocObject:
"""Represents a documented Python object."""
@@ -7,21 +6,18 @@ class DocObject:
name: str
kind: str
path: str
signature: Optional[str]
docstring: Optional[str]
members: Dict[str, "DocObject"]
signature: str | None
docstring: str | None
members: dict[str, DocObject]
def __init__(
self,
name: str,
kind: str,
path: str,
signature: Optional[str] = ...,
docstring: Optional[str] = ...,
signature: str | None = ...,
docstring: str | None = ...,
) -> None: ...
def add_member(self, obj: "DocObject") -> None: ...
def get_member(self, name: str) -> "DocObject": ...
def get_all_members(self) -> Iterable["DocObject"]: ...
def add_member(self, obj: DocObject) -> None: ...
def get_member(self, name: str) -> DocObject: ...
def get_all_members(self) -> Iterable[DocObject]: ...

View File

@@ -1,12 +1,22 @@
"""
# Summary
Documentation model representing a project.
This module defines the ``Project`` class, the top-level container used by
doc-forge to represent a documented codebase. A ``Project`` aggregates multiple
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.
---
"""
from typing import Dict, Iterable
from collections.abc import Iterable
from docforge.models.module import Module
@@ -15,12 +25,15 @@ class Project:
"""
Representation of a documentation project.
A ``Project`` serves as the root container for all modules discovered during
A `Project` serves as the root container for all modules discovered during
introspection. Each module is stored by its dotted import path.
Attributes:
name: Name of the project.
modules: Mapping of module paths to ``Module`` instances.
name (str):
Name of the project.
modules (dict[str, Module]):
Mapping of module paths to `Module` instances.
"""
def __init__(self, name: str) -> None:
@@ -28,17 +41,27 @@ class Project:
Initialize a Project instance.
Args:
name: Name used to identify the documentation project.
name (str):
Name used to identify the documentation project.
Example:
Create a project and register a module:
```python
project = Project("mypackage")
project.add_module(module)
```
"""
self.name = name
self.modules: Dict[str, Module] = {}
self.modules: dict[str, Module] = {}
def add_module(self, module: Module) -> None:
"""
Register a module in the project.
Args:
module: Module instance to add to the project.
module (Module):
Module instance to add to the project.
"""
self.modules[module.path] = module
@@ -47,13 +70,16 @@ class Project:
Retrieve a module by its dotted path.
Args:
path: Fully qualified dotted module path (for example ``pkg.module``).
path (str):
Fully qualified dotted module path (for example `pkg.module`).
Returns:
The corresponding ``Module`` instance.
Module:
The corresponding `Module` instance.
Raises:
KeyError: If the module does not exist in the project.
KeyError:
If the module does not exist in the project.
"""
return self.modules[path]
@@ -62,7 +88,8 @@ class Project:
Return all modules contained in the project.
Returns:
An iterable of ``Module`` instances.
Iterable[Module]:
An iterable of `Module` instances.
"""
return self.modules.values()
@@ -71,6 +98,7 @@ class Project:
Return the list of module import paths.
Returns:
A list containing the dotted paths of all modules in the project.
list[str]:
A list containing the dotted paths of all modules in the project.
"""
return list(self.modules.keys())
return list(self.modules.keys())

View File

@@ -1,20 +1,15 @@
from typing import Dict, Iterable
from collections.abc import Iterable
from docforge.models.module import Module
class Project:
"""Represents a documentation project."""
name: str
modules: Dict[str, Module]
modules: dict[str, Module]
def __init__(self, name: str) -> None: ...
def add_module(self, module: Module) -> None: ...
def get_module(self, path: str) -> Module: ...
def get_all_modules(self) -> Iterable[Module]: ...
def get_module_list(self) -> list[str]: ...

View File

@@ -26,11 +26,13 @@ independent of module hierarchy.
from .spec import NavSpec, load_nav_spec
from .resolver import ResolvedNav, resolve_nav
from .mkdocs import MkDocsNavEmitter
from .wiki import build_wiki_nav
__all__ = [
"NavSpec",
"ResolvedNav",
"MkDocsNavEmitter",
"build_wiki_nav",
"resolve_nav",
"load_nav_spec",
]

View File

@@ -1,11 +1,13 @@
from .spec import NavSpec, load_nav_spec
from .resolver import ResolvedNav, resolve_nav
from .mkdocs import MkDocsNavEmitter
from .resolver import ResolvedNav, resolve_nav
from .spec import NavSpec, load_nav_spec
from .wiki import build_wiki_nav
__all__ = [
"NavSpec",
"ResolvedNav",
"MkDocsNavEmitter",
"build_wiki_nav",
"resolve_nav",
"load_nav_spec",
]

View File

@@ -4,10 +4,18 @@ MkDocs navigation emitter.
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.
---
"""
from pathlib import Path
from typing import List, Dict, Any
from typing import Any
from docforge.nav.resolver import ResolvedNav
@@ -20,20 +28,22 @@ class MkDocsNavEmitter:
list structure expected by the MkDocs ``nav`` configuration field.
"""
def emit(self, nav: ResolvedNav) -> List[Dict[str, Any]]:
def emit(self, nav: ResolvedNav) -> list[dict[str, Any]]:
"""
Generate a navigation structure for ``mkdocs.yml``.
Args:
nav: Resolved navigation data describing documentation groups
nav (ResolvedNav):
Resolved navigation data describing documentation groups
and their associated Markdown files.
Returns:
A list of dictionaries representing the MkDocs navigation layout.
Each dictionary maps a navigation label to a page or a list of
pages.
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.
"""
result: List[Dict[str, Any]] = []
result: list[dict[str, Any]] = []
# Home entry (semantic path)
if nav.home:
@@ -41,7 +51,7 @@ class MkDocsNavEmitter:
# Group entries
for group, paths in nav.groups.items():
entries: List[str] = []
entries: list[str] = []
for p in paths:
# Convert filesystem path back to docs-relative path
rel_path = self._to_relative(p, nav._docs_root)
@@ -59,11 +69,14 @@ class MkDocsNavEmitter:
resulting path is relative to the documentation root.
Args:
path: Filesystem path to convert.
docs_root: Root directory of the documentation sources.
path (Path):
Filesystem path to convert.
docs_root (Path | None):
Root directory of the documentation sources.
Returns:
POSIX-style path relative to the documentation root.
str:
POSIX-style path relative to the documentation root.
"""
if docs_root and path.is_absolute():
try:
@@ -75,7 +88,7 @@ class MkDocsNavEmitter:
path_str = path.as_posix()
docs_root_str = docs_root.as_posix()
if path_str.startswith(docs_root_str + "/"):
return path_str[len(docs_root_str) + 1:]
return path_str[len(docs_root_str) + 1 :]
# Fallback for other cases
return path.as_posix().split("/docs/", 1)[-1]

View File

@@ -1,15 +1,14 @@
from typing import Dict, List, Any
from pathlib import Path
from typing import Any
from docforge.nav.resolver import ResolvedNav
class MkDocsNavEmitter:
"""
Converts a ResolvedNav into MkDocs-compatible `nav` data.
"""
def emit(self, nav: ResolvedNav) -> List[Dict[str, Any]]:
def emit(self, nav: ResolvedNav) -> list[dict[str, Any]]:
"""
Emit a structure suitable for insertion into mkdocs.yml.

View File

@@ -3,12 +3,19 @@ Navigation resolution utilities.
This module resolves a ``NavSpec`` against the filesystem by expanding glob
patterns and validating that referenced documentation files exist.
---
Notes:
- Glob resolution is recursive and returns paths in sorted order.
- Unmatched patterns raise ``FileNotFoundError`` to fail fast on typos.
---
"""
from pathlib import Path
from typing import Dict, Iterable, List
import glob
from collections.abc import Iterable
from pathlib import Path
from docforge.nav.spec import NavSpec
@@ -29,16 +36,19 @@ class ResolvedNav:
def __init__(
self,
home: str | None,
groups: Dict[str, List[Path]],
groups: dict[str, list[Path]],
docs_root: Path | None = None,
) -> None:
"""
Initialize a ResolvedNav instance.
Args:
home: Relative path to the home page within the documentation root.
groups: Mapping of group titles to resolved documentation file paths.
docs_root: Root directory of the documentation source files.
home (str | None):
Relative path to the home page within the documentation root.
groups (dict[str, list[Path]]):
Mapping of group titles to resolved documentation file paths.
docs_root (Path | None):
Root directory of the documentation source files.
"""
self.home = home
self.groups = groups
@@ -48,8 +58,10 @@ class ResolvedNav:
"""
Iterate over all files referenced by the navigation structure.
Returns:
An iterable of ``Path`` objects representing documentation files.
Yields:
Path:
A documentation file referenced by the navigation, including
the home page when defined.
Raises:
RuntimeError: If the home page is defined but the documentation
@@ -61,8 +73,7 @@ class ResolvedNav:
yield self._docs_root / self.home
for paths in self.groups.values():
for p in paths:
yield p
yield from paths
def resolve_nav(
@@ -76,11 +87,14 @@ def resolve_nav(
that referenced documentation files exist within the documentation root.
Args:
spec: Navigation specification describing documentation layout.
docs_root: Root directory containing documentation Markdown files.
spec (NavSpec):
Navigation specification describing documentation layout.
docs_root (Path):
Root directory containing documentation Markdown files.
Returns:
A ``ResolvedNav`` instance containing validated navigation paths.
ResolvedNav:
A `ResolvedNav` instance containing validated navigation paths.
Raises:
FileNotFoundError: If the documentation root does not exist or a
@@ -89,23 +103,23 @@ def resolve_nav(
if not docs_root.exists():
raise FileNotFoundError(docs_root)
def resolve_pattern(pattern: str) -> List[Path]:
def resolve_pattern(pattern: str) -> list[Path]:
"""
Resolve a glob pattern relative to the documentation root.
Args:
pattern: Glob pattern used to match documentation files.
pattern (str):
Glob pattern used to match documentation files.
Returns:
A sorted list of matching ``Path`` objects.
list[Path]:
A sorted list of matching `Path` objects.
Raises:
FileNotFoundError: If the pattern does not match any files.
"""
full = docs_root / pattern
matches = sorted(
Path(p) for p in glob.glob(str(full), recursive=True)
)
matches = sorted(Path(p) for p in glob.glob(str(full), recursive=True))
if not matches:
raise FileNotFoundError(pattern)
@@ -121,10 +135,10 @@ def resolve_nav(
home = spec.home
# Resolve navigation groups
resolved_groups: Dict[str, List[Path]] = {}
resolved_groups: dict[str, list[Path]] = {}
for group, patterns in spec.groups.items():
files: List[Path] = []
files: list[Path] = []
for pattern in patterns:
files.extend(resolve_pattern(pattern))
resolved_groups[group] = files

View File

@@ -1,9 +1,8 @@
from collections.abc import Iterable
from pathlib import Path
from typing import Dict, List, Iterable, Optional
from docforge.nav.spec import NavSpec
class ResolvedNav:
"""
Fully-resolved navigation tree.
@@ -13,17 +12,16 @@ class ResolvedNav:
- Order is preserved
"""
home: Optional[str]
groups: Dict[str, List[Path]]
_docs_root: Optional[Path]
home: str | None
groups: dict[str, list[Path]]
_docs_root: Path | None
def __init__(
self,
home: str | None,
groups: Dict[str, List[Path]],
groups: dict[str, list[Path]],
docs_root: Path | None = ...,
) -> None: ...
def all_files(self) -> Iterable[Path]:
"""
Return all resolved documentation files in nav order.
@@ -33,7 +31,6 @@ class ResolvedNav:
"""
...
def resolve_nav(
spec: NavSpec,
docs_root: Path,

View File

@@ -4,10 +4,20 @@ Navigation specification model.
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.
---
"""
from __future__ import annotations
from pathlib import Path
from typing import Dict, List, Optional
import yaml
@@ -24,34 +34,46 @@ class NavSpec:
``index.md``).
groups: Mapping of navigation group titles to lists of file patterns
or glob expressions.
icon: Optional mapping of theme icon entries (for example
``{"logo": "material/code-tags"}``) injected into the MkDocs
theme as ``theme.icon``.
"""
def __init__(
self,
home: Optional[str],
groups: Dict[str, List[str]],
home: str | None,
groups: dict[str, list[str]],
icon: dict[str, str] | None = None,
) -> None:
"""
Initialize a NavSpec instance.
Args:
home: Relative path to the home document.
groups: Mapping of group names to lists of path patterns
home (str | None):
Relative path to the home document.
groups (dict[str, list[str]]):
Mapping of group names to lists of path patterns
(glob expressions).
icon (dict[str, str] | None):
Optional mapping of theme icon entries applied to the
generated MkDocs configuration.
"""
self.home = home
self.groups = groups
self.icon = icon
@classmethod
def load(cls, path: Path) -> "NavSpec":
def load(cls, path: Path) -> NavSpec:
"""
Load a navigation specification from a YAML file.
Args:
path: Filesystem path to the navigation specification file.
path (Path):
Filesystem path to the navigation specification file.
Returns:
A ``NavSpec`` instance representing the parsed configuration.
NavSpec:
A ``NavSpec`` instance representing the parsed configuration.
Raises:
FileNotFoundError: If the specified file does not exist.
@@ -68,6 +90,7 @@ class NavSpec:
home = data.get("home")
groups = data.get("groups", {})
icon = data.get("icon")
if home is not None and not isinstance(home, str):
raise ValueError("home must be a string")
@@ -83,17 +106,26 @@ class NavSpec:
):
raise ValueError(f"group '{key}' must be a list of strings")
return cls(home=home, groups=groups)
if icon is not None and (
not isinstance(icon, dict)
or not all(
isinstance(k, str) and isinstance(v, str) for k, v in icon.items()
)
):
raise ValueError("icon must be a mapping of strings")
def all_patterns(self) -> List[str]:
return cls(home=home, groups=groups, icon=icon)
def all_patterns(self) -> list[str]:
"""
Return all path patterns referenced by the specification.
Returns:
A list containing the home document (if defined) and all
group pattern entries.
list[str]:
A list containing the home document (if defined) and all
group pattern entries.
"""
patterns: List[str] = []
patterns: list[str] = []
if self.home:
patterns.append(self.home)
@@ -112,10 +144,12 @@ def load_nav_spec(path: Path) -> NavSpec:
corresponding ``NavSpec`` instance.
Args:
path: Path to the navigation specification file.
path (Path):
Path to the navigation specification file.
Returns:
A ``NavSpec`` instance representing the parsed specification.
NavSpec:
A ``NavSpec`` instance representing the parsed specification.
Raises:
FileNotFoundError: If the specification file does not exist.
@@ -132,4 +166,5 @@ def load_nav_spec(path: Path) -> NavSpec:
return NavSpec(
home=data.get("home"),
groups=data.get("groups", {}),
icon=data.get("icon"),
)

View File

@@ -1,6 +1,4 @@
from pathlib import Path
from typing import Dict, List, Optional
class NavSpec:
"""
@@ -10,18 +8,16 @@ class NavSpec:
of filesystem structure or MkDocs specifics.
"""
home: Optional[str]
groups: Dict[str, List[str]]
home: str | None
groups: dict[str, list[str]]
def __init__(
self,
home: Optional[str],
groups: Dict[str, List[str]],
) -> None:
...
home: str | None,
groups: dict[str, list[str]],
) -> None: ...
@classmethod
def load(cls, path: Path) -> "NavSpec":
def load(cls, path: Path) -> NavSpec:
"""
Load and validate a nav specification from YAML.
@@ -31,12 +27,11 @@ class NavSpec:
"""
...
def all_patterns(self) -> List[str]:
def all_patterns(self) -> list[str]:
"""
Return all path patterns referenced by the spec
(including home and group entries).
"""
...
def load_nav_spec(path: Path) -> NavSpec: ...

165
docforge/nav/wiki.py Normal file
View File

@@ -0,0 +1,165 @@
"""
# Summary
Wiki navigation derivation.
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.
"""
import re
from collections.abc import Callable
from pathlib import Path
from typing import Any
def build_wiki_nav(wiki_dir: Path) -> list[dict[str, Any]]:
"""
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.
Args:
wiki_dir (Path):
Path to the hand-written wiki directory, for example ``docs/wiki``.
Returns:
list[dict[str, Any]]:
Navigation entries compatible with the MkDocs ``nav`` configuration.
The list is empty if the wiki contains no Markdown files.
Raises:
FileNotFoundError:
If the wiki directory does not exist.
"""
if not wiki_dir.exists():
raise FileNotFoundError(wiki_dir)
root = wiki_dir.parent
def rel(path: Path) -> str:
try:
return path.relative_to(root).as_posix()
except ValueError:
return path.as_posix()
nav: list[dict[str, Any]] = []
if (wiki_dir / "index.md").exists():
nav.append({"Home": rel(wiki_dir / "index.md")})
nav.extend(_render_entries(wiki_dir, rel))
return nav
def _render_entries(
base_dir: Path,
rel: Callable[[Path], str],
) -> list[dict[str, Any]]:
"""
Render navigation entries for the children of a wiki directory.
Markdown pages become labeled entries, subdirectories containing
Markdown become nested groups, and a nested ``index.md`` is emitted
first as the section root.
Args:
base_dir (Path):
Directory whose children are rendered.
rel (Callable[[Path], str]):
Callable converting a wiki file path into a docs-relative path.
Returns:
list[dict[str, Any]]:
Navigation entries for ``base_dir`` in natural sort order.
"""
children = sorted(
(child for child in base_dir.iterdir() if not child.name.startswith(".")),
key=lambda child: _natural_key(child.name),
)
entries: list[dict[str, Any]] = []
for child in children:
if child.is_dir():
if not any(child.rglob("*.md")):
continue
group: list[dict[str, Any]] = []
nested_index = child / "index.md"
if nested_index.exists():
group.append({_prettify(child.name): rel(nested_index)})
group.extend(_render_entries(child, rel))
entries.append({_prettify(child.name): group})
elif child.suffix == ".md":
if child.name == "index.md":
continue
entries.append({_prettify(child.stem): rel(child)})
return entries
def _prettify(name: str) -> str:
"""
Convert a filename or directory name into a navigation label.
Numeric order prefixes (``01_``, ``02-``, ``03.``) are stripped,
separators are replaced with spaces, and the result is title-cased.
Args:
name (str):
Filename stem or directory name to prettify.
Returns:
str:
Title-cased navigation label.
"""
name = re.sub(r"^\d+[_\-. ]?", "", name)
name = re.sub(r"[_-]+", " ", name).strip()
return name.title()
def _natural_key(name: str) -> list[object]:
"""
Build a natural sort key from a filename.
The key splits ``name`` into alternating non-digit and digit parts so
that numeric prefixes sort numerically (``02`` before ``10``).
Args:
name (str):
Filename or directory name to key.
Returns:
list[object]:
Mixed list of lowercased strings and integers used for sorting.
"""
return [
int(part) if part.isdigit() else part.lower()
for part in re.split(r"(\d+)", name)
]

41
docforge/nav/wiki.pyi Normal file
View File

@@ -0,0 +1,41 @@
from collections.abc import Callable
from pathlib import Path
from typing import Any
def build_wiki_nav(wiki_dir: Path) -> list[dict[str, Any]]:
"""
Derive an MkDocs navigation block from a wiki directory.
Args:
wiki_dir (Path):
Path to the hand-written wiki directory.
Returns:
list[dict[str, Any]]:
Wiki navigation entries compatible with the MkDocs `nav`
configuration.
Raises:
FileNotFoundError:
If the wiki directory does not exist.
"""
...
def _render_entries(
base_dir: Path,
rel: Callable[[Path], str],
) -> list[dict[str, Any]]:
"""
Render navigation entries for the children of a wiki directory.
Args:
base_dir (Path):
Directory whose children are rendered.
rel (Callable[[Path], str]):
Callable converting a wiki file path into a docs-relative path.
Returns:
list[dict[str, Any]]:
Navigation entries for `base_dir` in natural sort order.
"""
...

0
docforge/py.typed Normal file
View File

View File

@@ -1,13 +1,14 @@
"""
# Summary
Renderers layer for doc-forge.
The ``docforge.renderers`` package transforms the internal documentation
The `docforge.renderers` package transforms the internal documentation
models into files formatted for specific documentation systems.
---
Overview
--------
# Overview
Renderers consume the doc-forge project model and generate output suitable
for documentation tools or machine interfaces.
@@ -15,18 +16,17 @@ 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.
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
---------
# Extending
New renderers can be added by implementing the ``DocRenderer`` protocol
defined in ``docforge.renderers.base``.
New renderers can be added by implementing the `DocRenderer` protocol
defined in `docforge.renderers.base`.
---
"""

View File

@@ -1,5 +1,5 @@
from .mkdocs_renderer import MkDocsRenderer
from .mcp_renderer import MCPRenderer
from .mkdocs_renderer import MkDocsRenderer
__all__ = [
"MkDocsRenderer",

View File

@@ -1,9 +1,11 @@
"""
# Summary
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.
`DocRenderer` protocol.
"""
from pathlib import Path
@@ -16,12 +18,15 @@ class RendererConfig:
"""
Configuration container for documentation renderers.
A ``RendererConfig`` instance groups together the project model and the
A `RendererConfig` instance groups together the project model and the
output directory used during rendering.
Attributes:
out_dir: Directory where generated documentation files will be written.
project: Documentation project model to be rendered.
out_dir (Path):
Directory where generated documentation files will be written.
project (Project):
Documentation project model to be rendered.
"""
def __init__(self, out_dir: Path, project: Project) -> None:
@@ -29,8 +34,11 @@ class RendererConfig:
Initialize a RendererConfig instance.
Args:
out_dir: Target directory where documentation files should be written.
project: Introspected project model to render.
out_dir (Path):
Target directory where documentation files should be written.
project (Project):
Introspected project model to render.
"""
self.out_dir = out_dir
self.project = project
@@ -41,7 +49,7 @@ class DocRenderer(Protocol):
Protocol defining the interface for documentation renderers.
Implementations of this protocol are responsible for transforming a
``Project`` model into renderer-specific documentation sources.
`Project` model into renderer-specific documentation sources.
"""
name: str
@@ -55,8 +63,10 @@ class DocRenderer(Protocol):
Generate renderer-specific documentation sources.
Args:
project: Project model containing modules and documentation objects.
out_dir: Directory where generated documentation sources
should be written.
project (Project):
Project model containing modules and documentation objects.
out_dir (Path):
Directory where generated documentation sources should be written.
"""
...

View File

@@ -3,7 +3,6 @@ from typing import Protocol
from docforge.models import Project
class RendererConfig:
"""Renderer configuration container."""
@@ -12,7 +11,6 @@ class RendererConfig:
def __init__(self, out_dir: Path, project: Project) -> None: ...
class DocRenderer(Protocol):
"""Renderer interface."""

View File

@@ -1,8 +1,16 @@
"""
# Summary
MCP renderer implementation.
This module defines the `MCPRenderer` class, which generates documentation
resources compatible with the Model Context Protocol (MCP).
"""
import json
from pathlib import Path
from typing import Dict, List
from docforge.models import Project, Module, DocObject
from docforge.models import DocObject, Module, Project
class MCPRenderer:
@@ -21,24 +29,29 @@ class MCPRenderer:
Generate MCP documentation resources for a project.
The renderer serializes each module into a JSON resource and produces
supporting metadata files such as ``nav.json`` and ``index.json``.
supporting metadata files such as `nav.json` and `index.json`.
Args:
project: Documentation project model to render.
out_dir: Directory where MCP resources will be written.
project (Project):
Documentation project model to render.
out_dir (Path):
Directory where MCP resources will be written.
"""
modules_dir = out_dir / "modules"
modules_dir.mkdir(parents=True, exist_ok=True)
nav: List[Dict[str, str]] = []
nav: list[dict[str, str]] = []
for module in project.get_all_modules():
self._write_module(module, modules_dir)
nav.append({
"module": module.path,
"resource": f"doc://modules/{module.path}",
})
nav.append(
{
"module": module.path,
"resource": f"docs://modules/{module.path}",
}
)
# Write nav.json
(out_dir / "nav.json").write_text(
@@ -64,8 +77,11 @@ class MCPRenderer:
Serialize a module into an MCP resource file.
Args:
module: Module instance to serialize.
modules_dir: Directory where module JSON files are stored.
module (Module):
Module instance to serialize.
modules_dir (Path):
Directory where module JSON files are stored.
"""
payload = {
"module": module.path,
@@ -76,17 +92,19 @@ class MCPRenderer:
out.parent.mkdir(parents=True, exist_ok=True)
out.write_text(self._json(payload), encoding="utf-8")
def _render_module(self, module: Module) -> Dict:
def _render_module(self, module: Module) -> dict:
"""
Convert a Module model into MCP-compatible structured data.
Args:
module: Module instance to convert.
module (Module):
Module instance to convert.
Returns:
Dictionary representing the module and its documented objects.
dict:
Dictionary representing the module and its documented objects.
"""
data: Dict = {
data: dict = {
"path": module.path,
"docstring": module.docstring,
"objects": {},
@@ -97,17 +115,19 @@ class MCPRenderer:
return data
def _render_object(self, obj: DocObject) -> Dict:
def _render_object(self, obj: DocObject) -> dict:
"""
Recursively convert a DocObject into structured MCP data.
Args:
obj: Documentation object to convert.
obj (DocObject):
Documentation object to convert.
Returns:
Dictionary describing the object and any nested members.
dict:
Dictionary describing the object and any nested members.
"""
data: Dict = {
data: dict = {
"name": obj.name,
"kind": obj.kind,
"path": obj.path,
@@ -118,21 +138,22 @@ class MCPRenderer:
members = list(obj.get_all_members())
if members:
data["members"] = {
member.name: self._render_object(member)
for member in members
member.name: self._render_object(member) for member in members
}
return data
@staticmethod
def _json(data: Dict) -> str:
def _json(data: dict) -> str:
"""
Serialize data to formatted JSON.
Args:
data: Dictionary to serialize.
data (dict):
Dictionary to serialize.
Returns:
JSON string formatted with indentation and UTF-8 compatibility.
str:
JSON string formatted with indentation and UTF-8 compatibility.
"""
return json.dumps(data, indent=2, ensure_ascii=False)

View File

@@ -1,8 +1,7 @@
from pathlib import Path
from typing import Dict, List
from docforge.models import Project, Module, DocObject
from typing import Any
from docforge.models import DocObject, Module, Project
class MCPRenderer:
"""Renderer that emits MCP-native JSON resources from docforge models."""
@@ -15,12 +14,12 @@ class MCPRenderer:
def _write_module(self, module: Module, modules_dir: Path) -> None:
"""Serialize a module into an MCP JSON resource."""
def _render_module(self, module: Module) -> Dict:
def _render_module(self, module: Module) -> dict[str, Any]:
"""Render a Module into MCP-friendly structured data."""
def _render_object(self, obj: DocObject) -> Dict:
def _render_object(self, obj: DocObject) -> dict[str, Any]:
"""Recursively render a DocObject into structured MCP data."""
@staticmethod
def _json(data: Dict) -> str:
def _json(data: dict[str, Any]) -> str:
"""Serialize structured data to formatted JSON."""

View File

@@ -1,20 +1,23 @@
"""
# Summary
MkDocs renderer implementation.
This module defines the ``MkDocsRenderer`` class, which generates Markdown
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
- 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
- Optionally generating `README.md` from the root package docstring
"""
from pathlib import Path
from docforge.models import Project, Module
from docforge.models import Module, Project
class MkDocsRenderer:
@@ -45,10 +48,15 @@ class MkDocsRenderer:
specified output directory.
Args:
project: Project model containing modules to document.
out_dir: Directory where generated Markdown files will be written.
module_is_source: If True, treat the specified module as the
documentation root rather than nesting it inside a folder.
project (Project):
Project model containing modules to document.
out_dir (Path):
Directory where generated Markdown files will be written.
module_is_source (bool | None):
If True, treat the specified module as the documentation root
rather than nesting it inside a folder.
"""
out_dir.mkdir(parents=True, exist_ok=True)
self._ensure_root_index(project, out_dir)
@@ -58,8 +66,7 @@ class MkDocsRenderer:
# Detect packages (modules with children)
packages = {
p for p in paths
if any(other.startswith(p + ".") for other in paths)
p for p in paths if any(other.startswith(p + ".") for other in paths)
}
for module in modules:
@@ -75,28 +82,37 @@ class MkDocsRenderer:
project: Project,
docs_dir: Path,
module_is_source: bool | None = None,
readme_dir: Path | None = None,
) -> None:
"""
Generate a ``README.md`` file from the root module docstring.
Generate a `README.md` file from the root module docstring.
Behavior:
- If ``module_is_source`` is True, ``README.md`` is written to the
project root directory.
- If False, README generation is currently not implemented.
Notes:
- If `module_is_source` is True, `README.md` is written to the
project root directory.
- If False, README generation is currently not implemented.
Args:
project: Project model containing documentation metadata.
docs_dir: Directory containing generated documentation sources.
module_is_source: Whether the module is treated as the project
source root.
project (Project):
Project model containing documentation metadata.
docs_dir (Path):
Directory containing generated documentation sources.
module_is_source (bool | None):
Whether the module is treated as the project source root.
readme_dir (Path | None):
Directory where the generated README.md should be written.
Defaults to the parent of `docs_dir`.
"""
if not module_is_source:
# Future: support README generation per module
return
readme_path = docs_dir.parent / "README.md"
readme_root = readme_dir if readme_dir is not None else docs_dir.parent
readme_path = readme_root / "README.md"
root_module = None
for module in project.get_all_modules():
@@ -116,12 +132,12 @@ class MkDocsRenderer:
str(root_module.docstring),
)
content = (
f"# {project.name}\n\n"
f"{doc.strip()}\n"
)
content = f"# {project.name}\n\n" f"{doc.strip()}\n"
if not readme_path.exists() or readme_path.read_text(encoding="utf-8") != content:
if (
not readme_path.exists()
or readme_path.read_text(encoding="utf-8") != content
):
readme_path.write_text(
content,
encoding="utf-8",
@@ -136,10 +152,12 @@ class MkDocsRenderer:
Locate the root module corresponding to the project name.
Args:
project: Project model to inspect.
project (Project):
Project model to inspect.
Returns:
The root ``Module`` if found, otherwise ``None``.
Module | None:
The root `Module` if found, otherwise `None`.
"""
for module in project.get_all_modules():
if module.path == project.name:
@@ -156,16 +174,22 @@ class MkDocsRenderer:
"""
Write documentation for a single module.
Package modules are rendered as ``index.md`` files inside their
Package modules are rendered as `index.md` files inside their
corresponding directories, while leaf modules are written as
standalone Markdown pages.
Args:
module: Module to render.
packages: Set of module paths identified as packages.
out_dir: Base directory for generated documentation files.
module_is_source: Whether the module acts as the documentation
root directory.
module (Module):
Module to render.
packages (set[str]):
Set of module paths identified as packages.
out_dir (Path):
Base directory for generated documentation files.
module_is_source (bool | None):
Whether the module acts as the documentation root directory.
"""
parts = module.path.split(".")
@@ -202,16 +226,17 @@ class MkDocsRenderer:
Generate Markdown content for a module documentation page.
Args:
title: Page title displayed in the documentation.
module_path: Dotted import path of the module.
title (str):
Page title displayed in the documentation.
module_path (str):
Dotted import path of the module.
Returns:
Markdown source containing a mkdocstrings directive.
str:
Markdown source containing a mkdocstrings directive.
"""
return (
f"# {title}\n\n"
f"::: {module_path}\n"
)
return f"# {title}\n\n" f"::: {module_path}\n"
def _ensure_root_index(
self,
@@ -219,18 +244,20 @@ class MkDocsRenderer:
out_dir: Path,
) -> None:
"""
Ensure that the root ``index.md`` page exists.
Ensure that the root `index.md` page exists.
Args:
project: Project model used for the page title.
out_dir: Documentation output directory.
project (Project):
Project model used for the page title.
out_dir (Path):
Documentation output directory.
"""
root_index = out_dir / "index.md"
if not root_index.exists():
root_index.write_text(
f"# {project.name}\n\n"
"## Modules\n\n",
f"# {project.name}\n\n" "## Modules\n\n",
encoding="utf-8",
)
@@ -246,10 +273,17 @@ class MkDocsRenderer:
child modules.
Args:
parts: Module path components.
out_dir: Documentation output directory.
link_target: Link target used in the parent index.
title: Display title for the link.
parts (list[str]):
Module path components.
out_dir (Path):
Documentation output directory.
link_target (str):
Link target used in the parent index.
title (str):
Display title for the link.
"""
if len(parts) == 1:
parent_index = out_dir / "index.md"

View File

@@ -1,6 +1,6 @@
from pathlib import Path
from docforge.models import Project, Module
from docforge.models import Module, Project
class MkDocsRenderer:
name: str
@@ -11,14 +11,12 @@ class MkDocsRenderer:
out_dir: Path,
module_is_source: bool | None = None,
) -> None: ...
def generate_readme(
self,
project: Project,
docs_dir: Path,
module_is_source: bool | None = None,
) -> None:
) -> None: ...
def _write_module(
self,
module: Module,
@@ -26,9 +24,8 @@ class MkDocsRenderer:
out_dir: Path,
module_is_source: bool | None = None,
) -> None: ...
def _render_markdown(self, title: str, module_path: str) -> str: ...
def _ensure_root_index(self, project, out_dir) -> None: ...
def _ensure_parent_index(self, parts, out_dir, link_target, title) -> None: ...
def _ensure_root_index(self, project: Project, out_dir: Path) -> None: ...
def _ensure_parent_index(
self, parts: list[str], out_dir: Path, link_target: str, title: str
) -> None: ...

View File

@@ -1,4 +1,6 @@
"""
# Summary
Server layer for doc-forge.
This module exposes server implementations used to provide live access

View File

@@ -1,11 +1,28 @@
"""
# Summary
MCP server implementation.
This module defines the `MCPServer` class, which serves pre-generated
documentation bundles through the Model Context Protocol (MCP).
---
Notes:
- The served bundle is generated offline by `MCPRenderer`.
- Missing resources are reported as structured error dictionaries rather
than raising exceptions.
- The server exposes read-only resources and a single health-check tool.
---
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any, Literal
from mcp.server.fastmcp import FastMCP
class MCPServer:
"""
@@ -13,6 +30,14 @@ class MCPServer:
The server exposes documentation resources and diagnostic tools through
MCP endpoints backed by JSON files generated by the MCP renderer.
Attributes:
mcp_root (Path):
Directory containing the generated MCP documentation bundle.
app (FastMCP):
Underlying FastMCP application instance that registers resources
and tools.
"""
def __init__(self, mcp_root: Path, name: str) -> None:
@@ -20,11 +45,15 @@ class MCPServer:
Initialize the MCP server.
Args:
mcp_root: Directory containing the generated MCP documentation
bundle (for example ``index.json``, ``nav.json``, and
``modules/``).
name: Identifier used for the MCP server instance.
mcp_root (Path):
Directory containing the generated MCP documentation bundle
(for example `index.json`, `nav.json`, and `modules/`).
name (str):
Identifier used for the MCP server instance.
"""
from mcp.server.fastmcp import FastMCP
self.mcp_root = mcp_root
self.app = FastMCP(name)
@@ -43,11 +72,13 @@ class MCPServer:
instead of raising an exception.
Args:
path: Path to the JSON file to read.
path (Path):
Path to the JSON file to read.
Returns:
Parsed JSON data if the file exists, otherwise an error dictionary
describing the missing resource.
Any:
Parsed JSON data if the file exists, otherwise an error dictionary
describing the missing resource.
"""
if not path.exists():
return {
@@ -68,9 +99,9 @@ class MCPServer:
The server exposes documentation resources through the following
endpoints:
- ``docs://index`` – Project metadata
- ``docs://nav`` – Navigation structure
- ``docs://modules/{module}`` – Individual module documentation
- `docs://index` – Project metadata
- `docs://nav` – Navigation structure
- `docs://modules/{module}` – Individual module documentation
"""
@self.app.resource("docs://index")
@@ -83,9 +114,7 @@ class MCPServer:
@self.app.resource("docs://modules/{module}")
def module(module: str):
return self._read_json(
self.mcp_root / "modules" / f"{module}.json"
)
return self._read_json(self.mcp_root / "modules" / f"{module}.json")
# ------------------------------------------------------------------
# MCP tools
@@ -116,7 +145,8 @@ class MCPServer:
Start the MCP server.
Args:
transport: Transport mechanism used by the MCP server. Supported
options include ``stdio``, ``sse``, and ``streamable-http``.
transport (Literal["stdio", "sse", "streamable-http"]):
Transport mechanism used by the MCP server. Supported options
include `stdio`, `sse`, and `streamable-http`.
"""
self.app.run(transport=transport)

View File

@@ -1,22 +1,20 @@
from pathlib import Path
from typing import Literal, Any
from typing import Any, Literal
from mcp.server.fastmcp import FastMCP
class MCPServer:
"""MCP server for serving documentation."""
"""MCP server serving a pre-generated documentation bundle.
Exposes read-only documentation resources and a health-check tool.
"""
mcp_root: Path
app: FastMCP
def __init__(self, mcp_root: Path, name: str) -> None: ...
def _read_json(self, path: Path) -> Any: ...
def _register_resources(self) -> None: ...
def _register_tools(self) -> None: ...
def run(self, transport: Literal["stdio", "sse", "streamable-http"] = ...) -> None:
"""Start the MCP server."""

View File

@@ -0,0 +1,16 @@
theme:
features:
- toc.integrate
- header.autohide
- announce.dismiss
- footer.social
- content.code.select
- content.code.line_numbers
- content.tooltips
plugins:
- search
- swagger-ui-tag
- neoteroi.mkdocsoad:
use_pymdownx: true

View File

@@ -29,26 +29,6 @@ theme:
- search.share
- search.suggest
plugins:
- search
- mkdocstrings:
handlers:
python:
paths: ["."]
options:
docstring_style: google
show_source: false
show_signature_annotations: true
separate_signature: true
merge_init_into_class: true
inherited_members: true
annotations_path: brief
show_root_heading: true
group_by_category: true
show_category_heading: true
show_object_full_path: false
show_symbol_type_heading: true
markdown_extensions:
- pymdownx.superfences
- pymdownx.inlinehilite
@@ -57,7 +37,6 @@ markdown_extensions:
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.highlight:
linenums: true
anchor_linenums: true
@@ -76,3 +55,6 @@ markdown_extensions:
- pymdownx.caret
- pymdownx.tilde
- pymdownx.mark
extra_css:
- https://unpkg.com/dracula-prism/dist/css/dracula-prism.css

View File

@@ -0,0 +1,19 @@
plugins:
- search
- mkdocstrings:
handlers:
python:
paths: [".."]
options:
docstring_style: google
show_source: false
show_signature_annotations: true
separate_signature: true
merge_init_into_class: true
inherited_members: true
annotations_path: brief
show_root_heading: true
group_by_category: true
show_category_heading: true
show_object_full_path: false
show_symbol_type_heading: true

View File

@@ -0,0 +1,25 @@
theme:
features:
# Horizontal tab navigation (mongo-ops style)
- navigation.tabs
# Navigation UX
- toc.integrate
- header.autohide
- announce.dismiss
- footer.social
# Content & Code
- content.code.select
- content.code.line_numbers
- content.tooltips
palette:
scheme: slate
primary: blue grey
accent: teal
font:
text: Roboto
code: JetBrains Mono
icon:
logo: material/database
repo: fontawesome/brands/github
plugins:
- search

View File

@@ -0,0 +1,3 @@
# Api Utils
::: docforge.cli.api_utils

3
docs/lib/nav/wiki.md Normal file
View File

@@ -0,0 +1,3 @@
# Wiki
::: docforge.nav.wiki

View File

@@ -1,6 +1,6 @@
{
"project": "docforge",
"type": "docforge-model",
"modules_count": 22,
"modules_count": 24,
"source": "docforge"
}

View File

@@ -0,0 +1,67 @@
{
"module": "docforge.cli.api_utils",
"content": {
"path": "docforge.cli.api_utils",
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"objects": {
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
"path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME",
"signature": null,
"docstring": null
},
"OpenAPIMetadata": {
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.api_utils.OpenAPIMetadata",
"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.api_utils.OpenAPIMetadata.site_name",
"signature": null,
"docstring": null
},
"site_description": {
"name": "site_description",
"kind": "attribute",
"path": "docforge.cli.api_utils.OpenAPIMetadata.site_description",
"signature": null,
"docstring": null
},
"site_author": {
"name": "site_author",
"kind": "attribute",
"path": "docforge.cli.api_utils.OpenAPIMetadata.site_author",
"signature": null,
"docstring": null
}
}
},
"load_openapi_spec": {
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.api_utils.load_openapi_spec",
"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": "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": "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."
}
}
}
}

View File

@@ -0,0 +1,460 @@
{
"module": "docforge.cli.commands",
"content": {
"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": {
"api_utils": {
"name": "api_utils",
"kind": "module",
"path": "docforge.cli.commands.api_utils",
"signature": null,
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"members": {
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
"signature": null,
"docstring": null
},
"OpenAPIMetadata": {
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
"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": null,
"docstring": null
},
"site_description": {
"name": "site_description",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
"signature": null,
"docstring": null
},
"site_author": {
"name": "site_author",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
"signature": null,
"docstring": null
}
}
},
"load_openapi_spec": {
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.commands.api_utils.load_openapi_spec",
"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": "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": "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."
}
}
},
"mcp_utils": {
"name": "mcp_utils",
"kind": "module",
"path": "docforge.cli.commands.mcp_utils",
"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": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader",
"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": "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": "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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.discover_module_paths",
"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": 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": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources",
"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."
}
}
},
"MCPServer": {
"name": "MCPServer",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.MCPServer",
"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": null,
"docstring": null
},
"app": {
"name": "app",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPServer.app",
"signature": null,
"docstring": null
},
"run": {
"name": "run",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPServer.run",
"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`."
}
}
},
"generate_resources": {
"name": "generate_resources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.generate_resources",
"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": "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."
}
}
},
"mkdocs_utils": {
"name": "mkdocs_utils",
"kind": "module",
"path": "docforge.cli.commands.mkdocs_utils",
"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": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader",
"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": "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": "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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.discover_module_paths",
"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": 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": "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."
}
}
},
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_wiki_nav",
"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": "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": "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": 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": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources",
"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": "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`."
}
}
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.generate_sources",
"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": "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": "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": "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": "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": "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": "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."
}
}
},
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.GriffeLoader",
"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": "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": "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 ```"
}
}
},
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.cli.commands.DocObject",
"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": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.cli.commands.DocObject.add_member",
"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": "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": "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."
}
}
},
"cli": {
"name": "cli",
"kind": "attribute",
"path": "docforge.cli.commands.cli",
"signature": null,
"docstring": null
},
"build": {
"name": "build",
"kind": "function",
"path": "docforge.cli.commands.build",
"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": "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": "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."
}
}
}
}

View File

@@ -0,0 +1,820 @@
{
"module": "docforge.cli",
"content": {
"path": "docforge.cli",
"docstring": "# Summary\n\nCommand line interface entry point for doc-forge.\n\nThis module exposes the primary CLI entry function used by the\n`doc-forge` command. The actual command implementation resides in\n`docforge.cli.main`, while this module provides a stable import path\nfor external tools and the package entry point configuration.\n\nThe CLI is responsible for orchestrating documentation workflows such as\ngenerating renderer sources, building documentation sites, exporting\nmachine-readable documentation bundles, and starting development or MCP\nservers.\n\n---\n\n# Typical usage\n\nThe CLI is normally invoked through the installed command:\n\n```bash\ndoc-forge <command> [options]\n```\n\nProgrammatic invocation is also possible:\n\nExample:\n\n ```python\n from docforge.cli import main\n main()\n ```\n\n---",
"objects": {
"main": {
"name": "main",
"kind": "module",
"path": "docforge.cli.main",
"signature": null,
"docstring": "# Summary\n\nCommand-line entry point for the doc-forge CLI.\n\nThis module exposes the executable entry point that initializes the\nClick command group defined in `docforge.cli.commands`.",
"members": {
"cli": {
"name": "cli",
"kind": "attribute",
"path": "docforge.cli.main.cli",
"signature": null,
"docstring": null
},
"main": {
"name": "main",
"kind": "function",
"path": "docforge.cli.main.main",
"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."
}
}
},
"api_utils": {
"name": "api_utils",
"kind": "module",
"path": "docforge.cli.api_utils",
"signature": null,
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"members": {
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
"path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME",
"signature": null,
"docstring": null
},
"OpenAPIMetadata": {
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.api_utils.OpenAPIMetadata",
"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.api_utils.OpenAPIMetadata.site_name",
"signature": null,
"docstring": null
},
"site_description": {
"name": "site_description",
"kind": "attribute",
"path": "docforge.cli.api_utils.OpenAPIMetadata.site_description",
"signature": null,
"docstring": null
},
"site_author": {
"name": "site_author",
"kind": "attribute",
"path": "docforge.cli.api_utils.OpenAPIMetadata.site_author",
"signature": null,
"docstring": null
}
}
},
"load_openapi_spec": {
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.api_utils.load_openapi_spec",
"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": "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": "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."
}
}
},
"commands": {
"name": "commands",
"kind": "module",
"path": "docforge.cli.commands",
"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": {
"api_utils": {
"name": "api_utils",
"kind": "module",
"path": "docforge.cli.commands.api_utils",
"signature": null,
"docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
"members": {
"SWAGGER_SPEC_FILENAME": {
"name": "SWAGGER_SPEC_FILENAME",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
"signature": null,
"docstring": null
},
"OpenAPIMetadata": {
"name": "OpenAPIMetadata",
"kind": "class",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
"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": null,
"docstring": null
},
"site_description": {
"name": "site_description",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
"signature": null,
"docstring": null
},
"site_author": {
"name": "site_author",
"kind": "attribute",
"path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
"signature": null,
"docstring": null
}
}
},
"load_openapi_spec": {
"name": "load_openapi_spec",
"kind": "function",
"path": "docforge.cli.commands.api_utils.load_openapi_spec",
"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": "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": "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."
}
}
},
"mcp_utils": {
"name": "mcp_utils",
"kind": "module",
"path": "docforge.cli.commands.mcp_utils",
"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": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.GriffeLoader",
"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": "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": "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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.discover_module_paths",
"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": 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": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources",
"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."
}
}
},
"MCPServer": {
"name": "MCPServer",
"kind": "class",
"path": "docforge.cli.commands.mcp_utils.MCPServer",
"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": null,
"docstring": null
},
"app": {
"name": "app",
"kind": "attribute",
"path": "docforge.cli.commands.mcp_utils.MCPServer.app",
"signature": null,
"docstring": null
},
"run": {
"name": "run",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.MCPServer.run",
"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`."
}
}
},
"generate_resources": {
"name": "generate_resources",
"kind": "function",
"path": "docforge.cli.commands.mcp_utils.generate_resources",
"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": "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."
}
}
},
"mkdocs_utils": {
"name": "mkdocs_utils",
"kind": "module",
"path": "docforge.cli.commands.mkdocs_utils",
"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": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.mkdocs_utils.GriffeLoader",
"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": "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": "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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.discover_module_paths",
"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": 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": "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."
}
}
},
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.build_wiki_nav",
"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": "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": "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": 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": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources",
"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": "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`."
}
}
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.commands.mkdocs_utils.generate_sources",
"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": "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": "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": "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": "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": "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": "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."
}
}
},
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.commands.GriffeLoader",
"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": "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": "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 ```"
}
}
},
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.cli.commands.DocObject",
"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": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.cli.commands.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.cli.commands.DocObject.add_member",
"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": "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": "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."
}
}
},
"cli": {
"name": "cli",
"kind": "attribute",
"path": "docforge.cli.commands.cli",
"signature": null,
"docstring": null
},
"build": {
"name": "build",
"kind": "function",
"path": "docforge.cli.commands.build",
"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": "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": "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."
}
}
},
"mcp_utils": {
"name": "mcp_utils",
"kind": "module",
"path": "docforge.cli.mcp_utils",
"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": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.mcp_utils.GriffeLoader",
"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.mcp_utils.GriffeLoader.load_project",
"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.mcp_utils.GriffeLoader.load_module",
"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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.mcp_utils.discover_module_paths",
"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.mcp_utils.MCPRenderer",
"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.mcp_utils.MCPRenderer.name",
"signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mcp_utils.MCPRenderer.generate_sources",
"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."
}
}
},
"MCPServer": {
"name": "MCPServer",
"kind": "class",
"path": "docforge.cli.mcp_utils.MCPServer",
"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.mcp_utils.MCPServer.mcp_root",
"signature": null,
"docstring": null
},
"app": {
"name": "app",
"kind": "attribute",
"path": "docforge.cli.mcp_utils.MCPServer.app",
"signature": null,
"docstring": null
},
"run": {
"name": "run",
"kind": "function",
"path": "docforge.cli.mcp_utils.MCPServer.run",
"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`."
}
}
},
"generate_resources": {
"name": "generate_resources",
"kind": "function",
"path": "docforge.cli.mcp_utils.generate_resources",
"signature": "generate_resources(module: str, project_name: str | None, out_dir: Path) -> None",
"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.mcp_utils.serve",
"signature": "serve(module: str, mcp_root: Path) -> None",
"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."
}
}
},
"mkdocs_utils": {
"name": "mkdocs_utils",
"kind": "module",
"path": "docforge.cli.mkdocs_utils",
"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": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.mkdocs_utils.GriffeLoader",
"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.mkdocs_utils.GriffeLoader.load_project",
"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.mkdocs_utils.GriffeLoader.load_module",
"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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.discover_module_paths",
"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.mkdocs_utils.MkDocsNavEmitter",
"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.mkdocs_utils.MkDocsNavEmitter.emit",
"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."
}
}
},
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.build_wiki_nav",
"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.mkdocs_utils.load_nav_spec",
"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.mkdocs_utils.resolve_nav",
"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.mkdocs_utils.MkDocsRenderer",
"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.mkdocs_utils.MkDocsRenderer.name",
"signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.MkDocsRenderer.generate_sources",
"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.mkdocs_utils.MkDocsRenderer.generate_readme",
"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`."
}
}
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.generate_sources",
"signature": "generate_sources(module: str, docs_dir: Path, project_name: str | None = None, module_is_source: bool | None = None, readme_dir: Path | None = 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.mkdocs_utils.build_lib_nav",
"signature": "build_lib_nav(nav_file: Path, docs_root: Path) -> tuple[list[dict[str, Any]], dict[str, str] | None]",
"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.mkdocs_utils.build_wiki_nav_block",
"signature": "build_wiki_nav_block(wiki_dir: Path) -> list[dict[str, Any]]",
"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.mkdocs_utils.load_spec_icon",
"signature": "load_spec_icon(nav_file: Path) -> dict[str, str] | None",
"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.mkdocs_utils.generate_site_config",
"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) -> 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.mkdocs_utils.build_configs",
"signature": "build_configs(yml_paths: Iterable[Path]) -> None",
"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.mkdocs_utils.serve",
"signature": "serve(mkdocs_yml: Path) -> None",
"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."
}
}
}
}
}
}

View File

@@ -2,21 +2,21 @@
"module": "docforge.cli.main",
"content": {
"path": "docforge.cli.main",
"docstring": "Command-line entry point for the doc-forge CLI.\n\nThis module exposes the executable entry point that initializes the\nClick command group defined in ``docforge.cli.commands``.",
"docstring": "# Summary\n\nCommand-line entry point for the doc-forge CLI.\n\nThis module exposes the executable entry point that initializes the\nClick command group defined in `docforge.cli.commands`.",
"objects": {
"cli": {
"name": "cli",
"kind": "attribute",
"path": "docforge.cli.main.cli",
"signature": "<bound method Alias.signature of Alias('cli', 'docforge.cli.commands.cli')>",
"signature": null,
"docstring": null
},
"main": {
"name": "main",
"kind": "function",
"path": "docforge.cli.main.main",
"signature": "<bound method Function.signature of Function('main', 11, 19)>",
"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."
"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."
}
}
}

View File

@@ -0,0 +1,106 @@
{
"module": "docforge.cli.mcp_utils",
"content": {
"path": "docforge.cli.mcp_utils",
"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---",
"objects": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.mcp_utils.GriffeLoader",
"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.mcp_utils.GriffeLoader.load_project",
"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.mcp_utils.GriffeLoader.load_module",
"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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.mcp_utils.discover_module_paths",
"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.mcp_utils.MCPRenderer",
"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.mcp_utils.MCPRenderer.name",
"signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mcp_utils.MCPRenderer.generate_sources",
"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."
}
}
},
"MCPServer": {
"name": "MCPServer",
"kind": "class",
"path": "docforge.cli.mcp_utils.MCPServer",
"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.mcp_utils.MCPServer.mcp_root",
"signature": null,
"docstring": null
},
"app": {
"name": "app",
"kind": "attribute",
"path": "docforge.cli.mcp_utils.MCPServer.app",
"signature": null,
"docstring": null
},
"run": {
"name": "run",
"kind": "function",
"path": "docforge.cli.mcp_utils.MCPServer.run",
"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`."
}
}
},
"generate_resources": {
"name": "generate_resources",
"kind": "function",
"path": "docforge.cli.mcp_utils.generate_resources",
"signature": "generate_resources(module: str, project_name: str | None, out_dir: Path) -> None",
"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.mcp_utils.serve",
"signature": "serve(module: str, mcp_root: Path) -> None",
"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."
}
}
}
}

View File

@@ -0,0 +1,155 @@
{
"module": "docforge.cli.mkdocs_utils",
"content": {
"path": "docforge.cli.mkdocs_utils",
"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---",
"objects": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.cli.mkdocs_utils.GriffeLoader",
"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.mkdocs_utils.GriffeLoader.load_project",
"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.mkdocs_utils.GriffeLoader.load_module",
"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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.discover_module_paths",
"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.mkdocs_utils.MkDocsNavEmitter",
"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.mkdocs_utils.MkDocsNavEmitter.emit",
"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."
}
}
},
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.build_wiki_nav",
"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.mkdocs_utils.load_nav_spec",
"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.mkdocs_utils.resolve_nav",
"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.mkdocs_utils.MkDocsRenderer",
"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.mkdocs_utils.MkDocsRenderer.name",
"signature": null,
"docstring": null
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.MkDocsRenderer.generate_sources",
"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.mkdocs_utils.MkDocsRenderer.generate_readme",
"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`."
}
}
},
"generate_sources": {
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.generate_sources",
"signature": "generate_sources(module: str, docs_dir: Path, project_name: str | None = None, module_is_source: bool | None = None, readme_dir: Path | None = 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.mkdocs_utils.build_lib_nav",
"signature": "build_lib_nav(nav_file: Path, docs_root: Path) -> tuple[list[dict[str, Any]], dict[str, str] | None]",
"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.mkdocs_utils.build_wiki_nav_block",
"signature": "build_wiki_nav_block(wiki_dir: Path) -> list[dict[str, Any]]",
"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.mkdocs_utils.load_spec_icon",
"signature": "load_spec_icon(nav_file: Path) -> dict[str, str] | None",
"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.mkdocs_utils.generate_site_config",
"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) -> 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.mkdocs_utils.build_configs",
"signature": "build_configs(yml_paths: Iterable[Path]) -> None",
"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.mkdocs_utils.serve",
"signature": "serve(mkdocs_yml: Path) -> None",
"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."
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,220 @@
{
"module": "docforge.loaders.griffe_loader",
"content": {
"path": "docforge.loaders.griffe_loader",
"docstring": "# Summary\n\nUtilities for loading and introspecting Python modules using Griffe.\n\nThis module provides the `GriffeLoader` class and helper utilities used to\ndiscover Python modules, introspect their structure, and convert the results\ninto doc-forge documentation models.\n\n---\n\nNotes:\n - All analysis is static; analyzed modules are never executed.\n - Private members (names starting with `_`) are skipped during conversion.\n - Imported aliases that cannot be resolved (stdlib/third-party names) are\n skipped; aliases that resolve within the documented project are kept.\n\n---",
"objects": {
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.loaders.griffe_loader.DocObject",
"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.loaders.griffe_loader.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.loaders.griffe_loader.DocObject.add_member",
"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.loaders.griffe_loader.DocObject.get_member",
"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.loaders.griffe_loader.DocObject.get_all_members",
"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."
}
}
},
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.loaders.griffe_loader.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Module.add_object",
"signature": "add_object(obj: DocObject)",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Module.get_object",
"signature": "get_object(name: str)",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Module.get_all_objects",
"signature": "get_all_objects()",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
},
"Project": {
"name": "Project",
"kind": "class",
"path": "docforge.loaders.griffe_loader.Project",
"signature": "Project(name: str)",
"docstring": "Representation of a documentation project.\n\nA `Project` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name (str):\n Name of the project.\n\n modules (dict[str, Module]):\n Mapping of module paths to `Module` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Project.name",
"signature": null,
"docstring": null
},
"modules": {
"name": "modules",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Project.modules",
"signature": null,
"docstring": null
},
"add_module": {
"name": "add_module",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.add_module",
"signature": "add_module(module: Module)",
"docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project."
},
"get_module": {
"name": "get_module",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.get_module",
"signature": "get_module(path: str)",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path (str):\n Fully qualified dotted module path (for example `pkg.module`).\n\nReturns:\n Module:\n The corresponding `Module` instance.\n\nRaises:\n KeyError:\n If the module does not exist in the project."
},
"get_all_modules": {
"name": "get_all_modules",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.get_all_modules",
"signature": "get_all_modules()",
"docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances."
},
"get_module_list": {
"name": "get_module_list",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.get_module_list",
"signature": "get_module_list()",
"docstring": "Return the list of module import paths.\n\nReturns:\n list[str]:\n A list containing the dotted paths of all modules in the project."
}
}
},
"logger": {
"name": "logger",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.logger",
"signature": null,
"docstring": null
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.loaders.griffe_loader.discover_module_paths",
"signature": "discover_module_paths(module_name: str, project_root: Path | None = None) -> list[str]",
"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."
},
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.loaders.griffe_loader.GriffeLoader",
"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.loaders.griffe_loader.GriffeLoader.load_project",
"signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None) -> Project",
"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.loaders.griffe_loader.GriffeLoader.load_module",
"signature": "load_module(path: str) -> Module",
"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 ```"
}
}
}
}
}
}

View File

@@ -0,0 +1,259 @@
{
"module": "docforge.loaders",
"content": {
"path": "docforge.loaders",
"docstring": "# Summary\n\nLoader layer for doc-forge.\n\nThe `docforge.loaders` package is responsible for discovering Python modules\nand extracting documentation data using static analysis.\n\n---\n\n# Overview\n\nThis layer converts Python source code into an intermediate documentation\nmodel used by doc-forge. It performs module discovery, introspection, and\ninitial filtering before the data is passed to the core documentation models.\n\nCore capabilities include:\n\n- **Module discovery** – Locate Python modules and packages within a project.\n- **Static introspection** – Parse docstrings, signatures, and object\n hierarchies using the `griffe` library without executing the code.\n- **Public API filtering** – Exclude private members (names prefixed with\n `_`) to produce clean public documentation structures.\n\n---",
"objects": {
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.loaders.GriffeLoader",
"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.loaders.GriffeLoader.load_project",
"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.loaders.GriffeLoader.load_module",
"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 ```"
}
}
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.loaders.discover_module_paths",
"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."
},
"griffe_loader": {
"name": "griffe_loader",
"kind": "module",
"path": "docforge.loaders.griffe_loader",
"signature": null,
"docstring": "# Summary\n\nUtilities for loading and introspecting Python modules using Griffe.\n\nThis module provides the `GriffeLoader` class and helper utilities used to\ndiscover Python modules, introspect their structure, and convert the results\ninto doc-forge documentation models.\n\n---\n\nNotes:\n - All analysis is static; analyzed modules are never executed.\n - Private members (names starting with `_`) are skipped during conversion.\n - Imported aliases that cannot be resolved (stdlib/third-party names) are\n skipped; aliases that resolve within the documented project are kept.\n\n---",
"members": {
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.loaders.griffe_loader.DocObject",
"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.loaders.griffe_loader.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.loaders.griffe_loader.DocObject.add_member",
"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.loaders.griffe_loader.DocObject.get_member",
"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.loaders.griffe_loader.DocObject.get_all_members",
"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."
}
}
},
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.loaders.griffe_loader.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Module.add_object",
"signature": "add_object(obj: DocObject)",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Module.get_object",
"signature": "get_object(name: str)",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Module.get_all_objects",
"signature": "get_all_objects()",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
},
"Project": {
"name": "Project",
"kind": "class",
"path": "docforge.loaders.griffe_loader.Project",
"signature": "Project(name: str)",
"docstring": "Representation of a documentation project.\n\nA `Project` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name (str):\n Name of the project.\n\n modules (dict[str, Module]):\n Mapping of module paths to `Module` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Project.name",
"signature": null,
"docstring": null
},
"modules": {
"name": "modules",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.Project.modules",
"signature": null,
"docstring": null
},
"add_module": {
"name": "add_module",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.add_module",
"signature": "add_module(module: Module)",
"docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project."
},
"get_module": {
"name": "get_module",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.get_module",
"signature": "get_module(path: str)",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path (str):\n Fully qualified dotted module path (for example `pkg.module`).\n\nReturns:\n Module:\n The corresponding `Module` instance.\n\nRaises:\n KeyError:\n If the module does not exist in the project."
},
"get_all_modules": {
"name": "get_all_modules",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.get_all_modules",
"signature": "get_all_modules()",
"docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances."
},
"get_module_list": {
"name": "get_module_list",
"kind": "function",
"path": "docforge.loaders.griffe_loader.Project.get_module_list",
"signature": "get_module_list()",
"docstring": "Return the list of module import paths.\n\nReturns:\n list[str]:\n A list containing the dotted paths of all modules in the project."
}
}
},
"logger": {
"name": "logger",
"kind": "attribute",
"path": "docforge.loaders.griffe_loader.logger",
"signature": null,
"docstring": null
},
"discover_module_paths": {
"name": "discover_module_paths",
"kind": "function",
"path": "docforge.loaders.griffe_loader.discover_module_paths",
"signature": "discover_module_paths(module_name: str, project_root: Path | None = None) -> list[str]",
"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."
},
"GriffeLoader": {
"name": "GriffeLoader",
"kind": "class",
"path": "docforge.loaders.griffe_loader.GriffeLoader",
"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.loaders.griffe_loader.GriffeLoader.load_project",
"signature": "load_project(module_paths: list[str], project_name: str | None = None, skip_import_errors: bool | None = None) -> Project",
"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.loaders.griffe_loader.GriffeLoader.load_module",
"signature": "load_module(path: str) -> Module",
"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 ```"
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,507 @@
{
"module": "docforge.models",
"content": {
"path": "docforge.models",
"docstring": "# Summary\n\nModel layer for doc-forge.\n\nThe `docforge.models` package defines the core data structures used to\nrepresent Python source code as a structured documentation model.\n\n---\n\n# Overview\n\nThe model layer forms the central intermediate representation used throughout\ndoc-forge. Python modules and objects discovered during introspection are\nconverted into a hierarchy of documentation models that can later be rendered\ninto different documentation formats.\n\nKey components:\n\n- **Project** – Root container representing an entire documented codebase.\n- **Module** – Representation of a Python module or package containing\n documented members.\n- **DocObject** – Recursive structure representing Python objects such as\n classes, functions, methods, and attributes.\n\nThese models are intentionally **renderer-agnostic**, allowing the same\ndocumentation structure to be transformed into multiple output formats\n(e.g., MkDocs, MCP, or other renderers).\n\n---",
"objects": {
"Project": {
"name": "Project",
"kind": "class",
"path": "docforge.models.Project",
"signature": "Project(name: str)",
"docstring": "Representation of a documentation project.\n\nA `Project` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name (str):\n Name of the project.\n\n modules (dict[str, Module]):\n Mapping of module paths to `Module` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.models.Project.name",
"signature": null,
"docstring": null
},
"modules": {
"name": "modules",
"kind": "attribute",
"path": "docforge.models.Project.modules",
"signature": null,
"docstring": null
},
"add_module": {
"name": "add_module",
"kind": "function",
"path": "docforge.models.Project.add_module",
"signature": "add_module(module: Module)",
"docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project."
},
"get_module": {
"name": "get_module",
"kind": "function",
"path": "docforge.models.Project.get_module",
"signature": "get_module(path: str)",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path (str):\n Fully qualified dotted module path (for example `pkg.module`).\n\nReturns:\n Module:\n The corresponding `Module` instance.\n\nRaises:\n KeyError:\n If the module does not exist in the project."
},
"get_all_modules": {
"name": "get_all_modules",
"kind": "function",
"path": "docforge.models.Project.get_all_modules",
"signature": "get_all_modules()",
"docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances."
},
"get_module_list": {
"name": "get_module_list",
"kind": "function",
"path": "docforge.models.Project.get_module_list",
"signature": "get_module_list()",
"docstring": "Return the list of module import paths.\n\nReturns:\n list[str]:\n A list containing the dotted paths of all modules in the project."
}
}
},
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.models.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.models.Module.add_object",
"signature": "add_object(obj: DocObject)",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.models.Module.get_object",
"signature": "get_object(name: str)",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.models.Module.get_all_objects",
"signature": "get_all_objects()",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
},
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.models.DocObject",
"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.models.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.models.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.models.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.models.DocObject.add_member",
"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.models.DocObject.get_member",
"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.models.DocObject.get_all_members",
"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."
}
}
},
"module": {
"name": "module",
"kind": "module",
"path": "docforge.models.module",
"signature": null,
"docstring": "# Summary\n\nDocumentation model representing a Python module or package.\n\nThis module defines the `Module` class used in the doc-forge documentation\nmodel. A `Module` acts as a container for top-level documented objects\n(classes, functions, variables, and other members) discovered during\nintrospection.\n\n---\n\nNotes:\n - Only public members are stored; private names are filtered by the loader.\n\n---",
"members": {
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.models.module.DocObject",
"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.models.module.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.models.module.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.module.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.models.module.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.module.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.module.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.models.module.DocObject.add_member",
"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.models.module.DocObject.get_member",
"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.models.module.DocObject.get_all_members",
"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."
}
}
},
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.models.module.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.module.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.module.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.module.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.models.module.Module.add_object",
"signature": "add_object(obj: DocObject) -> None",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.models.module.Module.get_object",
"signature": "get_object(name: str) -> DocObject",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.models.module.Module.get_all_objects",
"signature": "get_all_objects() -> Iterable[DocObject]",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
}
}
},
"object": {
"name": "object",
"kind": "module",
"path": "docforge.models.object",
"signature": null,
"docstring": "# Summary\n\nDocumentation model representing individual Python objects.\n\nThis module defines the `DocObject` class, the fundamental recursive unit of\nthe doc-forge documentation model. Each `DocObject` represents a Python\nentity such as a class, function, method, or attribute, and may contain nested\nmembers that form a hierarchical documentation structure.\n\n---\n\nNotes:\n - `DocObject` instances form a tree mirroring the Python import hierarchy.\n - Objects are renderer-agnostic and may be consumed by any renderer.\n\n---",
"members": {
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.models.object.DocObject",
"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.models.object.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.models.object.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.object.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.models.object.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.object.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.object.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.models.object.DocObject.add_member",
"signature": "add_member(obj: DocObject) -> None",
"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.models.object.DocObject.get_member",
"signature": "get_member(name: str) -> DocObject",
"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.models.object.DocObject.get_all_members",
"signature": "get_all_members() -> Iterable[DocObject]",
"docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members."
}
}
}
}
},
"project": {
"name": "project",
"kind": "module",
"path": "docforge.models.project",
"signature": null,
"docstring": "# Summary\n\nDocumentation model representing a project.\n\nThis module defines the `Project` class, the top-level container used by\ndoc-forge to represent a documented codebase. A `Project` aggregates multiple\nmodules and provides access to them through a unified interface.\n\n---\n\nNotes:\n - Modules are keyed by their dotted import path.\n - Objects are renderer-agnostic; the same model feeds every renderer.\n\n---",
"members": {
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.models.project.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.project.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.project.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.project.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.models.project.Module.add_object",
"signature": "add_object(obj: DocObject)",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.models.project.Module.get_object",
"signature": "get_object(name: str)",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.models.project.Module.get_all_objects",
"signature": "get_all_objects()",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
},
"Project": {
"name": "Project",
"kind": "class",
"path": "docforge.models.project.Project",
"signature": "Project(name: str)",
"docstring": "Representation of a documentation project.\n\nA `Project` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name (str):\n Name of the project.\n\n modules (dict[str, Module]):\n Mapping of module paths to `Module` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.models.project.Project.name",
"signature": null,
"docstring": null
},
"modules": {
"name": "modules",
"kind": "attribute",
"path": "docforge.models.project.Project.modules",
"signature": null,
"docstring": null
},
"add_module": {
"name": "add_module",
"kind": "function",
"path": "docforge.models.project.Project.add_module",
"signature": "add_module(module: Module) -> None",
"docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project."
},
"get_module": {
"name": "get_module",
"kind": "function",
"path": "docforge.models.project.Project.get_module",
"signature": "get_module(path: str) -> Module",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path (str):\n Fully qualified dotted module path (for example `pkg.module`).\n\nReturns:\n Module:\n The corresponding `Module` instance.\n\nRaises:\n KeyError:\n If the module does not exist in the project."
},
"get_all_modules": {
"name": "get_all_modules",
"kind": "function",
"path": "docforge.models.project.Project.get_all_modules",
"signature": "get_all_modules() -> Iterable[Module]",
"docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances."
},
"get_module_list": {
"name": "get_module_list",
"kind": "function",
"path": "docforge.models.project.Project.get_module_list",
"signature": "get_module_list() -> list[str]",
"docstring": "Return the list of module import paths.\n\nReturns:\n list[str]:\n A list containing the dotted paths of all modules in the project."
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,132 @@
{
"module": "docforge.models.module",
"content": {
"path": "docforge.models.module",
"docstring": "# Summary\n\nDocumentation model representing a Python module or package.\n\nThis module defines the `Module` class used in the doc-forge documentation\nmodel. A `Module` acts as a container for top-level documented objects\n(classes, functions, variables, and other members) discovered during\nintrospection.\n\n---\n\nNotes:\n - Only public members are stored; private names are filtered by the loader.\n\n---",
"objects": {
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.models.module.DocObject",
"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.models.module.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.models.module.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.module.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.models.module.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.module.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.module.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.models.module.DocObject.add_member",
"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.models.module.DocObject.get_member",
"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.models.module.DocObject.get_all_members",
"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."
}
}
},
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.models.module.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.module.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.module.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.module.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.models.module.Module.add_object",
"signature": "add_object(obj: DocObject) -> None",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.models.module.Module.get_object",
"signature": "get_object(name: str) -> DocObject",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.models.module.Module.get_all_objects",
"signature": "get_all_objects() -> Iterable[DocObject]",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
}
}
}
}

View File

@@ -0,0 +1,81 @@
{
"module": "docforge.models.object",
"content": {
"path": "docforge.models.object",
"docstring": "# Summary\n\nDocumentation model representing individual Python objects.\n\nThis module defines the `DocObject` class, the fundamental recursive unit of\nthe doc-forge documentation model. Each `DocObject` represents a Python\nentity such as a class, function, method, or attribute, and may contain nested\nmembers that form a hierarchical documentation structure.\n\n---\n\nNotes:\n - `DocObject` instances form a tree mirroring the Python import hierarchy.\n - Objects are renderer-agnostic and may be consumed by any renderer.\n\n---",
"objects": {
"DocObject": {
"name": "DocObject",
"kind": "class",
"path": "docforge.models.object.DocObject",
"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.models.object.DocObject.name",
"signature": null,
"docstring": null
},
"kind": {
"name": "kind",
"kind": "attribute",
"path": "docforge.models.object.DocObject.kind",
"signature": null,
"docstring": null
},
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.object.DocObject.path",
"signature": null,
"docstring": null
},
"signature": {
"name": "signature",
"kind": "attribute",
"path": "docforge.models.object.DocObject.signature",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.object.DocObject.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.object.DocObject.members",
"signature": null,
"docstring": null
},
"add_member": {
"name": "add_member",
"kind": "function",
"path": "docforge.models.object.DocObject.add_member",
"signature": "add_member(obj: DocObject) -> None",
"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.models.object.DocObject.get_member",
"signature": "get_member(name: str) -> DocObject",
"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.models.object.DocObject.get_all_members",
"signature": "get_all_members() -> Iterable[DocObject]",
"docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members."
}
}
}
}
}
}

View File

@@ -0,0 +1,111 @@
{
"module": "docforge.models.project",
"content": {
"path": "docforge.models.project",
"docstring": "# Summary\n\nDocumentation model representing a project.\n\nThis module defines the `Project` class, the top-level container used by\ndoc-forge to represent a documented codebase. A `Project` aggregates multiple\nmodules and provides access to them through a unified interface.\n\n---\n\nNotes:\n - Modules are keyed by their dotted import path.\n - Objects are renderer-agnostic; the same model feeds every renderer.\n\n---",
"objects": {
"Module": {
"name": "Module",
"kind": "class",
"path": "docforge.models.project.Module",
"signature": "Module(path: str, docstring: str | None = None)",
"docstring": "Representation of a documented Python module or package.\n\nA `Module` stores metadata about the module itself and maintains a\ncollection of top-level documentation objects discovered during\nintrospection.\n\nAttributes:\n path (str):\n Dotted import path of the module.\n\n docstring (str | None):\n Module-level documentation string, if present.\n\n members (dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.",
"members": {
"path": {
"name": "path",
"kind": "attribute",
"path": "docforge.models.project.Module.path",
"signature": null,
"docstring": null
},
"docstring": {
"name": "docstring",
"kind": "attribute",
"path": "docforge.models.project.Module.docstring",
"signature": null,
"docstring": null
},
"members": {
"name": "members",
"kind": "attribute",
"path": "docforge.models.project.Module.members",
"signature": null,
"docstring": null
},
"add_object": {
"name": "add_object",
"kind": "function",
"path": "docforge.models.project.Module.add_object",
"signature": "add_object(obj: DocObject)",
"docstring": "Add a documented object to the module.\n\nArgs:\n obj (DocObject):\n Documentation object to register as a top-level member of the module."
},
"get_object": {
"name": "get_object",
"kind": "function",
"path": "docforge.models.project.Module.get_object",
"signature": "get_object(name: str)",
"docstring": "Retrieve a documented object by name.\n\nArgs:\n name (str):\n Name of the object to retrieve.\n\nReturns:\n DocObject:\n The corresponding `DocObject` instance.\n\nRaises:\n KeyError:\n If no object with the given name exists."
},
"get_all_objects": {
"name": "get_all_objects",
"kind": "function",
"path": "docforge.models.project.Module.get_all_objects",
"signature": "get_all_objects()",
"docstring": "Return all top-level documentation objects in the module.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing the module's public members."
}
}
},
"Project": {
"name": "Project",
"kind": "class",
"path": "docforge.models.project.Project",
"signature": "Project(name: str)",
"docstring": "Representation of a documentation project.\n\nA `Project` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name (str):\n Name of the project.\n\n modules (dict[str, Module]):\n Mapping of module paths to `Module` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.models.project.Project.name",
"signature": null,
"docstring": null
},
"modules": {
"name": "modules",
"kind": "attribute",
"path": "docforge.models.project.Project.modules",
"signature": null,
"docstring": null
},
"add_module": {
"name": "add_module",
"kind": "function",
"path": "docforge.models.project.Project.add_module",
"signature": "add_module(module: Module) -> None",
"docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project."
},
"get_module": {
"name": "get_module",
"kind": "function",
"path": "docforge.models.project.Project.get_module",
"signature": "get_module(path: str) -> Module",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path (str):\n Fully qualified dotted module path (for example `pkg.module`).\n\nReturns:\n Module:\n The corresponding `Module` instance.\n\nRaises:\n KeyError:\n If the module does not exist in the project."
},
"get_all_modules": {
"name": "get_all_modules",
"kind": "function",
"path": "docforge.models.project.Project.get_all_modules",
"signature": "get_all_modules() -> Iterable[Module]",
"docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances."
},
"get_module_list": {
"name": "get_module_list",
"kind": "function",
"path": "docforge.models.project.Project.get_module_list",
"signature": "get_module_list() -> list[str]",
"docstring": "Return the list of module import paths.\n\nReturns:\n list[str]:\n A list containing the dotted paths of all modules in the project."
}
}
}
}
}
}

View File

@@ -8,36 +8,43 @@
"name": "NavSpec",
"kind": "class",
"path": "docforge.nav.NavSpec",
"signature": "<bound method Alias.signature of Alias('NavSpec', 'docforge.nav.spec.NavSpec')>",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.",
"signature": "NavSpec(home: str | None, groups: dict[str, list[str]], icon: dict[str, str] | None = None)",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.NavSpec.home",
"signature": "<bound method Alias.signature of Alias('home', 'docforge.nav.spec.NavSpec.home')>",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.NavSpec.groups",
"signature": "<bound method Alias.signature of Alias('groups', 'docforge.nav.spec.NavSpec.groups')>",
"signature": null,
"docstring": null
},
"icon": {
"name": "icon",
"kind": "attribute",
"path": "docforge.nav.NavSpec.icon",
"signature": null,
"docstring": null
},
"load": {
"name": "load",
"kind": "function",
"path": "docforge.nav.NavSpec.load",
"signature": "<bound method Alias.signature of Alias('load', 'docforge.nav.spec.NavSpec.load')>",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path: Filesystem path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
"signature": "load(path: Path)",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path (Path):\n Filesystem path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
},
"all_patterns": {
"name": "all_patterns",
"kind": "function",
"path": "docforge.nav.NavSpec.all_patterns",
"signature": "<bound method Alias.signature of Alias('all_patterns', 'docforge.nav.spec.NavSpec.all_patterns')>",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n A list containing the home document (if defined) and all\n group pattern entries."
"signature": "all_patterns()",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n list[str]:\n A list containing the home document (if defined) and all\n group pattern entries."
}
}
},
@@ -45,36 +52,36 @@
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.nav.load_nav_spec",
"signature": "<bound method Alias.signature of Alias('load_nav_spec', 'docforge.nav.spec.load_nav_spec')>",
"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 to the navigation specification file.\n\nReturns:\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."
"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."
},
"ResolvedNav": {
"name": "ResolvedNav",
"kind": "class",
"path": "docforge.nav.ResolvedNav",
"signature": "<bound method Alias.signature of Alias('ResolvedNav', 'docforge.nav.resolver.ResolvedNav')>",
"signature": "ResolvedNav(home: str | None, groups: dict[str, list[Path]], docs_root: Path | None = None)",
"docstring": "Resolved navigation structure.\n\nA ``ResolvedNav`` represents navigation data after glob patterns have been\nexpanded and paths validated against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page.\n groups: Mapping of navigation group titles to lists of resolved\n documentation file paths.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.ResolvedNav.home",
"signature": "<bound method Alias.signature of Alias('home', 'docforge.nav.resolver.ResolvedNav.home')>",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.ResolvedNav.groups",
"signature": "<bound method Alias.signature of Alias('groups', 'docforge.nav.resolver.ResolvedNav.groups')>",
"signature": null,
"docstring": null
},
"all_files": {
"name": "all_files",
"kind": "function",
"path": "docforge.nav.ResolvedNav.all_files",
"signature": "<bound method Alias.signature of Alias('all_files', 'docforge.nav.resolver.ResolvedNav.all_files')>",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nReturns:\n An iterable of ``Path`` objects representing documentation files.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
"signature": "all_files()",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nYields:\n Path:\n A documentation file referenced by the navigation, including\n the home page when defined.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
}
}
},
@@ -82,87 +89,66 @@
"name": "resolve_nav",
"kind": "function",
"path": "docforge.nav.resolve_nav",
"signature": "<bound method Alias.signature of Alias('resolve_nav', 'docforge.nav.resolver.resolve_nav')>",
"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: Navigation specification describing documentation layout.\n docs_root: Root directory containing documentation Markdown files.\n\nReturns:\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."
"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."
},
"MkDocsNavEmitter": {
"name": "MkDocsNavEmitter",
"kind": "class",
"path": "docforge.nav.MkDocsNavEmitter",
"signature": "<bound method Alias.signature of Alias('MkDocsNavEmitter', 'docforge.nav.mkdocs.MkDocsNavEmitter')>",
"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.nav.MkDocsNavEmitter.emit",
"signature": "<bound method Alias.signature of Alias('emit', 'docforge.nav.mkdocs.MkDocsNavEmitter.emit')>",
"docstring": "Generate a navigation structure for ``mkdocs.yml``.\n\nArgs:\n nav: Resolved navigation data describing documentation groups\n and their associated Markdown files.\n\nReturns:\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."
"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."
}
}
},
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.nav.build_wiki_nav",
"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."
},
"mkdocs": {
"name": "mkdocs",
"kind": "module",
"path": "docforge.nav.mkdocs",
"signature": null,
"docstring": "MkDocs navigation emitter.\n\nThis module provides the ``MkDocsNavEmitter`` class, which converts a\n``ResolvedNav`` instance into the navigation structure required by the\nMkDocs ``nav`` configuration.",
"docstring": "MkDocs navigation emitter.\n\nThis module provides the ``MkDocsNavEmitter`` class, which converts a\n``ResolvedNav`` instance into the navigation structure required by the\nMkDocs ``nav`` configuration.\n\n---\n\nNotes:\n - The emitted structure is a list of dictionaries, one per top-level nav\n entry, matching the MkDocs ``nav`` YAML format.\n\n---",
"members": {
"Path": {
"name": "Path",
"kind": "alias",
"path": "docforge.nav.mkdocs.Path",
"signature": "<bound method Alias.signature of Alias('Path', 'pathlib.Path')>",
"docstring": null
},
"List": {
"name": "List",
"kind": "alias",
"path": "docforge.nav.mkdocs.List",
"signature": "<bound method Alias.signature of Alias('List', 'typing.List')>",
"docstring": null
},
"Dict": {
"name": "Dict",
"kind": "alias",
"path": "docforge.nav.mkdocs.Dict",
"signature": "<bound method Alias.signature of Alias('Dict', 'typing.Dict')>",
"docstring": null
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "docforge.nav.mkdocs.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
},
"ResolvedNav": {
"name": "ResolvedNav",
"kind": "class",
"path": "docforge.nav.mkdocs.ResolvedNav",
"signature": "<bound method Alias.signature of Alias('ResolvedNav', 'docforge.nav.resolver.ResolvedNav')>",
"signature": "ResolvedNav(home: str | None, groups: dict[str, list[Path]], docs_root: Path | None = None)",
"docstring": "Resolved navigation structure.\n\nA ``ResolvedNav`` represents navigation data after glob patterns have been\nexpanded and paths validated against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page.\n groups: Mapping of navigation group titles to lists of resolved\n documentation file paths.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.mkdocs.ResolvedNav.home",
"signature": "<bound method Alias.signature of Alias('home', 'docforge.nav.resolver.ResolvedNav.home')>",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.mkdocs.ResolvedNav.groups",
"signature": "<bound method Alias.signature of Alias('groups', 'docforge.nav.resolver.ResolvedNav.groups')>",
"signature": null,
"docstring": null
},
"all_files": {
"name": "all_files",
"kind": "function",
"path": "docforge.nav.mkdocs.ResolvedNav.all_files",
"signature": "<bound method Alias.signature of Alias('all_files', 'docforge.nav.resolver.ResolvedNav.all_files')>",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nReturns:\n An iterable of ``Path`` objects representing documentation files.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
"signature": "all_files()",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nYields:\n Path:\n A documentation file referenced by the navigation, including\n the home page when defined.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
}
}
},
@@ -170,15 +156,15 @@
"name": "MkDocsNavEmitter",
"kind": "class",
"path": "docforge.nav.mkdocs.MkDocsNavEmitter",
"signature": "<bound method Class.signature of Class('MkDocsNavEmitter', 15, 81)>",
"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.nav.mkdocs.MkDocsNavEmitter.emit",
"signature": "<bound method Function.signature of Function('emit', 23, 51)>",
"docstring": "Generate a navigation structure for ``mkdocs.yml``.\n\nArgs:\n nav: Resolved navigation data describing documentation groups\n and their associated Markdown files.\n\nReturns:\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."
"signature": "emit(nav: ResolvedNav) -> list[dict[str, Any]]",
"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."
}
}
}
@@ -189,77 +175,49 @@
"kind": "module",
"path": "docforge.nav.resolver",
"signature": null,
"docstring": "Navigation resolution utilities.\n\nThis module resolves a ``NavSpec`` against the filesystem by expanding glob\npatterns and validating that referenced documentation files exist.",
"docstring": "Navigation resolution utilities.\n\nThis module resolves a ``NavSpec`` against the filesystem by expanding glob\npatterns and validating that referenced documentation files exist.\n\n---\n\nNotes:\n - Glob resolution is recursive and returns paths in sorted order.\n - Unmatched patterns raise ``FileNotFoundError`` to fail fast on typos.\n\n---",
"members": {
"Path": {
"name": "Path",
"kind": "alias",
"path": "docforge.nav.resolver.Path",
"signature": "<bound method Alias.signature of Alias('Path', 'pathlib.Path')>",
"docstring": null
},
"Dict": {
"name": "Dict",
"kind": "alias",
"path": "docforge.nav.resolver.Dict",
"signature": "<bound method Alias.signature of Alias('Dict', 'typing.Dict')>",
"docstring": null
},
"Iterable": {
"name": "Iterable",
"kind": "alias",
"path": "docforge.nav.resolver.Iterable",
"signature": "<bound method Alias.signature of Alias('Iterable', 'typing.Iterable')>",
"docstring": null
},
"List": {
"name": "List",
"kind": "alias",
"path": "docforge.nav.resolver.List",
"signature": "<bound method Alias.signature of Alias('List', 'typing.List')>",
"docstring": null
},
"glob": {
"name": "glob",
"kind": "alias",
"path": "docforge.nav.resolver.glob",
"signature": "<bound method Alias.signature of Alias('glob', 'glob')>",
"docstring": null
},
"NavSpec": {
"name": "NavSpec",
"kind": "class",
"path": "docforge.nav.resolver.NavSpec",
"signature": "<bound method Alias.signature of Alias('NavSpec', 'docforge.nav.spec.NavSpec')>",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.",
"signature": "NavSpec(home: str | None, groups: dict[str, list[str]], icon: dict[str, str] | None = None)",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.resolver.NavSpec.home",
"signature": "<bound method Alias.signature of Alias('home', 'docforge.nav.spec.NavSpec.home')>",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.resolver.NavSpec.groups",
"signature": "<bound method Alias.signature of Alias('groups', 'docforge.nav.spec.NavSpec.groups')>",
"signature": null,
"docstring": null
},
"icon": {
"name": "icon",
"kind": "attribute",
"path": "docforge.nav.resolver.NavSpec.icon",
"signature": null,
"docstring": null
},
"load": {
"name": "load",
"kind": "function",
"path": "docforge.nav.resolver.NavSpec.load",
"signature": "<bound method Alias.signature of Alias('load', 'docforge.nav.spec.NavSpec.load')>",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path: Filesystem path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
"signature": "load(path: Path)",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path (Path):\n Filesystem path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
},
"all_patterns": {
"name": "all_patterns",
"kind": "function",
"path": "docforge.nav.resolver.NavSpec.all_patterns",
"signature": "<bound method Alias.signature of Alias('all_patterns', 'docforge.nav.spec.NavSpec.all_patterns')>",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n A list containing the home document (if defined) and all\n group pattern entries."
"signature": "all_patterns()",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n list[str]:\n A list containing the home document (if defined) and all\n group pattern entries."
}
}
},
@@ -267,7 +225,7 @@
"name": "ResolvedNav",
"kind": "class",
"path": "docforge.nav.resolver.ResolvedNav",
"signature": "<bound method Class.signature of Class('ResolvedNav', 16, 65)>",
"signature": "ResolvedNav(home: str | None, groups: dict[str, list[Path]], docs_root: Path | None = None)",
"docstring": "Resolved navigation structure.\n\nA ``ResolvedNav`` represents navigation data after glob patterns have been\nexpanded and paths validated against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page.\n groups: Mapping of navigation group titles to lists of resolved\n documentation file paths.",
"members": {
"home": {
@@ -288,8 +246,8 @@
"name": "all_files",
"kind": "function",
"path": "docforge.nav.resolver.ResolvedNav.all_files",
"signature": "<bound method Function.signature of Function('all_files', 47, 65)>",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nReturns:\n An iterable of ``Path`` objects representing documentation files.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
"signature": "all_files() -> Iterable[Path]",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nYields:\n Path:\n A documentation file referenced by the navigation, including\n the home page when defined.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
}
}
},
@@ -297,15 +255,8 @@
"name": "resolve_nav",
"kind": "function",
"path": "docforge.nav.resolver.resolve_nav",
"signature": "<bound method Function.signature of Function('resolve_nav', 68, 136)>",
"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: Navigation specification describing documentation layout.\n docs_root: Root directory containing documentation Markdown files.\n\nReturns:\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."
},
"Optional": {
"name": "Optional",
"kind": "alias",
"path": "docforge.nav.resolver.Optional",
"signature": "<bound method Alias.signature of Alias('Optional', 'typing.Optional')>",
"docstring": null
"signature": "resolve_nav(spec: NavSpec, docs_root: Path) -> ResolvedNav",
"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."
}
}
},
@@ -314,49 +265,14 @@
"kind": "module",
"path": "docforge.nav.spec",
"signature": null,
"docstring": "Navigation specification model.\n\nThis module defines the ``NavSpec`` class, which represents the navigation\nstructure defined by the user in the doc-forge navigation specification\n(typically ``docforge.nav.yml``).",
"docstring": "Navigation specification model.\n\nThis module defines the ``NavSpec`` class, which represents the navigation\nstructure defined by the user in the doc-forge navigation specification\n(typically ``docforge.nav.yml``).\n\n---\n\nNotes:\n - The spec file supports an optional ``icon`` mapping for MkDocs theme\n customization.\n - All file references in ``groups`` are relative to the documentation root.\n\n---",
"members": {
"Path": {
"name": "Path",
"kind": "alias",
"path": "docforge.nav.spec.Path",
"signature": "<bound method Alias.signature of Alias('Path', 'pathlib.Path')>",
"docstring": null
},
"Dict": {
"name": "Dict",
"kind": "alias",
"path": "docforge.nav.spec.Dict",
"signature": "<bound method Alias.signature of Alias('Dict', 'typing.Dict')>",
"docstring": null
},
"List": {
"name": "List",
"kind": "alias",
"path": "docforge.nav.spec.List",
"signature": "<bound method Alias.signature of Alias('List', 'typing.List')>",
"docstring": null
},
"Optional": {
"name": "Optional",
"kind": "alias",
"path": "docforge.nav.spec.Optional",
"signature": "<bound method Alias.signature of Alias('Optional', 'typing.Optional')>",
"docstring": null
},
"yaml": {
"name": "yaml",
"kind": "alias",
"path": "docforge.nav.spec.yaml",
"signature": "<bound method Alias.signature of Alias('yaml', 'yaml')>",
"docstring": null
},
"NavSpec": {
"name": "NavSpec",
"kind": "class",
"path": "docforge.nav.spec.NavSpec",
"signature": "<bound method Class.signature of Class('NavSpec', 15, 104)>",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.",
"signature": "NavSpec(home: str | None, groups: dict[str, list[str]], icon: dict[str, str] | None = None)",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.",
"members": {
"home": {
"name": "home",
@@ -372,19 +288,26 @@
"signature": null,
"docstring": null
},
"icon": {
"name": "icon",
"kind": "attribute",
"path": "docforge.nav.spec.NavSpec.icon",
"signature": null,
"docstring": null
},
"load": {
"name": "load",
"kind": "function",
"path": "docforge.nav.spec.NavSpec.load",
"signature": "<bound method Function.signature of Function('load', 45, 86)>",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path: Filesystem path to the navigation specification file.\n\nReturns:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
"signature": "load(path: Path) -> NavSpec",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path (Path):\n Filesystem path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
},
"all_patterns": {
"name": "all_patterns",
"kind": "function",
"path": "docforge.nav.spec.NavSpec.all_patterns",
"signature": "<bound method Function.signature of Function('all_patterns', 88, 104)>",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n A list containing the home document (if defined) and all\n group pattern entries."
"signature": "all_patterns() -> list[str]",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n list[str]:\n A list containing the home document (if defined) and all\n group pattern entries."
}
}
},
@@ -392,8 +315,24 @@
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.nav.spec.load_nav_spec",
"signature": "<bound method Function.signature of Function('load_nav_spec', 107, 135)>",
"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 to the navigation specification file.\n\nReturns:\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."
"signature": "load_nav_spec(path: Path) -> NavSpec",
"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."
}
}
},
"wiki": {
"name": "wiki",
"kind": "module",
"path": "docforge.nav.wiki",
"signature": null,
"docstring": "# Summary\n\nWiki navigation derivation.\n\nThis module provides ``build_wiki_nav``, which derives an MkDocs-ready\nnavigation block from the file structure of a hand-written wiki directory\n(typically ``docs/wiki``). wiki content is authored by hand and is never\nmodified by doc-forge; only the navigation layout is inferred.\n\n# Notes\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.",
"members": {
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.nav.wiki.build_wiki_nav",
"signature": "build_wiki_nav(wiki_dir: Path) -> list[dict[str, Any]]",
"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."
}
}
}

View File

@@ -0,0 +1,55 @@
{
"module": "docforge.nav.mkdocs",
"content": {
"path": "docforge.nav.mkdocs",
"docstring": "MkDocs navigation emitter.\n\nThis module provides the ``MkDocsNavEmitter`` class, which converts a\n``ResolvedNav`` instance into the navigation structure required by the\nMkDocs ``nav`` configuration.\n\n---\n\nNotes:\n - The emitted structure is a list of dictionaries, one per top-level nav\n entry, matching the MkDocs ``nav`` YAML format.\n\n---",
"objects": {
"ResolvedNav": {
"name": "ResolvedNav",
"kind": "class",
"path": "docforge.nav.mkdocs.ResolvedNav",
"signature": "ResolvedNav(home: str | None, groups: dict[str, list[Path]], docs_root: Path | None = None)",
"docstring": "Resolved navigation structure.\n\nA ``ResolvedNav`` represents navigation data after glob patterns have been\nexpanded and paths validated against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page.\n groups: Mapping of navigation group titles to lists of resolved\n documentation file paths.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.mkdocs.ResolvedNav.home",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.mkdocs.ResolvedNav.groups",
"signature": null,
"docstring": null
},
"all_files": {
"name": "all_files",
"kind": "function",
"path": "docforge.nav.mkdocs.ResolvedNav.all_files",
"signature": "all_files()",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nYields:\n Path:\n A documentation file referenced by the navigation, including\n the home page when defined.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
}
}
},
"MkDocsNavEmitter": {
"name": "MkDocsNavEmitter",
"kind": "class",
"path": "docforge.nav.mkdocs.MkDocsNavEmitter",
"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.nav.mkdocs.MkDocsNavEmitter.emit",
"signature": "emit(nav: ResolvedNav) -> list[dict[str, Any]]",
"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."
}
}
}
}
}
}

View File

@@ -0,0 +1,90 @@
{
"module": "docforge.nav.resolver",
"content": {
"path": "docforge.nav.resolver",
"docstring": "Navigation resolution utilities.\n\nThis module resolves a ``NavSpec`` against the filesystem by expanding glob\npatterns and validating that referenced documentation files exist.\n\n---\n\nNotes:\n - Glob resolution is recursive and returns paths in sorted order.\n - Unmatched patterns raise ``FileNotFoundError`` to fail fast on typos.\n\n---",
"objects": {
"NavSpec": {
"name": "NavSpec",
"kind": "class",
"path": "docforge.nav.resolver.NavSpec",
"signature": "NavSpec(home: str | None, groups: dict[str, list[str]], icon: dict[str, str] | None = None)",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.resolver.NavSpec.home",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.resolver.NavSpec.groups",
"signature": null,
"docstring": null
},
"icon": {
"name": "icon",
"kind": "attribute",
"path": "docforge.nav.resolver.NavSpec.icon",
"signature": null,
"docstring": null
},
"load": {
"name": "load",
"kind": "function",
"path": "docforge.nav.resolver.NavSpec.load",
"signature": "load(path: Path)",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path (Path):\n Filesystem path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
},
"all_patterns": {
"name": "all_patterns",
"kind": "function",
"path": "docforge.nav.resolver.NavSpec.all_patterns",
"signature": "all_patterns()",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n list[str]:\n A list containing the home document (if defined) and all\n group pattern entries."
}
}
},
"ResolvedNav": {
"name": "ResolvedNav",
"kind": "class",
"path": "docforge.nav.resolver.ResolvedNav",
"signature": "ResolvedNav(home: str | None, groups: dict[str, list[Path]], docs_root: Path | None = None)",
"docstring": "Resolved navigation structure.\n\nA ``ResolvedNav`` represents navigation data after glob patterns have been\nexpanded and paths validated against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page.\n groups: Mapping of navigation group titles to lists of resolved\n documentation file paths.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.resolver.ResolvedNav.home",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.resolver.ResolvedNav.groups",
"signature": null,
"docstring": null
},
"all_files": {
"name": "all_files",
"kind": "function",
"path": "docforge.nav.resolver.ResolvedNav.all_files",
"signature": "all_files() -> Iterable[Path]",
"docstring": "Iterate over all files referenced by the navigation structure.\n\nYields:\n Path:\n A documentation file referenced by the navigation, including\n the home page when defined.\n\nRaises:\n RuntimeError: If the home page is defined but the documentation\n root is not available for resolution."
}
}
},
"resolve_nav": {
"name": "resolve_nav",
"kind": "function",
"path": "docforge.nav.resolver.resolve_nav",
"signature": "resolve_nav(spec: NavSpec, docs_root: Path) -> ResolvedNav",
"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."
}
}
}
}

View File

@@ -0,0 +1,60 @@
{
"module": "docforge.nav.spec",
"content": {
"path": "docforge.nav.spec",
"docstring": "Navigation specification model.\n\nThis module defines the ``NavSpec`` class, which represents the navigation\nstructure defined by the user in the doc-forge navigation specification\n(typically ``docforge.nav.yml``).\n\n---\n\nNotes:\n - The spec file supports an optional ``icon`` mapping for MkDocs theme\n customization.\n - All file references in ``groups`` are relative to the documentation root.\n\n---",
"objects": {
"NavSpec": {
"name": "NavSpec",
"kind": "class",
"path": "docforge.nav.spec.NavSpec",
"signature": "NavSpec(home: str | None, groups: dict[str, list[str]], icon: dict[str, str] | None = None)",
"docstring": "Parsed representation of a navigation specification.\n\nA ``NavSpec`` describes the intended documentation navigation layout before\nit is resolved against the filesystem.\n\nAttributes:\n home: Relative path to the documentation home page (for example\n ``index.md``).\n groups: Mapping of navigation group titles to lists of file patterns\n or glob expressions.\n icon: Optional mapping of theme icon entries (for example\n ``{\"logo\": \"material/code-tags\"}``) injected into the MkDocs\n theme as ``theme.icon``.",
"members": {
"home": {
"name": "home",
"kind": "attribute",
"path": "docforge.nav.spec.NavSpec.home",
"signature": null,
"docstring": null
},
"groups": {
"name": "groups",
"kind": "attribute",
"path": "docforge.nav.spec.NavSpec.groups",
"signature": null,
"docstring": null
},
"icon": {
"name": "icon",
"kind": "attribute",
"path": "docforge.nav.spec.NavSpec.icon",
"signature": null,
"docstring": null
},
"load": {
"name": "load",
"kind": "function",
"path": "docforge.nav.spec.NavSpec.load",
"signature": "load(path: Path) -> NavSpec",
"docstring": "Load a navigation specification from a YAML file.\n\nArgs:\n path (Path):\n Filesystem path to the navigation specification file.\n\nReturns:\n NavSpec:\n A ``NavSpec`` instance representing the parsed configuration.\n\nRaises:\n FileNotFoundError: If the specified file does not exist.\n ValueError: If the file contents are not a valid navigation\n specification."
},
"all_patterns": {
"name": "all_patterns",
"kind": "function",
"path": "docforge.nav.spec.NavSpec.all_patterns",
"signature": "all_patterns() -> list[str]",
"docstring": "Return all path patterns referenced by the specification.\n\nReturns:\n list[str]:\n A list containing the home document (if defined) and all\n group pattern entries."
}
}
},
"load_nav_spec": {
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.nav.spec.load_nav_spec",
"signature": "load_nav_spec(path: Path) -> NavSpec",
"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."
}
}
}
}

View File

@@ -0,0 +1,16 @@
{
"module": "docforge.nav.wiki",
"content": {
"path": "docforge.nav.wiki",
"docstring": "# Summary\n\nWiki navigation derivation.\n\nThis module provides ``build_wiki_nav``, which derives an MkDocs-ready\nnavigation block from the file structure of a hand-written wiki directory\n(typically ``docs/wiki``). wiki content is authored by hand and is never\nmodified by doc-forge; only the navigation layout is inferred.\n\n# Notes\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.",
"objects": {
"build_wiki_nav": {
"name": "build_wiki_nav",
"kind": "function",
"path": "docforge.nav.wiki.build_wiki_nav",
"signature": "build_wiki_nav(wiki_dir: Path) -> list[dict[str, Any]]",
"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."
}
}
}
}

View File

@@ -2,70 +2,56 @@
"module": "docforge.renderers.base",
"content": {
"path": "docforge.renderers.base",
"docstring": "Renderer base interfaces and configuration models.\n\nThis module defines the base protocol and configuration container used by\ndoc-forge renderers. Concrete renderer implementations should implement the\n``DocRenderer`` protocol.",
"docstring": "# Summary\n\nRenderer base interfaces and configuration models.\n\nThis module defines the base protocol and configuration container used by\ndoc-forge renderers. Concrete renderer implementations should implement the\n`DocRenderer` protocol.",
"objects": {
"Path": {
"name": "Path",
"kind": "alias",
"path": "docforge.renderers.base.Path",
"signature": "<bound method Alias.signature of Alias('Path', 'pathlib.Path')>",
"docstring": null
},
"Protocol": {
"name": "Protocol",
"kind": "alias",
"path": "docforge.renderers.base.Protocol",
"signature": "<bound method Alias.signature of Alias('Protocol', 'typing.Protocol')>",
"docstring": null
},
"Project": {
"name": "Project",
"kind": "class",
"path": "docforge.renderers.base.Project",
"signature": "<bound method Alias.signature of Alias('Project', 'docforge.models.Project')>",
"docstring": "Representation of a documentation project.\n\nA ``Project`` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name: Name of the project.\n modules: Mapping of module paths to ``Module`` instances.",
"signature": "Project(name: str)",
"docstring": "Representation of a documentation project.\n\nA `Project` serves as the root container for all modules discovered during\nintrospection. Each module is stored by its dotted import path.\n\nAttributes:\n name (str):\n Name of the project.\n\n modules (dict[str, Module]):\n Mapping of module paths to `Module` instances.",
"members": {
"name": {
"name": "name",
"kind": "attribute",
"path": "docforge.renderers.base.Project.name",
"signature": "<bound method Alias.signature of Alias('name', 'docforge.models.project.Project.name')>",
"signature": null,
"docstring": null
},
"modules": {
"name": "modules",
"kind": "attribute",
"path": "docforge.renderers.base.Project.modules",
"signature": "<bound method Alias.signature of Alias('modules', 'docforge.models.project.Project.modules')>",
"signature": null,
"docstring": null
},
"add_module": {
"name": "add_module",
"kind": "function",
"path": "docforge.renderers.base.Project.add_module",
"signature": "<bound method Alias.signature of Alias('add_module', 'docforge.models.project.Project.add_module')>",
"docstring": "Register a module in the project.\n\nArgs:\n module: Module instance to add to the project."
"signature": "add_module(module: Module)",
"docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project."
},
"get_module": {
"name": "get_module",
"kind": "function",
"path": "docforge.renderers.base.Project.get_module",
"signature": "<bound method Alias.signature of Alias('get_module', 'docforge.models.project.Project.get_module')>",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path: Fully qualified dotted module path (for example ``pkg.module``).\n\nReturns:\n The corresponding ``Module`` instance.\n\nRaises:\n KeyError: If the module does not exist in the project."
"signature": "get_module(path: str)",
"docstring": "Retrieve a module by its dotted path.\n\nArgs:\n path (str):\n Fully qualified dotted module path (for example `pkg.module`).\n\nReturns:\n Module:\n The corresponding `Module` instance.\n\nRaises:\n KeyError:\n If the module does not exist in the project."
},
"get_all_modules": {
"name": "get_all_modules",
"kind": "function",
"path": "docforge.renderers.base.Project.get_all_modules",
"signature": "<bound method Alias.signature of Alias('get_all_modules', 'docforge.models.project.Project.get_all_modules')>",
"docstring": "Return all modules contained in the project.\n\nReturns:\n An iterable of ``Module`` instances."
"signature": "get_all_modules()",
"docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances."
},
"get_module_list": {
"name": "get_module_list",
"kind": "function",
"path": "docforge.renderers.base.Project.get_module_list",
"signature": "<bound method Alias.signature of Alias('get_module_list', 'docforge.models.project.Project.get_module_list')>",
"docstring": "Return the list of module import paths.\n\nReturns:\n A list containing the dotted paths of all modules in the project."
"signature": "get_module_list()",
"docstring": "Return the list of module import paths.\n\nReturns:\n list[str]:\n A list containing the dotted paths of all modules in the project."
}
}
},
@@ -73,8 +59,8 @@
"name": "RendererConfig",
"kind": "class",
"path": "docforge.renderers.base.RendererConfig",
"signature": "<bound method Class.signature of Class('RendererConfig', 15, 36)>",
"docstring": "Configuration container for documentation renderers.\n\nA ``RendererConfig`` instance groups together the project model and the\noutput directory used during rendering.\n\nAttributes:\n out_dir: Directory where generated documentation files will be written.\n project: Documentation project model to be rendered.",
"signature": "RendererConfig(out_dir: Path, project: Project)",
"docstring": "Configuration container for documentation renderers.\n\nA `RendererConfig` instance groups together the project model and the\noutput directory used during rendering.\n\nAttributes:\n out_dir (Path):\n Directory where generated documentation files will be written.\n\n project (Project):\n Documentation project model to be rendered.",
"members": {
"out_dir": {
"name": "out_dir",
@@ -96,8 +82,8 @@
"name": "DocRenderer",
"kind": "class",
"path": "docforge.renderers.base.DocRenderer",
"signature": "<bound method Class.signature of Class('DocRenderer', 39, 62)>",
"docstring": "Protocol defining the interface for documentation renderers.\n\nImplementations of this protocol are responsible for transforming a\n``Project`` model into renderer-specific documentation sources.",
"signature": null,
"docstring": "Protocol defining the interface for documentation renderers.\n\nImplementations of this protocol are responsible for transforming a\n`Project` model into renderer-specific documentation sources.",
"members": {
"name": {
"name": "name",
@@ -110,8 +96,8 @@
"name": "generate_sources",
"kind": "function",
"path": "docforge.renderers.base.DocRenderer.generate_sources",
"signature": "<bound method Function.signature of Function('generate_sources', 49, 62)>",
"docstring": "Generate renderer-specific documentation sources.\n\nArgs:\n project: Project model containing modules and documentation objects.\n out_dir: Directory where generated documentation sources\n should be written."
"signature": "generate_sources(project: Project, out_dir: Path) -> None",
"docstring": "Generate renderer-specific documentation sources.\n\nArgs:\n project (Project):\n Project model containing modules and documentation objects.\n\n out_dir (Path):\n Directory where generated documentation sources should be written."
}
}
}

Some files were not shown because too many files have changed in this diff Show More