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/cli/api_utils.py b/docforge/cli/api_utils.py
new file mode 100644
index 0000000..cb760c7
--- /dev/null
+++ b/docforge/cli/api_utils.py
@@ -0,0 +1,114 @@
+"""
+# 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 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: 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: Parsed OpenAPI specification.
+ docs_dir: 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 1bf8491..05ca0b6 100644
--- a/docforge/cli/commands.py
+++ b/docforge/cli/commands.py
@@ -10,7 +10,7 @@ from pathlib import Path
import click
-from docforge.cli import mcp_utils, mkdocs_utils
+from docforge.cli import api_utils, mcp_utils, mkdocs_utils
from docforge.loaders import GriffeLoader
@@ -28,19 +28,25 @@ 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("--api", is_flag=True, help="Build API docs from an OpenAPI spec")
@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/lib"),
- help="Directory for MD sources",
+ default=Path("docs"),
+ help="MkDocs documentation root",
)
@click.option(
"--nav",
@@ -67,8 +73,10 @@ def cli() -> None:
def build(
mcp: bool,
mkdocs: bool,
+ api: bool,
module_is_source: bool,
module: str | None,
+ openapi_spec: Path | None,
project_name: str | None,
site_name: str | None,
docs_dir: Path,
@@ -81,14 +89,13 @@ def build(
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
+ style of the selected platform, generates renderer-specific
+ documentation sources, and optionally builds the final output.
Depending on the selected options, the build can target:
- - MkDocs static documentation sites
+ - MkDocs static documentation sites for library reference docs
+ - Swagger-enabled API docs generated from an OpenAPI spec
- MCP structured documentation resources
Args:
@@ -96,7 +103,10 @@ def build(
Enable MCP documentation generation.
mkdocs (bool):
- Enable MkDocs documentation generation.
+ Enable MkDocs library documentation generation.
+
+ api (bool):
+ Enable API documentation generation from an OpenAPI spec.
module_is_source (bool):
Treat the specified module directory as the project root.
@@ -104,6 +114,9 @@ def build(
module (Optional[str]):
Python module import path to document.
+ openapi_spec (Optional[Path]):
+ Path to the OpenAPI JSON specification used for API docs.
+
project_name (Optional[str]):
Optional override for the project name.
@@ -111,7 +124,7 @@ def build(
Display name for the MkDocs site.
docs_dir (Path):
- Directory where Markdown documentation sources will be generated.
+ Shared documentation root used as the MkDocs ``docs_dir``.
nav_file (Path):
Path to the navigation specification file.
@@ -129,27 +142,72 @@ 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:
+ raise click.UsageError("Must specify either --mcp, --mkdocs, or --api")
+
+ if api:
+ if not openapi_spec:
+ raise click.UsageError("--openapi-spec is required for API build")
+ if site_name and not mkdocs:
+ raise click.UsageError(
+ "--site-name cannot be overridden for API build; "
+ "the OpenAPI spec provides the site name"
+ )
+
+ if (mkdocs or mcp) and not module:
+ raise click.UsageError(
+ "--module is required for MkDocs build"
+ if mkdocs
+ else "--module is required for MCP build"
+ )
+
+ spec: dict | None = None
+ if api:
+ spec = api_utils.load_openapi_spec(openapi_spec)
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}...")
+ 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=mkdocs_yml.parent,
)
+ if api:
+ api_dir = docs_dir / "api"
+ click.echo(f"Generating API sources in {api_dir}...")
+ api_utils.generate_api_sources(spec, api_dir)
+
+ if mkdocs or api:
+ modes: list[str] = []
+ if mkdocs:
+ modes.append("lib")
+ if api:
+ modes.append("api")
+
+ site_description: str | None = None
+ site_author: str | None = None
+ effective_site_name = site_name or module
+
+ if api:
+ metadata = api_utils.derive_metadata(spec)
+ effective_site_name = metadata.site_name
+ site_description = metadata.site_description
+ site_author = metadata.site_author
+
click.echo(f"Generating MkDocs config {mkdocs_yml}...")
mkdocs_utils.generate_config(
- docs_dir, nav_file, template, mkdocs_yml, site_name
+ docs_dir,
+ nav_file,
+ template,
+ mkdocs_yml,
+ effective_site_name,
+ modes=modes,
+ site_description=site_description,
+ site_author=site_author,
)
click.echo("Running MkDocs build...")
diff --git a/docforge/cli/commands.pyi b/docforge/cli/commands.pyi
index 0c1f1ec..1638a22 100644
--- a/docforge/cli/commands.pyi
+++ b/docforge/cli/commands.pyi
@@ -8,8 +8,10 @@ cli: Group
def build(
mcp: bool,
mkdocs: bool,
+ api: bool,
module_is_source: bool,
module: str | None,
+ openapi_spec: Path | None,
project_name: str | None,
site_name: str | None,
docs_dir: Path,
diff --git a/docforge/cli/mkdocs_utils.py b/docforge/cli/mkdocs_utils.py
index 5ab4d4d..da0d63e 100644
--- a/docforge/cli/mkdocs_utils.py
+++ b/docforge/cli/mkdocs_utils.py
@@ -5,6 +5,7 @@ Utilities for working with MkDocs in the doc-forge CLI.
"""
import os
+from collections.abc import Iterable
from importlib import resources
from pathlib import Path
@@ -74,6 +75,9 @@ def generate_config(
template: Path | None,
out: Path,
site_name: str,
+ modes: Iterable[str] | None = None,
+ site_description: str | None = None,
+ site_author: str | None = None,
) -> None:
"""
Generate an `mkdocs.yml` configuration file.
@@ -82,16 +86,21 @@ def generate_config(
with a navigation structure derived from the docforge navigation
specification.
+ The ``docs_dir`` is always written relative to the MkDocs root and is
+ expected to be the shared documentation parent (for example ``docs``),
+ with generated sources nested under ``lib/`` or ``api/`` subdirectories.
+
Args:
docs_dir (Path):
- Directory containing generated documentation Markdown files.
+ Shared documentation root used as the MkDocs ``docs_dir``.
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.
+ Optional path to a fully custom MkDocs configuration template.
+ If not provided, built-in templates are merged; the provided
+ template replaces the built-in templates entirely.
out (Path):
Destination path where the generated `mkdocs.yml` file will be written.
@@ -99,6 +108,17 @@ def generate_config(
site_name (str):
Display name for the generated documentation site.
+ modes (Optional[Iterable[str]]):
+ Documentation modes to enable. Each mode contributes its own
+ built-in template fragment (for example ``lib`` or ``api``),
+ merged on top of the shared ``mkdocs.common.yml`` template.
+
+ site_description (Optional[str]):
+ Optional site description written into the configuration.
+
+ site_author (Optional[str]):
+ Optional site author written into the configuration.
+
Raises:
click.FileError:
If the navigation specification or template file cannot be found.
@@ -110,26 +130,145 @@ def generate_config(
resolved = resolve_nav(spec, docs_dir)
nav_block = MkDocsNavEmitter().emit(resolved)
- # 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)
+ data = _load_template(template, modes)
data["site_name"] = site_name
+ if site_description:
+ data["site_description"] = site_description
+ if site_author:
+ data["site_author"] = site_author
data["docs_dir"] = Path(os.path.relpath(docs_dir, out.parent)).as_posix()
data["nav"] = nav_block
+ if spec.icon:
+ theme = data.setdefault("theme", {})
+ if not isinstance(theme, dict):
+ theme = {}
+ theme["icon"] = spec.icon
+ data["theme"] = theme
+
out.write_text(yaml.safe_dump(data, sort_keys=False), encoding="utf-8")
+def _load_template(
+ template: Path | None,
+ modes: Iterable[str] | None,
+) -> dict:
+ """
+ Load the MkDocs configuration template.
+
+ 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`` or ``api``).
+
+ Args:
+ template (Optional[Path]):
+ Optional fully custom template that replaces the built-ins.
+
+ modes (Optional[Iterable[str]]):
+ 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: 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: Existing list entries.
+ added: 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: Configuration being built up.
+ part: 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(mkdocs_yml: Path) -> None:
"""
Build the MkDocs documentation site.
diff --git a/docforge/cli/mkdocs_utils.pyi b/docforge/cli/mkdocs_utils.pyi
index c239ccb..a7e4613 100644
--- a/docforge/cli/mkdocs_utils.pyi
+++ b/docforge/cli/mkdocs_utils.pyi
@@ -1,3 +1,4 @@
+from collections.abc import Iterable
from pathlib import Path
def generate_sources(
@@ -5,9 +6,17 @@ def generate_sources(
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
+ docs_dir: Path,
+ nav_file: Path,
+ template: Path | None,
+ out: Path,
+ site_name: str,
+ modes: Iterable[str] | None = None,
+ site_description: str | None = None,
+ site_author: str | None = None,
) -> None: ...
def build(mkdocs_yml: Path) -> None: ...
def serve(mkdocs_yml: Path) -> None: ...
diff --git a/docforge/nav/spec.py b/docforge/nav/spec.py
index dd87b37..bcbf8a8 100644
--- a/docforge/nav/spec.py
+++ b/docforge/nav/spec.py
@@ -23,12 +23,16 @@ 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: str | None,
groups: dict[str, list[str]],
+ icon: dict[str, str] | None = None,
) -> None:
"""
Initialize a NavSpec instance.
@@ -37,9 +41,12 @@ class NavSpec:
home: Relative path to the home document.
groups: Mapping of group names to lists of path patterns
(glob expressions).
+ icon: 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":
@@ -67,6 +74,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")
@@ -82,7 +90,15 @@ 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")
+
+ return cls(home=home, groups=groups, icon=icon)
def all_patterns(self) -> list[str]:
"""
@@ -131,4 +147,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/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..431d4ba
--- /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/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/mcp/index.json b/docs/mcp/index.json
index 22bf131..9055418 100644
--- a/docs/mcp/index.json
+++ b/docs/mcp/index.json
@@ -1,6 +1,6 @@
{
"project": "docforge",
"type": "docforge-model",
- "modules_count": 22,
+ "modules_count": 23,
"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..547c81a
--- /dev/null
+++ b/docs/mcp/modules/docforge.cli.api_utils.json
@@ -0,0 +1,102 @@
+{
+ "module": "docforge.cli.api_utils",
+ "content": {
+ "path": "docforge.cli.api_utils",
+ "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
+ "objects": {
+ "json": {
+ "name": "json",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.json",
+ "signature": "",
+ "docstring": null
+ },
+ "dataclass": {
+ "name": "dataclass",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.dataclass",
+ "signature": "",
+ "docstring": null
+ },
+ "Path": {
+ "name": "Path",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.Path",
+ "signature": "",
+ "docstring": null
+ },
+ "click": {
+ "name": "click",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.click",
+ "signature": "",
+ "docstring": null
+ },
+ "SWAGGER_SPEC_FILENAME": {
+ "name": "SWAGGER_SPEC_FILENAME",
+ "kind": "attribute",
+ "path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME",
+ "signature": null,
+ "docstring": null
+ },
+ "OpenAPIMetadata": {
+ "name": "OpenAPIMetadata",
+ "kind": "class",
+ "path": "docforge.cli.api_utils.OpenAPIMetadata",
+ "signature": "",
+ "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": "",
+ "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: 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": "",
+ "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: 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": "",
+ "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: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written."
+ },
+ "Any": {
+ "name": "Any",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.Any",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/docs/mcp/modules/docforge.cli.commands.json b/docs/mcp/modules/docforge.cli.commands.json
index 66e93c2..5397439 100644
--- a/docs/mcp/modules/docforge.cli.commands.json
+++ b/docs/mcp/modules/docforge.cli.commands.json
@@ -18,6 +18,108 @@
"signature": "",
"docstring": null
},
+ "api_utils": {
+ "name": "api_utils",
+ "kind": "module",
+ "path": "docforge.cli.commands.api_utils",
+ "signature": "",
+ "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
+ "members": {
+ "json": {
+ "name": "json",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.json",
+ "signature": "",
+ "docstring": null
+ },
+ "dataclass": {
+ "name": "dataclass",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.dataclass",
+ "signature": "",
+ "docstring": null
+ },
+ "Path": {
+ "name": "Path",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.Path",
+ "signature": "",
+ "docstring": null
+ },
+ "click": {
+ "name": "click",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.click",
+ "signature": "",
+ "docstring": null
+ },
+ "SWAGGER_SPEC_FILENAME": {
+ "name": "SWAGGER_SPEC_FILENAME",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
+ "signature": "",
+ "docstring": null
+ },
+ "OpenAPIMetadata": {
+ "name": "OpenAPIMetadata",
+ "kind": "class",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
+ "signature": "",
+ "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": "",
+ "docstring": null
+ },
+ "site_description": {
+ "name": "site_description",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
+ "signature": "",
+ "docstring": null
+ },
+ "site_author": {
+ "name": "site_author",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
+ "load_openapi_spec": {
+ "name": "load_openapi_spec",
+ "kind": "function",
+ "path": "docforge.cli.commands.api_utils.load_openapi_spec",
+ "signature": "",
+ "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: 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": "",
+ "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: 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": "",
+ "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: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written."
+ },
+ "Any": {
+ "name": "Any",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.Any",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
"mcp_utils": {
"name": "mcp_utils",
"kind": "module",
@@ -152,6 +254,13 @@
"signature": "",
"docstring": null
},
+ "Iterable": {
+ "name": "Iterable",
+ "kind": "alias",
+ "path": "docforge.cli.commands.mkdocs_utils.Iterable",
+ "signature": "",
+ "docstring": null
+ },
"resources": {
"name": "resources",
"kind": "alias",
@@ -282,7 +391,7 @@
"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."
+ "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\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\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\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found."
},
"build": {
"name": "build",
@@ -334,21 +443,21 @@
"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": "",
+ "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\nstyle of the selected platform, generates renderer-specific\ndocumentation sources, and optionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites for library reference docs\n- Swagger-enabled API docs generated from an OpenAPI spec\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs library documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\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 openapi_spec (Optional[Path]):\n Path to the OpenAPI JSON specification used for API docs.\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 Shared documentation root used as the MkDocs ``docs_dir``.\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": "",
+ "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": "",
+ "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."
},
"Any": {
diff --git a/docs/mcp/modules/docforge.cli.json b/docs/mcp/modules/docforge.cli.json
index 95037a6..536047d 100644
--- a/docs/mcp/modules/docforge.cli.json
+++ b/docs/mcp/modules/docforge.cli.json
@@ -27,6 +27,108 @@
}
}
},
+ "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": {
+ "json": {
+ "name": "json",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.json",
+ "signature": "",
+ "docstring": null
+ },
+ "dataclass": {
+ "name": "dataclass",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.dataclass",
+ "signature": "",
+ "docstring": null
+ },
+ "Path": {
+ "name": "Path",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.Path",
+ "signature": "",
+ "docstring": null
+ },
+ "click": {
+ "name": "click",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.click",
+ "signature": "",
+ "docstring": null
+ },
+ "SWAGGER_SPEC_FILENAME": {
+ "name": "SWAGGER_SPEC_FILENAME",
+ "kind": "attribute",
+ "path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME",
+ "signature": null,
+ "docstring": null
+ },
+ "OpenAPIMetadata": {
+ "name": "OpenAPIMetadata",
+ "kind": "class",
+ "path": "docforge.cli.api_utils.OpenAPIMetadata",
+ "signature": "",
+ "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": "",
+ "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: 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": "",
+ "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: 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": "",
+ "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: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written."
+ },
+ "Any": {
+ "name": "Any",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.Any",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
"commands": {
"name": "commands",
"kind": "module",
@@ -48,6 +150,108 @@
"signature": "",
"docstring": null
},
+ "api_utils": {
+ "name": "api_utils",
+ "kind": "module",
+ "path": "docforge.cli.commands.api_utils",
+ "signature": "",
+ "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
+ "members": {
+ "json": {
+ "name": "json",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.json",
+ "signature": "",
+ "docstring": null
+ },
+ "dataclass": {
+ "name": "dataclass",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.dataclass",
+ "signature": "",
+ "docstring": null
+ },
+ "Path": {
+ "name": "Path",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.Path",
+ "signature": "",
+ "docstring": null
+ },
+ "click": {
+ "name": "click",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.click",
+ "signature": "",
+ "docstring": null
+ },
+ "SWAGGER_SPEC_FILENAME": {
+ "name": "SWAGGER_SPEC_FILENAME",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
+ "signature": "",
+ "docstring": null
+ },
+ "OpenAPIMetadata": {
+ "name": "OpenAPIMetadata",
+ "kind": "class",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
+ "signature": "",
+ "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": "",
+ "docstring": null
+ },
+ "site_description": {
+ "name": "site_description",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
+ "signature": "",
+ "docstring": null
+ },
+ "site_author": {
+ "name": "site_author",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
+ "load_openapi_spec": {
+ "name": "load_openapi_spec",
+ "kind": "function",
+ "path": "docforge.cli.commands.api_utils.load_openapi_spec",
+ "signature": "",
+ "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: 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": "",
+ "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: 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": "",
+ "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: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written."
+ },
+ "Any": {
+ "name": "Any",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.Any",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
"mcp_utils": {
"name": "mcp_utils",
"kind": "module",
@@ -182,6 +386,13 @@
"signature": "",
"docstring": null
},
+ "Iterable": {
+ "name": "Iterable",
+ "kind": "alias",
+ "path": "docforge.cli.commands.mkdocs_utils.Iterable",
+ "signature": "",
+ "docstring": null
+ },
"resources": {
"name": "resources",
"kind": "alias",
@@ -312,7 +523,7 @@
"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."
+ "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\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\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\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found."
},
"build": {
"name": "build",
@@ -364,21 +575,21 @@
"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": "",
+ "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\nstyle of the selected platform, generates renderer-specific\ndocumentation sources, and optionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites for library reference docs\n- Swagger-enabled API docs generated from an OpenAPI spec\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs library documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\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 openapi_spec (Optional[Path]):\n Path to the OpenAPI JSON specification used for API docs.\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 Shared documentation root used as the MkDocs ``docs_dir``.\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": "",
+ "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": "",
+ "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."
},
"Any": {
@@ -531,6 +742,13 @@
"signature": "",
"docstring": null
},
+ "Iterable": {
+ "name": "Iterable",
+ "kind": "alias",
+ "path": "docforge.cli.mkdocs_utils.Iterable",
+ "signature": "",
+ "docstring": null
+ },
"resources": {
"name": "resources",
"kind": "alias",
@@ -653,28 +871,28 @@
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.generate_sources",
- "signature": "",
+ "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.\n\n readme_dir (Optional[Path]):\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",
"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."
+ "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\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\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\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\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": "",
+ "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": "",
+ "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."
}
}
diff --git a/docs/mcp/modules/docforge.cli.mkdocs_utils.json b/docs/mcp/modules/docforge.cli.mkdocs_utils.json
index d906397..6a260f5 100644
--- a/docs/mcp/modules/docforge.cli.mkdocs_utils.json
+++ b/docs/mcp/modules/docforge.cli.mkdocs_utils.json
@@ -11,6 +11,13 @@
"signature": "",
"docstring": null
},
+ "Iterable": {
+ "name": "Iterable",
+ "kind": "alias",
+ "path": "docforge.cli.mkdocs_utils.Iterable",
+ "signature": "",
+ "docstring": null
+ },
"resources": {
"name": "resources",
"kind": "alias",
@@ -133,28 +140,28 @@
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.generate_sources",
- "signature": "",
+ "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.\n\n readme_dir (Optional[Path]):\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",
"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."
+ "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\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\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\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\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": "",
+ "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": "",
+ "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."
}
}
diff --git a/docs/mcp/modules/docforge.json b/docs/mcp/modules/docforge.json
index 2f65a43..ae0cb51 100644
--- a/docs/mcp/modules/docforge.json
+++ b/docs/mcp/modules/docforge.json
@@ -140,6 +140,108 @@
}
}
},
+ "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": {
+ "json": {
+ "name": "json",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.json",
+ "signature": "",
+ "docstring": null
+ },
+ "dataclass": {
+ "name": "dataclass",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.dataclass",
+ "signature": "",
+ "docstring": null
+ },
+ "Path": {
+ "name": "Path",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.Path",
+ "signature": "",
+ "docstring": null
+ },
+ "click": {
+ "name": "click",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.click",
+ "signature": "",
+ "docstring": null
+ },
+ "SWAGGER_SPEC_FILENAME": {
+ "name": "SWAGGER_SPEC_FILENAME",
+ "kind": "attribute",
+ "path": "docforge.cli.api_utils.SWAGGER_SPEC_FILENAME",
+ "signature": null,
+ "docstring": null
+ },
+ "OpenAPIMetadata": {
+ "name": "OpenAPIMetadata",
+ "kind": "class",
+ "path": "docforge.cli.api_utils.OpenAPIMetadata",
+ "signature": "",
+ "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": "",
+ "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: 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": "",
+ "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: 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": "",
+ "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: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written."
+ },
+ "Any": {
+ "name": "Any",
+ "kind": "alias",
+ "path": "docforge.cli.api_utils.Any",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
"commands": {
"name": "commands",
"kind": "module",
@@ -161,6 +263,108 @@
"signature": "",
"docstring": null
},
+ "api_utils": {
+ "name": "api_utils",
+ "kind": "module",
+ "path": "docforge.cli.commands.api_utils",
+ "signature": "",
+ "docstring": "# Summary\n\nUtilities for building API documentation from an OpenAPI specification.",
+ "members": {
+ "json": {
+ "name": "json",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.json",
+ "signature": "",
+ "docstring": null
+ },
+ "dataclass": {
+ "name": "dataclass",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.dataclass",
+ "signature": "",
+ "docstring": null
+ },
+ "Path": {
+ "name": "Path",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.Path",
+ "signature": "",
+ "docstring": null
+ },
+ "click": {
+ "name": "click",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.click",
+ "signature": "",
+ "docstring": null
+ },
+ "SWAGGER_SPEC_FILENAME": {
+ "name": "SWAGGER_SPEC_FILENAME",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.SWAGGER_SPEC_FILENAME",
+ "signature": "",
+ "docstring": null
+ },
+ "OpenAPIMetadata": {
+ "name": "OpenAPIMetadata",
+ "kind": "class",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata",
+ "signature": "",
+ "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": "",
+ "docstring": null
+ },
+ "site_description": {
+ "name": "site_description",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_description",
+ "signature": "",
+ "docstring": null
+ },
+ "site_author": {
+ "name": "site_author",
+ "kind": "attribute",
+ "path": "docforge.cli.commands.api_utils.OpenAPIMetadata.site_author",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
+ "load_openapi_spec": {
+ "name": "load_openapi_spec",
+ "kind": "function",
+ "path": "docforge.cli.commands.api_utils.load_openapi_spec",
+ "signature": "",
+ "docstring": "Load and validate an OpenAPI specification from a JSON file.\n\nArgs:\n spec_path: 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": "",
+ "docstring": "Derive MkDocs site metadata from an OpenAPI spec ``info`` block.\n\nArgs:\n spec: 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": "",
+ "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: Parsed OpenAPI specification.\n docs_dir: Directory (for example ``docs/api``) where the swagger\n sources are written."
+ },
+ "Any": {
+ "name": "Any",
+ "kind": "alias",
+ "path": "docforge.cli.commands.api_utils.Any",
+ "signature": "",
+ "docstring": null
+ }
+ }
+ },
"mcp_utils": {
"name": "mcp_utils",
"kind": "module",
@@ -295,6 +499,13 @@
"signature": "",
"docstring": null
},
+ "Iterable": {
+ "name": "Iterable",
+ "kind": "alias",
+ "path": "docforge.cli.commands.mkdocs_utils.Iterable",
+ "signature": "",
+ "docstring": null
+ },
"resources": {
"name": "resources",
"kind": "alias",
@@ -425,7 +636,7 @@
"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."
+ "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\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\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\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\n\nRaises:\n click.FileError:\n If the navigation specification or template file cannot be found."
},
"build": {
"name": "build",
@@ -477,21 +688,21 @@
"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": "",
+ "docstring": "Build documentation artifacts.\n\nThis command performs the full documentation build pipeline:\nstyle of the selected platform, generates renderer-specific\ndocumentation sources, and optionally builds the final output.\n\nDepending on the selected options, the build can target:\n\n- MkDocs static documentation sites for library reference docs\n- Swagger-enabled API docs generated from an OpenAPI spec\n- MCP structured documentation resources\n\nArgs:\n mcp (bool):\n Enable MCP documentation generation.\n\n mkdocs (bool):\n Enable MkDocs library documentation generation.\n\n api (bool):\n Enable API documentation generation from an OpenAPI spec.\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 openapi_spec (Optional[Path]):\n Path to the OpenAPI JSON specification used for API docs.\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 Shared documentation root used as the MkDocs ``docs_dir``.\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": "",
+ "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": "",
+ "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."
},
"Any": {
@@ -644,6 +855,13 @@
"signature": "",
"docstring": null
},
+ "Iterable": {
+ "name": "Iterable",
+ "kind": "alias",
+ "path": "docforge.cli.mkdocs_utils.Iterable",
+ "signature": "",
+ "docstring": null
+ },
"resources": {
"name": "resources",
"kind": "alias",
@@ -766,28 +984,28 @@
"name": "generate_sources",
"kind": "function",
"path": "docforge.cli.mkdocs_utils.generate_sources",
- "signature": "",
+ "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.\n\n readme_dir (Optional[Path]):\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",
"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."
+ "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\nThe ``docs_dir`` is always written relative to the MkDocs root and is\nexpected to be the shared documentation parent (for example ``docs``),\nwith generated sources nested under ``lib/`` or ``api/`` subdirectories.\n\nArgs:\n docs_dir (Path):\n Shared documentation root used as the MkDocs ``docs_dir``.\n\n nav_file (Path):\n Path to the `docforge.nav.yml` navigation specification.\n\n template (Optional[Path]):\n Optional path to a fully custom MkDocs configuration template.\n If not provided, built-in templates are merged; the provided\n template replaces the built-in templates entirely.\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\n modes (Optional[Iterable[str]]):\n Documentation modes to enable. Each mode contributes its own\n built-in template fragment (for example ``lib`` or ``api``),\n merged on top of the shared ``mkdocs.common.yml`` template.\n\n site_description (Optional[str]):\n Optional site description written into the configuration.\n\n site_author (Optional[str]):\n Optional site author written into the configuration.\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": "",
+ "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": "",
+ "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."
}
}
@@ -1635,7 +1853,7 @@
"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.",
+ "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",
@@ -1651,6 +1869,13 @@
"signature": "",
"docstring": null
},
+ "icon": {
+ "name": "icon",
+ "kind": "attribute",
+ "path": "docforge.nav.NavSpec.icon",
+ "signature": "",
+ "docstring": null
+ },
"load": {
"name": "load",
"kind": "function",
@@ -1829,7 +2054,7 @@
"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.",
+ "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",
@@ -1845,6 +2070,13 @@
"signature": "",
"docstring": null
},
+ "icon": {
+ "name": "icon",
+ "kind": "attribute",
+ "path": "docforge.nav.resolver.NavSpec.icon",
+ "signature": "",
+ "docstring": null
+ },
"load": {
"name": "load",
"kind": "function",
@@ -1925,8 +2157,8 @@
"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": "",
+ "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",
@@ -1942,18 +2174,25 @@
"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": "",
+ "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": "",
+ "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."
}
}
@@ -1962,7 +2201,7 @@
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.nav.spec.load_nav_spec",
- "signature": "",
+ "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."
}
}
diff --git a/docs/mcp/modules/docforge.nav.json b/docs/mcp/modules/docforge.nav.json
index 9f2d149..85ef248 100644
--- a/docs/mcp/modules/docforge.nav.json
+++ b/docs/mcp/modules/docforge.nav.json
@@ -9,7 +9,7 @@
"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.",
+ "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",
@@ -25,6 +25,13 @@
"signature": "",
"docstring": null
},
+ "icon": {
+ "name": "icon",
+ "kind": "attribute",
+ "path": "docforge.nav.NavSpec.icon",
+ "signature": "",
+ "docstring": null
+ },
"load": {
"name": "load",
"kind": "function",
@@ -203,7 +210,7 @@
"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.",
+ "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",
@@ -219,6 +226,13 @@
"signature": "",
"docstring": null
},
+ "icon": {
+ "name": "icon",
+ "kind": "attribute",
+ "path": "docforge.nav.resolver.NavSpec.icon",
+ "signature": "",
+ "docstring": null
+ },
"load": {
"name": "load",
"kind": "function",
@@ -299,8 +313,8 @@
"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": "",
+ "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",
@@ -316,18 +330,25 @@
"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": "",
+ "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": "",
+ "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."
}
}
@@ -336,7 +357,7 @@
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.nav.spec.load_nav_spec",
- "signature": "",
+ "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."
}
}
diff --git a/docs/mcp/modules/docforge.nav.resolver.json b/docs/mcp/modules/docforge.nav.resolver.json
index 096f242..2df085f 100644
--- a/docs/mcp/modules/docforge.nav.resolver.json
+++ b/docs/mcp/modules/docforge.nav.resolver.json
@@ -30,7 +30,7 @@
"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.",
+ "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",
@@ -46,6 +46,13 @@
"signature": "",
"docstring": null
},
+ "icon": {
+ "name": "icon",
+ "kind": "attribute",
+ "path": "docforge.nav.resolver.NavSpec.icon",
+ "signature": "",
+ "docstring": null
+ },
"load": {
"name": "load",
"kind": "function",
diff --git a/docs/mcp/modules/docforge.nav.spec.json b/docs/mcp/modules/docforge.nav.spec.json
index 99a8855..ab0d693 100644
--- a/docs/mcp/modules/docforge.nav.spec.json
+++ b/docs/mcp/modules/docforge.nav.spec.json
@@ -22,8 +22,8 @@
"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": "",
+ "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",
@@ -39,18 +39,25 @@
"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": "",
+ "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": "",
+ "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."
}
}
@@ -59,7 +66,7 @@
"name": "load_nav_spec",
"kind": "function",
"path": "docforge.nav.spec.load_nav_spec",
- "signature": "",
+ "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."
}
}
diff --git a/docs/mcp/nav.json b/docs/mcp/nav.json
index c3c9367..8f62362 100644
--- a/docs/mcp/nav.json
+++ b/docs/mcp/nav.json
@@ -7,6 +7,10 @@
"module": "docforge.cli",
"resource": "doc://modules/docforge.cli"
},
+ {
+ "module": "docforge.cli.api_utils",
+ "resource": "doc://modules/docforge.cli.api_utils"
+ },
{
"module": "docforge.cli.commands",
"resource": "doc://modules/docforge.cli.commands"
diff --git a/mkdocs.yml b/mkdocs.yml
index 0c54747..87ef16b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -21,6 +21,31 @@ theme:
- search.highlight
- search.share
- search.suggest
+ 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
- mkdocstrings:
@@ -41,52 +66,32 @@ plugins:
show_category_heading: true
show_object_full_path: false
show_symbol_type_heading: true
-markdown_extensions:
-- pymdownx.superfences
-- pymdownx.inlinehilite
-- pymdownx.snippets
-- admonition
-- pymdownx.details
-- pymdownx.superfences
-- 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
site_name: docforge
-docs_dir: docs/lib
+docs_dir: docs
nav:
-- Home: index.md
+- Home: lib/index.md
- 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
diff --git a/pyproject.toml b/pyproject.toml
index 3979bc9..6e02ea3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -67,6 +67,7 @@ mkdocs = [
"pymdown-extensions==10.16.1",
"neoteroi-mkdocs==1.1.3",
+ "mkdocs-swagger-ui-tag>=0.3.0",
]
sphinx = [
"sphinx>=5.0.0",
diff --git a/tests/cli/test_build_api.py b/tests/cli/test_build_api.py
new file mode 100644
index 0000000..3489e31
--- /dev/null
+++ b/tests/cli/test_build_api.py
@@ -0,0 +1,134 @@
+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 / "mkdocs.yml").read_text(encoding="utf-8")
+ assert "docs_dir: docs" 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_allows_site_name_for_lib(
+ cli_runner, mock_mkdocs_build, mock_mkdocs_load_config
+):
+ # site_name is accepted when --mkdocs is also present (lib mode owns it)
+ 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\n"
+ "groups:\n"
+ " API:\n"
+ " - api/index.md\n",
+ encoding="utf-8",
+ )
+
+ result = cli_runner.invoke(
+ cli,
+ [
+ "build",
+ "--mkdocs",
+ "--api",
+ "--module",
+ "testpkg",
+ "--openapi-spec",
+ str(spec_path),
+ ],
+ )
+
+ assert result.exit_code == 0, result.output
+
+ config = (cwd / "mkdocs.yml").read_text(encoding="utf-8")
+ assert "docs_dir: docs" in config
+ assert "swagger-ui-tag" in config
+ assert "mkdocstrings" in config
diff --git a/tests/cli/test_build_mkdocs.py b/tests/cli/test_build_mkdocs.py
index b44da95..501011b 100644
--- a/tests/cli/test_build_mkdocs.py
+++ b/tests/cli/test_build_mkdocs.py
@@ -18,7 +18,7 @@ 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")
+ nav_file.write_text("home: lib/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.
@@ -42,7 +42,7 @@ def test_mkdocs_build_full_flow(
assert mock_mkdocs_build() is True
assert (cwd / "mkdocs.yml").exists()
assert (cwd / "docs" / "lib" / "testpkg" / "mod.md").exists()
- assert "docs_dir: docs/lib" in (cwd / "mkdocs.yml").read_text()
+ assert "docs_dir: docs" in (cwd / "mkdocs.yml").read_text()
def test_mkdocs_build_missing_module_fails(cli_runner):
@@ -69,7 +69,7 @@ def test_mkdocs_build_without_site_name_uses_module_as_default_full_flow(
# Create nav spec expected by generate_config
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",
)