Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9e6945c26 | |||
| 85243c418d | |||
| 06ffd2febd | |||
| 8253c25928 | |||
| e8e16f3996 | |||
| f73282b997 |
60
.drone.yml
60
.drone.yml
@@ -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
6
.gitignore
vendored
@@ -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
47
CHANGELOG.md
Normal 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
21
LICENSE
Normal 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
570
README.md
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from .main import main
|
||||
|
||||
__all__ = [
|
||||
"main"
|
||||
]
|
||||
__all__ = ["main"]
|
||||
|
||||
118
docforge/cli/api_utils.py
Normal file
118
docforge/cli/api_utils.py
Normal 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")
|
||||
13
docforge/cli/api_utils.pyi
Normal file
13
docforge/cli/api_utils.pyi
Normal 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: ...
|
||||
@@ -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():
|
||||
|
||||
@@ -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: ...
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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: ...
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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: ...
|
||||
|
||||
@@ -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.
|
||||
|
||||
---
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from .project import Project
|
||||
from .module import Module
|
||||
from .object import DocObject
|
||||
from .project import Project
|
||||
|
||||
__all__ = [
|
||||
"Project",
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]: ...
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]: ...
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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]: ...
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"),
|
||||
)
|
||||
|
||||
@@ -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
165
docforge/nav/wiki.py
Normal 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
41
docforge/nav/wiki.pyi
Normal 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
0
docforge/py.typed
Normal 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`.
|
||||
|
||||
---
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from .mkdocs_renderer import MkDocsRenderer
|
||||
from .mcp_renderer import MCPRenderer
|
||||
from .mkdocs_renderer import MkDocsRenderer
|
||||
|
||||
__all__ = [
|
||||
"MkDocsRenderer",
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
...
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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: ...
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
Server layer for doc-forge.
|
||||
|
||||
This module exposes server implementations used to provide live access
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."""
|
||||
|
||||
16
docforge/templates/mkdocs.api.yml
Normal file
16
docforge/templates/mkdocs.api.yml
Normal 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
|
||||
@@ -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
|
||||
19
docforge/templates/mkdocs.lib.yml
Normal file
19
docforge/templates/mkdocs.lib.yml
Normal 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
|
||||
25
docforge/templates/mkdocs.wiki.yml
Normal file
25
docforge/templates/mkdocs.wiki.yml
Normal 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
|
||||
3
docs/lib/cli/api_utils.md
Normal file
3
docs/lib/cli/api_utils.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Api Utils
|
||||
|
||||
::: docforge.cli.api_utils
|
||||
3
docs/lib/nav/wiki.md
Normal file
3
docs/lib/nav/wiki.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Wiki
|
||||
|
||||
::: docforge.nav.wiki
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"project": "docforge",
|
||||
"type": "docforge-model",
|
||||
"modules_count": 22,
|
||||
"modules_count": 24,
|
||||
"source": "docforge"
|
||||
}
|
||||
67
docs/mcp/modules/docforge.cli.api_utils.json
Normal file
67
docs/mcp/modules/docforge.cli.api_utils.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
460
docs/mcp/modules/docforge.cli.commands.json
Normal file
460
docs/mcp/modules/docforge.cli.commands.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
820
docs/mcp/modules/docforge.cli.json
Normal file
820
docs/mcp/modules/docforge.cli.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
106
docs/mcp/modules/docforge.cli.mcp_utils.json
Normal file
106
docs/mcp/modules/docforge.cli.mcp_utils.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
155
docs/mcp/modules/docforge.cli.mkdocs_utils.json
Normal file
155
docs/mcp/modules/docforge.cli.mkdocs_utils.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2635
docs/mcp/modules/docforge.json
Normal file
2635
docs/mcp/modules/docforge.json
Normal file
File diff suppressed because one or more lines are too long
220
docs/mcp/modules/docforge.loaders.griffe_loader.json
Normal file
220
docs/mcp/modules/docforge.loaders.griffe_loader.json
Normal 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 ```"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
259
docs/mcp/modules/docforge.loaders.json
Normal file
259
docs/mcp/modules/docforge.loaders.json
Normal 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 ```"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
507
docs/mcp/modules/docforge.models.json
Normal file
507
docs/mcp/modules/docforge.models.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
132
docs/mcp/modules/docforge.models.module.json
Normal file
132
docs/mcp/modules/docforge.models.module.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
81
docs/mcp/modules/docforge.models.object.json
Normal file
81
docs/mcp/modules/docforge.models.object.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
111
docs/mcp/modules/docforge.models.project.json
Normal file
111
docs/mcp/modules/docforge.models.project.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
55
docs/mcp/modules/docforge.nav.mkdocs.json
Normal file
55
docs/mcp/modules/docforge.nav.mkdocs.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
90
docs/mcp/modules/docforge.nav.resolver.json
Normal file
90
docs/mcp/modules/docforge.nav.resolver.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
docs/mcp/modules/docforge.nav.spec.json
Normal file
60
docs/mcp/modules/docforge.nav.spec.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
docs/mcp/modules/docforge.nav.wiki.json
Normal file
16
docs/mcp/modules/docforge.nav.wiki.json
Normal 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."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user