feat: add wiki build kind with file-structure-derived navigation

- add build_wiki_nav deriving MkDocs nav from docs/wiki file structure
  (index.md -> Home, numeric prefixes stripped and title-cased, nested
  dirs become groups, natural ordering)
- add --wiki / --wiki-dir to build; wiki-only builds need no --module
- merge wiki nav before generated lib/api nav; wiki Home replaces the
  nav spec Home entry
- add mkdocs.wiki.yml template fragment and nav/cli tests
- dogfood doc-forge's own docs/wiki and regenerate site output
This commit is contained in:
2026-09-11 23:38:23 +05:30
parent bacf17b930
commit 8c6c46caf2
44 changed files with 798 additions and 17 deletions

View File

@@ -29,6 +29,9 @@ def cli() -> None:
@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(
"--wiki", is_flag=True, help="Include a hand-written wiki in the MkDocs site"
)
@click.option(
"--module-is-source",
is_flag=True,
@@ -48,6 +51,12 @@ def cli() -> None:
default=Path("docs"),
help="MkDocs documentation root",
)
@click.option(
"--wiki-dir",
type=click.Path(path_type=Path),
default=Path("docs/wiki"),
help="Hand-written wiki directory included in the MkDocs site",
)
@click.option(
"--nav",
"nav_file",
@@ -74,12 +83,14 @@ def build(
mcp: bool,
mkdocs: bool,
api: bool,
wiki: bool,
module_is_source: bool,
module: str | None,
openapi_spec: Path | None,
project_name: str | None,
site_name: str | None,
docs_dir: Path,
wiki_dir: Path,
nav_file: Path,
template: Path | None,
mkdocs_yml: Path,
@@ -96,6 +107,7 @@ def build(
- MkDocs static documentation sites for library reference docs
- Swagger-enabled API docs generated from an OpenAPI spec
- Hand-written wiki pages included in the MkDocs site
- MCP structured documentation resources
Args:
@@ -108,6 +120,9 @@ def build(
api (bool):
Enable API documentation generation from an OpenAPI spec.
wiki (bool):
Include a hand-written wiki directory in the MkDocs site.
module_is_source (bool):
Treat the specified module directory as the project root.
@@ -126,6 +141,9 @@ def build(
docs_dir (Path):
Shared documentation root used as the MkDocs ``docs_dir``.
wiki_dir (Path):
Directory containing hand-written wiki markdown files.
nav_file (Path):
Path to the navigation specification file.
@@ -142,13 +160,13 @@ def build(
click.UsageError:
If required options are missing or conflicting.
"""
if not mcp and not mkdocs and not api:
raise click.UsageError("Must specify either --mcp, --mkdocs, or --api")
if not mcp and not mkdocs and not api and not wiki:
raise click.UsageError("Must specify either --mcp, --mkdocs, --wiki, or --api")
if api:
if not openapi_spec:
raise click.UsageError("--openapi-spec is required for API build")
if site_name and not mkdocs:
if site_name and not mkdocs and not wiki:
raise click.UsageError(
"--site-name cannot be overridden for API build; "
"the OpenAPI spec provides the site name"
@@ -181,16 +199,18 @@ def build(
click.echo(f"Generating API sources in {api_dir}...")
api_utils.generate_api_sources(spec, api_dir)
if mkdocs or api:
if mkdocs or api or wiki:
modes: list[str] = []
if mkdocs:
modes.append("lib")
if api:
modes.append("api")
if wiki:
modes.append("wiki")
site_description: str | None = None
site_author: str | None = None
effective_site_name = site_name or module
effective_site_name = site_name or module or Path.cwd().name
if api:
metadata = api_utils.derive_metadata(spec)
@@ -208,6 +228,7 @@ def build(
modes=modes,
site_description=site_description,
site_author=site_author,
wiki_dir=wiki_dir if wiki else None,
)
click.echo("Running MkDocs build...")