From 06ffd2febd4450009316512b78b57477fbe8d4f7 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Sat, 17 Oct 2026 02:16:44 +0530 Subject: [PATCH] chore(release): 0.0.7 Squash-merge lib-standardisation: adopt repo standards across packaging, tooling, docs, and CI. - standardize pyproject.toml (canonical packaging, lint config, extras, GSDFC pydoclint) - add py.typed marker, modernize type hints and Google-style docstrings - nest generated docs under docs/lib and docs/mcp; add hand-written wiki - adopt standard Type A PyPI CI pipeline (tag==version guard + quality gate) - promote generated CHANGELOG.md; bump version to 0.0.7 --- .drone.yml | 74 +- .gitignore | 6 + CHANGELOG.md | 43 + LICENSE | 21 + README.md | 55 +- docforge.nav.yml | 44 +- docforge/__init__.py | 55 +- docforge/__init__.pyi | 6 +- docforge/cli/__init__.py | 4 +- docforge/cli/__init__.pyi | 4 +- docforge/cli/api_utils.py | 118 + docforge/cli/api_utils.pyi | 13 + docforge/cli/commands.py | 341 ++- docforge/cli/commands.pyi | 31 +- docforge/cli/main.py | 2 +- docforge/cli/mcp_utils.py | 16 +- docforge/cli/mcp_utils.pyi | 4 +- docforge/cli/mkdocs_utils.py | 391 ++- docforge/cli/mkdocs_utils.pyi | 26 +- docforge/loaders/griffe_loader.py | 122 +- docforge/loaders/griffe_loader.pyi | 14 +- docforge/models/__init__.pyi | 2 +- docforge/models/module.py | 19 +- docforge/models/module.pyi | 12 +- docforge/models/object.py | 29 +- docforge/models/object.pyi | 22 +- docforge/models/project.py | 24 +- docforge/models/project.pyi | 9 +- docforge/nav/__init__.py | 2 + docforge/nav/__init__.pyi | 6 +- docforge/nav/mkdocs.py | 37 +- docforge/nav/mkdocs.pyi | 5 +- docforge/nav/resolver.py | 58 +- docforge/nav/resolver.pyi | 13 +- docforge/nav/spec.py | 65 +- docforge/nav/spec.pyi | 19 +- docforge/nav/wiki.py | 165 ++ docforge/nav/wiki.pyi | 41 + docforge/py.typed | 0 docforge/renderers/__init__.pyi | 2 +- docforge/renderers/base.pyi | 2 - docforge/renderers/mcp_renderer.py | 34 +- docforge/renderers/mcp_renderer.pyi | 11 +- docforge/renderers/mkdocs_renderer.py | 49 +- docforge/renderers/mkdocs_renderer.pyi | 15 +- docforge/servers/mcp_server.py | 22 +- docforge/servers/mcp_server.pyi | 12 +- docforge/templates/mkdocs.api.yml | 16 + .../{mkdocs.sample.yml => mkdocs.common.yml} | 24 +- docforge/templates/mkdocs.lib.yml | 19 + docforge/templates/mkdocs.wiki.yml | 25 + docs/lib/cli/api_utils.md | 3 + docs/{ => lib}/cli/commands.md | 0 docs/{ => lib}/cli/index.md | 0 docs/{ => lib}/cli/main.md | 0 docs/{ => lib}/cli/mcp_utils.md | 0 docs/{ => lib}/cli/mkdocs_utils.md | 0 docs/{ => lib}/index.md | 0 docs/{ => lib}/loaders/griffe_loader.md | 0 docs/{ => lib}/loaders/index.md | 0 docs/{ => lib}/models/index.md | 0 docs/{ => lib}/models/module.md | 0 docs/{ => lib}/models/object.md | 0 docs/{ => lib}/models/project.md | 0 docs/{ => lib}/nav/index.md | 0 docs/{ => lib}/nav/mkdocs.md | 0 docs/{ => lib}/nav/resolver.md | 0 docs/{ => lib}/nav/spec.md | 0 docs/lib/nav/wiki.md | 3 + docs/{ => lib}/renderers/base.md | 0 docs/{ => lib}/renderers/index.md | 0 docs/{ => lib}/renderers/mcp_renderer.md | 0 docs/{ => lib}/renderers/mkdocs_renderer.md | 0 docs/{ => lib}/servers/index.md | 0 docs/{ => lib}/servers/mcp_server.md | 0 {mcp_docs => docs/mcp}/index.json | 2 +- docs/mcp/modules/docforge.cli.api_utils.json | 67 + docs/mcp/modules/docforge.cli.commands.json | 460 ++++ docs/mcp/modules/docforge.cli.json | 820 +++++++ .../mcp}/modules/docforge.cli.main.json | 4 +- .../mcp}/modules/docforge.cli.mcp_utils.json | 54 +- .../modules/docforge.cli.mkdocs_utils.json | 155 ++ {mcp_docs => docs/mcp}/modules/docforge.json | 2108 ++++++++--------- .../docforge.loaders.griffe_loader.json | 248 +- .../mcp}/modules/docforge.loaders.json | 264 +-- .../mcp}/modules/docforge.models.json | 192 +- .../mcp}/modules/docforge.models.module.json | 57 +- .../mcp}/modules/docforge.models.object.json | 35 +- .../mcp}/modules/docforge.models.project.json | 44 +- .../mcp}/modules/docforge.nav.json | 253 +- docs/mcp/modules/docforge.nav.mkdocs.json | 55 + docs/mcp/modules/docforge.nav.resolver.json | 90 + docs/mcp/modules/docforge.nav.spec.json | 60 + docs/mcp/modules/docforge.nav.wiki.json | 16 + .../mcp}/modules/docforge.renderers.base.json | 36 +- .../mcp}/modules/docforge.renderers.json | 413 ++-- .../docforge.renderers.mcp_renderer.json | 224 +- .../docforge.renderers.mkdocs_renderer.json | 135 +- .../mcp}/modules/docforge.servers.json | 60 +- .../modules/docforge.servers.mcp_server.json | 39 + docs/mcp/nav.json | 98 + mkdocs.yml => docs/mkdocs.lib.yml | 49 +- docs/mkdocs.wiki.yml | 73 + docs/wiki/01_overview.md | 43 + docs/wiki/02_components.md | 55 + docs/wiki/03_conventions.md | 58 + docs/wiki/04_iterative_workflow.md | 61 + docs/wiki/05_development/01_environment.md | 30 + docs/wiki/05_development/02_quality_gates.md | 34 + docs/wiki/05_development/03_gsdfc_guide.md | 129 + docs/wiki/05_development/04_mcp_guide.md | 62 + docs/wiki/05_development/05_mkdocs_configs.md | 59 + docs/wiki/index.md | 325 +++ mcp_docs/modules/docforge.cli.commands.json | 377 --- mcp_docs/modules/docforge.cli.json | 684 ------ .../modules/docforge.cli.mkdocs_utils.json | 155 -- mcp_docs/modules/docforge.nav.mkdocs.json | 83 - mcp_docs/modules/docforge.nav.resolver.json | 125 - mcp_docs/modules/docforge.nav.spec.json | 88 - .../modules/docforge.servers.mcp_server.json | 81 - mcp_docs/nav.json | 90 - pyproject.toml | 138 +- tests/cli/test_build_api.py | 142 ++ tests/cli/test_build_mcp.py | 6 +- tests/cli/test_build_mkdocs.py | 123 +- tests/cli/test_build_wiki.py | 165 ++ tests/cli/test_mkdocs_utils.py | 79 + tests/cli/test_serve_mcp.py | 1 + tests/cli/test_serve_mkdocs.py | 1 + tests/conftest.py | 6 +- tests/introspection/test_alias_safety.py | 6 +- .../introspection/test_classes_and_methods.py | 6 +- .../test_functions_and_signatures.py | 6 +- tests/introspection/test_import_failures.py | 8 +- .../introspection/test_missing_docstrings.py | 4 +- tests/introspection/test_private_members.py | 6 +- tests/introspection/test_single_module.py | 6 +- tests/nav/test_mkdocs.py | 3 +- tests/nav/test_resolver.py | 3 +- tests/nav/test_wiki.py | 106 + tests/renderers/mcp/test_mcp_content.py | 2 +- tests/renderers/mcp/test_mcp_idempotency.py | 2 +- .../renderers/mcp/test_mcp_module_coverage.py | 7 +- tests/renderers/mcp/test_mcp_signatures.py | 73 + tests/renderers/mcp/test_mcp_structure.py | 2 +- tests/renderers/mkdocs/test_mkdocs_content.py | 4 +- .../mkdocs/test_mkdocs_idempotency.py | 4 +- .../mkdocs/test_mkdocs_module_coverage.py | 10 +- .../renderers/mkdocs/test_mkdocs_structure.py | 2 +- 149 files changed, 7132 insertions(+), 4594 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 docforge/cli/api_utils.py create mode 100644 docforge/cli/api_utils.pyi create mode 100644 docforge/nav/wiki.py create mode 100644 docforge/nav/wiki.pyi create mode 100644 docforge/py.typed create mode 100644 docforge/templates/mkdocs.api.yml rename docforge/templates/{mkdocs.sample.yml => mkdocs.common.yml} (62%) create mode 100644 docforge/templates/mkdocs.lib.yml create mode 100644 docforge/templates/mkdocs.wiki.yml create mode 100644 docs/lib/cli/api_utils.md rename docs/{ => lib}/cli/commands.md (100%) rename docs/{ => lib}/cli/index.md (100%) rename docs/{ => lib}/cli/main.md (100%) rename docs/{ => lib}/cli/mcp_utils.md (100%) rename docs/{ => lib}/cli/mkdocs_utils.md (100%) rename docs/{ => lib}/index.md (100%) rename docs/{ => lib}/loaders/griffe_loader.md (100%) rename docs/{ => lib}/loaders/index.md (100%) rename docs/{ => lib}/models/index.md (100%) rename docs/{ => lib}/models/module.md (100%) rename docs/{ => lib}/models/object.md (100%) rename docs/{ => lib}/models/project.md (100%) rename docs/{ => lib}/nav/index.md (100%) rename docs/{ => lib}/nav/mkdocs.md (100%) rename docs/{ => lib}/nav/resolver.md (100%) rename docs/{ => lib}/nav/spec.md (100%) create mode 100644 docs/lib/nav/wiki.md rename docs/{ => lib}/renderers/base.md (100%) rename docs/{ => lib}/renderers/index.md (100%) rename docs/{ => lib}/renderers/mcp_renderer.md (100%) rename docs/{ => lib}/renderers/mkdocs_renderer.md (100%) rename docs/{ => lib}/servers/index.md (100%) rename docs/{ => lib}/servers/mcp_server.md (100%) rename {mcp_docs => docs/mcp}/index.json (77%) create mode 100644 docs/mcp/modules/docforge.cli.api_utils.json create mode 100644 docs/mcp/modules/docforge.cli.commands.json create mode 100644 docs/mcp/modules/docforge.cli.json rename {mcp_docs => docs/mcp}/modules/docforge.cli.main.json (81%) rename {mcp_docs => docs/mcp}/modules/docforge.cli.mcp_utils.json (62%) create mode 100644 docs/mcp/modules/docforge.cli.mkdocs_utils.json rename {mcp_docs => docs/mcp}/modules/docforge.json (57%) rename {mcp_docs => docs/mcp}/modules/docforge.loaders.griffe_loader.json (58%) rename {mcp_docs => docs/mcp}/modules/docforge.loaders.json (59%) rename {mcp_docs => docs/mcp}/modules/docforge.models.json (69%) rename {mcp_docs => docs/mcp}/modules/docforge.models.module.json (65%) rename {mcp_docs => docs/mcp}/modules/docforge.models.object.json (69%) rename {mcp_docs => docs/mcp}/modules/docforge.models.project.json (70%) rename {mcp_docs => docs/mcp}/modules/docforge.nav.json (50%) create mode 100644 docs/mcp/modules/docforge.nav.mkdocs.json create mode 100644 docs/mcp/modules/docforge.nav.resolver.json create mode 100644 docs/mcp/modules/docforge.nav.spec.json create mode 100644 docs/mcp/modules/docforge.nav.wiki.json rename {mcp_docs => docs/mcp}/modules/docforge.renderers.base.json (73%) rename {mcp_docs => docs/mcp}/modules/docforge.renderers.json (69%) rename {mcp_docs => docs/mcp}/modules/docforge.renderers.mcp_renderer.json (66%) rename {mcp_docs => docs/mcp}/modules/docforge.renderers.mkdocs_renderer.json (68%) rename {mcp_docs => docs/mcp}/modules/docforge.servers.json (56%) create mode 100644 docs/mcp/modules/docforge.servers.mcp_server.json create mode 100644 docs/mcp/nav.json rename mkdocs.yml => docs/mkdocs.lib.yml (89%) create mode 100644 docs/mkdocs.wiki.yml create mode 100644 docs/wiki/01_overview.md create mode 100644 docs/wiki/02_components.md create mode 100644 docs/wiki/03_conventions.md create mode 100644 docs/wiki/04_iterative_workflow.md create mode 100644 docs/wiki/05_development/01_environment.md create mode 100644 docs/wiki/05_development/02_quality_gates.md create mode 100644 docs/wiki/05_development/03_gsdfc_guide.md create mode 100644 docs/wiki/05_development/04_mcp_guide.md create mode 100644 docs/wiki/05_development/05_mkdocs_configs.md create mode 100644 docs/wiki/index.md delete mode 100644 mcp_docs/modules/docforge.cli.commands.json delete mode 100644 mcp_docs/modules/docforge.cli.json delete mode 100644 mcp_docs/modules/docforge.cli.mkdocs_utils.json delete mode 100644 mcp_docs/modules/docforge.nav.mkdocs.json delete mode 100644 mcp_docs/modules/docforge.nav.resolver.json delete mode 100644 mcp_docs/modules/docforge.nav.spec.json delete mode 100644 mcp_docs/modules/docforge.servers.mcp_server.json delete mode 100644 mcp_docs/nav.json create mode 100644 tests/cli/test_build_api.py create mode 100644 tests/cli/test_build_wiki.py create mode 100644 tests/cli/test_mkdocs_utils.py create mode 100644 tests/nav/test_wiki.py create mode 100644 tests/renderers/mcp/test_mcp_signatures.py diff --git a/.drone.yml b/.drone.yml index ddd0ac4..122d0f6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,3 +1,21 @@ +# Drone standard — Type A: PyPI package +# +# Canonical pipeline for internal Python libraries that ship a wheel/sdist to +# the private index (dagpipe, doc-forge, hexa, mail-intake, mongo-ops, +# omniread, openapi-first, py-jwt). +# +# Two pipelines ship together: +# build-and-publish-pypi — tag-triggered build + quality gate + publish. +# backfill-pypi-from-tags — custom-triggered replay of every git tag that is +# missing from the index (disaster recovery). +# +# Secrets (Drone): PIP_REPO_URL, PIP_USERNAME, PIP_PASSWORD. +# Copy to /.drone.yml unchanged; the package name and version are read +# from pyproject.toml, so no per-repo edits are required. +# +# Version guard: the tag build fails unless the git tag equals the version in +# pyproject.toml (see the versioning standard). This stops a tag from looking +# like a release while silently publishing nothing. --- kind: pipeline type: docker @@ -23,20 +41,46 @@ 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 + - | + AUTH_URL="https://${PIP_USERNAME}:${PIP_PASSWORD}@$(echo "${PIP_REPO_URL#*://}" | sed '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 +95,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 +142,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" \ diff --git a/.gitignore b/.gitignore index d173c8f..7c70e5d 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b762b6e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,43 @@ +# 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. + +### Fixed +- Loader-generated signatures render cleanly and unresolvable aliases are + dropped from generated models. +- Stub fixes for typed API surfaces. + +[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 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..87328b2 --- /dev/null +++ b/LICENSE @@ -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. \ No newline at end of file diff --git a/README.md b/README.md index 6a3a6f1..e27d8be 100644 --- a/README.md +++ b/README.md @@ -23,29 +23,49 @@ pip install doc-forge # CLI usage -## Generate an MkDocs site from a Python package: +Each site kind (`lib`, `api`, `wiki`) is built independently into `site/{kind}`. + +## Build the library reference from a Python package: ```bash doc-forge build --mkdocs --module my_package ``` +## Build the API reference from an OpenAPI spec: + +```bash +doc-forge build --api --openapi-spec spec.json +``` + +## 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 ``` - -## Generate MkDocs site and MCP JSON documentation: +## Build several kinds in one pass: ```bash -doc-forge build --mcp --mkdocs --module my_package +doc-forge build --mcp --mkdocs --wiki --module my_package ``` -## Serve MkDocs locally: +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 --mkdocs --module my_package +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: @@ -130,7 +150,9 @@ 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. -- 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 `---` @@ -190,7 +212,10 @@ Example: engine.run() ``` -Avoid fenced code blocks inside structured sections. +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. --- @@ -522,6 +547,20 @@ Example: --- +# Type parity (`.pyi` stubs and `py.typed`) + +Documented APIs ship matching type information: + +- Each `.py` module has a synchronized `.pyi` stub in the same package. +- Packages expose a `py.typed` marker so type checkers (and consumers) + use the authored signatures instead of `Any`. +- When signatures change, update the `.py` implementation and its `.pyi` + stub together. +- Doc-forge documents the docstrings in `.py`; the `.pyi` stub is the + machine-consumable signature surface. + +--- + # Parsing guarantees GSDFC ensures doc-forge can deterministically extract: diff --git a/docforge.nav.yml b/docforge.nav.yml index c152294..0e87587 100644 --- a/docforge.nav.yml +++ b/docforge.nav.yml @@ -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 \ No newline at end of file diff --git a/docforge/__init__.py b/docforge/__init__.py index a777233..9fdef89 100644 --- a/docforge/__init__.py +++ b/docforge/__init__.py @@ -22,29 +22,49 @@ pip install doc-forge # CLI usage -## Generate an MkDocs site from a Python package: +Each site kind (`lib`, `api`, `wiki`) is built independently into `site/{kind}`. + +## Build the library reference from a Python package: ```bash doc-forge build --mkdocs --module my_package ``` +## Build the API reference from an OpenAPI spec: + +```bash +doc-forge build --api --openapi-spec spec.json +``` + +## 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 ``` - -## Generate MkDocs site and MCP JSON documentation: +## Build several kinds in one pass: ```bash -doc-forge build --mcp --mkdocs --module my_package +doc-forge build --mcp --mkdocs --wiki --module my_package ``` -## Serve MkDocs locally: +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 --mkdocs --module my_package +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: @@ -129,7 +149,9 @@ 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. -- 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 `---` @@ -189,7 +211,10 @@ Example: engine.run() ``` -Avoid fenced code blocks inside structured sections. +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. --- @@ -521,6 +546,20 @@ Example: --- +# Type parity (`.pyi` stubs and `py.typed`) + +Documented APIs ship matching type information: + +- Each `.py` module has a synchronized `.pyi` stub in the same package. +- Packages expose a `py.typed` marker so type checkers (and consumers) + use the authored signatures instead of `Any`. +- When signatures change, update the `.py` implementation and its `.pyi` + stub together. +- Doc-forge documents the docstrings in `.py`; the `.pyi` stub is the + machine-consumable signature surface. + +--- + # Parsing guarantees GSDFC ensures doc-forge can deterministically extract: diff --git a/docforge/__init__.pyi b/docforge/__init__.pyi index 5823fb1..bd6340e 100644 --- a/docforge/__init__.pyi +++ b/docforge/__init__.pyi @@ -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", diff --git a/docforge/cli/__init__.py b/docforge/cli/__init__.py index feeca82..79ed9a3 100644 --- a/docforge/cli/__init__.py +++ b/docforge/cli/__init__.py @@ -37,6 +37,4 @@ Example: from .main import main -__all__ = [ - "main" -] +__all__ = ["main"] diff --git a/docforge/cli/__init__.pyi b/docforge/cli/__init__.pyi index aef0a0c..21db616 100644 --- a/docforge/cli/__init__.pyi +++ b/docforge/cli/__init__.pyi @@ -1,5 +1,3 @@ from .main import main -__all__ = [ - "main" -] +__all__ = ["main"] diff --git a/docforge/cli/api_utils.py b/docforge/cli/api_utils.py new file mode 100644 index 0000000..2041967 --- /dev/null +++ b/docforge/cli/api_utils.py @@ -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'\n' + if not index_path.exists() or index_path.read_text(encoding="utf-8") != content: + index_path.write_text(content, encoding="utf-8") diff --git a/docforge/cli/api_utils.pyi b/docforge/cli/api_utils.pyi new file mode 100644 index 0000000..f7c1f13 --- /dev/null +++ b/docforge/cli/api_utils.pyi @@ -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: ... diff --git a/docforge/cli/commands.py b/docforge/cli/commands.py index f25f6f0..0007b2f 100644 --- a/docforge/cli/commands.py +++ b/docforge/cli/commands.py @@ -4,14 +4,26 @@ 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 click +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() @@ -27,75 +39,143 @@ 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 (bool): Enable MCP documentation generation. mkdocs (bool): - Enable MkDocs documentation generation. + 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 (Optional[str]): + module (str | None): Python module import path to document. - project_name (Optional[str]): + 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 (Optional[str]): - Display name for the MkDocs site. + site_name (str | None): + Display name for the lib and wiki MkDocs sites. docs_dir (Path): - Directory where Markdown documentation sources will be generated. + 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 (Optional[Path]): + template (Path | None): Optional custom MkDocs configuration template. - mkdocs_yml (Path): - Output path for the generated MkDocs configuration. - out_dir (Path): Output directory for generated MCP resources. @@ -103,34 +183,102 @@ def build( 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.") @@ -138,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: @@ -154,17 +318,30 @@ 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 (bool): Serve documentation using the MCP server. mkdocs (bool): - Serve the MkDocs development site. + Serve the MkDocs development site from ``--mkdocs-yml``. - module (Optional[str]): + 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): @@ -177,17 +354,37 @@ def serve( 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() @@ -202,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. @@ -215,7 +412,7 @@ def tree( module (str): Python module import path to introspect. - project_name (Optional[str]): + project_name (str | None): Optional name to display as the project root. """ loader = GriffeLoader() @@ -229,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. @@ -237,7 +434,7 @@ def _print_object(obj, indent: str) -> None: and prints each object with indentation to represent hierarchy. Args: - obj: + obj (DocObject): Documentation object to print. indent (str): diff --git a/docforge/cli/commands.pyi b/docforge/cli/commands.pyi index a38d851..0b4cb69 100644 --- a/docforge/cli/commands.pyi +++ b/docforge/cli/commands.pyi @@ -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: ... diff --git a/docforge/cli/main.py b/docforge/cli/main.py index d1ab265..3dea046 100644 --- a/docforge/cli/main.py +++ b/docforge/cli/main.py @@ -22,4 +22,4 @@ def main() -> None: if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/docforge/cli/mcp_utils.py b/docforge/cli/mcp_utils.py index 4421a1f..41aef9a 100644 --- a/docforge/cli/mcp_utils.py +++ b/docforge/cli/mcp_utils.py @@ -2,10 +2,22 @@ # 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 @@ -24,7 +36,7 @@ def generate_resources(module: str, project_name: str | None, out_dir: Path) -> Python module import path used as the entry point for documentation generation. - project_name (Optional[str]): + project_name (str | None): Optional override for the project name used in generated documentation metadata. @@ -61,7 +73,7 @@ def serve(module: str, mcp_root: Path) -> None: 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", diff --git a/docforge/cli/mcp_utils.pyi b/docforge/cli/mcp_utils.pyi index 5e9ac4d..84d2fa1 100644 --- a/docforge/cli/mcp_utils.pyi +++ b/docforge/cli/mcp_utils.pyi @@ -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: ... diff --git a/docforge/cli/mkdocs_utils.py b/docforge/cli/mkdocs_utils.py index 3244e38..fb349f4 100644 --- a/docforge/cli/mkdocs_utils.py +++ b/docforge/cli/mkdocs_utils.py @@ -2,15 +2,35 @@ # 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 pathlib import Path +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( @@ -18,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. @@ -34,12 +55,16 @@ def generate_sources( docs_dir (Path): Directory where the generated Markdown files will be written. - project_name (Optional[str]): + project_name (str | None): Optional override for the project name used in documentation metadata. - module_is_source (Optional[bool]): + 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) @@ -56,92 +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 (Path): - Directory containing generated documentation Markdown files. - nav_file (Path): Path to the `docforge.nav.yml` navigation specification. - template (Optional[Path]): - Optional path to a custom MkDocs configuration template. If not - provided, a built-in template will be used. + docs_root (Path): + Shared documentation root containing the ``lib`` sources. - out (Path): - Destination path where the generated `mkdocs.yml` file will be written. - - site_name (str): - Display name for the generated documentation site. + 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. + 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): - 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.FileError: + If a referenced template file cannot be found. + """ + 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")) + + 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 the configuration file does not exist. + If a configuration file does not exist. """ - if not mkdocs_yml.exists(): - raise click.ClickException(f"mkdocs.yml not found: {mkdocs_yml}") - - from mkdocs.config import load_config 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: @@ -163,4 +449,5 @@ def serve(mkdocs_yml: Path) -> None: 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)) diff --git a/docforge/cli/mkdocs_utils.pyi b/docforge/cli/mkdocs_utils.pyi index 052bee9..776ace6 100644 --- a/docforge/cli/mkdocs_utils.pyi +++ b/docforge/cli/mkdocs_utils.pyi @@ -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: ... diff --git a/docforge/loaders/griffe_loader.py b/docforge/loaders/griffe_loader.py index 2cac54a..a682d2b 100644 --- a/docforge/loaders/griffe_loader.py +++ b/docforge/loaders/griffe_loader.py @@ -6,21 +6,32 @@ Utilities for loading and introspecting Python modules using Griffe. This module provides the `GriffeLoader` class and helper utilities used to discover Python modules, introspect their structure, and convert the results into doc-forge documentation models. + +--- + +Notes: + - All analysis is static; analyzed modules are never executed. + - Private members (names starting with `_`) are skipped during conversion. + - Imported aliases that cannot be resolved (stdlib/third-party names) are + skipped; aliases that resolve within the documented project are kept. + +--- """ 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__) @@ -28,7 +39,7 @@ 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. @@ -45,12 +56,12 @@ def discover_module_paths( module_name (str): Top-level package name to discover modules from. - project_root (Path, optional): + project_root (Path | None): Root directory used to resolve module paths. If not provided, the current working directory is used. Returns: - List[str]: + list[str]: A sorted list of unique dotted module import paths. Raises: @@ -65,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": @@ -87,6 +98,10 @@ class GriffeLoader: This loader uses the Griffe introspection engine to analyze Python source code and transform the extracted information into `Project`, `Module`, and `DocObject` instances used by doc-forge. + + Attributes: + _loader (_GriffeLoader): + Internal Griffe loader with dedicated module and line collections. """ def __init__(self) -> None: @@ -102,10 +117,10 @@ 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. @@ -115,14 +130,14 @@ class GriffeLoader: object. Args: - module_paths (List[str]): + module_paths (list[str]): List of dotted module import paths to load. - project_name (str, optional): + project_name (str | None): Optional override for the project name. Defaults to the top-level name of the first module. - skip_import_errors (bool, optional): + skip_import_errors (bool | None): If True, modules that fail to load will be skipped instead of raising an error. Returns: @@ -171,6 +186,21 @@ class GriffeLoader: Returns: 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] @@ -204,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)) @@ -240,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 @@ -250,7 +284,7 @@ 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. @@ -259,7 +293,7 @@ class GriffeLoader: Griffe object to inspect. Returns: - Optional[str]: + str | None: The raw docstring text if available, otherwise `None`. """ try: @@ -267,21 +301,57 @@ class GriffeLoader: 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 (Object): Griffe object to inspect. Returns: - Optional[str]: - 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 diff --git a/docforge/loaders/griffe_loader.pyi b/docforge/loaders/griffe_loader.pyi index 037f147..1fa04b0 100644 --- a/docforge/loaders/griffe_loader.pyi +++ b/docforge/loaders/griffe_loader.pyi @@ -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.""" diff --git a/docforge/models/__init__.pyi b/docforge/models/__init__.pyi index 0fe95b1..0b0a510 100644 --- a/docforge/models/__init__.pyi +++ b/docforge/models/__init__.pyi @@ -1,6 +1,6 @@ -from .project import Project from .module import Module from .object import DocObject +from .project import Project __all__ = [ "Project", diff --git a/docforge/models/module.py b/docforge/models/module.py index ee1bffc..7d17f1f 100644 --- a/docforge/models/module.py +++ b/docforge/models/module.py @@ -7,9 +7,16 @@ 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 @@ -26,17 +33,17 @@ class Module: path (str): Dotted import path of the module. - docstring (Optional[str]): + docstring (str | None): Module-level documentation string, if present. - members (Dict[str, DocObject]): + 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. @@ -45,12 +52,12 @@ class Module: path (str): Dotted import path identifying the module. - docstring (Optional[str]): + 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: """ diff --git a/docforge/models/module.pyi b/docforge/models/module.pyi index e5145be..e9abd8d 100644 --- a/docforge/models/module.pyi +++ b/docforge/models/module.pyi @@ -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]: ... diff --git a/docforge/models/object.py b/docforge/models/object.py index b305c0d..17e51f8 100644 --- a/docforge/models/object.py +++ b/docforge/models/object.py @@ -7,9 +7,17 @@ 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: @@ -30,13 +38,13 @@ class DocObject: path (str): Fully qualified dotted path to the object. - signature (Optional[str]): + signature (str | None): Callable signature if the object represents a callable. - docstring (Optional[str]): + docstring (str | None): Raw docstring text extracted from the source code. - members (Dict[str, DocObject]): + members (dict[str, DocObject]): Mapping of member names to child `DocObject` instances. """ @@ -45,8 +53,8 @@ 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. @@ -61,10 +69,10 @@ class DocObject: path (str): Fully qualified dotted path of the object. - signature (Optional[str]): + signature (str | None): Callable signature if applicable. - docstring (Optional[str]): + docstring (str | None): Documentation string associated with the object. """ self.name = name @@ -72,7 +80,7 @@ class DocObject: 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: """ @@ -82,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 diff --git a/docforge/models/object.pyi b/docforge/models/object.pyi index b7f589a..e92142b 100644 --- a/docforge/models/object.pyi +++ b/docforge/models/object.pyi @@ -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]: ... diff --git a/docforge/models/project.py b/docforge/models/project.py index 431362b..7760703 100644 --- a/docforge/models/project.py +++ b/docforge/models/project.py @@ -6,9 +6,17 @@ 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 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 @@ -24,7 +32,7 @@ class Project: name (str): Name of the project. - modules (Dict[str, Module]): + modules (dict[str, Module]): Mapping of module paths to `Module` instances. """ @@ -35,9 +43,17 @@ class Project: Args: 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: """ @@ -85,4 +101,4 @@ class Project: list[str]: A list containing the dotted paths of all modules in the project. """ - return list(self.modules.keys()) \ No newline at end of file + return list(self.modules.keys()) diff --git a/docforge/models/project.pyi b/docforge/models/project.pyi index 95f7844..3e209a9 100644 --- a/docforge/models/project.pyi +++ b/docforge/models/project.pyi @@ -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]: ... diff --git a/docforge/nav/__init__.py b/docforge/nav/__init__.py index f9fd853..645f2c7 100644 --- a/docforge/nav/__init__.py +++ b/docforge/nav/__init__.py @@ -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", ] diff --git a/docforge/nav/__init__.pyi b/docforge/nav/__init__.pyi index 2db95eb..02624fe 100644 --- a/docforge/nav/__init__.pyi +++ b/docforge/nav/__init__.pyi @@ -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", ] diff --git a/docforge/nav/mkdocs.py b/docforge/nav/mkdocs.py index b053341..7f33d9b 100644 --- a/docforge/nav/mkdocs.py +++ b/docforge/nav/mkdocs.py @@ -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] diff --git a/docforge/nav/mkdocs.pyi b/docforge/nav/mkdocs.pyi index 9fb6aec..ec89e3e 100644 --- a/docforge/nav/mkdocs.pyi +++ b/docforge/nav/mkdocs.pyi @@ -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. diff --git a/docforge/nav/resolver.py b/docforge/nav/resolver.py index e1911a6..f3c2382 100644 --- a/docforge/nav/resolver.py +++ b/docforge/nav/resolver.py @@ -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 diff --git a/docforge/nav/resolver.pyi b/docforge/nav/resolver.pyi index ea7a239..0bc6d95 100644 --- a/docforge/nav/resolver.pyi +++ b/docforge/nav/resolver.pyi @@ -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, diff --git a/docforge/nav/spec.py b/docforge/nav/spec.py index b3c8a51..8158350 100644 --- a/docforge/nav/spec.py +++ b/docforge/nav/spec.py @@ -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"), ) diff --git a/docforge/nav/spec.pyi b/docforge/nav/spec.pyi index fd3bf4d..5f9022c 100644 --- a/docforge/nav/spec.pyi +++ b/docforge/nav/spec.pyi @@ -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: ... diff --git a/docforge/nav/wiki.py b/docforge/nav/wiki.py new file mode 100644 index 0000000..0829d5c --- /dev/null +++ b/docforge/nav/wiki.py @@ -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) + ] diff --git a/docforge/nav/wiki.pyi b/docforge/nav/wiki.pyi new file mode 100644 index 0000000..a0d435c --- /dev/null +++ b/docforge/nav/wiki.pyi @@ -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. + """ + ... diff --git a/docforge/py.typed b/docforge/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/docforge/renderers/__init__.pyi b/docforge/renderers/__init__.pyi index f0135ff..ecc5bea 100644 --- a/docforge/renderers/__init__.pyi +++ b/docforge/renderers/__init__.pyi @@ -1,5 +1,5 @@ -from .mkdocs_renderer import MkDocsRenderer from .mcp_renderer import MCPRenderer +from .mkdocs_renderer import MkDocsRenderer __all__ = [ "MkDocsRenderer", diff --git a/docforge/renderers/base.pyi b/docforge/renderers/base.pyi index 5800b4f..600a931 100644 --- a/docforge/renderers/base.pyi +++ b/docforge/renderers/base.pyi @@ -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.""" diff --git a/docforge/renderers/mcp_renderer.py b/docforge/renderers/mcp_renderer.py index 8f01a01..2e3f97a 100644 --- a/docforge/renderers/mcp_renderer.py +++ b/docforge/renderers/mcp_renderer.py @@ -9,9 +9,8 @@ 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: @@ -42,15 +41,17 @@ class MCPRenderer: 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( @@ -91,7 +92,7 @@ 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. @@ -100,10 +101,10 @@ class MCPRenderer: Module instance to convert. Returns: - Dict: + dict: Dictionary representing the module and its documented objects. """ - data: Dict = { + data: dict = { "path": module.path, "docstring": module.docstring, "objects": {}, @@ -114,7 +115,7 @@ 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. @@ -123,10 +124,10 @@ class MCPRenderer: Documentation object to convert. Returns: - Dict: + dict: Dictionary describing the object and any nested members. """ - data: Dict = { + data: dict = { "name": obj.name, "kind": obj.kind, "path": obj.path, @@ -137,19 +138,18 @@ 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 (Dict): + data (dict): Dictionary to serialize. Returns: diff --git a/docforge/renderers/mcp_renderer.pyi b/docforge/renderers/mcp_renderer.pyi index 3025fee..b047d06 100644 --- a/docforge/renderers/mcp_renderer.pyi +++ b/docforge/renderers/mcp_renderer.pyi @@ -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.""" diff --git a/docforge/renderers/mkdocs_renderer.py b/docforge/renderers/mkdocs_renderer.py index c58e9ea..8880592 100644 --- a/docforge/renderers/mkdocs_renderer.py +++ b/docforge/renderers/mkdocs_renderer.py @@ -16,7 +16,8 @@ The renderer ensures a consistent documentation structure by: """ from pathlib import Path -from docforge.models import Project, Module + +from docforge.models import Module, Project class MkDocsRenderer: @@ -53,7 +54,7 @@ class MkDocsRenderer: out_dir (Path): Directory where generated Markdown files will be written. - module_is_source (bool, optional): + module_is_source (bool | None): If True, treat the specified module as the documentation root rather than nesting it inside a folder. """ @@ -65,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: @@ -82,15 +82,15 @@ 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. - 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): @@ -99,15 +99,20 @@ class MkDocsRenderer: docs_dir (Path): Directory containing generated documentation sources. - module_is_source (bool, optional): + 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(): @@ -127,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", @@ -151,7 +156,7 @@ class MkDocsRenderer: Project model to inspect. Returns: - Optional[Module]: + Module | None: The root `Module` if found, otherwise `None`. """ for module in project.get_all_modules(): @@ -183,7 +188,7 @@ class MkDocsRenderer: out_dir (Path): Base directory for generated documentation files. - module_is_source (bool, optional): + module_is_source (bool | None): Whether the module acts as the documentation root directory. """ @@ -231,10 +236,7 @@ class MkDocsRenderer: 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, @@ -255,8 +257,7 @@ class MkDocsRenderer: 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", ) diff --git a/docforge/renderers/mkdocs_renderer.pyi b/docforge/renderers/mkdocs_renderer.pyi index 584e425..a574149 100644 --- a/docforge/renderers/mkdocs_renderer.pyi +++ b/docforge/renderers/mkdocs_renderer.pyi @@ -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: ... diff --git a/docforge/servers/mcp_server.py b/docforge/servers/mcp_server.py index 1fde6ef..1ee5688 100644 --- a/docforge/servers/mcp_server.py +++ b/docforge/servers/mcp_server.py @@ -5,6 +5,16 @@ 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 @@ -22,6 +32,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: @@ -96,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 diff --git a/docforge/servers/mcp_server.pyi b/docforge/servers/mcp_server.pyi index f4341d5..8b2308a 100644 --- a/docforge/servers/mcp_server.pyi +++ b/docforge/servers/mcp_server.pyi @@ -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.""" diff --git a/docforge/templates/mkdocs.api.yml b/docforge/templates/mkdocs.api.yml new file mode 100644 index 0000000..89cfd3e --- /dev/null +++ b/docforge/templates/mkdocs.api.yml @@ -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 \ No newline at end of file diff --git a/docforge/templates/mkdocs.sample.yml b/docforge/templates/mkdocs.common.yml similarity index 62% rename from docforge/templates/mkdocs.sample.yml rename to docforge/templates/mkdocs.common.yml index 3d17c33..39bcadd 100644 --- a/docforge/templates/mkdocs.sample.yml +++ b/docforge/templates/mkdocs.common.yml @@ -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 \ No newline at end of file diff --git a/docforge/templates/mkdocs.lib.yml b/docforge/templates/mkdocs.lib.yml new file mode 100644 index 0000000..1545867 --- /dev/null +++ b/docforge/templates/mkdocs.lib.yml @@ -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 \ No newline at end of file diff --git a/docforge/templates/mkdocs.wiki.yml b/docforge/templates/mkdocs.wiki.yml new file mode 100644 index 0000000..210e0f8 --- /dev/null +++ b/docforge/templates/mkdocs.wiki.yml @@ -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 \ No newline at end of file diff --git a/docs/lib/cli/api_utils.md b/docs/lib/cli/api_utils.md new file mode 100644 index 0000000..62040b8 --- /dev/null +++ b/docs/lib/cli/api_utils.md @@ -0,0 +1,3 @@ +# Api Utils + +::: docforge.cli.api_utils diff --git a/docs/cli/commands.md b/docs/lib/cli/commands.md similarity index 100% rename from docs/cli/commands.md rename to docs/lib/cli/commands.md diff --git a/docs/cli/index.md b/docs/lib/cli/index.md similarity index 100% rename from docs/cli/index.md rename to docs/lib/cli/index.md diff --git a/docs/cli/main.md b/docs/lib/cli/main.md similarity index 100% rename from docs/cli/main.md rename to docs/lib/cli/main.md diff --git a/docs/cli/mcp_utils.md b/docs/lib/cli/mcp_utils.md similarity index 100% rename from docs/cli/mcp_utils.md rename to docs/lib/cli/mcp_utils.md diff --git a/docs/cli/mkdocs_utils.md b/docs/lib/cli/mkdocs_utils.md similarity index 100% rename from docs/cli/mkdocs_utils.md rename to docs/lib/cli/mkdocs_utils.md diff --git a/docs/index.md b/docs/lib/index.md similarity index 100% rename from docs/index.md rename to docs/lib/index.md diff --git a/docs/loaders/griffe_loader.md b/docs/lib/loaders/griffe_loader.md similarity index 100% rename from docs/loaders/griffe_loader.md rename to docs/lib/loaders/griffe_loader.md diff --git a/docs/loaders/index.md b/docs/lib/loaders/index.md similarity index 100% rename from docs/loaders/index.md rename to docs/lib/loaders/index.md diff --git a/docs/models/index.md b/docs/lib/models/index.md similarity index 100% rename from docs/models/index.md rename to docs/lib/models/index.md diff --git a/docs/models/module.md b/docs/lib/models/module.md similarity index 100% rename from docs/models/module.md rename to docs/lib/models/module.md diff --git a/docs/models/object.md b/docs/lib/models/object.md similarity index 100% rename from docs/models/object.md rename to docs/lib/models/object.md diff --git a/docs/models/project.md b/docs/lib/models/project.md similarity index 100% rename from docs/models/project.md rename to docs/lib/models/project.md diff --git a/docs/nav/index.md b/docs/lib/nav/index.md similarity index 100% rename from docs/nav/index.md rename to docs/lib/nav/index.md diff --git a/docs/nav/mkdocs.md b/docs/lib/nav/mkdocs.md similarity index 100% rename from docs/nav/mkdocs.md rename to docs/lib/nav/mkdocs.md diff --git a/docs/nav/resolver.md b/docs/lib/nav/resolver.md similarity index 100% rename from docs/nav/resolver.md rename to docs/lib/nav/resolver.md diff --git a/docs/nav/spec.md b/docs/lib/nav/spec.md similarity index 100% rename from docs/nav/spec.md rename to docs/lib/nav/spec.md diff --git a/docs/lib/nav/wiki.md b/docs/lib/nav/wiki.md new file mode 100644 index 0000000..c60c750 --- /dev/null +++ b/docs/lib/nav/wiki.md @@ -0,0 +1,3 @@ +# Wiki + +::: docforge.nav.wiki diff --git a/docs/renderers/base.md b/docs/lib/renderers/base.md similarity index 100% rename from docs/renderers/base.md rename to docs/lib/renderers/base.md diff --git a/docs/renderers/index.md b/docs/lib/renderers/index.md similarity index 100% rename from docs/renderers/index.md rename to docs/lib/renderers/index.md diff --git a/docs/renderers/mcp_renderer.md b/docs/lib/renderers/mcp_renderer.md similarity index 100% rename from docs/renderers/mcp_renderer.md rename to docs/lib/renderers/mcp_renderer.md diff --git a/docs/renderers/mkdocs_renderer.md b/docs/lib/renderers/mkdocs_renderer.md similarity index 100% rename from docs/renderers/mkdocs_renderer.md rename to docs/lib/renderers/mkdocs_renderer.md diff --git a/docs/servers/index.md b/docs/lib/servers/index.md similarity index 100% rename from docs/servers/index.md rename to docs/lib/servers/index.md diff --git a/docs/servers/mcp_server.md b/docs/lib/servers/mcp_server.md similarity index 100% rename from docs/servers/mcp_server.md rename to docs/lib/servers/mcp_server.md diff --git a/mcp_docs/index.json b/docs/mcp/index.json similarity index 77% rename from mcp_docs/index.json rename to docs/mcp/index.json index 22bf131..6ce9145 100644 --- a/mcp_docs/index.json +++ b/docs/mcp/index.json @@ -1,6 +1,6 @@ { "project": "docforge", "type": "docforge-model", - "modules_count": 22, + "modules_count": 24, "source": "docforge" } \ No newline at end of file diff --git a/docs/mcp/modules/docforge.cli.api_utils.json b/docs/mcp/modules/docforge.cli.api_utils.json new file mode 100644 index 0000000..ae164da --- /dev/null +++ b/docs/mcp/modules/docforge.cli.api_utils.json @@ -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." + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/modules/docforge.cli.commands.json b/docs/mcp/modules/docforge.cli.commands.json new file mode 100644 index 0000000..2d73bff --- /dev/null +++ b/docs/mcp/modules/docforge.cli.commands.json @@ -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." + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/modules/docforge.cli.json b/docs/mcp/modules/docforge.cli.json new file mode 100644 index 0000000..b1b7190 --- /dev/null +++ b/docs/mcp/modules/docforge.cli.json @@ -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 [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." + } + } + } + } + } +} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.cli.main.json b/docs/mcp/modules/docforge.cli.main.json similarity index 81% rename from mcp_docs/modules/docforge.cli.main.json rename to docs/mcp/modules/docforge.cli.main.json index 0d98853..244177c 100644 --- a/mcp_docs/modules/docforge.cli.main.json +++ b/docs/mcp/modules/docforge.cli.main.json @@ -8,14 +8,14 @@ "name": "cli", "kind": "attribute", "path": "docforge.cli.main.cli", - "signature": "", + "signature": null, "docstring": null }, "main": { "name": "main", "kind": "function", "path": "docforge.cli.main.main", - "signature": "", + "signature": "main() -> None", "docstring": "Run the doc-forge command-line interface.\n\nThis function initializes and executes the Click CLI application.\nIt is used as the console entry point when invoking `doc-forge`\nfrom the command line." } } diff --git a/mcp_docs/modules/docforge.cli.mcp_utils.json b/docs/mcp/modules/docforge.cli.mcp_utils.json similarity index 62% rename from mcp_docs/modules/docforge.cli.mcp_utils.json rename to docs/mcp/modules/docforge.cli.mcp_utils.json index 29ee704..f60ac5e 100644 --- a/mcp_docs/modules/docforge.cli.mcp_utils.json +++ b/docs/mcp/modules/docforge.cli.mcp_utils.json @@ -2,42 +2,28 @@ "module": "docforge.cli.mcp_utils", "content": { "path": "docforge.cli.mcp_utils", - "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.", + "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": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.mcp_utils.Path", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.mcp_utils.click", - "signature": "", - "docstring": null - }, "GriffeLoader": { "name": "GriffeLoader", "kind": "class", "path": "docforge.cli.mcp_utils.GriffeLoader", - "signature": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } }, @@ -45,28 +31,28 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.cli.mcp_utils.discover_module_paths", - "signature": "", - "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, optional):\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." + "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": "", + "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": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.cli.mcp_utils.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path)", "docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written." } } @@ -75,28 +61,28 @@ "name": "MCPServer", "kind": "class", "path": "docforge.cli.mcp_utils.MCPServer", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "app": { "name": "app", "kind": "attribute", "path": "docforge.cli.mcp_utils.MCPServer.app", - "signature": "", + "signature": null, "docstring": null }, "run": { "name": "run", "kind": "function", "path": "docforge.cli.mcp_utils.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')", "docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`." } } @@ -105,14 +91,14 @@ "name": "generate_resources", "kind": "function", "path": "docforge.cli.mcp_utils.generate_resources", - "signature": "", - "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 (Optional[str]):\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." + "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": "", + "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." } } diff --git a/docs/mcp/modules/docforge.cli.mkdocs_utils.json b/docs/mcp/modules/docforge.cli.mkdocs_utils.json new file mode 100644 index 0000000..21b100a --- /dev/null +++ b/docs/mcp/modules/docforge.cli.mkdocs_utils.json @@ -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." + } + } + } +} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.json b/docs/mcp/modules/docforge.json similarity index 57% rename from mcp_docs/modules/docforge.json rename to docs/mcp/modules/docforge.json index 19ae863..a963a48 100644 --- a/mcp_docs/modules/docforge.json +++ b/docs/mcp/modules/docforge.json @@ -2,28 +2,28 @@ "module": "docforge", "content": { "path": "docforge", - "docstring": "# Summary\n\nRenderer-agnostic Python documentation compiler that converts Python docstrings\ninto structured documentation for both humans (MkDocs) and machines (MCP / AI agents).\n\n`doc-forge` statically analyzes source code, builds a semantic model of modules,\nclasses, functions, and attributes, and renders that model into documentation\noutputs without executing user code.\n\n---\n\n# Installation\n\nInstall using pip:\n\n```bash\npip install doc-forge\n```\n\n---\n\n# CLI usage\n\n## Generate an MkDocs site from a Python package:\n\n```bash\ndoc-forge build --mkdocs --module my_package\n```\n\n## Generate MCP JSON documentation:\n\n```bash\ndoc-forge build --mcp --module my_package\n```\n\n\n## Generate MkDocs site and MCP JSON documentation:\n\n```bash\ndoc-forge build --mcp --mkdocs --module my_package\n```\n\n## Serve MkDocs locally:\n\n```bash\ndoc-forge serve --mkdocs --module my_package\n```\n\n## Serve MCP locally:\n\n```bash\ndoc-forge serve --mcp --module my_package\n```\n\n---\n\n# Core concepts\n\n## Loader\nExtracts symbols, signatures, and docstrings using static analysis.\n\n## Semantic model\nStructured, renderer-agnostic representation of the API.\n\n## Renderer\nConverts the semantic model into output formats such as MkDocs or MCP JSON.\n\n## Symbol\nAny documentable object\n\n- module\n- class\n- function\n- method\n- property\n- attribute\n\n---\n\n# Architecture\n\n`doc-forge` follows a compiler architecture:\n\n## Front-end:\n\nStatic analysis of modules, classes, functions, type hints, and docstrings.\n\n## Middle-end:\n\nBuilds a semantic model describing symbols and relationships.\n\n## Back-end:\n\nRenders documentation using interchangeable renderers.\n\nThis architecture ensures deterministic documentation generation.\n\n---\n\n# Rendering pipeline\n\nTypical flow:\n\n Python package\n |\n Loader (static analysis)\n |\n Semantic model\n |\n Renderer\n |\n MkDocs site or MCP JSON\n\n---\n\n# Google-Styled Doc-Forge Convention (GSDFC)\n\nGSDFC defines how docstrings must be written so they render correctly in MkDocs and remain machine-parsable by doc-forge and AI tooling.\n\n- Docstrings are the single source of truth.\n- `doc-forge` compiles docstrings but does not generate documentation content.\n- Documentation follows the Python import hierarchy.\n- Every public symbol should have a complete and accurate docstring.\n\n---\n\n## General rules\n\n- Use **Markdown headings** at package and module level.\n- Use **Google-style structured sections** at class, function, and method level.\n- Use type hints in signatures instead of duplicating types in prose.\n- Write summaries in imperative form.\n- Sections are separated by `---`\n\n---\n\n# Notes subsection grouping\n\nGroup related information using labeled subsections.\n\nExample:\n\n Notes:\n **Guarantees:**\n\n - deterministic behavior\n\n **Lifecycle:**\n\n - created during initialization\n - reused across executions\n\n **Thread safety:**\n\n - safe for concurrent reads\n\n---\n\n# Example formatting\n\n- Use indentation for examples.\n- Indent section contents using four spaces.\n- Use code blocks for example code.\n\nExample:\n Single example:\n\n Example:\n\n ```python\n foo = Foo(\"example\")\n process(foo, multiplier=2)\n ```\n\n Multiple examples:\n\n Example:\n Create foo:\n\n ```python\n foo = Foo(\"example\")\n ```\n\n Run engine:\n\n ```python\n engine = BarEngine([foo])\n engine.run()\n ```\n\nAvoid fenced code blocks inside structured sections.\n\n---\n\n# Separator rules\n\nUse horizontal separators only at docstring root level to separate sections:\n\n```markdown\n---\n```\n\nAllowed locations:\n\n- package docstrings\n- module docstrings\n- major documentation sections\n\nDo not use separators inside code sections.\n\n---\n\n# Package docstrings\n\nPackage docstrings act as the documentation home page.\n\nRecommended sections:\n\n # Summary\n # Installation\n # Quick start\n # CLI usage\n # Core concepts\n # Architecture\n # Rendering pipeline\n # Examples\n # Notes\n\nExample:\n Package Doc String:\n\n '''\n # Summary\n\n Foo-bar processing framework.\n\n Provides tools for defining Foo objects and executing Bar pipelines.\n\n ---\n\n # Installation\n\n ```bash\n pip install foo-bar\n ```\n\n ---\n\n # Quick start\n\n ```python\n from foobar import Foo, BarEngine\n\n foo = Foo(\"example\")\n engine = BarEngine([foo])\n\n result = engine.run()\n ```\n\n ---\n '''\n\n---\n\n# Module docstrings\n\nModule docstrings describe a subsystem.\n\nRecommended sections:\n\n # Summary\n # Examples\n # Notes\n\nExample:\n Module Doc String:\n\n '''\n # Summary\n\n Foo execution subsystem.\n\n Provides utilities for executing Foo objects through Bar stages.\n\n ---\n\n Example:\n\n ```python\n from foobar.engine import BarEngine\n from foobar.foo import Foo\n\n foo = Foo(\"example\")\n\n engine = BarEngine([foo])\n engine.run()\n ```\n\n ---\n '''\n\n---\n\n# Class docstrings\n\nClass docstrings define object responsibility, lifecycle, and attributes.\n\nRecommended sections:\n\n Attributes:\n Notes:\n Example:\n Raises:\n\nExample:\n Simple Foo:\n\n ```python\n class Foo:\n '''\n Represents a unit of work.\n\n Attributes:\n name (str):\n Identifier of the foo instance.\n\n value (int):\n Numeric value associated with foo.\n\n Notes:\n Guarantees:\n\n - instances are immutable after creation\n\n Lifecycle:\n\n - create instance\n - pass to processing engine\n\n Example:\n Create and inspect a Foo:\n\n ```python\n foo = Foo(\"example\", value=42)\n print(foo.name)\n ```\n '''\n ```\n\n Complex Bar:\n\n ```python\n class BarEngine:\n '''\n Executes Foo objects through Bar stages.\n\n Attributes:\n foos (tuple[Foo, ...]):\n Foo instances managed by the engine.\n\n Notes:\n Guarantees:\n\n - deterministic execution order\n\n Example:\n Run engine:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n ```\n\n---\n\n# Function and method docstrings\n\nFunction docstrings define API contracts.\n\nRecommended sections:\n\n Args:\n Returns:\n Raises:\n Yields:\n Notes:\n Example:\n\nExample:\n Simple process method:\n\n ```python\n def process(foo: Foo, multiplier: int) -> int:\n '''\n Process a Foo instance.\n\n Args:\n foo (Foo):\n Foo instance to process.\n\n multiplier (int):\n Value used to scale foo.\n\n Returns:\n int:\n Processed result.\n\n Raises:\n ValueError:\n If multiplier is negative.\n\n Notes:\n Guarantees:\n\n - foo is not modified\n\n Example:\n Process foo:\n\n ```python\n foo = Foo(\"example\", value=10)\n\n result = process(foo, multiplier=2)\n print(result)\n ```\n '''\n ```\n\n Multiple Examples:\n\n ```python\n def combine(foo_a: Foo, foo_b: Foo) -> Foo:\n '''\n Combine two Foo instances.\n\n Args:\n foo_a (Foo):\n First foo.\n\n foo_b (Foo):\n Second foo.\n\n Returns:\n Foo:\n Combined foo.\n\n Example:\n Basic usage:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n combined = combine(foo1, foo2)\n ```\n\n Pipeline usage:\n\n ```python\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n ```\n\n---\n\n# Property docstrings\n\nProperties must document return values.\n\nExample:\n Property Doc String:\n\n ```python\n @property\n def foos(self) -> tuple[Foo, ...]:\n '''\n Return contained Foo instances.\n\n Returns:\n tuple[Foo, ...]:\n Stored foo objects.\n\n Example:\n ```python\n container = FooContainer()\n\n foos = container.foos\n ```\n '''\n ```\n\n---\n\n# Attribute documentation\n\nDocument attributes in class docstrings using `Attributes:`.\n\nExample:\n Attribute Doc String:\n\n ```python\n '''\n Represents a processing stage.\n\n Attributes:\n id (str):\n Unique identifier.\n\n enabled (bool):\n Whether the stage is active.\n '''\n ```\n\n---\n\n# Parsing guarantees\n\nGSDFC ensures doc-forge can deterministically extract:\n\n- symbol kind (module, class, function, property, attribute)\n- symbol name\n- parameters\n- return values\n- attributes\n- examples\n- structured Notes subsections\n\nThis enables:\n\n- reliable MkDocs rendering\n- deterministic MCP export\n- accurate AI semantic interpretation\n\n---\n\nNotes:\n - doc-forge never executes analyzed modules.\n - Documentation is generated entirely through static analysis.", + "docstring": "# Summary\n\nRenderer-agnostic Python documentation compiler that converts Python docstrings\ninto structured documentation for both humans (MkDocs) and machines (MCP / AI agents).\n\n`doc-forge` statically analyzes source code, builds a semantic model of modules,\nclasses, functions, and attributes, and renders that model into documentation\noutputs without executing user code.\n\n---\n\n# Installation\n\nInstall using pip:\n\n```bash\npip install doc-forge\n```\n\n---\n\n# CLI usage\n\nEach site kind (`lib`, `api`, `wiki`) is built independently into `site/{kind}`.\n\n## Build the library reference from a Python package:\n\n```bash\ndoc-forge build --mkdocs --module my_package\n```\n\n## Build the API reference from an OpenAPI spec:\n\n```bash\ndoc-forge build --api --openapi-spec spec.json\n```\n\n## Build the hand-written wiki:\n\n```bash\ndoc-forge build --wiki --site-name my_package\n```\n\n## Generate MCP JSON documentation:\n\n```bash\ndoc-forge build --mcp --module my_package\n```\n\n## Build several kinds in one pass:\n\n```bash\ndoc-forge build --mcp --mkdocs --wiki --module my_package\n```\n\nEach enabled kind gets its own MkDocs config (`docs/mkdocs.{lib,api,wiki}.yml`)\nand its own site under `site/`.\n\n## Serve a site locally:\n\n```bash\ndoc-forge serve --wiki # preview from docs/mkdocs.wiki.yml\ndoc-forge serve --lib\ndoc-forge serve --api\n# or any config directly:\ndoc-forge serve --mkdocs --mkdocs-yml docs/mkdocs.wiki.yml\n```\n\n## Serve MCP locally:\n\n```bash\ndoc-forge serve --mcp --module my_package\n```\n\n---\n\n# Core concepts\n\n## Loader\nExtracts symbols, signatures, and docstrings using static analysis.\n\n## Semantic model\nStructured, renderer-agnostic representation of the API.\n\n## Renderer\nConverts the semantic model into output formats such as MkDocs or MCP JSON.\n\n## Symbol\nAny documentable object\n\n- module\n- class\n- function\n- method\n- property\n- attribute\n\n---\n\n# Architecture\n\n`doc-forge` follows a compiler architecture:\n\n## Front-end:\n\nStatic analysis of modules, classes, functions, type hints, and docstrings.\n\n## Middle-end:\n\nBuilds a semantic model describing symbols and relationships.\n\n## Back-end:\n\nRenders documentation using interchangeable renderers.\n\nThis architecture ensures deterministic documentation generation.\n\n---\n\n# Rendering pipeline\n\nTypical flow:\n\n Python package\n |\n Loader (static analysis)\n |\n Semantic model\n |\n Renderer\n |\n MkDocs site or MCP JSON\n\n---\n\n# Google-Styled Doc-Forge Convention (GSDFC)\n\nGSDFC defines how docstrings must be written so they render correctly in MkDocs and remain machine-parsable by doc-forge and AI tooling.\n\n- Docstrings are the single source of truth.\n- `doc-forge` compiles docstrings but does not generate documentation content.\n- Documentation follows the Python import hierarchy.\n- Every public symbol should have a complete and accurate docstring.\n\n---\n\n## General rules\n\n- Use **Markdown headings** at package and module level.\n- Use **Google-style structured sections** at class, function, and method level.\n- Use type hints in signatures.\n- Use parenthesized types in prose entries (`name (Type):`) that match the\n signature types. This keeps docstrings self-contained and machine-parseable.\n- Write summaries in imperative form.\n- Sections are separated by `---`\n\n---\n\n# Notes subsection grouping\n\nGroup related information using labeled subsections.\n\nExample:\n\n Notes:\n **Guarantees:**\n\n - deterministic behavior\n\n **Lifecycle:**\n\n - created during initialization\n - reused across executions\n\n **Thread safety:**\n\n - safe for concurrent reads\n\n---\n\n# Example formatting\n\n- Use indentation for examples.\n- Indent section contents using four spaces.\n- Use code blocks for example code.\n\nExample:\n Single example:\n\n Example:\n\n ```python\n foo = Foo(\"example\")\n process(foo, multiplier=2)\n ```\n\n Multiple examples:\n\n Example:\n Create foo:\n\n ```python\n foo = Foo(\"example\")\n ```\n\n Run engine:\n\n ```python\n engine = BarEngine([foo])\n engine.run()\n ```\n\nAvoid fenced code blocks inside argument descriptions and other prose lines.\n\nInside `Example:` sections, fenced `python` code blocks are allowed and must be\nindented four spaces, matching the examples below.\n\n---\n\n# Separator rules\n\nUse horizontal separators only at docstring root level to separate sections:\n\n```markdown\n---\n```\n\nAllowed locations:\n\n- package docstrings\n- module docstrings\n- major documentation sections\n\nDo not use separators inside code sections.\n\n---\n\n# Package docstrings\n\nPackage docstrings act as the documentation home page.\n\nRecommended sections:\n\n # Summary\n # Installation\n # Quick start\n # CLI usage\n # Core concepts\n # Architecture\n # Rendering pipeline\n # Examples\n # Notes\n\nExample:\n Package Doc String:\n\n '''\n # Summary\n\n Foo-bar processing framework.\n\n Provides tools for defining Foo objects and executing Bar pipelines.\n\n ---\n\n # Installation\n\n ```bash\n pip install foo-bar\n ```\n\n ---\n\n # Quick start\n\n ```python\n from foobar import Foo, BarEngine\n\n foo = Foo(\"example\")\n engine = BarEngine([foo])\n\n result = engine.run()\n ```\n\n ---\n '''\n\n---\n\n# Module docstrings\n\nModule docstrings describe a subsystem.\n\nRecommended sections:\n\n # Summary\n # Examples\n # Notes\n\nExample:\n Module Doc String:\n\n '''\n # Summary\n\n Foo execution subsystem.\n\n Provides utilities for executing Foo objects through Bar stages.\n\n ---\n\n Example:\n\n ```python\n from foobar.engine import BarEngine\n from foobar.foo import Foo\n\n foo = Foo(\"example\")\n\n engine = BarEngine([foo])\n engine.run()\n ```\n\n ---\n '''\n\n---\n\n# Class docstrings\n\nClass docstrings define object responsibility, lifecycle, and attributes.\n\nRecommended sections:\n\n Attributes:\n Notes:\n Example:\n Raises:\n\nExample:\n Simple Foo:\n\n ```python\n class Foo:\n '''\n Represents a unit of work.\n\n Attributes:\n name (str):\n Identifier of the foo instance.\n\n value (int):\n Numeric value associated with foo.\n\n Notes:\n Guarantees:\n\n - instances are immutable after creation\n\n Lifecycle:\n\n - create instance\n - pass to processing engine\n\n Example:\n Create and inspect a Foo:\n\n ```python\n foo = Foo(\"example\", value=42)\n print(foo.name)\n ```\n '''\n ```\n\n Complex Bar:\n\n ```python\n class BarEngine:\n '''\n Executes Foo objects through Bar stages.\n\n Attributes:\n foos (tuple[Foo, ...]):\n Foo instances managed by the engine.\n\n Notes:\n Guarantees:\n\n - deterministic execution order\n\n Example:\n Run engine:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n ```\n\n---\n\n# Function and method docstrings\n\nFunction docstrings define API contracts.\n\nRecommended sections:\n\n Args:\n Returns:\n Raises:\n Yields:\n Notes:\n Example:\n\nExample:\n Simple process method:\n\n ```python\n def process(foo: Foo, multiplier: int) -> int:\n '''\n Process a Foo instance.\n\n Args:\n foo (Foo):\n Foo instance to process.\n\n multiplier (int):\n Value used to scale foo.\n\n Returns:\n int:\n Processed result.\n\n Raises:\n ValueError:\n If multiplier is negative.\n\n Notes:\n Guarantees:\n\n - foo is not modified\n\n Example:\n Process foo:\n\n ```python\n foo = Foo(\"example\", value=10)\n\n result = process(foo, multiplier=2)\n print(result)\n ```\n '''\n ```\n\n Multiple Examples:\n\n ```python\n def combine(foo_a: Foo, foo_b: Foo) -> Foo:\n '''\n Combine two Foo instances.\n\n Args:\n foo_a (Foo):\n First foo.\n\n foo_b (Foo):\n Second foo.\n\n Returns:\n Foo:\n Combined foo.\n\n Example:\n Basic usage:\n\n ```python\n foo1 = Foo(\"a\")\n foo2 = Foo(\"b\")\n\n combined = combine(foo1, foo2)\n ```\n\n Pipeline usage:\n\n ```python\n engine = BarEngine([foo1, foo2])\n engine.run()\n ```\n '''\n ```\n\n---\n\n# Property docstrings\n\nProperties must document return values.\n\nExample:\n Property Doc String:\n\n ```python\n @property\n def foos(self) -> tuple[Foo, ...]:\n '''\n Return contained Foo instances.\n\n Returns:\n tuple[Foo, ...]:\n Stored foo objects.\n\n Example:\n ```python\n container = FooContainer()\n\n foos = container.foos\n ```\n '''\n ```\n\n---\n\n# Attribute documentation\n\nDocument attributes in class docstrings using `Attributes:`.\n\nExample:\n Attribute Doc String:\n\n ```python\n '''\n Represents a processing stage.\n\n Attributes:\n id (str):\n Unique identifier.\n\n enabled (bool):\n Whether the stage is active.\n '''\n ```\n\n---\n\n# Type parity (`.pyi` stubs and `py.typed`)\n\nDocumented APIs ship matching type information:\n\n- Each `.py` module has a synchronized `.pyi` stub in the same package.\n- Packages expose a `py.typed` marker so type checkers (and consumers)\n use the authored signatures instead of `Any`.\n- When signatures change, update the `.py` implementation and its `.pyi`\n stub together.\n- Doc-forge documents the docstrings in `.py`; the `.pyi` stub is the\n machine-consumable signature surface.\n\n---\n\n# Parsing guarantees\n\nGSDFC ensures doc-forge can deterministically extract:\n\n- symbol kind (module, class, function, property, attribute)\n- symbol name\n- parameters\n- return values\n- attributes\n- examples\n- structured Notes subsections\n\nThis enables:\n\n- reliable MkDocs rendering\n- deterministic MCP export\n- accurate AI semantic interpretation\n\n---\n\nNotes:\n - doc-forge never executes analyzed modules.\n - Documentation is generated entirely through static analysis.", "objects": { "GriffeLoader": { "name": "GriffeLoader", "kind": "class", "path": "docforge.GriffeLoader", - "signature": "", - "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.", + "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.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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.GriffeLoader.load_module", - "signature": "", - "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." + "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 ```" } } }, @@ -31,36 +31,36 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.discover_module_paths", - "signature": "", - "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, optional):\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." + "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." }, "MkDocsRenderer": { "name": "MkDocsRenderer", "kind": "class", "path": "docforge.MkDocsRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.MkDocsRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "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.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "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`." } } }, @@ -68,21 +68,21 @@ "name": "MCPRenderer", "kind": "class", "path": "docforge.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.MCPRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path)", "docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written." } } @@ -91,21 +91,21 @@ "name": "main", "kind": "module", "path": "docforge.main", - "signature": "", + "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.main.cli", - "signature": "", + "signature": null, "docstring": null }, "main": { "name": "main", "kind": "function", "path": "docforge.main.main", - "signature": "", + "signature": "main()", "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." } } @@ -128,228 +128,156 @@ "name": "cli", "kind": "attribute", "path": "docforge.cli.main.cli", - "signature": "", + "signature": null, "docstring": null }, "main": { "name": "main", "kind": "function", "path": "docforge.cli.main.main", - "signature": "", + "signature": "main() -> None", "docstring": "Run the doc-forge command-line interface.\n\nThis function initializes and executes the Click CLI application.\nIt is used as the console entry point when invoking `doc-forge`\nfrom the command line." } } }, + "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.", + "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": { - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.click", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.Path", - "signature": "", - "docstring": null - }, - "Sequence": { - "name": "Sequence", - "kind": "alias", - "path": "docforge.cli.commands.Sequence", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.cli.commands.Optional", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "mkdocs_utils": { - "name": "mkdocs_utils", + "api_utils": { + "name": "api_utils", "kind": "module", - "path": "docforge.cli.commands.mkdocs_utils", - "signature": "", - "docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.", + "path": "docforge.cli.commands.api_utils", + "signature": null, + "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.Path", - "signature": "", + "SWAGGER_SPEC_FILENAME": { + "name": "SWAGGER_SPEC_FILENAME", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME", + "signature": null, "docstring": null }, - "resources": { - "name": "resources", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.resources", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.click", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.yaml", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", + "OpenAPIMetadata": { + "name": "OpenAPIMetadata", "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.GriffeLoader", - "signature": "", - "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.", + "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": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.discover_module_paths", - "signature": "", - "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, optional):\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." - }, - "MkDocsRenderer": { - "name": "MkDocsRenderer", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer", - "signature": "", - "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", + "site_name": { + "name": "site_name", "kind": "attribute", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.name", - "signature": "", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_name", + "signature": null, "docstring": null }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "site_description": { + "name": "site_description", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description", + "signature": null, + "docstring": null }, - "generate_readme": { - "name": "generate_readme", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "site_author": { + "name": "site_author", + "kind": "attribute", + "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author", + "signature": null, + "docstring": null } } }, - "load_nav_spec": { - "name": "load_nav_spec", + "load_openapi_spec": { + "name": "load_openapi_spec", "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.load_nav_spec", - "signature": "", - "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." + "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." }, - "resolve_nav": { - "name": "resolve_nav", + "derive_metadata": { + "name": "derive_metadata", "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.resolve_nav", - "signature": "", - "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." + "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." }, - "MkDocsNavEmitter": { - "name": "MkDocsNavEmitter", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter", - "signature": "", - "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": "", - "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." - } - } - }, - "generate_sources": { - "name": "generate_sources", + "generate_api_sources": { + "name": "generate_api_sources", "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.generate_sources", - "signature": "", - "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 (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module." - }, - "generate_config": { - "name": "generate_config", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." - }, - "build": { - "name": "build", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.build", - "signature": "", - "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\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." - }, - "serve": { - "name": "serve", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.serve", - "signature": "", - "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." + "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." } } }, @@ -357,43 +285,29 @@ "name": "mcp_utils", "kind": "module", "path": "docforge.cli.commands.mcp_utils", - "signature": "", - "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.", + "signature": null, + "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.\n\n---\n\nNotes:\n - `generate_resources` produces the bundle consumed by `MCPServer`:\n `index.json`, `nav.json`, and per-module resources under `modules/`.\n - Resource URIs use the `docs://` scheme: `docs://index`, `docs://nav`,\n and `docs://modules/{module}`.\n\n---", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.mcp_utils.Path", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.mcp_utils.click", - "signature": "", - "docstring": null - }, "GriffeLoader": { "name": "GriffeLoader", "kind": "class", "path": "docforge.cli.commands.mcp_utils.GriffeLoader", - "signature": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } }, @@ -401,28 +315,28 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.cli.commands.mcp_utils.discover_module_paths", - "signature": "", - "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, optional):\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." + "signature": "discover_module_paths(module_name: str, project_root: Path | None = None)", + "docstring": "Discover Python modules within a package directory.\n\nThe function scans the filesystem for `.py` files inside the specified\npackage and converts them into dotted module import paths.\n\nDiscovery rules:\n\n- Directories containing `__init__.py` are treated as packages.\n- Each `.py` file is treated as a module.\n- Results are returned as dotted import paths.\n\nArgs:\n module_name (str):\n Top-level package name to discover modules from.\n\n project_root (Path | None):\n Root directory used to resolve module paths. If not provided, the\n current working directory is used.\n\nReturns:\n list[str]:\n A sorted list of unique dotted module import paths.\n\nRaises:\n FileNotFoundError:\n If the specified package directory does not exist." }, "MCPRenderer": { "name": "MCPRenderer", "kind": "class", "path": "docforge.cli.commands.mcp_utils.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.cli.commands.mcp_utils.MCPRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path)", "docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written." } } @@ -431,28 +345,28 @@ "name": "MCPServer", "kind": "class", "path": "docforge.cli.commands.mcp_utils.MCPServer", - "signature": "", - "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.", + "signature": "MCPServer(mcp_root: Path, name: str)", + "docstring": "MCP server for serving a pre-generated documentation bundle.\n\nThe server exposes documentation resources and diagnostic tools through\nMCP endpoints backed by JSON files generated by the MCP renderer.\n\nAttributes:\n mcp_root (Path):\n Directory containing the generated MCP documentation bundle.\n\n app (FastMCP):\n Underlying FastMCP application instance that registers resources\n and tools.", "members": { "mcp_root": { "name": "mcp_root", "kind": "attribute", "path": "docforge.cli.commands.mcp_utils.MCPServer.mcp_root", - "signature": "", + "signature": null, "docstring": null }, "app": { "name": "app", "kind": "attribute", "path": "docforge.cli.commands.mcp_utils.MCPServer.app", - "signature": "", + "signature": null, "docstring": null }, "run": { "name": "run", "kind": "function", "path": "docforge.cli.commands.mcp_utils.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')", "docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`." } } @@ -461,18 +375,268 @@ "name": "generate_resources", "kind": "function", "path": "docforge.cli.commands.mcp_utils.generate_resources", - "signature": "", - "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 (Optional[str]):\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." + "signature": "generate_resources(module: str, project_name: str | None, out_dir: Path)", + "docstring": "Generate MCP documentation resources from a Python module.\n\nThe function performs project introspection, builds the internal\ndocumentation model, and renders MCP-compatible JSON resources\nto the specified output directory.\n\nArgs:\n module (str):\n Python module import path used as the entry point for\n documentation generation.\n\n project_name (str | None):\n Optional override for the project name used in generated\n documentation metadata.\n\n out_dir (Path):\n Directory where MCP resources (index.json, nav.json, and module data)\n will be written." }, "serve": { "name": "serve", "kind": "function", "path": "docforge.cli.commands.mcp_utils.serve", - "signature": "", + "signature": "serve(module: str, mcp_root: Path)", "docstring": "Start an MCP server for a pre-generated documentation bundle.\n\nThe server exposes documentation resources such as project metadata,\nnavigation structure, and module documentation through MCP endpoints.\n\nArgs:\n module (str):\n Python module import path used to identify the served\n documentation instance.\n\n mcp_root (Path):\n Path to the directory containing the MCP documentation\n bundle (index.json, nav.json, and modules/).\n\nRaises:\n click.ClickException:\n If the MCP documentation bundle is missing required files or directories." } } }, + "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", @@ -484,36 +648,22 @@ "name": "build", "kind": "function", "path": "docforge.cli.commands.build", - "signature": "", - "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\n\n1. Introspects the Python project using Griffe\n2. Generates renderer-specific documentation sources\n3. Optionally builds the final documentation output\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs documentation generation.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Directory where Markdown documentation sources will be generated.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\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." + "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": "", - "docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing documentation\n- An MCP server exposing structured documentation resources\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site.\n\n module (Optional[str]):\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." + "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": "", - "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 (Optional[str]):\n Optional name to display as the project root." - }, - "Group": { - "name": "Group", - "kind": "alias", - "path": "docforge.cli.commands.Group", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.cli.commands.Any", - "signature": "", - "docstring": null + "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." } } }, @@ -522,42 +672,28 @@ "kind": "module", "path": "docforge.cli.mcp_utils", "signature": null, - "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.", + "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.\n\n---\n\nNotes:\n - `generate_resources` produces the bundle consumed by `MCPServer`:\n `index.json`, `nav.json`, and per-module resources under `modules/`.\n - Resource URIs use the `docs://` scheme: `docs://index`, `docs://nav`,\n and `docs://modules/{module}`.\n\n---", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.mcp_utils.Path", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.mcp_utils.click", - "signature": "", - "docstring": null - }, "GriffeLoader": { "name": "GriffeLoader", "kind": "class", "path": "docforge.cli.mcp_utils.GriffeLoader", - "signature": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } }, @@ -565,28 +701,28 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.cli.mcp_utils.discover_module_paths", - "signature": "", - "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, optional):\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." + "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": "", + "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": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.cli.mcp_utils.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path)", "docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written." } } @@ -595,28 +731,28 @@ "name": "MCPServer", "kind": "class", "path": "docforge.cli.mcp_utils.MCPServer", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "app": { "name": "app", "kind": "attribute", "path": "docforge.cli.mcp_utils.MCPServer.app", - "signature": "", + "signature": null, "docstring": null }, "run": { "name": "run", "kind": "function", "path": "docforge.cli.mcp_utils.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')", "docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`." } } @@ -625,14 +761,14 @@ "name": "generate_resources", "kind": "function", "path": "docforge.cli.mcp_utils.generate_resources", - "signature": "", - "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 (Optional[str]):\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." + "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": "", + "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." } } @@ -642,56 +778,28 @@ "kind": "module", "path": "docforge.cli.mkdocs_utils", "signature": null, - "docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.", + "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": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.Path", - "signature": "", - "docstring": null - }, - "resources": { - "name": "resources", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.resources", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.click", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.yaml", - "signature": "", - "docstring": null - }, "GriffeLoader": { "name": "GriffeLoader", "kind": "class", "path": "docforge.cli.mkdocs_utils.GriffeLoader", - "signature": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } }, @@ -699,66 +807,73 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.cli.mkdocs_utils.discover_module_paths", - "signature": "", - "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, optional):\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." - }, - "MkDocsRenderer": { - "name": "MkDocsRenderer", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.MkDocsRenderer", - "signature": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\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": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." - } - } - }, - "load_nav_spec": { - "name": "load_nav_spec", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.load_nav_spec", - "signature": "", - "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." - }, - "resolve_nav": { - "name": "resolve_nav", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.resolve_nav", - "signature": "", - "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": "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": "", + "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": "", - "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.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`." } } }, @@ -766,28 +881,49 @@ "name": "generate_sources", "kind": "function", "path": "docforge.cli.mkdocs_utils.generate_sources", - "signature": "", - "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 (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module." + "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``." }, - "generate_config": { - "name": "generate_config", + "build_lib_nav": { + "name": "build_lib_nav", "kind": "function", - "path": "docforge.cli.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." + "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": { - "name": "build", + "build_wiki_nav_block": { + "name": "build_wiki_nav_block", "kind": "function", - "path": "docforge.cli.mkdocs_utils.build", - "signature": "", - "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\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." + "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": "", + "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." } } @@ -805,22 +941,22 @@ "name": "GriffeLoader", "kind": "class", "path": "docforge.loaders.GriffeLoader", - "signature": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } }, @@ -828,119 +964,135 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.loaders.discover_module_paths", - "signature": "", - "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, optional):\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." + "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.", + "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": { - "logging": { - "name": "logging", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.logging", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Path", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.List", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Optional", - "signature": "", - "docstring": null - }, - "ModulesCollection": { - "name": "ModulesCollection", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.ModulesCollection", - "signature": "", - "docstring": null - }, - "LinesCollection": { - "name": "LinesCollection", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.LinesCollection", - "signature": "", - "docstring": null - }, - "Object": { - "name": "Object", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Object", - "signature": "", - "docstring": null - }, - "AliasResolutionError": { - "name": "AliasResolutionError", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.AliasResolutionError", - "signature": "", - "docstring": null + "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": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.loaders.griffe_loader.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -949,125 +1101,53 @@ "name": "Project", "kind": "class", "path": "docforge.loaders.griffe_loader.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.loaders.griffe_loader.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } }, - "DocObject": { - "name": "DocObject", - "kind": "class", - "path": "docforge.loaders.griffe_loader.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\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": "", - "docstring": null - }, - "kind": { - "name": "kind", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.kind", - "signature": "", - "docstring": null - }, - "path": { - "name": "path", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.path", - "signature": "", - "docstring": null - }, - "signature": { - "name": "signature", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.signature", - "signature": "", - "docstring": null - }, - "docstring": { - "name": "docstring", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.docstring", - "signature": "", - "docstring": null - }, - "members": { - "name": "members", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.members", - "signature": "", - "docstring": null - }, - "add_member": { - "name": "add_member", - "kind": "function", - "path": "docforge.loaders.griffe_loader.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a member." - }, - "get_member": { - "name": "get_member", - "kind": "function", - "path": "docforge.loaders.griffe_loader.DocObject.get_member", - "signature": "", - "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": "", - "docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members." - } - } - }, "logger": { "name": "logger", "kind": "attribute", @@ -1079,29 +1159,29 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.loaders.griffe_loader.discover_module_paths", - "signature": "", - "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, optional):\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." + "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": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } } @@ -1120,49 +1200,49 @@ "name": "Project", "kind": "class", "path": "docforge.models.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.models.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.models.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } @@ -1171,49 +1251,49 @@ "name": "Module", "kind": "class", "path": "docforge.models.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.models.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -1222,70 +1302,70 @@ "name": "DocObject", "kind": "class", "path": "docforge.models.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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": "", + "signature": null, "docstring": null }, "kind": { "name": "kind", "kind": "attribute", "path": "docforge.models.DocObject.kind", - "signature": "", + "signature": null, "docstring": null }, "path": { "name": "path", "kind": "attribute", "path": "docforge.models.DocObject.path", - "signature": "", + "signature": null, "docstring": null }, "signature": { "name": "signature", "kind": "attribute", "path": "docforge.models.DocObject.signature", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.DocObject.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.DocObject.members", - "signature": "", + "signature": null, "docstring": null }, "add_member": { "name": "add_member", "kind": "function", "path": "docforge.models.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -1295,97 +1375,76 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.module.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.module.Iterable", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.models.module.Optional", - "signature": "", - "docstring": null - }, "DocObject": { "name": "DocObject", "kind": "class", "path": "docforge.models.module.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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": "", + "signature": null, "docstring": null }, "kind": { "name": "kind", "kind": "attribute", "path": "docforge.models.module.DocObject.kind", - "signature": "", + "signature": null, "docstring": null }, "path": { "name": "path", "kind": "attribute", "path": "docforge.models.module.DocObject.path", - "signature": "", + "signature": null, "docstring": null }, "signature": { "name": "signature", "kind": "attribute", "path": "docforge.models.module.DocObject.signature", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.module.DocObject.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.module.DocObject.members", - "signature": "", + "signature": null, "docstring": null }, "add_member": { "name": "add_member", "kind": "function", "path": "docforge.models.module.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -1394,8 +1453,8 @@ "name": "Module", "kind": "class", "path": "docforge.models.module.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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", @@ -1422,21 +1481,21 @@ "name": "add_object", "kind": "function", "path": "docforge.models.module.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -1448,35 +1507,14 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.object.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.object.Iterable", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.models.object.Optional", - "signature": "", - "docstring": null - }, "DocObject": { "name": "DocObject", "kind": "class", "path": "docforge.models.object.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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", @@ -1524,21 +1562,21 @@ "name": "add_member", "kind": "function", "path": "docforge.models.object.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -1550,69 +1588,55 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.project.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.project.Iterable", - "signature": "", - "docstring": null - }, "Module": { "name": "Module", "kind": "class", "path": "docforge.models.project.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.project.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.project.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.models.project.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -1621,8 +1645,8 @@ "name": "Project", "kind": "class", "path": "docforge.models.project.Project", - "signature": "", - "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.", + "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", @@ -1642,28 +1666,28 @@ "name": "add_module", "kind": "function", "path": "docforge.models.project.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } @@ -1683,36 +1707,43 @@ "name": "NavSpec", "kind": "class", "path": "docforge.nav.NavSpec", - "signature": "", - "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.NavSpec.groups", - "signature": "", + "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": "", - "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": "", - "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." } } }, @@ -1720,36 +1751,36 @@ "name": "load_nav_spec", "kind": "function", "path": "docforge.nav.load_nav_spec", - "signature": "", - "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": "", + "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.ResolvedNav.groups", - "signature": "", + "signature": null, "docstring": null }, "all_files": { "name": "all_files", "kind": "function", "path": "docforge.nav.ResolvedNav.all_files", - "signature": "", - "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." } } }, @@ -1757,87 +1788,66 @@ "name": "resolve_nav", "kind": "function", "path": "docforge.nav.resolve_nav", - "signature": "", - "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": "", + "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": "", - "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": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.mkdocs.List", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.mkdocs.Dict", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.nav.mkdocs.Any", - "signature": "", - "docstring": null - }, "ResolvedNav": { "name": "ResolvedNav", "kind": "class", "path": "docforge.nav.mkdocs.ResolvedNav", - "signature": "", + "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.mkdocs.ResolvedNav.groups", - "signature": "", + "signature": null, "docstring": null }, "all_files": { "name": "all_files", "kind": "function", "path": "docforge.nav.mkdocs.ResolvedNav.all_files", - "signature": "", - "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." } } }, @@ -1845,15 +1855,15 @@ "name": "MkDocsNavEmitter", "kind": "class", "path": "docforge.nav.mkdocs.MkDocsNavEmitter", - "signature": "", + "signature": null, "docstring": "Emit MkDocs navigation structures from resolved navigation data.\n\nThe emitter transforms a ``ResolvedNav`` object into the YAML-compatible\nlist structure expected by the MkDocs ``nav`` configuration field.", "members": { "emit": { "name": "emit", "kind": "function", "path": "docforge.nav.mkdocs.MkDocsNavEmitter.emit", - "signature": "", - "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." } } } @@ -1864,77 +1874,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": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.resolver.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.nav.resolver.Iterable", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.resolver.List", - "signature": "", - "docstring": null - }, - "glob": { - "name": "glob", - "kind": "alias", - "path": "docforge.nav.resolver.glob", - "signature": "", - "docstring": null - }, "NavSpec": { "name": "NavSpec", "kind": "class", "path": "docforge.nav.resolver.NavSpec", - "signature": "", - "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.resolver.NavSpec.groups", - "signature": "", + "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": "", - "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": "", - "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." } } }, @@ -1942,7 +1924,7 @@ "name": "ResolvedNav", "kind": "class", "path": "docforge.nav.resolver.ResolvedNav", - "signature": "", + "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": { @@ -1963,8 +1945,8 @@ "name": "all_files", "kind": "function", "path": "docforge.nav.resolver.ResolvedNav.all_files", - "signature": "", - "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." } } }, @@ -1972,15 +1954,8 @@ "name": "resolve_nav", "kind": "function", "path": "docforge.nav.resolver.resolve_nav", - "signature": "", - "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": "", - "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." } } }, @@ -1989,49 +1964,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": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.spec.Dict", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.spec.List", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.nav.spec.Optional", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.nav.spec.yaml", - "signature": "", - "docstring": null - }, "NavSpec": { "name": "NavSpec", "kind": "class", "path": "docforge.nav.spec.NavSpec", - "signature": "", - "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", @@ -2047,19 +1987,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": "", - "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": "", - "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." } } }, @@ -2067,8 +2014,24 @@ "name": "load_nav_spec", "kind": "function", "path": "docforge.nav.spec.load_nav_spec", - "signature": "", - "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." } } } @@ -2085,29 +2048,29 @@ "name": "MkDocsRenderer", "kind": "class", "path": "docforge.renderers.MkDocsRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.renderers.MkDocsRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.renderers.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "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.renderers.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "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`." } } }, @@ -2115,21 +2078,21 @@ "name": "MCPRenderer", "kind": "class", "path": "docforge.renderers.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.renderers.MCPRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.renderers.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path)", "docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written." } } @@ -2141,67 +2104,53 @@ "signature": null, "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.", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.base.Path", - "signature": "", - "docstring": null - }, - "Protocol": { - "name": "Protocol", - "kind": "alias", - "path": "docforge.renderers.base.Protocol", - "signature": "", - "docstring": null - }, "Project": { "name": "Project", "kind": "class", "path": "docforge.renderers.base.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.renderers.base.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.renderers.base.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } @@ -2210,7 +2159,7 @@ "name": "RendererConfig", "kind": "class", "path": "docforge.renderers.base.RendererConfig", - "signature": "", + "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": { @@ -2233,7 +2182,7 @@ "name": "DocRenderer", "kind": "class", "path": "docforge.renderers.base.DocRenderer", - "signature": "", + "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": { @@ -2247,7 +2196,7 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.base.DocRenderer.generate_sources", - "signature": "", + "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." } } @@ -2261,82 +2210,75 @@ "signature": null, "docstring": "# Summary\n\nMCP renderer implementation.\n\nThis module defines the `MCPRenderer` class, which generates documentation\nresources compatible with the Model Context Protocol (MCP).", "members": { - "json": { - "name": "json", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.json", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.Path", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.Dict", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.List", - "signature": "", - "docstring": null - }, - "Project": { - "name": "Project", + "DocObject": { + "name": "DocObject", "kind": "class", - "path": "docforge.renderers.mcp_renderer.Project", - "signature": "", - "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.", + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.Project.name", - "signature": "", + "path": "docforge.renderers.mcp_renderer.DocObject.name", + "signature": null, "docstring": null }, - "modules": { - "name": "modules", + "kind": { + "name": "kind", "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.Project.modules", - "signature": "", + "path": "docforge.renderers.mcp_renderer.DocObject.kind", + "signature": null, "docstring": null }, - "add_module": { - "name": "add_module", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.add_module", - "signature": "", - "docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project." + "path": { + "name": "path", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.path", + "signature": null, + "docstring": null }, - "get_module": { - "name": "get_module", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_module", - "signature": "", - "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." + "signature": { + "name": "signature", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.signature", + "signature": null, + "docstring": null }, - "get_all_modules": { - "name": "get_all_modules", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_all_modules", - "signature": "", - "docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances." + "docstring": { + "name": "docstring", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.docstring", + "signature": null, + "docstring": null }, - "get_module_list": { - "name": "get_module_list", + "members": { + "name": "members", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.members", + "signature": null, + "docstring": null + }, + "add_member": { + "name": "add_member", "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_module_list", - "signature": "", - "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." + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.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.renderers.mcp_renderer.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." } } }, @@ -2344,122 +2286,101 @@ "name": "Module", "kind": "class", "path": "docforge.renderers.mcp_renderer.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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.renderers.mcp_renderer.Module.path", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.renderers.mcp_renderer.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.renderers.mcp_renderer.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.renderers.mcp_renderer.Module.add_object", - "signature": "", + "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.renderers.mcp_renderer.Module.get_object", - "signature": "", + "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.renderers.mcp_renderer.Module.get_all_objects", - "signature": "", + "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", + "Project": { + "name": "Project", "kind": "class", - "path": "docforge.renderers.mcp_renderer.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.DocObject.name", - "signature": "", + "path": "docforge.renderers.mcp_renderer.Project.name", + "signature": null, "docstring": null }, - "kind": { - "name": "kind", + "modules": { + "name": "modules", "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.kind", - "signature": "", + "path": "docforge.renderers.mcp_renderer.Project.modules", + "signature": null, "docstring": null }, - "path": { - "name": "path", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.path", - "signature": "", - "docstring": null - }, - "signature": { - "name": "signature", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.signature", - "signature": "", - "docstring": null - }, - "docstring": { - "name": "docstring", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.docstring", - "signature": "", - "docstring": null - }, - "members": { - "name": "members", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.members", - "signature": "", - "docstring": null - }, - "add_member": { - "name": "add_member", + "add_module": { + "name": "add_module", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a member." + "path": "docforge.renderers.mcp_renderer.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_member": { - "name": "get_member", + "get_module": { + "name": "get_module", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.get_member", - "signature": "", - "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." + "path": "docforge.renderers.mcp_renderer.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_members": { - "name": "get_all_members", + "get_all_modules": { + "name": "get_all_modules", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.get_all_members", - "signature": "", - "docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members." + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.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." } } }, @@ -2467,7 +2388,7 @@ "name": "MCPRenderer", "kind": "class", "path": "docforge.renderers.mcp_renderer.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { @@ -2481,7 +2402,7 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.mcp_renderer.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path) -> None", "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." } } @@ -2495,120 +2416,113 @@ "signature": null, "docstring": "# Summary\n\nMkDocs renderer implementation.\n\nThis module defines the `MkDocsRenderer` class, which generates Markdown\ndocumentation sources compatible with MkDocs Material and the mkdocstrings\nplugin.\n\nThe renderer ensures a consistent documentation structure by:\n\n- Creating a root `index.md` if one does not exist\n- Generating package index pages automatically\n- Linking child modules within parent package pages\n- Optionally generating `README.md` from the root package docstring", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.mkdocs_renderer.Path", - "signature": "", - "docstring": null - }, - "Project": { - "name": "Project", - "kind": "class", - "path": "docforge.renderers.mkdocs_renderer.Project", - "signature": "", - "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.mkdocs_renderer.Project.name", - "signature": "", - "docstring": null - }, - "modules": { - "name": "modules", - "kind": "attribute", - "path": "docforge.renderers.mkdocs_renderer.Project.modules", - "signature": "", - "docstring": null - }, - "add_module": { - "name": "add_module", - "kind": "function", - "path": "docforge.renderers.mkdocs_renderer.Project.add_module", - "signature": "", - "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.mkdocs_renderer.Project.get_module", - "signature": "", - "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.mkdocs_renderer.Project.get_all_modules", - "signature": "", - "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.mkdocs_renderer.Project.get_module_list", - "signature": "", - "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.renderers.mkdocs_renderer.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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.renderers.mkdocs_renderer.Module.path", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.renderers.mkdocs_renderer.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.renderers.mkdocs_renderer.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.renderers.mkdocs_renderer.Module.add_object", - "signature": "", + "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.renderers.mkdocs_renderer.Module.get_object", - "signature": "", + "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.renderers.mkdocs_renderer.Module.get_all_objects", - "signature": "", + "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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.Project.name", + "signature": null, + "docstring": null + }, + "modules": { + "name": "modules", + "kind": "attribute", + "path": "docforge.renderers.mkdocs_renderer.Project.modules", + "signature": null, + "docstring": null + }, + "add_module": { + "name": "add_module", + "kind": "function", + "path": "docforge.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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." + } + } + }, "MkDocsRenderer": { "name": "MkDocsRenderer", "kind": "class", "path": "docforge.renderers.mkdocs_renderer.MkDocsRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.", "members": { "name": { @@ -2622,15 +2536,15 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.mkdocs_renderer.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "signature": "generate_sources(project: Project, out_dir: Path, module_is_source: bool | None = 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.renderers.mkdocs_renderer.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "signature": "generate_readme(project: Project, docs_dir: Path, module_is_source: bool | None = None, readme_dir: Path | None = 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`." } } } @@ -2649,28 +2563,28 @@ "name": "MCPServer", "kind": "class", "path": "docforge.servers.MCPServer", - "signature": "", - "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.", + "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.servers.MCPServer.mcp_root", - "signature": "", + "signature": null, "docstring": null }, "app": { "name": "app", "kind": "attribute", "path": "docforge.servers.MCPServer.app", - "signature": "", + "signature": null, "docstring": null }, "run": { "name": "run", "kind": "function", "path": "docforge.servers.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')", "docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`." } } @@ -2680,56 +2594,14 @@ "kind": "module", "path": "docforge.servers.mcp_server", "signature": null, - "docstring": "# Summary\n\nMCP server implementation.\n\nThis module defines the `MCPServer` class, which serves pre-generated\ndocumentation bundles through the Model Context Protocol (MCP).", + "docstring": "# Summary\n\nMCP server implementation.\n\nThis module defines the `MCPServer` class, which serves pre-generated\ndocumentation bundles through the Model Context Protocol (MCP).\n\n---\n\nNotes:\n - The served bundle is generated offline by `MCPRenderer`.\n - Missing resources are reported as structured error dictionaries rather\n than raising exceptions.\n - The server exposes read-only resources and a single health-check tool.\n\n---", "members": { - "annotations": { - "name": "annotations", - "kind": "alias", - "path": "docforge.servers.mcp_server.annotations", - "signature": "", - "docstring": null - }, - "json": { - "name": "json", - "kind": "alias", - "path": "docforge.servers.mcp_server.json", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.servers.mcp_server.Path", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.servers.mcp_server.Any", - "signature": "", - "docstring": null - }, - "Literal": { - "name": "Literal", - "kind": "alias", - "path": "docforge.servers.mcp_server.Literal", - "signature": "", - "docstring": null - }, - "FastMCP": { - "name": "FastMCP", - "kind": "alias", - "path": "docforge.servers.mcp_server.FastMCP", - "signature": "", - "docstring": null - }, "MCPServer": { "name": "MCPServer", "kind": "class", "path": "docforge.servers.mcp_server.MCPServer", - "signature": "", - "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.", + "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", @@ -2749,7 +2621,7 @@ "name": "run", "kind": "function", "path": "docforge.servers.mcp_server.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http') -> None", "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`." } } diff --git a/mcp_docs/modules/docforge.loaders.griffe_loader.json b/docs/mcp/modules/docforge.loaders.griffe_loader.json similarity index 58% rename from mcp_docs/modules/docforge.loaders.griffe_loader.json rename to docs/mcp/modules/docforge.loaders.griffe_loader.json index 3c14fa9..ab2f26e 100644 --- a/mcp_docs/modules/docforge.loaders.griffe_loader.json +++ b/docs/mcp/modules/docforge.loaders.griffe_loader.json @@ -2,111 +2,127 @@ "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.", + "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": { - "logging": { - "name": "logging", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.logging", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Path", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.List", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Optional", - "signature": "", - "docstring": null - }, - "ModulesCollection": { - "name": "ModulesCollection", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.ModulesCollection", - "signature": "", - "docstring": null - }, - "LinesCollection": { - "name": "LinesCollection", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.LinesCollection", - "signature": "", - "docstring": null - }, - "Object": { - "name": "Object", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Object", - "signature": "", - "docstring": null - }, - "AliasResolutionError": { - "name": "AliasResolutionError", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.AliasResolutionError", - "signature": "", - "docstring": null + "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": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.loaders.griffe_loader.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -115,125 +131,53 @@ "name": "Project", "kind": "class", "path": "docforge.loaders.griffe_loader.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.loaders.griffe_loader.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } }, - "DocObject": { - "name": "DocObject", - "kind": "class", - "path": "docforge.loaders.griffe_loader.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\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": "", - "docstring": null - }, - "kind": { - "name": "kind", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.kind", - "signature": "", - "docstring": null - }, - "path": { - "name": "path", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.path", - "signature": "", - "docstring": null - }, - "signature": { - "name": "signature", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.signature", - "signature": "", - "docstring": null - }, - "docstring": { - "name": "docstring", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.docstring", - "signature": "", - "docstring": null - }, - "members": { - "name": "members", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.members", - "signature": "", - "docstring": null - }, - "add_member": { - "name": "add_member", - "kind": "function", - "path": "docforge.loaders.griffe_loader.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a member." - }, - "get_member": { - "name": "get_member", - "kind": "function", - "path": "docforge.loaders.griffe_loader.DocObject.get_member", - "signature": "", - "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": "", - "docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members." - } - } - }, "logger": { "name": "logger", "kind": "attribute", @@ -245,29 +189,29 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.loaders.griffe_loader.discover_module_paths", - "signature": "", - "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, optional):\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." + "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": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } } diff --git a/mcp_docs/modules/docforge.loaders.json b/docs/mcp/modules/docforge.loaders.json similarity index 59% rename from mcp_docs/modules/docforge.loaders.json rename to docs/mcp/modules/docforge.loaders.json index 02a1470..93a695a 100644 --- a/mcp_docs/modules/docforge.loaders.json +++ b/docs/mcp/modules/docforge.loaders.json @@ -8,22 +8,22 @@ "name": "GriffeLoader", "kind": "class", "path": "docforge.loaders.GriffeLoader", - "signature": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } }, @@ -31,119 +31,135 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.loaders.discover_module_paths", - "signature": "", - "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, optional):\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." + "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.", + "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": { - "logging": { - "name": "logging", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.logging", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Path", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.List", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Optional", - "signature": "", - "docstring": null - }, - "ModulesCollection": { - "name": "ModulesCollection", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.ModulesCollection", - "signature": "", - "docstring": null - }, - "LinesCollection": { - "name": "LinesCollection", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.LinesCollection", - "signature": "", - "docstring": null - }, - "Object": { - "name": "Object", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.Object", - "signature": "", - "docstring": null - }, - "AliasResolutionError": { - "name": "AliasResolutionError", - "kind": "alias", - "path": "docforge.loaders.griffe_loader.AliasResolutionError", - "signature": "", - "docstring": null + "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": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.loaders.griffe_loader.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -152,125 +168,53 @@ "name": "Project", "kind": "class", "path": "docforge.loaders.griffe_loader.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.loaders.griffe_loader.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.loaders.griffe_loader.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } }, - "DocObject": { - "name": "DocObject", - "kind": "class", - "path": "docforge.loaders.griffe_loader.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\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": "", - "docstring": null - }, - "kind": { - "name": "kind", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.kind", - "signature": "", - "docstring": null - }, - "path": { - "name": "path", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.path", - "signature": "", - "docstring": null - }, - "signature": { - "name": "signature", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.signature", - "signature": "", - "docstring": null - }, - "docstring": { - "name": "docstring", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.docstring", - "signature": "", - "docstring": null - }, - "members": { - "name": "members", - "kind": "attribute", - "path": "docforge.loaders.griffe_loader.DocObject.members", - "signature": "", - "docstring": null - }, - "add_member": { - "name": "add_member", - "kind": "function", - "path": "docforge.loaders.griffe_loader.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a member." - }, - "get_member": { - "name": "get_member", - "kind": "function", - "path": "docforge.loaders.griffe_loader.DocObject.get_member", - "signature": "", - "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": "", - "docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members." - } - } - }, "logger": { "name": "logger", "kind": "attribute", @@ -282,29 +226,29 @@ "name": "discover_module_paths", "kind": "function", "path": "docforge.loaders.griffe_loader.discover_module_paths", - "signature": "", - "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, optional):\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." + "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": "", - "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.", + "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": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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." + "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": "", - "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." + "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 ```" } } } diff --git a/mcp_docs/modules/docforge.models.json b/docs/mcp/modules/docforge.models.json similarity index 69% rename from mcp_docs/modules/docforge.models.json rename to docs/mcp/modules/docforge.models.json index ecb4506..5f5dab0 100644 --- a/mcp_docs/modules/docforge.models.json +++ b/docs/mcp/modules/docforge.models.json @@ -8,49 +8,49 @@ "name": "Project", "kind": "class", "path": "docforge.models.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.models.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.models.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } @@ -59,49 +59,49 @@ "name": "Module", "kind": "class", "path": "docforge.models.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.models.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -110,70 +110,70 @@ "name": "DocObject", "kind": "class", "path": "docforge.models.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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": "", + "signature": null, "docstring": null }, "kind": { "name": "kind", "kind": "attribute", "path": "docforge.models.DocObject.kind", - "signature": "", + "signature": null, "docstring": null }, "path": { "name": "path", "kind": "attribute", "path": "docforge.models.DocObject.path", - "signature": "", + "signature": null, "docstring": null }, "signature": { "name": "signature", "kind": "attribute", "path": "docforge.models.DocObject.signature", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.DocObject.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.DocObject.members", - "signature": "", + "signature": null, "docstring": null }, "add_member": { "name": "add_member", "kind": "function", "path": "docforge.models.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -183,97 +183,76 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.module.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.module.Iterable", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.models.module.Optional", - "signature": "", - "docstring": null - }, "DocObject": { "name": "DocObject", "kind": "class", "path": "docforge.models.module.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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": "", + "signature": null, "docstring": null }, "kind": { "name": "kind", "kind": "attribute", "path": "docforge.models.module.DocObject.kind", - "signature": "", + "signature": null, "docstring": null }, "path": { "name": "path", "kind": "attribute", "path": "docforge.models.module.DocObject.path", - "signature": "", + "signature": null, "docstring": null }, "signature": { "name": "signature", "kind": "attribute", "path": "docforge.models.module.DocObject.signature", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.module.DocObject.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.module.DocObject.members", - "signature": "", + "signature": null, "docstring": null }, "add_member": { "name": "add_member", "kind": "function", "path": "docforge.models.module.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -282,8 +261,8 @@ "name": "Module", "kind": "class", "path": "docforge.models.module.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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", @@ -310,21 +289,21 @@ "name": "add_object", "kind": "function", "path": "docforge.models.module.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -336,35 +315,14 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.object.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.object.Iterable", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.models.object.Optional", - "signature": "", - "docstring": null - }, "DocObject": { "name": "DocObject", "kind": "class", "path": "docforge.models.object.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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", @@ -412,21 +370,21 @@ "name": "add_member", "kind": "function", "path": "docforge.models.object.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -438,69 +396,55 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.project.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.project.Iterable", - "signature": "", - "docstring": null - }, "Module": { "name": "Module", "kind": "class", "path": "docforge.models.project.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.project.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.project.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.models.project.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -509,8 +453,8 @@ "name": "Project", "kind": "class", "path": "docforge.models.project.Project", - "signature": "", - "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.", + "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", @@ -530,28 +474,28 @@ "name": "add_module", "kind": "function", "path": "docforge.models.project.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } diff --git a/mcp_docs/modules/docforge.models.module.json b/docs/mcp/modules/docforge.models.module.json similarity index 65% rename from mcp_docs/modules/docforge.models.module.json rename to docs/mcp/modules/docforge.models.module.json index 465083c..927669e 100644 --- a/mcp_docs/modules/docforge.models.module.json +++ b/docs/mcp/modules/docforge.models.module.json @@ -2,97 +2,76 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.module.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.module.Iterable", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.models.module.Optional", - "signature": "", - "docstring": null - }, "DocObject": { "name": "DocObject", "kind": "class", "path": "docforge.models.module.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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": "", + "signature": null, "docstring": null }, "kind": { "name": "kind", "kind": "attribute", "path": "docforge.models.module.DocObject.kind", - "signature": "", + "signature": null, "docstring": null }, "path": { "name": "path", "kind": "attribute", "path": "docforge.models.module.DocObject.path", - "signature": "", + "signature": null, "docstring": null }, "signature": { "name": "signature", "kind": "attribute", "path": "docforge.models.module.DocObject.signature", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.module.DocObject.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.module.DocObject.members", - "signature": "", + "signature": null, "docstring": null }, "add_member": { "name": "add_member", "kind": "function", "path": "docforge.models.module.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } @@ -101,8 +80,8 @@ "name": "Module", "kind": "class", "path": "docforge.models.module.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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", @@ -129,21 +108,21 @@ "name": "add_object", "kind": "function", "path": "docforge.models.module.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } diff --git a/mcp_docs/modules/docforge.models.object.json b/docs/mcp/modules/docforge.models.object.json similarity index 69% rename from mcp_docs/modules/docforge.models.object.json rename to docs/mcp/modules/docforge.models.object.json index 66cb8c0..4b6c72e 100644 --- a/mcp_docs/modules/docforge.models.object.json +++ b/docs/mcp/modules/docforge.models.object.json @@ -2,35 +2,14 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.object.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.object.Iterable", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.models.object.Optional", - "signature": "", - "docstring": null - }, "DocObject": { "name": "DocObject", "kind": "class", "path": "docforge.models.object.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "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", @@ -78,21 +57,21 @@ "name": "add_member", "kind": "function", "path": "docforge.models.object.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a 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": "", + "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": "", + "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." } } diff --git a/mcp_docs/modules/docforge.models.project.json b/docs/mcp/modules/docforge.models.project.json similarity index 70% rename from mcp_docs/modules/docforge.models.project.json rename to docs/mcp/modules/docforge.models.project.json index 429ecef..b0c9f06 100644 --- a/mcp_docs/modules/docforge.models.project.json +++ b/docs/mcp/modules/docforge.models.project.json @@ -2,69 +2,55 @@ "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.", + "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": { - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.models.project.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.models.project.Iterable", - "signature": "", - "docstring": null - }, "Module": { "name": "Module", "kind": "class", "path": "docforge.models.project.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.models.project.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.models.project.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.models.project.Module.add_object", - "signature": "", + "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": "", + "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": "", + "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." } } @@ -73,8 +59,8 @@ "name": "Project", "kind": "class", "path": "docforge.models.project.Project", - "signature": "", - "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.", + "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", @@ -94,28 +80,28 @@ "name": "add_module", "kind": "function", "path": "docforge.models.project.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } diff --git a/mcp_docs/modules/docforge.nav.json b/docs/mcp/modules/docforge.nav.json similarity index 50% rename from mcp_docs/modules/docforge.nav.json rename to docs/mcp/modules/docforge.nav.json index 7c913c2..3568800 100644 --- a/mcp_docs/modules/docforge.nav.json +++ b/docs/mcp/modules/docforge.nav.json @@ -8,36 +8,43 @@ "name": "NavSpec", "kind": "class", "path": "docforge.nav.NavSpec", - "signature": "", - "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.NavSpec.groups", - "signature": "", + "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": "", - "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": "", - "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": "", - "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": "", + "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.ResolvedNav.groups", - "signature": "", + "signature": null, "docstring": null }, "all_files": { "name": "all_files", "kind": "function", "path": "docforge.nav.ResolvedNav.all_files", - "signature": "", - "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": "", - "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": "", + "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": "", - "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": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.mkdocs.List", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.mkdocs.Dict", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.nav.mkdocs.Any", - "signature": "", - "docstring": null - }, "ResolvedNav": { "name": "ResolvedNav", "kind": "class", "path": "docforge.nav.mkdocs.ResolvedNav", - "signature": "", + "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.mkdocs.ResolvedNav.groups", - "signature": "", + "signature": null, "docstring": null }, "all_files": { "name": "all_files", "kind": "function", "path": "docforge.nav.mkdocs.ResolvedNav.all_files", - "signature": "", - "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": "", + "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": "", - "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": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.resolver.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.nav.resolver.Iterable", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.resolver.List", - "signature": "", - "docstring": null - }, - "glob": { - "name": "glob", - "kind": "alias", - "path": "docforge.nav.resolver.glob", - "signature": "", - "docstring": null - }, "NavSpec": { "name": "NavSpec", "kind": "class", "path": "docforge.nav.resolver.NavSpec", - "signature": "", - "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": "", + "signature": null, "docstring": null }, "groups": { "name": "groups", "kind": "attribute", "path": "docforge.nav.resolver.NavSpec.groups", - "signature": "", + "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": "", - "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": "", - "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": "", + "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": "", - "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": "", - "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": "", - "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": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.spec.Dict", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.spec.List", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.nav.spec.Optional", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.nav.spec.yaml", - "signature": "", - "docstring": null - }, "NavSpec": { "name": "NavSpec", "kind": "class", "path": "docforge.nav.spec.NavSpec", - "signature": "", - "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": "", - "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": "", - "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": "", - "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." } } } diff --git a/docs/mcp/modules/docforge.nav.mkdocs.json b/docs/mcp/modules/docforge.nav.mkdocs.json new file mode 100644 index 0000000..5288f18 --- /dev/null +++ b/docs/mcp/modules/docforge.nav.mkdocs.json @@ -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." + } + } + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/modules/docforge.nav.resolver.json b/docs/mcp/modules/docforge.nav.resolver.json new file mode 100644 index 0000000..1921a28 --- /dev/null +++ b/docs/mcp/modules/docforge.nav.resolver.json @@ -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." + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/modules/docforge.nav.spec.json b/docs/mcp/modules/docforge.nav.spec.json new file mode 100644 index 0000000..c99c121 --- /dev/null +++ b/docs/mcp/modules/docforge.nav.spec.json @@ -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." + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/modules/docforge.nav.wiki.json b/docs/mcp/modules/docforge.nav.wiki.json new file mode 100644 index 0000000..3d4affb --- /dev/null +++ b/docs/mcp/modules/docforge.nav.wiki.json @@ -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." + } + } + } +} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.renderers.base.json b/docs/mcp/modules/docforge.renderers.base.json similarity index 73% rename from mcp_docs/modules/docforge.renderers.base.json rename to docs/mcp/modules/docforge.renderers.base.json index f19dd9b..a879ee6 100644 --- a/mcp_docs/modules/docforge.renderers.base.json +++ b/docs/mcp/modules/docforge.renderers.base.json @@ -4,67 +4,53 @@ "path": "docforge.renderers.base", "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": "", - "docstring": null - }, - "Protocol": { - "name": "Protocol", - "kind": "alias", - "path": "docforge.renderers.base.Protocol", - "signature": "", - "docstring": null - }, "Project": { "name": "Project", "kind": "class", "path": "docforge.renderers.base.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.renderers.base.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.renderers.base.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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,7 +59,7 @@ "name": "RendererConfig", "kind": "class", "path": "docforge.renderers.base.RendererConfig", - "signature": "", + "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": { @@ -96,7 +82,7 @@ "name": "DocRenderer", "kind": "class", "path": "docforge.renderers.base.DocRenderer", - "signature": "", + "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": { @@ -110,7 +96,7 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.base.DocRenderer.generate_sources", - "signature": "", + "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." } } diff --git a/mcp_docs/modules/docforge.renderers.json b/docs/mcp/modules/docforge.renderers.json similarity index 69% rename from mcp_docs/modules/docforge.renderers.json rename to docs/mcp/modules/docforge.renderers.json index 8d68b06..0eb7e8d 100644 --- a/mcp_docs/modules/docforge.renderers.json +++ b/docs/mcp/modules/docforge.renderers.json @@ -8,29 +8,29 @@ "name": "MkDocsRenderer", "kind": "class", "path": "docforge.renderers.MkDocsRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.renderers.MkDocsRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.renderers.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "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.renderers.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "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`." } } }, @@ -38,21 +38,21 @@ "name": "MCPRenderer", "kind": "class", "path": "docforge.renderers.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { "name": "name", "kind": "attribute", "path": "docforge.renderers.MCPRenderer.name", - "signature": "", + "signature": null, "docstring": null }, "generate_sources": { "name": "generate_sources", "kind": "function", "path": "docforge.renderers.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path)", "docstring": "Generate MCP documentation resources for a project.\n\nThe renderer serializes each module into a JSON resource and produces\nsupporting metadata files such as `nav.json` and `index.json`.\n\nArgs:\n project (Project):\n Documentation project model to render.\n\n out_dir (Path):\n Directory where MCP resources will be written." } } @@ -64,67 +64,53 @@ "signature": null, "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.", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.base.Path", - "signature": "", - "docstring": null - }, - "Protocol": { - "name": "Protocol", - "kind": "alias", - "path": "docforge.renderers.base.Protocol", - "signature": "", - "docstring": null - }, "Project": { "name": "Project", "kind": "class", "path": "docforge.renderers.base.Project", - "signature": "", - "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.", + "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": "", + "signature": null, "docstring": null }, "modules": { "name": "modules", "kind": "attribute", "path": "docforge.renderers.base.Project.modules", - "signature": "", + "signature": null, "docstring": null }, "add_module": { "name": "add_module", "kind": "function", "path": "docforge.renderers.base.Project.add_module", - "signature": "", + "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": "", + "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": "", + "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": "", + "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." } } @@ -133,7 +119,7 @@ "name": "RendererConfig", "kind": "class", "path": "docforge.renderers.base.RendererConfig", - "signature": "", + "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": { @@ -156,7 +142,7 @@ "name": "DocRenderer", "kind": "class", "path": "docforge.renderers.base.DocRenderer", - "signature": "", + "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": { @@ -170,7 +156,7 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.base.DocRenderer.generate_sources", - "signature": "", + "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." } } @@ -184,82 +170,75 @@ "signature": null, "docstring": "# Summary\n\nMCP renderer implementation.\n\nThis module defines the `MCPRenderer` class, which generates documentation\nresources compatible with the Model Context Protocol (MCP).", "members": { - "json": { - "name": "json", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.json", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.Path", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.Dict", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.List", - "signature": "", - "docstring": null - }, - "Project": { - "name": "Project", + "DocObject": { + "name": "DocObject", "kind": "class", - "path": "docforge.renderers.mcp_renderer.Project", - "signature": "", - "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.", + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.Project.name", - "signature": "", + "path": "docforge.renderers.mcp_renderer.DocObject.name", + "signature": null, "docstring": null }, - "modules": { - "name": "modules", + "kind": { + "name": "kind", "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.Project.modules", - "signature": "", + "path": "docforge.renderers.mcp_renderer.DocObject.kind", + "signature": null, "docstring": null }, - "add_module": { - "name": "add_module", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.add_module", - "signature": "", - "docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project." + "path": { + "name": "path", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.path", + "signature": null, + "docstring": null }, - "get_module": { - "name": "get_module", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_module", - "signature": "", - "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." + "signature": { + "name": "signature", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.signature", + "signature": null, + "docstring": null }, - "get_all_modules": { - "name": "get_all_modules", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_all_modules", - "signature": "", - "docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances." + "docstring": { + "name": "docstring", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.docstring", + "signature": null, + "docstring": null }, - "get_module_list": { - "name": "get_module_list", + "members": { + "name": "members", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.members", + "signature": null, + "docstring": null + }, + "add_member": { + "name": "add_member", "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_module_list", - "signature": "", - "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." + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.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.renderers.mcp_renderer.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." } } }, @@ -267,122 +246,101 @@ "name": "Module", "kind": "class", "path": "docforge.renderers.mcp_renderer.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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.renderers.mcp_renderer.Module.path", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.renderers.mcp_renderer.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.renderers.mcp_renderer.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.renderers.mcp_renderer.Module.add_object", - "signature": "", + "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.renderers.mcp_renderer.Module.get_object", - "signature": "", + "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.renderers.mcp_renderer.Module.get_all_objects", - "signature": "", + "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", + "Project": { + "name": "Project", "kind": "class", - "path": "docforge.renderers.mcp_renderer.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.DocObject.name", - "signature": "", + "path": "docforge.renderers.mcp_renderer.Project.name", + "signature": null, "docstring": null }, - "kind": { - "name": "kind", + "modules": { + "name": "modules", "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.kind", - "signature": "", + "path": "docforge.renderers.mcp_renderer.Project.modules", + "signature": null, "docstring": null }, - "path": { - "name": "path", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.path", - "signature": "", - "docstring": null - }, - "signature": { - "name": "signature", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.signature", - "signature": "", - "docstring": null - }, - "docstring": { - "name": "docstring", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.docstring", - "signature": "", - "docstring": null - }, - "members": { - "name": "members", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.members", - "signature": "", - "docstring": null - }, - "add_member": { - "name": "add_member", + "add_module": { + "name": "add_module", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a member." + "path": "docforge.renderers.mcp_renderer.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_member": { - "name": "get_member", + "get_module": { + "name": "get_module", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.get_member", - "signature": "", - "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." + "path": "docforge.renderers.mcp_renderer.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_members": { - "name": "get_all_members", + "get_all_modules": { + "name": "get_all_modules", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.get_all_members", - "signature": "", - "docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members." + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.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." } } }, @@ -390,7 +348,7 @@ "name": "MCPRenderer", "kind": "class", "path": "docforge.renderers.mcp_renderer.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { @@ -404,7 +362,7 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.mcp_renderer.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path) -> None", "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." } } @@ -418,120 +376,113 @@ "signature": null, "docstring": "# Summary\n\nMkDocs renderer implementation.\n\nThis module defines the `MkDocsRenderer` class, which generates Markdown\ndocumentation sources compatible with MkDocs Material and the mkdocstrings\nplugin.\n\nThe renderer ensures a consistent documentation structure by:\n\n- Creating a root `index.md` if one does not exist\n- Generating package index pages automatically\n- Linking child modules within parent package pages\n- Optionally generating `README.md` from the root package docstring", "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.mkdocs_renderer.Path", - "signature": "", - "docstring": null - }, - "Project": { - "name": "Project", - "kind": "class", - "path": "docforge.renderers.mkdocs_renderer.Project", - "signature": "", - "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.mkdocs_renderer.Project.name", - "signature": "", - "docstring": null - }, - "modules": { - "name": "modules", - "kind": "attribute", - "path": "docforge.renderers.mkdocs_renderer.Project.modules", - "signature": "", - "docstring": null - }, - "add_module": { - "name": "add_module", - "kind": "function", - "path": "docforge.renderers.mkdocs_renderer.Project.add_module", - "signature": "", - "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.mkdocs_renderer.Project.get_module", - "signature": "", - "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.mkdocs_renderer.Project.get_all_modules", - "signature": "", - "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.mkdocs_renderer.Project.get_module_list", - "signature": "", - "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.renderers.mkdocs_renderer.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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.renderers.mkdocs_renderer.Module.path", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.renderers.mkdocs_renderer.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.renderers.mkdocs_renderer.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.renderers.mkdocs_renderer.Module.add_object", - "signature": "", + "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.renderers.mkdocs_renderer.Module.get_object", - "signature": "", + "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.renderers.mkdocs_renderer.Module.get_all_objects", - "signature": "", + "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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.Project.name", + "signature": null, + "docstring": null + }, + "modules": { + "name": "modules", + "kind": "attribute", + "path": "docforge.renderers.mkdocs_renderer.Project.modules", + "signature": null, + "docstring": null + }, + "add_module": { + "name": "add_module", + "kind": "function", + "path": "docforge.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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." + } + } + }, "MkDocsRenderer": { "name": "MkDocsRenderer", "kind": "class", "path": "docforge.renderers.mkdocs_renderer.MkDocsRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.", "members": { "name": { @@ -545,15 +496,15 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.mkdocs_renderer.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "signature": "generate_sources(project: Project, out_dir: Path, module_is_source: bool | None = 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.renderers.mkdocs_renderer.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "signature": "generate_readme(project: Project, docs_dir: Path, module_is_source: bool | None = None, readme_dir: Path | None = 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`." } } } diff --git a/mcp_docs/modules/docforge.renderers.mcp_renderer.json b/docs/mcp/modules/docforge.renderers.mcp_renderer.json similarity index 66% rename from mcp_docs/modules/docforge.renderers.mcp_renderer.json rename to docs/mcp/modules/docforge.renderers.mcp_renderer.json index fe936ee..a9b54d4 100644 --- a/mcp_docs/modules/docforge.renderers.mcp_renderer.json +++ b/docs/mcp/modules/docforge.renderers.mcp_renderer.json @@ -4,82 +4,75 @@ "path": "docforge.renderers.mcp_renderer", "docstring": "# Summary\n\nMCP renderer implementation.\n\nThis module defines the `MCPRenderer` class, which generates documentation\nresources compatible with the Model Context Protocol (MCP).", "objects": { - "json": { - "name": "json", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.json", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.Path", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.Dict", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.renderers.mcp_renderer.List", - "signature": "", - "docstring": null - }, - "Project": { - "name": "Project", + "DocObject": { + "name": "DocObject", "kind": "class", - "path": "docforge.renderers.mcp_renderer.Project", - "signature": "", - "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.", + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.Project.name", - "signature": "", + "path": "docforge.renderers.mcp_renderer.DocObject.name", + "signature": null, "docstring": null }, - "modules": { - "name": "modules", + "kind": { + "name": "kind", "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.Project.modules", - "signature": "", + "path": "docforge.renderers.mcp_renderer.DocObject.kind", + "signature": null, "docstring": null }, - "add_module": { - "name": "add_module", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.add_module", - "signature": "", - "docstring": "Register a module in the project.\n\nArgs:\n module (Module):\n Module instance to add to the project." + "path": { + "name": "path", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.path", + "signature": null, + "docstring": null }, - "get_module": { - "name": "get_module", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_module", - "signature": "", - "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." + "signature": { + "name": "signature", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.signature", + "signature": null, + "docstring": null }, - "get_all_modules": { - "name": "get_all_modules", - "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_all_modules", - "signature": "", - "docstring": "Return all modules contained in the project.\n\nReturns:\n Iterable[Module]:\n An iterable of `Module` instances." + "docstring": { + "name": "docstring", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.docstring", + "signature": null, + "docstring": null }, - "get_module_list": { - "name": "get_module_list", + "members": { + "name": "members", + "kind": "attribute", + "path": "docforge.renderers.mcp_renderer.DocObject.members", + "signature": null, + "docstring": null + }, + "add_member": { + "name": "add_member", "kind": "function", - "path": "docforge.renderers.mcp_renderer.Project.get_module_list", - "signature": "", - "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." + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.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.renderers.mcp_renderer.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." } } }, @@ -87,122 +80,101 @@ "name": "Module", "kind": "class", "path": "docforge.renderers.mcp_renderer.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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.renderers.mcp_renderer.Module.path", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.renderers.mcp_renderer.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.renderers.mcp_renderer.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.renderers.mcp_renderer.Module.add_object", - "signature": "", + "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.renderers.mcp_renderer.Module.get_object", - "signature": "", + "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.renderers.mcp_renderer.Module.get_all_objects", - "signature": "", + "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", + "Project": { + "name": "Project", "kind": "class", - "path": "docforge.renderers.mcp_renderer.DocObject", - "signature": "", - "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 (Optional[str]):\n Callable signature if the object represents a callable.\n\n docstring (Optional[str]):\n Raw docstring text extracted from the source code.\n\n members (Dict[str, DocObject]):\n Mapping of member names to child `DocObject` instances.", + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.DocObject.name", - "signature": "", + "path": "docforge.renderers.mcp_renderer.Project.name", + "signature": null, "docstring": null }, - "kind": { - "name": "kind", + "modules": { + "name": "modules", "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.kind", - "signature": "", + "path": "docforge.renderers.mcp_renderer.Project.modules", + "signature": null, "docstring": null }, - "path": { - "name": "path", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.path", - "signature": "", - "docstring": null - }, - "signature": { - "name": "signature", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.signature", - "signature": "", - "docstring": null - }, - "docstring": { - "name": "docstring", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.docstring", - "signature": "", - "docstring": null - }, - "members": { - "name": "members", - "kind": "attribute", - "path": "docforge.renderers.mcp_renderer.DocObject.members", - "signature": "", - "docstring": null - }, - "add_member": { - "name": "add_member", + "add_module": { + "name": "add_module", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.add_member", - "signature": "", - "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: Documentation object to add as a member." + "path": "docforge.renderers.mcp_renderer.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_member": { - "name": "get_member", + "get_module": { + "name": "get_module", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.get_member", - "signature": "", - "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." + "path": "docforge.renderers.mcp_renderer.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_members": { - "name": "get_all_members", + "get_all_modules": { + "name": "get_all_modules", "kind": "function", - "path": "docforge.renderers.mcp_renderer.DocObject.get_all_members", - "signature": "", - "docstring": "Return all child members of the object.\n\nReturns:\n Iterable[DocObject]:\n An iterable of `DocObject` instances representing nested members." + "path": "docforge.renderers.mcp_renderer.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.renderers.mcp_renderer.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." } } }, @@ -210,7 +182,7 @@ "name": "MCPRenderer", "kind": "class", "path": "docforge.renderers.mcp_renderer.MCPRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that generates MCP-compatible documentation resources.\n\nThis renderer converts doc-forge project models into structured JSON\nresources suitable for consumption by systems implementing the Model\nContext Protocol (MCP).", "members": { "name": { @@ -224,7 +196,7 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.mcp_renderer.MCPRenderer.generate_sources", - "signature": "", + "signature": "generate_sources(project: Project, out_dir: Path) -> None", "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." } } diff --git a/mcp_docs/modules/docforge.renderers.mkdocs_renderer.json b/docs/mcp/modules/docforge.renderers.mkdocs_renderer.json similarity index 68% rename from mcp_docs/modules/docforge.renderers.mkdocs_renderer.json rename to docs/mcp/modules/docforge.renderers.mkdocs_renderer.json index e7923a6..3454abb 100644 --- a/mcp_docs/modules/docforge.renderers.mkdocs_renderer.json +++ b/docs/mcp/modules/docforge.renderers.mkdocs_renderer.json @@ -4,120 +4,113 @@ "path": "docforge.renderers.mkdocs_renderer", "docstring": "# Summary\n\nMkDocs renderer implementation.\n\nThis module defines the `MkDocsRenderer` class, which generates Markdown\ndocumentation sources compatible with MkDocs Material and the mkdocstrings\nplugin.\n\nThe renderer ensures a consistent documentation structure by:\n\n- Creating a root `index.md` if one does not exist\n- Generating package index pages automatically\n- Linking child modules within parent package pages\n- Optionally generating `README.md` from the root package docstring", "objects": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.renderers.mkdocs_renderer.Path", - "signature": "", - "docstring": null - }, - "Project": { - "name": "Project", - "kind": "class", - "path": "docforge.renderers.mkdocs_renderer.Project", - "signature": "", - "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.mkdocs_renderer.Project.name", - "signature": "", - "docstring": null - }, - "modules": { - "name": "modules", - "kind": "attribute", - "path": "docforge.renderers.mkdocs_renderer.Project.modules", - "signature": "", - "docstring": null - }, - "add_module": { - "name": "add_module", - "kind": "function", - "path": "docforge.renderers.mkdocs_renderer.Project.add_module", - "signature": "", - "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.mkdocs_renderer.Project.get_module", - "signature": "", - "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.mkdocs_renderer.Project.get_all_modules", - "signature": "", - "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.mkdocs_renderer.Project.get_module_list", - "signature": "", - "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.renderers.mkdocs_renderer.Module", - "signature": "", - "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 (Optional[str]):\n Module-level documentation string, if present.\n\n members (Dict[str, DocObject]):\n Mapping of object names to their corresponding `DocObject` representations.", + "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.renderers.mkdocs_renderer.Module.path", - "signature": "", + "signature": null, "docstring": null }, "docstring": { "name": "docstring", "kind": "attribute", "path": "docforge.renderers.mkdocs_renderer.Module.docstring", - "signature": "", + "signature": null, "docstring": null }, "members": { "name": "members", "kind": "attribute", "path": "docforge.renderers.mkdocs_renderer.Module.members", - "signature": "", + "signature": null, "docstring": null }, "add_object": { "name": "add_object", "kind": "function", "path": "docforge.renderers.mkdocs_renderer.Module.add_object", - "signature": "", + "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.renderers.mkdocs_renderer.Module.get_object", - "signature": "", + "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.renderers.mkdocs_renderer.Module.get_all_objects", - "signature": "", + "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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.Project.name", + "signature": null, + "docstring": null + }, + "modules": { + "name": "modules", + "kind": "attribute", + "path": "docforge.renderers.mkdocs_renderer.Project.modules", + "signature": null, + "docstring": null + }, + "add_module": { + "name": "add_module", + "kind": "function", + "path": "docforge.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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.renderers.mkdocs_renderer.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." + } + } + }, "MkDocsRenderer": { "name": "MkDocsRenderer", "kind": "class", "path": "docforge.renderers.mkdocs_renderer.MkDocsRenderer", - "signature": "", + "signature": null, "docstring": "Renderer that produces Markdown documentation for MkDocs.\n\nGenerated pages use mkdocstrings directives to reference Python modules,\nallowing MkDocs to render API documentation dynamically.", "members": { "name": { @@ -131,15 +124,15 @@ "name": "generate_sources", "kind": "function", "path": "docforge.renderers.mkdocs_renderer.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\n If True, treat the specified module as the documentation root\n rather than nesting it inside a folder." + "signature": "generate_sources(project: Project, out_dir: Path, module_is_source: bool | None = 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.renderers.mkdocs_renderer.MkDocsRenderer.generate_readme", - "signature": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." + "signature": "generate_readme(project: Project, docs_dir: Path, module_is_source: bool | None = None, readme_dir: Path | None = 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`." } } } diff --git a/mcp_docs/modules/docforge.servers.json b/docs/mcp/modules/docforge.servers.json similarity index 56% rename from mcp_docs/modules/docforge.servers.json rename to docs/mcp/modules/docforge.servers.json index af152fd..4bf8fb2 100644 --- a/mcp_docs/modules/docforge.servers.json +++ b/docs/mcp/modules/docforge.servers.json @@ -8,28 +8,28 @@ "name": "MCPServer", "kind": "class", "path": "docforge.servers.MCPServer", - "signature": "", - "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.", + "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.servers.MCPServer.mcp_root", - "signature": "", + "signature": null, "docstring": null }, "app": { "name": "app", "kind": "attribute", "path": "docforge.servers.MCPServer.app", - "signature": "", + "signature": null, "docstring": null }, "run": { "name": "run", "kind": "function", "path": "docforge.servers.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http')", "docstring": "Start the MCP server.\n\nArgs:\n transport (Literal[\"stdio\", \"sse\", \"streamable-http\"]):\n Transport mechanism used by the MCP server. Supported options\n include `stdio`, `sse`, and `streamable-http`." } } @@ -39,56 +39,14 @@ "kind": "module", "path": "docforge.servers.mcp_server", "signature": null, - "docstring": "# Summary\n\nMCP server implementation.\n\nThis module defines the `MCPServer` class, which serves pre-generated\ndocumentation bundles through the Model Context Protocol (MCP).", + "docstring": "# Summary\n\nMCP server implementation.\n\nThis module defines the `MCPServer` class, which serves pre-generated\ndocumentation bundles through the Model Context Protocol (MCP).\n\n---\n\nNotes:\n - The served bundle is generated offline by `MCPRenderer`.\n - Missing resources are reported as structured error dictionaries rather\n than raising exceptions.\n - The server exposes read-only resources and a single health-check tool.\n\n---", "members": { - "annotations": { - "name": "annotations", - "kind": "alias", - "path": "docforge.servers.mcp_server.annotations", - "signature": "", - "docstring": null - }, - "json": { - "name": "json", - "kind": "alias", - "path": "docforge.servers.mcp_server.json", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.servers.mcp_server.Path", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.servers.mcp_server.Any", - "signature": "", - "docstring": null - }, - "Literal": { - "name": "Literal", - "kind": "alias", - "path": "docforge.servers.mcp_server.Literal", - "signature": "", - "docstring": null - }, - "FastMCP": { - "name": "FastMCP", - "kind": "alias", - "path": "docforge.servers.mcp_server.FastMCP", - "signature": "", - "docstring": null - }, "MCPServer": { "name": "MCPServer", "kind": "class", "path": "docforge.servers.mcp_server.MCPServer", - "signature": "", - "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.", + "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", @@ -108,7 +66,7 @@ "name": "run", "kind": "function", "path": "docforge.servers.mcp_server.MCPServer.run", - "signature": "", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http') -> None", "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`." } } diff --git a/docs/mcp/modules/docforge.servers.mcp_server.json b/docs/mcp/modules/docforge.servers.mcp_server.json new file mode 100644 index 0000000..a1fb995 --- /dev/null +++ b/docs/mcp/modules/docforge.servers.mcp_server.json @@ -0,0 +1,39 @@ +{ + "module": "docforge.servers.mcp_server", + "content": { + "path": "docforge.servers.mcp_server", + "docstring": "# Summary\n\nMCP server implementation.\n\nThis module defines the `MCPServer` class, which serves pre-generated\ndocumentation bundles through the Model Context Protocol (MCP).\n\n---\n\nNotes:\n - The served bundle is generated offline by `MCPRenderer`.\n - Missing resources are reported as structured error dictionaries rather\n than raising exceptions.\n - The server exposes read-only resources and a single health-check tool.\n\n---", + "objects": { + "MCPServer": { + "name": "MCPServer", + "kind": "class", + "path": "docforge.servers.mcp_server.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.servers.mcp_server.MCPServer.mcp_root", + "signature": null, + "docstring": null + }, + "app": { + "name": "app", + "kind": "attribute", + "path": "docforge.servers.mcp_server.MCPServer.app", + "signature": null, + "docstring": null + }, + "run": { + "name": "run", + "kind": "function", + "path": "docforge.servers.mcp_server.MCPServer.run", + "signature": "run(transport: Literal['stdio', 'sse', 'streamable-http'] = 'streamable-http') -> None", + "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`." + } + } + } + } + } +} \ No newline at end of file diff --git a/docs/mcp/nav.json b/docs/mcp/nav.json new file mode 100644 index 0000000..c73b16b --- /dev/null +++ b/docs/mcp/nav.json @@ -0,0 +1,98 @@ +[ + { + "module": "docforge", + "resource": "docs://modules/docforge" + }, + { + "module": "docforge.cli", + "resource": "docs://modules/docforge.cli" + }, + { + "module": "docforge.cli.api_utils", + "resource": "docs://modules/docforge.cli.api_utils" + }, + { + "module": "docforge.cli.commands", + "resource": "docs://modules/docforge.cli.commands" + }, + { + "module": "docforge.cli.main", + "resource": "docs://modules/docforge.cli.main" + }, + { + "module": "docforge.cli.mcp_utils", + "resource": "docs://modules/docforge.cli.mcp_utils" + }, + { + "module": "docforge.cli.mkdocs_utils", + "resource": "docs://modules/docforge.cli.mkdocs_utils" + }, + { + "module": "docforge.loaders", + "resource": "docs://modules/docforge.loaders" + }, + { + "module": "docforge.loaders.griffe_loader", + "resource": "docs://modules/docforge.loaders.griffe_loader" + }, + { + "module": "docforge.models", + "resource": "docs://modules/docforge.models" + }, + { + "module": "docforge.models.module", + "resource": "docs://modules/docforge.models.module" + }, + { + "module": "docforge.models.object", + "resource": "docs://modules/docforge.models.object" + }, + { + "module": "docforge.models.project", + "resource": "docs://modules/docforge.models.project" + }, + { + "module": "docforge.nav", + "resource": "docs://modules/docforge.nav" + }, + { + "module": "docforge.nav.mkdocs", + "resource": "docs://modules/docforge.nav.mkdocs" + }, + { + "module": "docforge.nav.resolver", + "resource": "docs://modules/docforge.nav.resolver" + }, + { + "module": "docforge.nav.spec", + "resource": "docs://modules/docforge.nav.spec" + }, + { + "module": "docforge.nav.wiki", + "resource": "docs://modules/docforge.nav.wiki" + }, + { + "module": "docforge.renderers", + "resource": "docs://modules/docforge.renderers" + }, + { + "module": "docforge.renderers.base", + "resource": "docs://modules/docforge.renderers.base" + }, + { + "module": "docforge.renderers.mcp_renderer", + "resource": "docs://modules/docforge.renderers.mcp_renderer" + }, + { + "module": "docforge.renderers.mkdocs_renderer", + "resource": "docs://modules/docforge.renderers.mkdocs_renderer" + }, + { + "module": "docforge.servers", + "resource": "docs://modules/docforge.servers" + }, + { + "module": "docforge.servers.mcp_server", + "resource": "docs://modules/docforge.servers.mcp_server" + } +] \ No newline at end of file diff --git a/mkdocs.yml b/docs/mkdocs.lib.yml similarity index 89% rename from mkdocs.yml rename to docs/mkdocs.lib.yml index 9fc5e49..d9d7c63 100644 --- a/mkdocs.yml +++ b/docs/mkdocs.lib.yml @@ -21,33 +21,15 @@ theme: - search.highlight - 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 + icon: + logo: material/file-document-multiple + repo: fontawesome/brands/github markdown_extensions: - pymdownx.superfences - pymdownx.inlinehilite - pymdownx.snippets - admonition - pymdownx.details -- pymdownx.superfences - pymdownx.highlight: linenums: true anchor_linenums: true @@ -62,7 +44,31 @@ markdown_extensions: - pymdownx.caret - pymdownx.tilde - pymdownx.mark +extra_css: +- https://unpkg.com/dracula-prism/dist/css/dracula-prism.css +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 site_name: docforge +docs_dir: lib +site_dir: ../site/lib nav: - Home: index.md - Loaders: @@ -87,5 +93,6 @@ nav: - cli/index.md - cli/main.md - cli/commands.md + - cli/api_utils.md - cli/mcp_utils.md - cli/mkdocs_utils.md diff --git a/docs/mkdocs.wiki.yml b/docs/mkdocs.wiki.yml new file mode 100644 index 0000000..e1eb24b --- /dev/null +++ b/docs/mkdocs.wiki.yml @@ -0,0 +1,73 @@ +theme: + name: material + palette: + scheme: slate + primary: blue grey + accent: teal + font: + text: Roboto + code: JetBrains Mono + features: + - navigation.sections + - navigation.expand + - navigation.top + - navigation.instant + - navigation.tracking + - navigation.indexes + - content.code.copy + - content.code.annotate + - content.tabs.link + - content.action.edit + - search.highlight + - search.share + - search.suggest + - navigation.tabs + - toc.integrate + - header.autohide + - announce.dismiss + - footer.social + - content.code.select + - content.code.line_numbers + - content.tooltips + icon: + logo: material/file-document-multiple + repo: fontawesome/brands/github +markdown_extensions: +- pymdownx.superfences +- pymdownx.inlinehilite +- pymdownx.snippets +- admonition +- pymdownx.details +- pymdownx.highlight: + linenums: true + anchor_linenums: true + line_spans: __span + pygments_lang_class: true +- pymdownx.tabbed: + alternate_style: true +- pymdownx.tasklist: + custom_checkbox: true +- tables +- footnotes +- pymdownx.caret +- pymdownx.tilde +- pymdownx.mark +extra_css: +- https://unpkg.com/dracula-prism/dist/css/dracula-prism.css +plugins: +- search +site_name: doc-forge +docs_dir: wiki +site_dir: ../site/wiki +nav: +- Home: index.md +- Overview: 01_overview.md +- Components: 02_components.md +- Conventions: 03_conventions.md +- Iterative Workflow: 04_iterative_workflow.md +- Development: + - Environment: 05_development/01_environment.md + - Quality Gates: 05_development/02_quality_gates.md + - GSDFC Guide: 05_development/03_gsdfc_guide.md + - MCP Guide: 05_development/04_mcp_guide.md + - MkDocs Configs: 05_development/05_mkdocs_configs.md diff --git a/docs/wiki/01_overview.md b/docs/wiki/01_overview.md new file mode 100644 index 0000000..d82d55d --- /dev/null +++ b/docs/wiki/01_overview.md @@ -0,0 +1,43 @@ +# Library Overview + +`docforge` turns GSDFC-compliant Python docstrings into maintainable reference +documentation. It never edits source docstrings; it reads them, renders them, +and assembles documentation sites from all available material. + +--- + +## 🧭 Which Build Should You Use? + +| Kind | Source | Output | +|-----------|----------------------------|---------------------------------| +| `lib` | GSDFC docstrings | `docs/lib/**` rendered markdown | +| `api` | OpenAPI JSON spec | `docs/api/**` rendered markdown | +| `wiki` | Hand-written markdown | `docs/wiki/**` (unchanged) | +| `mcp` | GSDFC docstrings + renderers | `docs/mcp/**` structured JSON | + +--- + +## 🏗️ Architecture + +Each enabled site kind produces its own MkDocs configuration and build: + +1. `--mkdocs` (lib) writes `docs/mkdocs.lib.yml` and builds `site/lib/`. +2. `--api` writes `docs/mkdocs.api.yml` and builds `site/api/`. +3. `--wiki` writes `docs/mkdocs.wiki.yml` and builds `site/wiki/`. + +Every site is self-contained (own theme assets and search index) with +navigation derived or scoped to that kind. Hand-written wiki content is never +overwritten or regenerated — only its navigation is derived automatically. + +--- + +## 🔄 Lifecycle Rules + +`docs/mcp/**` is a self-contained, machine-readable reference generated from +docforge's own GSDFC docstrings. `doc-forge serve --mcp --module docforge` +serves it over MCP. See the [MCP Guide](05_development/04_mcp_guide.md). + +--- + +## ➡️ Read Next +- [02 – Components](02_components.md) · [03 – Conventions](03_conventions.md) \ No newline at end of file diff --git a/docs/wiki/02_components.md b/docs/wiki/02_components.md new file mode 100644 index 0000000..d82fbdd --- /dev/null +++ b/docs/wiki/02_components.md @@ -0,0 +1,55 @@ +# Components + +`docforge` is split into four horizontal layers. Everything flows top to +bottom through the CLI. + +--- + +## 1. Loaders & Models + +The `docforge/loaders` package wraps `griffe` to extract modules, functions, +classes, and Google-style docstring sections. Loaded data is normalized into +the object model under `docforge/models` (`Project`, `Module`, `DocObject`). + +--- + +## 2. Navigation + +`docforge/nav` parses `docforge.nav.yml` specs (`NavSpec`, `Resolver`, and the +MkDocs nav emitter) and, since the wiki kind, derives wiki navigation from the +file structure via `build_wiki_nav`. + +--- + +## 3. Renderers + +`docforge/renderers` turn model data into artifacts: + +- `MkDocsRenderer` → `docs/lib/**` reference markdown +- `MCPRenderer` → `docs/mcp/**` structured documentation + +--- + +## 4. Servers + +`docforge/servers` serves generated artifacts over live protocols: + +- `MCPServer` → serves a pre-generated `docs/mcp/**` bundle through MCP + resources (`docs://index`, `docs://nav`, `docs://modules/{module}`) + +--- + +## 5. CLI + +`docforge/cli` wires it all together: + +- `commands.py` — the `build` command and its `--mkdocs` / `--api` / `--wiki` + / `--mcp` modes +- `mkdocs_utils.py` — per-kind config generation (`docs/mkdocs.{lib,api,wiki}.yml`) + with navigation re-rooted to each kind's `docs_dir` +- `api_utils.py` — OpenAPI loading and API docs generation + +--- + +## Related +- [01 – Overview](01_overview.md) · [03 – Conventions](03_conventions.md) \ No newline at end of file diff --git a/docs/wiki/03_conventions.md b/docs/wiki/03_conventions.md new file mode 100644 index 0000000..a3a0f56 --- /dev/null +++ b/docs/wiki/03_conventions.md @@ -0,0 +1,58 @@ +# Conventions + +--- + +## GSDFC docstrings + +All documented source uses the Google-Styled Doc-Forge Convention (GSDFC): +`Args:`, `Returns:`, `Raises:`, and `Attributes:` sections with properly typed +signatures. + +The authoritative GSDFC specification lives in the `docforge/__init__.py` +package docstring, which is exported verbatim into +`docs/mcp/modules/docforge.json`, so the MCP bundle is self-documenting. + +Key rules: + +1. Use parenthesized types in prose entries (`name (Type):`) that match the + signature types. +2. Use `# Summary`, `# Examples`, and `# Notes` sections at module level. +3. Use `Args:`, `Returns:`, `Raises:`, `Yields:`, `Notes:`, and `Example:` + sections at function and method level. +4. Always update the matching `.pyi` stub alongside the `.py` implementation. +5. Every distributable package ships a `py.typed` marker so type checkers + consume the authored signatures instead of `Any`. + +--- + +## `.pyi` stubs and `py.typed` + +Every module ships a matching `.pyi` stub kept in sync with the `.py` +implementation. When signatures change, update both files. Packages expose a +`py.typed` marker so consumers and type checkers use the authored signatures. + +--- + +## Wiki pages + +1. Hand-written markdown lives in `docs/wiki/**` and is never generated. +2. File names use a numeric prefix: `01_overview.md`, `02_components.md`. +3. Nested directories become nested navigation groups: + `05_development/01_environment.md` → group *Development*. +4. `index.md` is the site `Home` at the root, and a section root inside a + directory. +5. Navigation labels are derived by stripping the numeric prefix and applying + title case on the remaining words. + +--- + +## Templates + +MkDocs config fragments live in `docforge/templates`. The `mkdocs.wiki.yml` +fragment carries only the `search` plugin, since wiki pages contain no +mkdocstrings directives. + +--- + +## Related +- [02 – Components](02_components.md) · [04 – Iterative Workflow](04_iterative_workflow.md) \ No newline at end of file diff --git a/docs/wiki/04_iterative_workflow.md b/docs/wiki/04_iterative_workflow.md new file mode 100644 index 0000000..65fa1c4 --- /dev/null +++ b/docs/wiki/04_iterative_workflow.md @@ -0,0 +1,61 @@ +# Iterative Workflow + +A docs build runs through the CLI in a single pass. + +--- + +## 🚀 Build commands + +```bash +# Library reference only +doc-forge build --mkdocs --module docforge + +# Wiki + library (each an independent MkDocs build) +doc-forge build --wiki --mkdocs --module docforge + +# Wiki only — no module required +doc-forge build --wiki --site-name docforge + +# MCP structured bundle +doc-forge build --mcp --module docforge +``` + +--- + +## 🔄 What a build does + +1. Validates the requested modes (`--mkdocs`, `--api`, `--wiki`, `--mcp`). +2. Generates library sources under `docs/lib/**` with `MkDocsRenderer`. +3. Generates API sources under `docs/api/**` when `--api` is given. +4. Derives the wiki navigation from `docs/wiki/**`. +5. Writes one MkDocs config per site kind (`docs/mkdocs.{lib,api,wiki}.yml`), + re-rooting navigation paths to each kind's `docs_dir`. +6. Runs `mkdocs build` once per config, emitting self-contained sites + `site/lib/`, `site/api/`, and `site/wiki/`. + +--- + +## 🧭 Explore the sites + +```bash +doc-forge build --wiki --mkdocs --module docforge +doc-forge serve --wiki # serves site preview from docs/mkdocs.wiki.yml +doc-forge serve --lib +doc-forge serve --api +# or target any config directly: +doc-forge serve --mkdocs --mkdocs-yml docs/mkdocs.wiki.yml +``` + +--- + +## 📦 Serve the MCP bundle + +```bash +doc-forge build --mcp --module docforge +doc-forge serve --mcp --module docforge +``` + +--- + +## Related +- [03 – Conventions](03_conventions.md) · [01 – Environment](05_development/01_environment.md) \ No newline at end of file diff --git a/docs/wiki/05_development/01_environment.md b/docs/wiki/05_development/01_environment.md new file mode 100644 index 0000000..aedfcd9 --- /dev/null +++ b/docs/wiki/05_development/01_environment.md @@ -0,0 +1,30 @@ +# Environment Setup + +--- + +## 🚀 Create the environment + +```bash +python -m venv .venv +.venv\Scripts\activate +pip install -e . +``` + +Requires Python 3.10+ (per `pyproject.toml`). + +--- + +## 📦 Dependencies + +Development extras include: + +- `pytest`, `pytest-cov` — test suite and coverage +- `ruff` — lint and format checking +- `black` — auto-formatting +- `mypy` — strict typing checks +- `pydoclint` — docstring ↔ signature consistency checks + +--- + +## Related +- [04 – Iterative Workflow](../04_iterative_workflow.md) · [02 – Quality Gates](02_quality_gates.md) \ No newline at end of file diff --git a/docs/wiki/05_development/02_quality_gates.md b/docs/wiki/05_development/02_quality_gates.md new file mode 100644 index 0000000..c157aaf --- /dev/null +++ b/docs/wiki/05_development/02_quality_gates.md @@ -0,0 +1,34 @@ +# Quality Gates + +Run all checks before pushing: + +--- + +## 🚀 Commands + +```bash +.venv\Scripts\python.exe -m pytest +.venv\Scripts\python.exe -m ruff check docforge tests +.venv\Scripts\python.exe -m black --check docforge tests +.venv\Scripts\python.exe -m mypy docforge +.venv\Scripts\pydoclint.exe docforge +``` + +--- + +## 📁 Test layout + +| Path | Covers | +|--------------------------|------------------------------------| +| `tests/nav/` | Nav spec, resolver, wiki nav | +| `tests/cli/` | Build command flows and modes | +| `tests/renderers/` | MkDocs / MCP rendering | + +CLI tests use the `cli_runner` fixture with `mock_mkdocs_build` and +`mock_mkdocs_load_config` so they exercise the full flow without invoking a +real MkDocs build. + +--- + +## Related +- [01 – Environment](01_environment.md) · [03 – GSDFC Guide](03_gsdfc_guide.md) \ No newline at end of file diff --git a/docs/wiki/05_development/03_gsdfc_guide.md b/docs/wiki/05_development/03_gsdfc_guide.md new file mode 100644 index 0000000..faa6a84 --- /dev/null +++ b/docs/wiki/05_development/03_gsdfc_guide.md @@ -0,0 +1,129 @@ +# GSDFC Docstring Guide + +This page is the practical companion to the authoritative GSDFC specification +in the `docforge/__init__.py` package docstring. It describes how to write +docstrings that render correctly in MkDocs and stay machine-parseable by +doc-forge, MkDocs, and MCP clients. + +--- + +## 🧭 Overview + +- Docstrings are the single source of truth. +- `doc-forge` compiles docstrings but never rewrites them. +- Every public symbol should have a complete, accurate docstring. +- Type hints live in signatures; prose entries repeat the type in + parentheses and must match the signature. + +--- + +## 📦 Module docstrings + +Modules use Markdown headings and `---` separators. + +Recommended sections: + +- `# Summary` — what the subsystem does +- `# Examples` — a representative usage snippet +- `# Notes` — guarantees, lifecycle, and thread-safety notes + +--- + +## 📦 Class docstrings + +Recommended sections, in order: + +- summary line describing responsibility +- `Attributes:` — instance attributes with `name (Type):` entries +- `Notes:` — grouped subsections such as **Guarantees**, **Lifecycle** +- `Example:` — indented `python` code block + +--- + +## 📦 Function and method docstrings + +Recommended section order: + +1. `Args:` +2. `Returns:` +3. `Raises:` +4. `Yields:` +5. `Notes:` +6. `Example:` + +Formatting rules: + +- `Args:` entries are `name (Type):` followed by an indented description. +- `Returns:` entries are `Type:` followed by an indented description. +- `Raises:` entries are `ExceptionType:` followed by an indented condition. +- `Yields:` replaces `Returns:` for generators. +- Summaries are written in the imperative mood. +- Fenced `python` blocks are allowed inside `Example:` sections, indented + four spaces. + +--- + +## 📦 Property docstrings + +Properties document their return values with a `Returns:` section and, when +meaningful, an `Example:`. + +--- + +## 🚀 Example + +```python +def process(foo: Foo, multiplier: int) -> int: + """Process a Foo instance. + + Args: + foo (Foo): + Foo instance to process. + + multiplier (int): + Value used to scale foo. + + Returns: + int: + Processed result. + + Raises: + ValueError: + If multiplier is negative. + + Example: + Process foo: + + ```python + foo = Foo("example", value=10) + result = process(foo, multiplier=2) + print(result) + ``` + """ +``` + +--- + +## 🔄 Keeping stubs in sync + +Every `.py` module ships a matching `.pyi` stub. When a signature or a public +symbol changes, update both files. Signature annotations in the stub must +match the implementation. + +--- + +## 🛡️ Enforcement + +`pydoclint` (Google style) runs in CI and verifies that `Args:`/`Returns:` +sections match function signatures, including types. + +- `allow-init-docstring = true` — `__init__` docstrings are allowed. +- `skip-checking-raises = true` — `Raises:` sections are descriptive and are + not required to map to literal `raise` statements. +- `check-class-attributes = false` — `Attributes:` sections document instance + attributes without class-level annotations. + +--- + +## Related +- [02 – Quality Gates](02_quality_gates.md) · [04 – MCP Guide](04_mcp_guide.md) \ No newline at end of file diff --git a/docs/wiki/05_development/04_mcp_guide.md b/docs/wiki/05_development/04_mcp_guide.md new file mode 100644 index 0000000..c5d474e --- /dev/null +++ b/docs/wiki/05_development/04_mcp_guide.md @@ -0,0 +1,62 @@ +# MCP Guide + +Doc-forge can export a machine-readable **MCP bundle** from a project's +GSDFC docstrings and serve that bundle over the Model Context Protocol (MCP). +The bundle is self-contained: readers can derive the full API reference — +signatures, docstrings, and structure — for the documented project. + +--- + +## 🚀 Building the bundle + +```bash +doc-forge build --mcp --module docforge +``` + +This writes structured JSON into `docs/mcp/`: + +- `index.json` — project metadata and module count +- `nav.json` — module list with `docs://modules/{module}` resource URIs +- `modules/{dotted.path}.json` — per-module serialized documentation + +--- + +## 🚀 Serving the bundle + +```bash +doc-forge serve --mcp --module docforge +``` + +The `MCPServer` (in `docforge/servers/mcp_server.py`) exposes: + +| Resource | Description | +|----------------------|-----------------------------------| +| `docs://index` | Project metadata | +| `docs://nav` | Navigation structure | +| `docs://modules/{module}` | Individual module documentation | + +The server also registers a single diagnostic tool, `ping`, and is read-only. +Missing resources are returned as structured error dictionaries rather than +exceptions. The default transport is `streamable-http`; `stdio` and `sse` are +supported via `MCPServer.run`. + +--- + +## 📦 Bundle contents + +Each module resource contains: + +- `path` — dotted module path +- `docstring` — the raw GSDFC module docstring +- `objects` — a recursive mapping of public symbols with `name`, `kind`, + `path`, `signature`, and `docstring`, plus nested `members` + +Because the bundle is generated from docstrings, the quality of the bundle +equals the quality of the project's GSDFC docstrings. For docforge itself, +the GSDFC specification is carried in `modules/docforge.json` via the +`docforge/__init__.py` package docstring, making the bundle self-documenting. + +--- + +## Related +- [03 – GSDFC Guide](03_gsdfc_guide.md) · [05 – MkDocs Configs](05_mkdocs_configs.md) \ No newline at end of file diff --git a/docs/wiki/05_development/05_mkdocs_configs.md b/docs/wiki/05_development/05_mkdocs_configs.md new file mode 100644 index 0000000..658d776 --- /dev/null +++ b/docs/wiki/05_development/05_mkdocs_configs.md @@ -0,0 +1,59 @@ +# MkDocs Configuration Model + +Each documentation kind (lib, api, wiki) is built by its own MkDocs site. A +repo that documents kind `{kind}` carries a config at `docs/mkdocs.{kind}.yml` +that sets `docs_dir` to the kind's source directory and `site_dir` to +`../site/{kind}`. + +--- + +## 📄 File wins + +`docs/mkdocs.{kind}.yml` is a repo-owned file, not a build byproduct: + +- **Absent** — `doc-forge build --{kind}` materializes a copy from the + packaged templates (see below) and then builds `site/{kind}`. +- **Present** — the build uses the file verbatim. Edits to the theme, palette, + plugins, markdown extensions, nav, or `site_dir` are respected as-is. +- **`--refresh`** — force-regenerates the file from the templates, + replacing any local changes. + +Because a present file is never rewritten, rerunning a build is a no-op for +versioned configs: the working tree stays clean. + +--- + +## 🧩 Templates + +The built-in defaults live in `docforge/templates/`: + +| File | Role | +|-----------------------|-----------------------------------------------| +| `mkdocs.common.yml` | Shared theme + markdown extensions | +| `mkdocs.lib.yml` | `mkdocstrings` handler for library reference | +| `mkdocs.api.yml` | Swagger/OpenAPI plugins and API-side features | +| `mkdocs.wiki.yml` | Wiki look: horizontal `navigation.tabs` header, blue grey/teal palette, Roboto | + +A per-kind config is generated by deep-merging the common template with the +kind fragment, then filling in generation-time values (`site_name`, +`docs_dir`, `site_dir`, `nav`, API `site_description`/`site_author`, and the +theme `icon` from `docforge.nav.yml`). Pass `--template ` to replace the +built-in templates entirely. + +--- + +## 🏗️ Supported layouts + +- **Per-kind config** — the standard layout; each kind builds to + `site/{kind}` and is served under `//{kind}/`. +- **Legacy root config** — a repo with a single kind may instead author root + `mkdocs.yml` (for example mongo-ops, whose wiki uses `docs_dir: docs/wiki`). + doc-forge never reads or writes root `mkdocs.yml`; the docs service maps the + kind to the root `site/` dir in this case. + +Commit `docs/mkdocs.{kind}.yml` so served docs are reproducible from source. + +--- + +## Related +- [04 – MCP Guide](04_mcp_guide.md) \ No newline at end of file diff --git a/docs/wiki/index.md b/docs/wiki/index.md new file mode 100644 index 0000000..8e18c46 --- /dev/null +++ b/docs/wiki/index.md @@ -0,0 +1,325 @@ +# 🧩 docforge — Docstring-Driven Documentation Forge + +`docforge` is an internal documentation tool that generates reference documentation from Google-Styled Doc-Forge Convention (GSDFC) docstrings and assembles it into per-kind MkDocs sites, alongside hand-written wiki pages and OpenAPI-based API docs. + +> **Doc model:** this wiki is written for humans — how‑to guides, examples, +> and testing recipes. The authoritative API contracts live in the code +> (docstrings) and the machine‑readable bundle under `docs/mcp/`. + +--- + +## 🚀 Key Features + +- 🧪 GSDFC docstring extraction via Griffe +- 🧭 Auto-derived navigation for hand-written wiki pages +- 🗂 Independent MkDocs builds per kind (lib, api, wiki) into `site/{kind}` +- 🔌 Material MkDocs theming out of the box +- 📦 MCP structured documentation resources + +--- + +## 📦 Installation + +```bash +# Internal PyPI (TBD) +pip install docforge +``` + +--- + +## 📁 Documentation Structure + +| Section | Description | +|----------------------------------------------| -------------------------------------------------- | +| [Overview](01_overview.md) | What docforge is and how it fits the pipeline | +| [Components](02_components.md) | Loaders, models, nav, renderers, CLI, servers | +| [Conventions](03_conventions.md) | GSDFC, `.pyi` stubs, and template conventions | +| [Iterative Workflow](04_iterative_workflow.md) | How a docs build runs end to end | +| [Environment](05_development/01_environment.md) | Environment setup | +| [Quality Gates](05_development/02_quality_gates.md) | Test layout and quality checks | +| [GSDFC Guide](05_development/03_gsdfc_guide.md) | How to write GSDFC-conformant docstrings | +| [MCP Guide](05_development/04_mcp_guide.md) | Building, serving, and consuming the MCP bundle | +| [MkDocs Configs](05_development/05_mkdocs_configs.md) | MkDocs config generation and templates | + +--- + +## 🔗 Related Resources + +- **Source Code:** the `doc-forge` repository +- **MCP Bundle:** generated by `doc-forge build --mcp --module docforge` into `docs/mcp/` +- **Wiki Kind:** hand-written content lives in `docs/wiki/`; use the prompt in the + wiki-related resource below +````markdown +# AGENTS.md — Wiki Authoring Guide (Aetoskia) + +This file instructs AI agents how to create, extend, and maintain the wiki +(`docs/wiki/**`) for any Aetoskia repository. + +> **Workflow:** this prompt covers **phase 2 only**. Phase 1 — writing GSDFC docstrings +> (plus `.pyi` stubs and `py.typed`) — is done by the agent using the doc-forge MCP +> bundle: `doc://modules/docforge` carries the full GSDFC spec. Write the wiki only +> after docstrings exist and `doc-forge build --mcp --module ` produced the +> repo's own bundle. + +--- + +## 1. Doc model — know the two sources of truth + +Every repo keeps two distinct kinds of documentation that must **not** bleed +into each other: + +| Kind | Source | Where | Audience | +|-------------------|-----------------------|------------------------------------------|------------------------------------| +| **Wiki** | Hand-written markdown | `docs/wiki/**` | Humans (how-to, examples, testing) | +| **API reference** | Docstrings (GSDFC) | Generated → `docs/lib/**`, `docs/mcp/**` | Consumers (exact contracts) | + +Rules: + +- The wiki is written **for humans** — how-to guides, recipes, and testing + patterns. It is never generated. +- API contracts (signatures, parameter types, exact behavior) live in the + docstrings and the machine-readable bundle under `docs/mcp/`. **Never** + duplicate full API documentation in the wiki — link to the lib site instead. +- If a page starts to drift into contract territory, cut it down to usage and + point at `docs/lib/`. +- This doc model is stated on every index page as a blockquote; keep it there: + > **Doc model:** this wiki is written for humans — how‑to guides, examples, + > and testing recipes. The authoritative API contracts live in the code + > (docstrings) and the machine‑readable bundle under `docs/mcp/`. + +--- + +## 2. Directory layout & file naming + +``` +docs/wiki/ +├── index.md # site Home +├── 01_overview.md +├── 02_components.md +├── 03_use_cases/ # nested directory → nav group +│ ├── 01_basic_crud.md +│ ├── 02_custom_repo.md +│ └── ... +├── 04_best_practices.md +├── 06_error_handling.md +└── 07_testing_example.md +``` + +- Location: `docs/wiki/` (hand-written only). +- File names: `NN_snake_case_name.md` with a **zero-padded two-digit** numeric + prefix. e.g. `01_overview.md`, `03_use_cases/07_caching.md`. +- Top-level pages use `NN_name.md` directly. High-volume sections get their own + directory, e.g. `03_use_cases/NN_name.md` (nav group "Use Cases"). +- **No frontmatter.** Every file opens directly with an H1 `# Title`. +- Navigation labels are short human titles set explicitly in + `docs/mkdocs.wiki.yml` (title case) — often **shorter** than the page H1. + Example: nav label `Basic CRUD` vs page H1 `Use Case 1: Basic FastAPI CRUD API`. + Never use the raw filename slug as the label. +- Renumbering: prefixes order pages. When inserting a page, pick the next + number in the relevant group (subgroup numbers stay grouped). + +--- + +## 3. Navigation — `docs/mkdocs.wiki.yml` is the source of truth + +Every wiki page **must** be wired into the nav defined in +`docs/mkdocs.wiki.yml`. If a page is not in the nav, it is orphaned. + +- The `nav:` block mirrors the directory tree; directories become nested + groups. +- When a section has many pages, group them **by theme** into nested + subgroups. mongo-ops groups its use cases into: + `Getting Started`, `Data & Queries`, `Caching`, `Population`, + `Advanced Usage`. +- Keep `index.md`'s **Documentation Structure** table in sync with the nav — + it is the human-facing version of the same TOC. Every nav entry needs a row + (or nested bullet group) there. +- Nav label = human title (title case), not the filename slug. + +--- + +## 4. Page anatomy + +### 4.1 `index.md` (Home) + +``` +# 🧩 — + + +> **Doc model:** … (see §1) + +--- + +## 🚀 Key Features (bullet list, emoji per feature) +## 📦 Installation (code blocks: internal PyPI, extras, local source) +## 📁 Documentation Structure (table = TOC, mirrors nav exactly) +## 🔗 Related Resources (bullets: source repo, internal PyPI, CI) +--- +© Aetoskia Internal — `` +``` + +### 4.2 Overview page (`01_*`) + +- Opens with `# Library Overview`, one sentence about what the library does, + then a line stating the page builds the mental model. +- Sections: `## 🏗️ Architecture` (ASCII diagram + numbered layer list), + `## 🔄 Lifecycle Rules` (table: step / call / why), + `## 🧭 Which … Should You Use?` (decision table). +- Ends with `## ➡️ Read Next` (cross-links to the next pages to read). + +### 4.3 Components page (`02_*`) + +- Validated reference for the public API surface — describes what each + component is for and how the pieces wire together. Keep it usage-level; + exact signatures belong in `docs/lib/`. +- Anatomy: numbered sections, one per component (`## 1. MongoConnectionManager`, + `## 2. BaseDocument`, …), with `### 8.1`-style sub-numbering for related + types under a component (e.g. the cache layer's backend / stats / config / + in-memory / redis implementations). Ends with `## Related`. + +### 4.4 Use-case page (the most common) + +Standard anatomy, in this order: + +``` +# Use Case N: + +**Scenario:** + +--- + +## 📦 What's New? (table: Component | Description — new API used here) +## 🚀 Example (languaged code block, complete runnable-looking snippet) +## 💡 Tips (bullets: gotchas, ordering, common mistakes) +## Related (§5) +``` + +### 4.5 Deep-dive / worked-example page + +For intricate flows (population shapes, cache round-trips), use numbered +depth-first sections and comparison tables: + +``` +## 1. (### 1a., ### 1b., … per sub-case) +## 2. +## 3. +## 4. When to use which (comparison table) +## Related +``` + +### 4.6 Best Practices page (`04_*`) + +- Flat themed `##` sections (e.g. Layering, Lifecycle, Data & Performance, + Transactions & Errors, Testing), each a short list of numbered conventions. +- Pure prose — no large code blocks. + +### 4.7 Error Handling (`06_*`) / Testing pages + +- **Error Handling:** an exceptions table (`Exception | Source | Meaning / fix`), + a `> ` note on which failures are by design, a `## 🚀 FastAPI Mapping Example` + code block, then `## 💡 Tips` bullets, then `## Related`. +- **Testing example (`07_*`):** `## 🚀 Mock-Based Quickstart` (focused code + block), `## 💡 Notes` tip list, `## Related`. + +Common to all pages: no frontmatter, `---` between every major section, and a +`## Related` (or variant) footer as the **last** section. + +--- + +## 5. The `## Related` footer + +Every page ends with a cross-link footer. Rules: + +- Always the **last** section, always preceded by a `---`. +- Standard heading: `## Related` (no emoji). +- One bullet line; links separated by ` · ` (middle dot plus spaces). +- Link label format: `[NN – Title](relative_path)` — en-dash, page number, title. +- Paths are **relative**: same directory → `02_custom_repo.md`; parent → + `../01_overview.md`; child → `03_use_cases/01_basic_crud.md`. +- Link order follows nav order (each `Related` points to related next/sibling + pages, plus the overview/components anchor). + +Examples (from mongo-ops): + +``` +## Related +- [02 – Custom repository](02_custom_repo.md) · [04 – Pagination](04_pagination.md) · [Overview](../01_overview.md) +``` + +Variants: + +- `## ➡️ Read Next` — used on the overview page (linear reading order). +- `## 🔗 Related Resources` — only on `index.md`, one bullet per external resource. + +--- + +## 6. Tone & formatting rules + +- **Written for humans**: short sentences, concrete examples, plain words. +- Emoji-prefixed H2 headings for recognizable section types + (`📦 What's New?`, `🚀 Example`, `💡 Tips`, `🚀 Key Features`). +- `---` horizontal rule between every major section. +- Code blocks always declare a language (```python, ```bash, etc.). +- Use tables for comparisons and structured decisions; bullets for lists; + ASCII diagrams for architecture. +- Bold key terms inline. Use `inline code` for symbols/APIs. +- Keep pages focused: one recipe/purpose per page. If a page balloons past + ~10 KB, split it (add a numbered deep-dive page instead). +- Match tone of existing pages in the repo before writing new ones. +- Ground every `## 🚀 Example`, `💡 Tips`, and `📦 What's New?` row in the + library's actual source, tests, and its `docs/mcp` bundle — never invent + APIs or behavior. Signatures and exceptions come from the code; gotchas + come from the tests. + +--- + +## 7. Build & verify workflow + +After creating or editing wiki pages: + +```bash +# 1. Build the wiki (from the repo root) +doc-forge build --wiki # wiki only +doc-forge build --wiki --mkdocs --module # wiki + lib together + +# 2. Preview locally +doc-forge serve --wiki + +# 3. Collect into the hub (run from the docs/ service repo) +python collect.py # copies site, regenerates index + nginx.conf +python collect.py --dry-run # preview without writing +``` + +Verification checklist: + +- `doc-forge build --wiki` completes with no warnings about missing files. +- Every new page is present in `docs/mkdocs.wiki.yml` **and** in the index + Documentation Structure table. +- Every page ends with a `## Related` block and no dead links (paths resolve). +- After `collect.py`: the hub card links to both `/wiki/` and `/lib/` and the + pages render (spot-check with the served site). +- If code/docstrings changed (no change when wiki-only), run the repo gates: + `black`, `ruff`, `mypy`, `pytest`. + +--- + +## 8. Before/after checklist + +**Before creating a page:** + +- [ ] Confirm it is genuinely wiki material (how-to) and not API contract. +- [ ] Find the right filename (`NN_snake_case.md`) and directory for its theme. +- [ ] Outline the sections per §4 anatomy that fits the content. + +**After creating/editing a page:** + +- [ ] Page wired into `docs/mkdocs.wiki.yml` nav (themed subgroup if needed). +- [ ] `index.md` Documentation Structure table updated. +- [ ] `## Related` footer present, relative links, nav order. +- [ ] `---` separators consistent; no frontmatter; emoji headings where apt. +- [ ] Build passes; collect run; hub shows `/wiki/` + `/lib/` links. +- [ ] No orphaned files, no dead links. +```` +--- + +© Aetoskia Internal — `docforge` 1.0 \ No newline at end of file diff --git a/mcp_docs/modules/docforge.cli.commands.json b/mcp_docs/modules/docforge.cli.commands.json deleted file mode 100644 index 5daa267..0000000 --- a/mcp_docs/modules/docforge.cli.commands.json +++ /dev/null @@ -1,377 +0,0 @@ -{ - "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.", - "objects": { - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.click", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.Path", - "signature": "", - "docstring": null - }, - "Sequence": { - "name": "Sequence", - "kind": "alias", - "path": "docforge.cli.commands.Sequence", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.cli.commands.Optional", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "mkdocs_utils": { - "name": "mkdocs_utils", - "kind": "module", - "path": "docforge.cli.commands.mkdocs_utils", - "signature": "", - "docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.", - "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.Path", - "signature": "", - "docstring": null - }, - "resources": { - "name": "resources", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.resources", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.click", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.yaml", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.discover_module_paths", - "signature": "", - "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, optional):\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." - }, - "MkDocsRenderer": { - "name": "MkDocsRenderer", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer", - "signature": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\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": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." - } - } - }, - "load_nav_spec": { - "name": "load_nav_spec", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.load_nav_spec", - "signature": "", - "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." - }, - "resolve_nav": { - "name": "resolve_nav", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.resolve_nav", - "signature": "", - "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." - }, - "MkDocsNavEmitter": { - "name": "MkDocsNavEmitter", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter", - "signature": "", - "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": "", - "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." - } - } - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.generate_sources", - "signature": "", - "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 (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module." - }, - "generate_config": { - "name": "generate_config", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." - }, - "build": { - "name": "build", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.build", - "signature": "", - "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\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." - }, - "serve": { - "name": "serve", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.serve", - "signature": "", - "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." - } - } - }, - "mcp_utils": { - "name": "mcp_utils", - "kind": "module", - "path": "docforge.cli.commands.mcp_utils", - "signature": "", - "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.", - "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.mcp_utils.Path", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.mcp_utils.click", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.mcp_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.discover_module_paths", - "signature": "", - "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, optional):\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": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources", - "signature": "", - "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": "", - "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.", - "members": { - "mcp_root": { - "name": "mcp_root", - "kind": "attribute", - "path": "docforge.cli.commands.mcp_utils.MCPServer.mcp_root", - "signature": "", - "docstring": null - }, - "app": { - "name": "app", - "kind": "attribute", - "path": "docforge.cli.commands.mcp_utils.MCPServer.app", - "signature": "", - "docstring": null - }, - "run": { - "name": "run", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.MCPServer.run", - "signature": "", - "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": "", - "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 (Optional[str]):\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": "", - "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." - } - } - }, - "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": "", - "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\n\n1. Introspects the Python project using Griffe\n2. Generates renderer-specific documentation sources\n3. Optionally builds the final documentation output\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs documentation generation.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Directory where Markdown documentation sources will be generated.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\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": "", - "docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing documentation\n- An MCP server exposing structured documentation resources\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site.\n\n module (Optional[str]):\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": "", - "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 (Optional[str]):\n Optional name to display as the project root." - }, - "Group": { - "name": "Group", - "kind": "alias", - "path": "docforge.cli.commands.Group", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.cli.commands.Any", - "signature": "", - "docstring": null - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.cli.json b/mcp_docs/modules/docforge.cli.json deleted file mode 100644 index e985c55..0000000 --- a/mcp_docs/modules/docforge.cli.json +++ /dev/null @@ -1,684 +0,0 @@ -{ - "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 [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": "", - "docstring": null - }, - "main": { - "name": "main", - "kind": "function", - "path": "docforge.cli.main.main", - "signature": "", - "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." - } - } - }, - "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.", - "members": { - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.click", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.Path", - "signature": "", - "docstring": null - }, - "Sequence": { - "name": "Sequence", - "kind": "alias", - "path": "docforge.cli.commands.Sequence", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.cli.commands.Optional", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "mkdocs_utils": { - "name": "mkdocs_utils", - "kind": "module", - "path": "docforge.cli.commands.mkdocs_utils", - "signature": "", - "docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.", - "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.Path", - "signature": "", - "docstring": null - }, - "resources": { - "name": "resources", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.resources", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.click", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.cli.commands.mkdocs_utils.yaml", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.discover_module_paths", - "signature": "", - "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, optional):\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." - }, - "MkDocsRenderer": { - "name": "MkDocsRenderer", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer", - "signature": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\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": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." - } - } - }, - "load_nav_spec": { - "name": "load_nav_spec", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.load_nav_spec", - "signature": "", - "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." - }, - "resolve_nav": { - "name": "resolve_nav", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.resolve_nav", - "signature": "", - "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." - }, - "MkDocsNavEmitter": { - "name": "MkDocsNavEmitter", - "kind": "class", - "path": "docforge.cli.commands.mkdocs_utils.MkDocsNavEmitter", - "signature": "", - "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": "", - "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." - } - } - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.generate_sources", - "signature": "", - "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 (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module." - }, - "generate_config": { - "name": "generate_config", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." - }, - "build": { - "name": "build", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.build", - "signature": "", - "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\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." - }, - "serve": { - "name": "serve", - "kind": "function", - "path": "docforge.cli.commands.mkdocs_utils.serve", - "signature": "", - "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." - } - } - }, - "mcp_utils": { - "name": "mcp_utils", - "kind": "module", - "path": "docforge.cli.commands.mcp_utils", - "signature": "", - "docstring": "# Summary\n\nUtilities for working with MCP in the doc-forge CLI.", - "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.commands.mcp_utils.Path", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.commands.mcp_utils.click", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.commands.mcp_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.discover_module_paths", - "signature": "", - "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, optional):\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": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.MCPRenderer.generate_sources", - "signature": "", - "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": "", - "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.", - "members": { - "mcp_root": { - "name": "mcp_root", - "kind": "attribute", - "path": "docforge.cli.commands.mcp_utils.MCPServer.mcp_root", - "signature": "", - "docstring": null - }, - "app": { - "name": "app", - "kind": "attribute", - "path": "docforge.cli.commands.mcp_utils.MCPServer.app", - "signature": "", - "docstring": null - }, - "run": { - "name": "run", - "kind": "function", - "path": "docforge.cli.commands.mcp_utils.MCPServer.run", - "signature": "", - "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": "", - "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 (Optional[str]):\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": "", - "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." - } - } - }, - "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": "", - "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\n\n1. Introspects the Python project using Griffe\n2. Generates renderer-specific documentation sources\n3. Optionally builds the final documentation output\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs documentation generation.\n\n module_is_source (bool):\n Treat the specified module directory as the project root.\n\n module (Optional[str]):\n Python module import path to document.\n\n project_name (Optional[str]):\n Optional override for the project name.\n\n site_name (Optional[str]):\n Display name for the MkDocs site.\n\n docs_dir (Path):\n Directory where Markdown documentation sources will be generated.\n\n nav_file (Path):\n Path to the navigation specification file.\n\n template (Optional[Path]):\n Optional custom MkDocs configuration template.\n\n mkdocs_yml (Path):\n Output path for the generated MkDocs configuration.\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": "", - "docstring": "Serve generated documentation locally.\n\nDepending on the selected mode, this command starts either:\n\n- A MkDocs development server for browsing documentation\n- An MCP server exposing structured documentation resources\n\nArgs:\n mcp (bool):\n Serve documentation using the MCP server.\n\n mkdocs (bool):\n Serve the MkDocs development site.\n\n module (Optional[str]):\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": "", - "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 (Optional[str]):\n Optional name to display as the project root." - }, - "Group": { - "name": "Group", - "kind": "alias", - "path": "docforge.cli.commands.Group", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.cli.commands.Any", - "signature": "", - "docstring": null - } - } - }, - "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.", - "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.mcp_utils.Path", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.mcp_utils.click", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.mcp_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.mcp_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.mcp_utils.discover_module_paths", - "signature": "", - "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, optional):\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": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.mcp_utils.MCPRenderer.generate_sources", - "signature": "", - "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": "", - "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.", - "members": { - "mcp_root": { - "name": "mcp_root", - "kind": "attribute", - "path": "docforge.cli.mcp_utils.MCPServer.mcp_root", - "signature": "", - "docstring": null - }, - "app": { - "name": "app", - "kind": "attribute", - "path": "docforge.cli.mcp_utils.MCPServer.app", - "signature": "", - "docstring": null - }, - "run": { - "name": "run", - "kind": "function", - "path": "docforge.cli.mcp_utils.MCPServer.run", - "signature": "", - "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": "", - "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 (Optional[str]):\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": "", - "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.", - "members": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.Path", - "signature": "", - "docstring": null - }, - "resources": { - "name": "resources", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.resources", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.click", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.yaml", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.discover_module_paths", - "signature": "", - "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, optional):\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." - }, - "MkDocsRenderer": { - "name": "MkDocsRenderer", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.MkDocsRenderer", - "signature": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\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": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." - } - } - }, - "load_nav_spec": { - "name": "load_nav_spec", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.load_nav_spec", - "signature": "", - "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." - }, - "resolve_nav": { - "name": "resolve_nav", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.resolve_nav", - "signature": "", - "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." - }, - "MkDocsNavEmitter": { - "name": "MkDocsNavEmitter", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.MkDocsNavEmitter", - "signature": "", - "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": "", - "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." - } - } - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.generate_sources", - "signature": "", - "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 (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module." - }, - "generate_config": { - "name": "generate_config", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." - }, - "build": { - "name": "build", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.build", - "signature": "", - "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\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." - }, - "serve": { - "name": "serve", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.serve", - "signature": "", - "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." - } - } - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.cli.mkdocs_utils.json b/mcp_docs/modules/docforge.cli.mkdocs_utils.json deleted file mode 100644 index 219bacf..0000000 --- a/mcp_docs/modules/docforge.cli.mkdocs_utils.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "module": "docforge.cli.mkdocs_utils", - "content": { - "path": "docforge.cli.mkdocs_utils", - "docstring": "# Summary\n\nUtilities for working with MkDocs in the doc-forge CLI.", - "objects": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.Path", - "signature": "", - "docstring": null - }, - "resources": { - "name": "resources", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.resources", - "signature": "", - "docstring": null - }, - "click": { - "name": "click", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.click", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.cli.mkdocs_utils.yaml", - "signature": "", - "docstring": null - }, - "GriffeLoader": { - "name": "GriffeLoader", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.GriffeLoader", - "signature": "", - "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.", - "members": { - "load_project": { - "name": "load_project", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.GriffeLoader.load_project", - "signature": "", - "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, optional):\n Optional override for the project name. Defaults to the top-level\n name of the first module.\n\n skip_import_errors (bool, optional):\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": "", - "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." - } - } - }, - "discover_module_paths": { - "name": "discover_module_paths", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.discover_module_paths", - "signature": "", - "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, optional):\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." - }, - "MkDocsRenderer": { - "name": "MkDocsRenderer", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.MkDocsRenderer", - "signature": "", - "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": "", - "docstring": null - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.MkDocsRenderer.generate_sources", - "signature": "", - "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, optional):\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": "", - "docstring": "Generate a `README.md` file from the root module docstring.\n\nBehavior:\n\n- If `module_is_source` is True, `README.md` is written to the project\n 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, optional):\n Whether the module is treated as the project source root." - } - } - }, - "load_nav_spec": { - "name": "load_nav_spec", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.load_nav_spec", - "signature": "", - "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." - }, - "resolve_nav": { - "name": "resolve_nav", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.resolve_nav", - "signature": "", - "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." - }, - "MkDocsNavEmitter": { - "name": "MkDocsNavEmitter", - "kind": "class", - "path": "docforge.cli.mkdocs_utils.MkDocsNavEmitter", - "signature": "", - "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": "", - "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." - } - } - }, - "generate_sources": { - "name": "generate_sources", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.generate_sources", - "signature": "", - "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 (Optional[str]):\n Optional override for the project name used in documentation metadata.\n\n module_is_source (Optional[bool]):\n If True, treat the specified module directory as the project root\n rather than a nested module." - }, - "generate_config": { - "name": "generate_config", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.generate_config", - "signature": "", - "docstring": "Generate an `mkdocs.yml` configuration file.\n\nThe configuration is created by combining a template configuration\nwith a navigation structure derived from the docforge navigation\nspecification.\n\nArgs:\n docs_dir (Path):\n Directory containing generated documentation Markdown files.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a custom MkDocs configuration template. If not\n provided, a built-in template will be used.\n\n out (Path):\n Destination path where the generated `mkdocs.yml` file will be written.\n\n site_name (str):\n Display name for the generated documentation site.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found." - }, - "build": { - "name": "build", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.build", - "signature": "", - "docstring": "Build the MkDocs documentation site.\n\nThis function loads the MkDocs configuration and runs the MkDocs\nbuild command to generate the final static documentation site.\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." - }, - "serve": { - "name": "serve", - "kind": "function", - "path": "docforge.cli.mkdocs_utils.serve", - "signature": "", - "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." - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.nav.mkdocs.json b/mcp_docs/modules/docforge.nav.mkdocs.json deleted file mode 100644 index a5da244..0000000 --- a/mcp_docs/modules/docforge.nav.mkdocs.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "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.", - "objects": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.nav.mkdocs.Path", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.mkdocs.List", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.mkdocs.Dict", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.nav.mkdocs.Any", - "signature": "", - "docstring": null - }, - "ResolvedNav": { - "name": "ResolvedNav", - "kind": "class", - "path": "docforge.nav.mkdocs.ResolvedNav", - "signature": "", - "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": "", - "docstring": null - }, - "groups": { - "name": "groups", - "kind": "attribute", - "path": "docforge.nav.mkdocs.ResolvedNav.groups", - "signature": "", - "docstring": null - }, - "all_files": { - "name": "all_files", - "kind": "function", - "path": "docforge.nav.mkdocs.ResolvedNav.all_files", - "signature": "", - "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." - } - } - }, - "MkDocsNavEmitter": { - "name": "MkDocsNavEmitter", - "kind": "class", - "path": "docforge.nav.mkdocs.MkDocsNavEmitter", - "signature": "", - "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": "", - "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." - } - } - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.nav.resolver.json b/mcp_docs/modules/docforge.nav.resolver.json deleted file mode 100644 index 1f75460..0000000 --- a/mcp_docs/modules/docforge.nav.resolver.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "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.", - "objects": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.nav.resolver.Path", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.resolver.Dict", - "signature": "", - "docstring": null - }, - "Iterable": { - "name": "Iterable", - "kind": "alias", - "path": "docforge.nav.resolver.Iterable", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.resolver.List", - "signature": "", - "docstring": null - }, - "glob": { - "name": "glob", - "kind": "alias", - "path": "docforge.nav.resolver.glob", - "signature": "", - "docstring": null - }, - "NavSpec": { - "name": "NavSpec", - "kind": "class", - "path": "docforge.nav.resolver.NavSpec", - "signature": "", - "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.", - "members": { - "home": { - "name": "home", - "kind": "attribute", - "path": "docforge.nav.resolver.NavSpec.home", - "signature": "", - "docstring": null - }, - "groups": { - "name": "groups", - "kind": "attribute", - "path": "docforge.nav.resolver.NavSpec.groups", - "signature": "", - "docstring": null - }, - "load": { - "name": "load", - "kind": "function", - "path": "docforge.nav.resolver.NavSpec.load", - "signature": "", - "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." - }, - "all_patterns": { - "name": "all_patterns", - "kind": "function", - "path": "docforge.nav.resolver.NavSpec.all_patterns", - "signature": "", - "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." - } - } - }, - "ResolvedNav": { - "name": "ResolvedNav", - "kind": "class", - "path": "docforge.nav.resolver.ResolvedNav", - "signature": "", - "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": "", - "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." - } - } - }, - "resolve_nav": { - "name": "resolve_nav", - "kind": "function", - "path": "docforge.nav.resolver.resolve_nav", - "signature": "", - "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": "", - "docstring": null - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.nav.spec.json b/mcp_docs/modules/docforge.nav.spec.json deleted file mode 100644 index d434545..0000000 --- a/mcp_docs/modules/docforge.nav.spec.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "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``).", - "objects": { - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.nav.spec.Path", - "signature": "", - "docstring": null - }, - "Dict": { - "name": "Dict", - "kind": "alias", - "path": "docforge.nav.spec.Dict", - "signature": "", - "docstring": null - }, - "List": { - "name": "List", - "kind": "alias", - "path": "docforge.nav.spec.List", - "signature": "", - "docstring": null - }, - "Optional": { - "name": "Optional", - "kind": "alias", - "path": "docforge.nav.spec.Optional", - "signature": "", - "docstring": null - }, - "yaml": { - "name": "yaml", - "kind": "alias", - "path": "docforge.nav.spec.yaml", - "signature": "", - "docstring": null - }, - "NavSpec": { - "name": "NavSpec", - "kind": "class", - "path": "docforge.nav.spec.NavSpec", - "signature": "", - "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.", - "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 - }, - "load": { - "name": "load", - "kind": "function", - "path": "docforge.nav.spec.NavSpec.load", - "signature": "", - "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." - }, - "all_patterns": { - "name": "all_patterns", - "kind": "function", - "path": "docforge.nav.spec.NavSpec.all_patterns", - "signature": "", - "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." - } - } - }, - "load_nav_spec": { - "name": "load_nav_spec", - "kind": "function", - "path": "docforge.nav.spec.load_nav_spec", - "signature": "", - "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." - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/modules/docforge.servers.mcp_server.json b/mcp_docs/modules/docforge.servers.mcp_server.json deleted file mode 100644 index e5ba618..0000000 --- a/mcp_docs/modules/docforge.servers.mcp_server.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "module": "docforge.servers.mcp_server", - "content": { - "path": "docforge.servers.mcp_server", - "docstring": "# Summary\n\nMCP server implementation.\n\nThis module defines the `MCPServer` class, which serves pre-generated\ndocumentation bundles through the Model Context Protocol (MCP).", - "objects": { - "annotations": { - "name": "annotations", - "kind": "alias", - "path": "docforge.servers.mcp_server.annotations", - "signature": "", - "docstring": null - }, - "json": { - "name": "json", - "kind": "alias", - "path": "docforge.servers.mcp_server.json", - "signature": "", - "docstring": null - }, - "Path": { - "name": "Path", - "kind": "alias", - "path": "docforge.servers.mcp_server.Path", - "signature": "", - "docstring": null - }, - "Any": { - "name": "Any", - "kind": "alias", - "path": "docforge.servers.mcp_server.Any", - "signature": "", - "docstring": null - }, - "Literal": { - "name": "Literal", - "kind": "alias", - "path": "docforge.servers.mcp_server.Literal", - "signature": "", - "docstring": null - }, - "FastMCP": { - "name": "FastMCP", - "kind": "alias", - "path": "docforge.servers.mcp_server.FastMCP", - "signature": "", - "docstring": null - }, - "MCPServer": { - "name": "MCPServer", - "kind": "class", - "path": "docforge.servers.mcp_server.MCPServer", - "signature": "", - "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.", - "members": { - "mcp_root": { - "name": "mcp_root", - "kind": "attribute", - "path": "docforge.servers.mcp_server.MCPServer.mcp_root", - "signature": null, - "docstring": null - }, - "app": { - "name": "app", - "kind": "attribute", - "path": "docforge.servers.mcp_server.MCPServer.app", - "signature": null, - "docstring": null - }, - "run": { - "name": "run", - "kind": "function", - "path": "docforge.servers.mcp_server.MCPServer.run", - "signature": "", - "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`." - } - } - } - } - } -} \ No newline at end of file diff --git a/mcp_docs/nav.json b/mcp_docs/nav.json deleted file mode 100644 index c3c9367..0000000 --- a/mcp_docs/nav.json +++ /dev/null @@ -1,90 +0,0 @@ -[ - { - "module": "docforge", - "resource": "doc://modules/docforge" - }, - { - "module": "docforge.cli", - "resource": "doc://modules/docforge.cli" - }, - { - "module": "docforge.cli.commands", - "resource": "doc://modules/docforge.cli.commands" - }, - { - "module": "docforge.cli.main", - "resource": "doc://modules/docforge.cli.main" - }, - { - "module": "docforge.cli.mcp_utils", - "resource": "doc://modules/docforge.cli.mcp_utils" - }, - { - "module": "docforge.cli.mkdocs_utils", - "resource": "doc://modules/docforge.cli.mkdocs_utils" - }, - { - "module": "docforge.loaders", - "resource": "doc://modules/docforge.loaders" - }, - { - "module": "docforge.loaders.griffe_loader", - "resource": "doc://modules/docforge.loaders.griffe_loader" - }, - { - "module": "docforge.models", - "resource": "doc://modules/docforge.models" - }, - { - "module": "docforge.models.module", - "resource": "doc://modules/docforge.models.module" - }, - { - "module": "docforge.models.object", - "resource": "doc://modules/docforge.models.object" - }, - { - "module": "docforge.models.project", - "resource": "doc://modules/docforge.models.project" - }, - { - "module": "docforge.nav", - "resource": "doc://modules/docforge.nav" - }, - { - "module": "docforge.nav.mkdocs", - "resource": "doc://modules/docforge.nav.mkdocs" - }, - { - "module": "docforge.nav.resolver", - "resource": "doc://modules/docforge.nav.resolver" - }, - { - "module": "docforge.nav.spec", - "resource": "doc://modules/docforge.nav.spec" - }, - { - "module": "docforge.renderers", - "resource": "doc://modules/docforge.renderers" - }, - { - "module": "docforge.renderers.base", - "resource": "doc://modules/docforge.renderers.base" - }, - { - "module": "docforge.renderers.mcp_renderer", - "resource": "doc://modules/docforge.renderers.mcp_renderer" - }, - { - "module": "docforge.renderers.mkdocs_renderer", - "resource": "doc://modules/docforge.renderers.mkdocs_renderer" - }, - { - "module": "docforge.servers", - "resource": "doc://modules/docforge.servers" - }, - { - "module": "docforge.servers.mcp_server", - "resource": "doc://modules/docforge.servers.mcp_server" - } -] \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 4bd4257..2699576 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "doc-forge" -version = "0.0.6" +version = "0.0.7" description = "A renderer-agnostic Python documentation compiler" readme = "README.md" requires-python = ">=3.10" @@ -17,6 +17,19 @@ authors = [ maintainers = [ { name = "Aetos Skia", email = "dev@aetoskia.com" } ] + + +keywords = [ + "documentation", + "docs", + "compiler", + "mkdocs", + "mcp", + "griffe", + "docstrings", + "sphinx", +] + classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", @@ -25,9 +38,12 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Framework :: FastAPI", "Topic :: Software Development :: Libraries", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", + "Topic :: Documentation", + "Typing :: Typed", ] @@ -51,20 +67,33 @@ mkdocs = [ "pymdown-extensions==10.16.1", "neoteroi-mkdocs==1.1.3", + "mkdocs-swagger-ui-tag>=0.3.0", ] sphinx = [ "sphinx>=5.0.0", "sphinx-autodoc-typehints>=1.19.0", ] mcp = [ - "mcp>=1.0.0", + "mcp>=1.0.0,<2.0.0", ] dev = [ - "pytest>=7.0.0", - "pytest-cov>=4.0.0", + "pytest>=8.0.0", + "pytest-asyncio>=0.21.0", + "pytest-cov>=4.1.0", "black>=23.0.0", - "ruff>=0.1.0", - "mypy>=1.0.0", + "ruff>=0.3.0", + "mypy>=1.8.0", + "pydoclint>=0.9.1", + "build>=1.0.0", + "twine>=4.0.0", + "pre-commit>=3.4.0", +] +docs = [ + "doc-forge[mkdocs]", +] + +all = [ + "doc-forge[dev,docs,mcp]", ] @@ -80,15 +109,108 @@ Versions = "https://git.aetoskia.com/aetos/doc-forge/tags" packages = { find = { include = ["docforge*"] } } [tool.setuptools.package-data] -docforge = ["templates/*.yml"] +docforge = ["py.typed", "templates/*.yml"] + + +[tool.pytest.ini_options] +testpaths = ["tests"] +asyncio_mode = "auto" +python_files = ["test_*.py"] +python_classes = ["Test*"] +python_functions = ["test_*"] +addopts = [ + "--strict-markers", + "--strict-config", + "--cov=docforge", + "--cov-report=term-missing", + "--cov-report=html", + "--cov-report=xml", +] + + +[tool.black] +line-length = 88 +target-version = ["py310", "py311", "py312", "py313"] +include = '\.pyi?$' +extend-exclude = ''' +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | build + | dist +)/ +''' [tool.ruff] -line-length = 100 +line-length = 88 target-version = "py310" +[tool.ruff.lint] +select = [ + "E", + "W", + "F", + "I", + "B", + "C4", + "UP", +] +ignore = [ + "E501", + "B008", + "C901", +] + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["F401", "I001"] +"tests/*" = ["B008"] + [tool.mypy] python_version = "3.10" strict = true +exclude = [ + "tests/", +] +files = ["docforge"] + +[[tool.mypy.overrides]] +module = [ + "griffe.*", + "mcp.*", + "click", + "pydantic", +] ignore_missing_imports = true + + +[tool.pydoclint] +style = "google" +exclude = '\.pyi$|tests/' +allow-init-docstring = true +skip-checking-raises = true +check-class-attributes = false + + +[tool.coverage.run] +source = ["docforge"] +omit = [ + "*/tests/*", + "*/test_*.py", +] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "if __name__ == .__main__.:", + "raise AssertionError", + "raise NotImplementedError", + "if TYPE_CHECKING:", + "@abstractmethod", +] \ No newline at end of file diff --git a/tests/cli/test_build_api.py b/tests/cli/test_build_api.py new file mode 100644 index 0000000..83c7446 --- /dev/null +++ b/tests/cli/test_build_api.py @@ -0,0 +1,142 @@ +import json +from pathlib import Path + +from docforge.cli.main import cli + + +def _write_spec(cwd, title="Aetoskia Auth Server", description="Auth docs"): + spec = { + "openapi": "3.1.0", + "info": { + "title": title, + "description": description, + "contact": { + "name": "Aetoskia Dev Team", + "email": "dev@aetoskia.com", + }, + "version": "0.0.5", + }, + "paths": {}, + } + path = cwd / "openapi.json" + path.write_text(json.dumps(spec), encoding="utf-8") + return path + + +def test_api_build_full_flow( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + spec_path = _write_spec(cwd) + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text( + "home: api/index.md\ngroups: {}\n" + "icon:\n" + " logo: material/database\n" + " repo: fontawesome/brands/github\n", + encoding="utf-8", + ) + + result = cli_runner.invoke( + cli, + ["build", "--api", "--openapi-spec", str(spec_path)], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + + api_dir = cwd / "docs" / "api" + assert (api_dir / "openapi.json").exists() + index = (api_dir / "index.md").read_text(encoding="utf-8") + assert '' in index + + config = (cwd / "docs" / "mkdocs.api.yml").read_text(encoding="utf-8") + assert "docs_dir: api" in config + assert "site_dir: ../site/api" in config + assert "- API Reference: index.md" in config + assert "site_name: Aetoskia Auth Server" in config + assert "site_description: Auth docs" in config + assert "site_author: Aetoskia Dev Team" in config + assert "swagger-ui-tag" in config + assert "logo: material/database" in config + assert "repo: fontawesome/brands/github" in config + + +def test_api_build_missing_spec_fails(cli_runner): + result = cli_runner.invoke(cli, ["build", "--api"]) + assert result.exit_code != 0 + assert "--openapi-spec is required" in result.output + + +def test_api_build_spec_not_found(cli_runner): + result = cli_runner.invoke(cli, ["build", "--api", "--openapi-spec", "nope.json"]) + assert result.exit_code != 0 + assert "OpenAPI spec not found" in result.output + + +def test_api_build_rejects_site_name_override(cli_runner): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + spec_path = _write_spec(cwd) + + result = cli_runner.invoke( + cli, + ["build", "--api", "--openapi-spec", str(spec_path), "--site-name", "X"], + ) + assert result.exit_code != 0 + assert "cannot be overridden" in result.output + + +def test_api_build_combined_with_mkdocs_emits_separate_configs( + cli_runner, mock_mkdocs_build, mock_mkdocs_load_config +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + pkg = cwd / "testpkg" + pkg.mkdir() + (pkg / "__init__.py").write_text("") + (pkg / "mod.py").write_text("def f(): ...\n") + + spec_path = _write_spec(cwd) + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text("home: lib/testpkg/index.md\ngroups: {}\n") + + result = cli_runner.invoke( + cli, + [ + "build", + "--mkdocs", + "--api", + "--module", + "testpkg", + "--openapi-spec", + str(spec_path), + ], + ) + + assert result.exit_code == 0, result.output + + lib_config = cwd / "docs" / "mkdocs.lib.yml" + api_config = cwd / "docs" / "mkdocs.api.yml" + assert lib_config.exists() + assert api_config.exists() + + lib_text = lib_config.read_text(encoding="utf-8") + assert "docs_dir: lib" in lib_text + assert "site_dir: ../site/lib" in lib_text + assert "Home: testpkg/index.md" in lib_text + + api_text = api_config.read_text(encoding="utf-8") + assert "docs_dir: api" in api_text + assert "site_dir: ../site/api" in api_text + assert "- API Reference: index.md" in api_text + assert "site_name: Aetoskia Auth Server" in api_text + assert "swagger-ui-tag" in api_text + assert "mkdocstrings" in lib_text diff --git a/tests/cli/test_build_mcp.py b/tests/cli/test_build_mcp.py index f783945..88ff93e 100644 --- a/tests/cli/test_build_mcp.py +++ b/tests/cli/test_build_mcp.py @@ -1,6 +1,8 @@ from pathlib import Path + from docforge.cli.main import cli + def test_mcp_build(cli_runner): with cli_runner.isolated_filesystem(): cwd = Path.cwd() @@ -9,7 +11,7 @@ def test_mcp_build(cli_runner): (pkg / "__init__.py").write_text("") (pkg / "mod.py").write_text("def f(): ...\n") - out_dir = cwd / "mcp_docs" + out_dir = cwd / "docs" / "mcp" result = cli_runner.invoke( cli, @@ -18,8 +20,6 @@ def test_mcp_build(cli_runner): "--mcp", "--module", "testpkg", - "--out-dir", - str(out_dir), ], ) diff --git a/tests/cli/test_build_mkdocs.py b/tests/cli/test_build_mkdocs.py index a84722f..b65489e 100644 --- a/tests/cli/test_build_mkdocs.py +++ b/tests/cli/test_build_mkdocs.py @@ -1,6 +1,8 @@ from pathlib import Path + from docforge.cli.main import cli + def test_mkdocs_build_full_flow( cli_runner, mock_mkdocs_build, @@ -16,12 +18,8 @@ def test_mkdocs_build_full_flow( (pkg / "mod.py").write_text("def f(): ...\n") nav_file = cwd / "docforge.nav.yml" - nav_file.write_text("home: testpkg/index.md\ngroups: {}\n") - - # We need to create a dummy testpkg/index.md for nav resolution if it's there - # But generate_sources will create it. - # Wait, the current logic runs generate_sources first, THEN generate_config. - + nav_file.write_text("home: lib/testpkg/index.md\ngroups: {}\n") + result = cli_runner.invoke( cli, [ @@ -31,23 +29,27 @@ def test_mkdocs_build_full_flow( "testpkg", "--site-name", "Test Site", - "--docs-dir", - "docs", - "--mkdocs-yml", - "mkdocs.yml", ], ) assert result.exit_code == 0 assert mock_mkdocs_build() is True - assert (cwd / "mkdocs.yml").exists() - assert (cwd / "docs" / "testpkg" / "mod.md").exists() + + config = cwd / "docs" / "mkdocs.lib.yml" + assert config.exists() + assert (cwd / "docs" / "lib" / "testpkg" / "mod.md").exists() + content = config.read_text(encoding="utf-8") + assert "docs_dir: lib" in content + assert "site_dir: ../site/lib" in content + assert "Home: testpkg/index.md" in content + def test_mkdocs_build_missing_module_fails(cli_runner): result = cli_runner.invoke(cli, ["build", "--mkdocs", "--site-name", "Test"]) assert result.exit_code != 0 assert "--module is required" in result.output + def test_mkdocs_build_without_site_name_uses_module_as_default_full_flow( cli_runner, mock_mkdocs_build, @@ -63,37 +65,98 @@ def test_mkdocs_build_without_site_name_uses_module_as_default_full_flow( (pkg / "__init__.py").write_text("") (pkg / "mod.py").write_text("def f(): ...\n") - # Create nav spec expected by generate_config + # Create nav spec expected by build_lib_nav nav_file = cwd / "docforge.nav.yml" nav_file.write_text( - "home: testpkg/index.md\ngroups: {}\n", + "home: lib/testpkg/index.md\ngroups: {}\n", encoding="utf-8", ) result = cli_runner.invoke( cli, - [ - "build", - "--mkdocs", - "--module", - "testpkg", - "--docs-dir", - "docs", - "--mkdocs-yml", - "mkdocs.yml", - ], + ["build", "--mkdocs", "--module", "testpkg"], ) assert result.exit_code == 0 assert mock_mkdocs_build() is True - # MkDocs config must exist - mkdocs_yml = cwd / "mkdocs.yml" - assert mkdocs_yml.exists() + # The per-kind MkDocs config must exist + config = cwd / "docs" / "mkdocs.lib.yml" + assert config.exists() # Site name must default to module name - content = mkdocs_yml.read_text() + content = config.read_text(encoding="utf-8") assert "site_name: testpkg" in content - # Docs must be generated - assert (cwd / "docs" / "testpkg" / "mod.md").exists() + # Docs must be generated under the nested docs/lib dir + assert (cwd / "docs" / "lib" / "testpkg" / "mod.md").exists() + + +def test_existing_lib_config_used_verbatim_without_refresh( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + pkg = cwd / "testpkg" + pkg.mkdir() + (pkg / "__init__.py").write_text("") + (pkg / "mod.py").write_text("def f(): ...\n") + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text( + "home: lib/testpkg/index.md\ngroups: {}\n", + encoding="utf-8", + ) + + config = cwd / "docs" / "mkdocs.lib.yml" + config.parent.mkdir(parents=True) + sentinel = "site_name: Custom Lib\nnav: []\n" + config.write_text(sentinel, encoding="utf-8") + + result = cli_runner.invoke( + cli, + ["build", "--mkdocs", "--module", "testpkg"], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + assert config.read_text(encoding="utf-8") == sentinel + assert "Using existing MkDocs config" in result.output + + +def test_refresh_rebases_existing_lib_config( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + pkg = cwd / "testpkg" + pkg.mkdir() + (pkg / "__init__.py").write_text("") + (pkg / "mod.py").write_text("def f(): ...\n") + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text( + "home: lib/testpkg/index.md\ngroups: {}\n", + encoding="utf-8", + ) + + config = cwd / "docs" / "mkdocs.lib.yml" + config.parent.mkdir(parents=True) + config.write_text("site_name: Stale\nnav: []\n", encoding="utf-8") + + result = cli_runner.invoke( + cli, + ["build", "--mkdocs", "--module", "testpkg", "--refresh"], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + content = config.read_text(encoding="utf-8") + assert "site_name: testpkg" in content + assert "docs_dir: lib" in content + assert "site_dir: ../site/lib" in content + assert "Home: testpkg/index.md" in content diff --git a/tests/cli/test_build_wiki.py b/tests/cli/test_build_wiki.py new file mode 100644 index 0000000..811babf --- /dev/null +++ b/tests/cli/test_build_wiki.py @@ -0,0 +1,165 @@ +from pathlib import Path + +from docforge.cli.main import cli + + +def test_wiki_only_build_requires_no_module( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + wiki = cwd / "docs" / "wiki" + wiki.mkdir(parents=True) + (wiki / "index.md").write_text("# Home", encoding="utf-8") + (wiki / "01_overview.md").write_text("# Overview", encoding="utf-8") + + result = cli_runner.invoke( + cli, + [ + "build", + "--wiki", + "--site-name", + "Wiki Site", + ], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + config = cwd / "docs" / "mkdocs.wiki.yml" + assert config.exists() + + content = config.read_text(encoding="utf-8") + assert "docs_dir: wiki" in content + assert "site_dir: ../site/wiki" in content + assert "Home: index.md" in content + assert "Overview: 01_overview.md" in content + + +def test_wiki_and_mkdocs_emit_separate_configs( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + pkg = cwd / "testpkg" + pkg.mkdir() + (pkg / "__init__.py").write_text("") + (pkg / "mod.py").write_text("def f(): ...\n") + + nav_file = cwd / "docforge.nav.yml" + nav_file.write_text( + "home: lib/testpkg/index.md\ngroups: {}\n", + encoding="utf-8", + ) + + wiki = cwd / "docs" / "wiki" + wiki.mkdir(parents=True) + (wiki / "index.md").write_text("# Home", encoding="utf-8") + + result = cli_runner.invoke( + cli, + [ + "build", + "--mkdocs", + "--wiki", + "--module", + "testpkg", + "--site-name", + "Split Site", + ], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + assert (cwd / "docs" / "lib" / "testpkg" / "mod.md").exists() + + lib_config = (cwd / "docs" / "mkdocs.lib.yml").read_text(encoding="utf-8") + wiki_config = (cwd / "docs" / "mkdocs.wiki.yml").read_text(encoding="utf-8") + + assert "docs_dir: lib" in lib_config + assert "site_dir: ../site/lib" in lib_config + assert "Home: testpkg/index.md" in lib_config + + assert "docs_dir: wiki" in wiki_config + assert "site_dir: ../site/wiki" in wiki_config + assert "Home: index.md" in wiki_config + + +def test_wiki_without_module_flag_ok( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + wiki = cwd / "docs" / "wiki" + wiki.mkdir(parents=True) + (wiki / "index.md").write_text("# Home", encoding="utf-8") + + result = cli_runner.invoke( + cli, + ["build", "--wiki", "--site-name", "S"], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + + +def test_wiki_existing_config_used_verbatim_without_refresh( + cli_runner, + mock_mkdocs_build, + mock_mkdocs_load_config, +): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + + wiki = cwd / "docs" / "wiki" + wiki.mkdir(parents=True) + (wiki / "index.md").write_text("# Home", encoding="utf-8") + + config = cwd / "docs" / "mkdocs.wiki.yml" + sentinel = "site_name: Custom Wiki\nnav: []\n" + config.write_text(sentinel, encoding="utf-8") + + result = cli_runner.invoke( + cli, + ["build", "--wiki", "--site-name", "Wiki Site"], + ) + + assert result.exit_code == 0, result.output + assert mock_mkdocs_build() is True + assert config.read_text(encoding="utf-8") == sentinel + assert "Using existing MkDocs config" in result.output + + +def test_missing_wiki_dir_errors(cli_runner, mock_mkdocs_build): + with cli_runner.isolated_filesystem(): + cwd = Path.cwd() + (cwd / "docs").mkdir() + + result = cli_runner.invoke( + cli, + [ + "build", + "--wiki", + "--site-name", + "S", + "--wiki-dir", + "docs/wiki", + ], + ) + + assert result.exit_code != 0 + assert "Wiki dir not found" in result.output + + +def test_no_flag_raises_usage_error(cli_runner): + result = cli_runner.invoke(cli, ["build"]) + assert result.exit_code != 0 + assert "--mcp, --mkdocs, --wiki, or --api" in result.output diff --git a/tests/cli/test_mkdocs_utils.py b/tests/cli/test_mkdocs_utils.py new file mode 100644 index 0000000..6e1ccea --- /dev/null +++ b/tests/cli/test_mkdocs_utils.py @@ -0,0 +1,79 @@ +import pytest +from click.exceptions import FileError + +from docforge.cli.mkdocs_utils import ( + _strip_scope, + build_lib_nav, + build_wiki_nav_block, + load_spec_icon, +) + + +def test_strip_scope_nested_entries(): + block = [ + {"Home": "wiki/index.md"}, + { + "Development": [ + {"Environment": "wiki/05_development/01_environment.md"}, + "wiki/05_development/02_quality_gates.md", + ] + }, + ] + stripped = _strip_scope(block, "wiki") + assert stripped == [ + {"Home": "index.md"}, + { + "Development": [ + {"Environment": "05_development/01_environment.md"}, + "05_development/02_quality_gates.md", + ] + }, + ] + + +def test_strip_scope_leaves_unscoped_paths(): + block = [{"Other": "static/pages.md"}] + assert _strip_scope(block, "lib") == [{"Other": "static/pages.md"}] + + +def test_build_lib_nav_reroots_group_paths(tmp_path): + docs = tmp_path / "docs" + lib = docs / "lib" / "testpkg" + lib.mkdir(parents=True) + (lib / "index.md").write_text("# Pkg", encoding="utf-8") + (lib / "mod.md").write_text("# Mod", encoding="utf-8") + + nav_file = tmp_path / "docforge.nav.yml" + nav_file.write_text( + "home: lib/testpkg/index.md\n" + "groups:\n" + " Reference:\n" + " - lib/testpkg/mod.md\n", + encoding="utf-8", + ) + + block, icon = build_lib_nav(nav_file, docs) + assert block == [{"Home": "testpkg/index.md"}, {"Reference": ["testpkg/mod.md"]}] + assert icon is None + + +def test_build_lib_nav_missing_spec_raises(tmp_path): + with pytest.raises(FileError): + build_lib_nav(tmp_path / "missing.yml", tmp_path) + + +def test_build_wiki_nav_block_reroots_entries(tmp_path): + wiki = tmp_path / "docs" / "wiki" + wiki.mkdir(parents=True) + (wiki / "index.md").write_text("# Home", encoding="utf-8") + (wiki / "01_overview.md").write_text("# Overview", encoding="utf-8") + + block = build_wiki_nav_block(wiki) + assert block == [{"Home": "index.md"}, {"Overview": "01_overview.md"}] + + +def test_load_spec_icon(tmp_path): + nav_file = tmp_path / "docforge.nav.yml" + nav_file.write_text("home: index.md\nicon:\n logo: material/code-tags\n") + assert load_spec_icon(nav_file) == {"logo": "material/code-tags"} + assert load_spec_icon(tmp_path / "missing.yml") is None diff --git a/tests/cli/test_serve_mcp.py b/tests/cli/test_serve_mcp.py index 4e0db66..4e82ff0 100644 --- a/tests/cli/test_serve_mcp.py +++ b/tests/cli/test_serve_mcp.py @@ -1,5 +1,6 @@ from docforge.cli.main import cli + def test_mcp_serve( cli_runner, fake_mcp_docs, diff --git a/tests/cli/test_serve_mkdocs.py b/tests/cli/test_serve_mkdocs.py index 7ac9261..fa6415f 100644 --- a/tests/cli/test_serve_mkdocs.py +++ b/tests/cli/test_serve_mkdocs.py @@ -1,5 +1,6 @@ from docforge.cli.main import cli + def test_mkdocs_serve( cli_runner, fake_mkdocs_yml, diff --git a/tests/conftest.py b/tests/conftest.py index e3973b7..178441d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,8 @@ -import sys import json -import pytest +import sys from pathlib import Path +import pytest from click.testing import CliRunner @@ -45,6 +45,7 @@ plugins: @pytest.fixture def mock_mkdocs_load_config(monkeypatch): """Mock mkdocs.config.load_config.""" + def fake_load_config(path): return object() # dummy config object @@ -81,6 +82,7 @@ def mock_mkdocs_serve(monkeypatch): ) return lambda: called["value"] + @pytest.fixture def fake_mcp_docs(tmp_path: Path) -> Path: """ diff --git a/tests/introspection/test_alias_safety.py b/tests/introspection/test_alias_safety.py index 599a663..055af78 100644 --- a/tests/introspection/test_alias_safety.py +++ b/tests/introspection/test_alias_safety.py @@ -2,11 +2,9 @@ from docforge import GriffeLoader def test_alias_does_not_crash(temp_package): - (temp_package / "alias.py").write_text( - '''from typing import List + (temp_package / "alias.py").write_text("""from typing import List Alias = List[int] -''' - ) +""") loader = GriffeLoader() project = loader.load_project(["testpkg.alias"]) diff --git a/tests/introspection/test_classes_and_methods.py b/tests/introspection/test_classes_and_methods.py index 759652c..dbe2ea1 100644 --- a/tests/introspection/test_classes_and_methods.py +++ b/tests/introspection/test_classes_and_methods.py @@ -2,15 +2,13 @@ from docforge import GriffeLoader def test_class_and_methods(temp_package): - (temp_package / "cls.py").write_text( - '''class MyClass: + (temp_package / "cls.py").write_text('''class MyClass: """Class doc.""" def method(self, x: int) -> int: """Method doc.""" return x -''' - ) +''') loader = GriffeLoader() project = loader.load_project(["testpkg.cls"]) diff --git a/tests/introspection/test_functions_and_signatures.py b/tests/introspection/test_functions_and_signatures.py index 221ecb1..5164c5b 100644 --- a/tests/introspection/test_functions_and_signatures.py +++ b/tests/introspection/test_functions_and_signatures.py @@ -2,12 +2,10 @@ from docforge import GriffeLoader def test_function_signature(temp_package): - (temp_package / "fn.py").write_text( - '''def add(a: int, b: int = 1) -> int: + (temp_package / "fn.py").write_text('''def add(a: int, b: int = 1) -> int: """Adds numbers.""" return a + b -''' - ) +''') loader = GriffeLoader() project = loader.load_project(["testpkg.fn"]) diff --git a/tests/introspection/test_import_failures.py b/tests/introspection/test_import_failures.py index 8f80b71..acfc9a2 100644 --- a/tests/introspection/test_import_failures.py +++ b/tests/introspection/test_import_failures.py @@ -1,4 +1,5 @@ import pytest + from docforge import GriffeLoader @@ -6,9 +7,8 @@ def test_load_project_raises_on_missing_module_by_default(): loader = GriffeLoader() with pytest.raises(ImportError): - loader.load_project( - ["nonexistent.module", "sys"] - ) + loader.load_project(["nonexistent.module", "sys"]) + def test_load_project_skips_missing_modules_when_enabled(): loader = GriffeLoader() @@ -18,4 +18,4 @@ def test_load_project_skips_missing_modules_when_enabled(): skip_import_errors=True, ) - assert "sys" in project.modules \ No newline at end of file + assert "sys" in project.modules diff --git a/tests/introspection/test_missing_docstrings.py b/tests/introspection/test_missing_docstrings.py index 05e8499..97c18bf 100644 --- a/tests/introspection/test_missing_docstrings.py +++ b/tests/introspection/test_missing_docstrings.py @@ -2,9 +2,7 @@ from docforge import GriffeLoader def test_missing_docstrings(temp_package): - (temp_package / "nodoc.py").write_text( - '''def f(): pass''' - ) + (temp_package / "nodoc.py").write_text("""def f(): pass""") loader = GriffeLoader() project = loader.load_project(["testpkg.nodoc"]) diff --git a/tests/introspection/test_private_members.py b/tests/introspection/test_private_members.py index a7aae6d..a77b395 100644 --- a/tests/introspection/test_private_members.py +++ b/tests/introspection/test_private_members.py @@ -2,11 +2,9 @@ from docforge import GriffeLoader def test_private_members_excluded(temp_package): - (temp_package / "priv.py").write_text( - '''def _hidden(): pass + (temp_package / "priv.py").write_text("""def _hidden(): pass def visible(): pass -''' - ) +""") loader = GriffeLoader() project = loader.load_project(["testpkg.priv"]) diff --git a/tests/introspection/test_single_module.py b/tests/introspection/test_single_module.py index 3358f85..060f68c 100644 --- a/tests/introspection/test_single_module.py +++ b/tests/introspection/test_single_module.py @@ -2,13 +2,11 @@ from docforge import GriffeLoader def test_load_single_module(temp_package): - (temp_package / "mod.py").write_text( - '''"""Module docstring."""\n + (temp_package / "mod.py").write_text('''"""Module docstring."""\n def foo(): """Foo docstring.""" pass -''' - ) +''') loader = GriffeLoader() project = loader.load_project(["testpkg.mod"]) diff --git a/tests/nav/test_mkdocs.py b/tests/nav/test_mkdocs.py index 2022208..d275418 100644 --- a/tests/nav/test_mkdocs.py +++ b/tests/nav/test_mkdocs.py @@ -1,7 +1,6 @@ from pathlib import Path -from docforge.nav import ResolvedNav -from docforge.nav import MkDocsNavEmitter +from docforge.nav import MkDocsNavEmitter, ResolvedNav def test_emit_mkdocs_nav(): diff --git a/tests/nav/test_resolver.py b/tests/nav/test_resolver.py index 260d95a..77eb10a 100644 --- a/tests/nav/test_resolver.py +++ b/tests/nav/test_resolver.py @@ -2,8 +2,7 @@ from pathlib import Path import pytest -from docforge.nav import NavSpec -from docforge.nav import resolve_nav +from docforge.nav import NavSpec, resolve_nav def _write_docs(root: Path, paths: list[str]) -> None: diff --git a/tests/nav/test_wiki.py b/tests/nav/test_wiki.py new file mode 100644 index 0000000..5d0fe0c --- /dev/null +++ b/tests/nav/test_wiki.py @@ -0,0 +1,106 @@ +from pathlib import Path + +import pytest + +from docforge.nav import build_wiki_nav + + +def _write_wiki(root: Path, files: list[str]) -> None: + for rel in files: + full = root / rel + full.parent.mkdir(parents=True, exist_ok=True) + full.write_text(f"# {rel}", encoding="utf-8") + + +def test_missing_wiki_dir_raises(tmp_path: Path): + with pytest.raises(FileNotFoundError): + build_wiki_nav(tmp_path / "nope") + + +def test_empty_wiki_dir_returns_empty(tmp_path: Path): + wiki = tmp_path / "wiki" + wiki.mkdir() + + assert build_wiki_nav(wiki) == [] + + +def test_index_becomes_home(tmp_path: Path): + wiki = tmp_path / "docs" / "wiki" + _write_wiki(wiki, ["index.md", "01_overview.md"]) + + nav = build_wiki_nav(wiki) + + assert nav[0] == {"Home": "wiki/index.md"} + assert {"Overview": "wiki/01_overview.md"} in nav + + +def test_number_prefix_stripped_and_prettified(tmp_path: Path): + wiki = tmp_path / "docs" / "wiki" + _write_wiki(wiki, ["01_basic_crud.md", "02_custom_repo.md", "10_transactions.md"]) + + nav = build_wiki_nav(wiki) + + labels = [list(entry)[0] for entry in nav] + assert labels == ["Basic Crud", "Custom Repo", "Transactions"] + + +def test_directory_becomes_nested_group(tmp_path: Path): + wiki = tmp_path / "docs" / "wiki" + _write_wiki( + wiki, + [ + "index.md", + "03_use_cases/01_basic_crud.md", + "03_use_cases/02_custom_repo.md", + ], + ) + + nav = build_wiki_nav(wiki) + + assert {"Home": "wiki/index.md"} in nav + assert { + "Use Cases": [ + {"Basic Crud": "wiki/03_use_cases/01_basic_crud.md"}, + {"Custom Repo": "wiki/03_use_cases/02_custom_repo.md"}, + ] + } in nav + + +def test_nested_index_is_section_root(tmp_path: Path): + wiki = tmp_path / "docs" / "wiki" + _write_wiki( + wiki, + [ + "guide/index.md", + "guide/01_setup.md", + ], + ) + + nav = build_wiki_nav(wiki) + + assert { + "Guide": [ + {"Guide": "wiki/guide/index.md"}, + {"Setup": "wiki/guide/01_setup.md"}, + ] + } in nav + + +def test_hidden_entries_ignored(tmp_path: Path): + wiki = tmp_path / "docs" / "wiki" + _write_wiki(wiki, ["index.md", ".draft.md"]) + (wiki / ".hidden").mkdir() + + nav = build_wiki_nav(wiki) + + assert nav == [{"Home": "wiki/index.md"}] + + +def test_natural_order_for_zero_padded_prefixes(tmp_path: Path): + wiki = tmp_path / "docs" / "wiki" + _write_wiki(wiki, ["02_b.md", "10_j.md", "01_a.md"]) + + nav = build_wiki_nav(wiki) + + labels = [list(entry)[0] for entry in nav if list(entry)[0] in {"A", "B", "J"}] + assert labels == ["A", "B", "J"] diff --git a/tests/renderers/mcp/test_mcp_content.py b/tests/renderers/mcp/test_mcp_content.py index 1a6b5f6..f528e34 100644 --- a/tests/renderers/mcp/test_mcp_content.py +++ b/tests/renderers/mcp/test_mcp_content.py @@ -2,7 +2,7 @@ import json from pathlib import Path from docforge import MCPRenderer -from docforge.models import Project, Module +from docforge.models import Module, Project def test_mcp_file_content(tmp_path: Path): diff --git a/tests/renderers/mcp/test_mcp_idempotency.py b/tests/renderers/mcp/test_mcp_idempotency.py index 2b215bb..cd56ffb 100644 --- a/tests/renderers/mcp/test_mcp_idempotency.py +++ b/tests/renderers/mcp/test_mcp_idempotency.py @@ -1,7 +1,7 @@ from pathlib import Path from docforge import MCPRenderer -from docforge.models import Project, Module +from docforge.models import Module, Project def test_mcp_idempotent(tmp_path: Path): diff --git a/tests/renderers/mcp/test_mcp_module_coverage.py b/tests/renderers/mcp/test_mcp_module_coverage.py index b7623d4..47f373c 100644 --- a/tests/renderers/mcp/test_mcp_module_coverage.py +++ b/tests/renderers/mcp/test_mcp_module_coverage.py @@ -1,7 +1,7 @@ from pathlib import Path -from docforge.loaders import GriffeLoader, discover_module_paths from docforge import MCPRenderer +from docforge.loaders import GriffeLoader, discover_module_paths def test_mcp_emits_all_modules(tmp_path: Path) -> None: @@ -22,10 +22,7 @@ def test_mcp_emits_all_modules(tmp_path: Path) -> None: for p in (tmp_path / "modules").rglob("*.json") } - expected = { - f"modules/{m.path}.json" - for m in project.get_all_modules() - } + expected = {f"modules/{m.path}.json" for m in project.get_all_modules()} missing = expected - emitted assert not missing, f"Missing MCP module JSON files: {missing}" diff --git a/tests/renderers/mcp/test_mcp_signatures.py b/tests/renderers/mcp/test_mcp_signatures.py new file mode 100644 index 0000000..9f2cc09 --- /dev/null +++ b/tests/renderers/mcp/test_mcp_signatures.py @@ -0,0 +1,73 @@ +import json +from pathlib import Path + +from docforge import MCPRenderer +from docforge.loaders import GriffeLoader, discover_module_paths + + +def _load_docforge_bundle(tmp_path: Path) -> Path: + project_root = Path(__file__).resolve().parents[3] + loader = GriffeLoader() + paths = discover_module_paths("docforge", project_root=project_root) + project = loader.load_project(paths) + + out_dir = tmp_path / "mcp" + MCPRenderer().generate_sources(project, out_dir) + return out_dir + + +def test_mcp_signatures_are_clean(tmp_path: Path) -> None: + out_dir = _load_docforge_bundle(tmp_path) + + object_payload = json.loads( + (out_dir / "modules" / "docforge.models.object.json").read_text( + encoding="utf-8" + ) + ) + + cls = object_payload["content"]["objects"]["DocObject"] + assert isinstance(cls["signature"], str) + assert "bound method" not in cls["signature"] + assert cls["signature"].startswith("DocObject(") + + renderer_payload = json.loads( + (out_dir / "modules" / "docforge.renderers.mcp_renderer.json").read_text( + encoding="utf-8" + ) + ) + + method = renderer_payload["content"]["objects"]["MCPRenderer"]["members"][ + "generate_sources" + ] + assert isinstance(method["signature"], str) + assert "bound method" not in method["signature"] + assert method["signature"].startswith("generate_sources(") + + +def test_mcp_skips_unresolvable_import_aliases(tmp_path: Path) -> None: + out_dir = _load_docforge_bundle(tmp_path) + + renderer_payload = json.loads( + (out_dir / "modules" / "docforge.renderers.mcp_renderer.json").read_text( + encoding="utf-8" + ) + ) + + object_names = set(renderer_payload["content"]["objects"]) + assert "json" not in object_names + assert "Path" not in object_names + + +def test_mcp_keeps_resolvable_package_reexports(tmp_path: Path) -> None: + out_dir = _load_docforge_bundle(tmp_path) + + root_payload = json.loads( + (out_dir / "modules" / "docforge.json").read_text(encoding="utf-8") + ) + + discover = root_payload["content"]["objects"]["discover_module_paths"] + assert discover["name"] == "discover_module_paths" + assert isinstance(discover["signature"], str) + assert "bound method" not in discover["signature"] + assert discover["signature"].startswith("discover_module_paths(") + assert discover["docstring"] is not None diff --git a/tests/renderers/mcp/test_mcp_structure.py b/tests/renderers/mcp/test_mcp_structure.py index 341488f..ebf1f9b 100644 --- a/tests/renderers/mcp/test_mcp_structure.py +++ b/tests/renderers/mcp/test_mcp_structure.py @@ -1,7 +1,7 @@ from pathlib import Path from docforge import MCPRenderer -from docforge.models import Project, Module +from docforge.models import Module, Project def test_mcp_directory_structure(tmp_path: Path): diff --git a/tests/renderers/mkdocs/test_mkdocs_content.py b/tests/renderers/mkdocs/test_mkdocs_content.py index 80cee04..733a095 100644 --- a/tests/renderers/mkdocs/test_mkdocs_content.py +++ b/tests/renderers/mkdocs/test_mkdocs_content.py @@ -1,7 +1,7 @@ from pathlib import Path from docforge import MkDocsRenderer -from docforge.models import Project, Module +from docforge.models import Module, Project def test_mkdocs_file_content(tmp_path: Path): @@ -47,4 +47,4 @@ def test_generate_readme_source_root(tmp_path: Path): content = readme.read_text() assert "# testpkg" in content - assert "Test package documentation." in content \ No newline at end of file + assert "Test package documentation." in content diff --git a/tests/renderers/mkdocs/test_mkdocs_idempotency.py b/tests/renderers/mkdocs/test_mkdocs_idempotency.py index f894665..94d2f4d 100644 --- a/tests/renderers/mkdocs/test_mkdocs_idempotency.py +++ b/tests/renderers/mkdocs/test_mkdocs_idempotency.py @@ -1,7 +1,7 @@ from pathlib import Path from docforge import MkDocsRenderer -from docforge.models import Project, Module +from docforge.models import Module, Project def test_mkdocs_idempotent(tmp_path: Path): @@ -50,4 +50,4 @@ def test_generate_readme_idempotent(tmp_path: Path): second = readme.read_text() - assert first == second \ No newline at end of file + assert first == second diff --git a/tests/renderers/mkdocs/test_mkdocs_module_coverage.py b/tests/renderers/mkdocs/test_mkdocs_module_coverage.py index 835096e..bf2f16f 100644 --- a/tests/renderers/mkdocs/test_mkdocs_module_coverage.py +++ b/tests/renderers/mkdocs/test_mkdocs_module_coverage.py @@ -1,7 +1,7 @@ from pathlib import Path -from docforge.loaders import GriffeLoader, discover_module_paths from docforge import MkDocsRenderer +from docforge.loaders import GriffeLoader, discover_module_paths def test_mkdocs_emits_all_modules(tmp_path: Path) -> None: @@ -23,10 +23,7 @@ def test_mkdocs_emits_all_modules(tmp_path: Path) -> None: module_is_source=True, ) - emitted = { - p.relative_to(tmp_path).as_posix() - for p in tmp_path.rglob("*.md") - } + emitted = {p.relative_to(tmp_path).as_posix() for p in tmp_path.rglob("*.md")} module_paths = [m.path for m in project.get_all_modules()] @@ -34,8 +31,7 @@ def test_mkdocs_emits_all_modules(tmp_path: Path) -> None: for path in module_paths: parts = path.split(".") is_package = any( - other != path and other.startswith(path + ".") - for other in module_paths + other != path and other.startswith(path + ".") for other in module_paths ) if is_package: diff --git a/tests/renderers/mkdocs/test_mkdocs_structure.py b/tests/renderers/mkdocs/test_mkdocs_structure.py index 4c6788f..f204808 100644 --- a/tests/renderers/mkdocs/test_mkdocs_structure.py +++ b/tests/renderers/mkdocs/test_mkdocs_structure.py @@ -1,7 +1,7 @@ from pathlib import Path from docforge import MkDocsRenderer -from docforge.models import Project, Module +from docforge.models import Module, Project def test_mkdocs_directory_structure(tmp_path: Path):