Files
docs/doc-forge/wiki/search/search_index.json

1 line
35 KiB
JSON

{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udde9 docforge \u2014 Docstring-Driven Documentation Forge","text":"<p><code>docforge</code> is an internal documentation tool that generates reference documentation from Google-Styled Doc-Forge Convention (GSDFC) docstrings and assembles it into per-kind MkDocs sites, alongside hand-written wiki pages and OpenAPI-based API docs.</p> <p>Doc model: this wiki is written for humans \u2014 how\u2011to guides, examples, and testing recipes. The authoritative API contracts live in the code (docstrings) and the machine\u2011readable bundle under <code>docs/mcp/</code>.</p>"},{"location":"#key-features","title":"\ud83d\ude80 Key Features","text":"<ul> <li>\ud83e\uddea GSDFC docstring extraction via Griffe</li> <li>\ud83e\udded Auto-derived navigation for hand-written wiki pages</li> <li>\ud83d\uddc2 Independent MkDocs builds per kind (lib, api, wiki) into <code>site/{kind}</code></li> <li>\ud83d\udd0c Material MkDocs theming out of the box</li> <li>\ud83d\udce6 MCP structured documentation resources</li> </ul>"},{"location":"#installation","title":"\ud83d\udce6 Installation","text":"<pre><code># Internal PyPI (TBD)\npip install docforge\n</code></pre>"},{"location":"#documentation-structure","title":"\ud83d\udcc1 Documentation Structure","text":"Section Description Overview What docforge is and how it fits the pipeline Components Loaders, models, nav, renderers, CLI, servers Conventions GSDFC, <code>.pyi</code> stubs, and template conventions Iterative Workflow How a docs build runs end to end Environment Environment setup Quality Gates Test layout and quality checks GSDFC Guide How to write GSDFC-conformant docstrings MCP Guide Building, serving, and consuming the MCP bundle MkDocs Configs MkDocs config generation and templates"},{"location":"#related-resources","title":"\ud83d\udd17 Related Resources","text":"<ul> <li>Source Code: the <code>doc-forge</code> repository</li> <li>MCP Bundle: generated by <code>doc-forge build --mcp --module docforge</code> into <code>docs/mcp/</code></li> <li>Wiki Kind: hand-written content lives in <code>docs/wiki/</code>; use the prompt in the wiki-related resource below <pre><code># AGENTS.md \u2014 Wiki Authoring Guide (Aetoskia)\n\nThis file instructs AI agents how to create, extend, and maintain the wiki\n(`docs/wiki/**`) for any Aetoskia repository.\n\n&gt; **Workflow:** this prompt covers **phase 2 only**. Phase 1 \u2014 writing GSDFC docstrings\n&gt; (plus `.pyi` stubs and `py.typed`) \u2014 is done by the agent using the doc-forge MCP\n&gt; bundle: `doc://modules/docforge` carries the full GSDFC spec. Write the wiki only\n&gt; after docstrings exist and `doc-forge build --mcp --module &lt;pkg&gt;` produced the\n&gt; repo's own bundle.\n\n---\n\n## 1. Doc model \u2014 know the two sources of truth\n\nEvery repo keeps two distinct kinds of documentation that must **not** bleed\ninto each other:\n\n| Kind | Source | Where | Audience |\n|-------------------|-----------------------|------------------------------------------|------------------------------------|\n| **Wiki** | Hand-written markdown | `docs/wiki/**` | Humans (how-to, examples, testing) |\n| **API reference** | Docstrings (GSDFC) | Generated \u2192 `docs/lib/**`, `docs/mcp/**` | Consumers (exact contracts) |\n\nRules:\n\n- The wiki is written **for humans** \u2014 how-to guides, recipes, and testing\n patterns. It is never generated.\n- API contracts (signatures, parameter types, exact behavior) live in the\n docstrings and the machine-readable bundle under `docs/mcp/`. **Never**\n duplicate full API documentation in the wiki \u2014 link to the lib site instead.\n- If a page starts to drift into contract territory, cut it down to usage and\n point at `docs/lib/`.\n- This doc model is stated on every index page as a blockquote; keep it there:\n &gt; **Doc model:** this wiki is written for humans \u2014 how\u2011to guides, examples,\n &gt; and testing recipes. The authoritative API contracts live in the code\n &gt; (docstrings) and the machine\u2011readable bundle under `docs/mcp/`.\n\n---\n\n## 2. Directory layout &amp; file naming\n\n```\ndocs/wiki/\n\u251c\u2500\u2500 index.md # site Home\n\u251c\u2500\u2500 01_overview.md\n\u251c\u2500\u2500 02_components.md\n\u251c\u2500\u2500 03_use_cases/ # nested directory \u2192 nav group\n\u2502 \u251c\u2500\u2500 01_basic_crud.md\n\u2502 \u251c\u2500\u2500 02_custom_repo.md\n\u2502 \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 04_best_practices.md\n\u251c\u2500\u2500 06_error_handling.md\n\u2514\u2500\u2500 07_testing_example.md\n```\n\n- Location: `docs/wiki/` (hand-written only).\n- File names: `NN_snake_case_name.md` with a **zero-padded two-digit** numeric\n prefix. e.g. `01_overview.md`, `03_use_cases/07_caching.md`.\n- Top-level pages use `NN_name.md` directly. High-volume sections get their own\n directory, e.g. `03_use_cases/NN_name.md` (nav group \"Use Cases\").\n- **No frontmatter.** Every file opens directly with an H1 `# Title`.\n- Navigation labels are short human titles set explicitly in\n `docs/mkdocs.wiki.yml` (title case) \u2014 often **shorter** than the page H1.\n Example: nav label `Basic CRUD` vs page H1 `Use Case 1: Basic FastAPI CRUD API`.\n Never use the raw filename slug as the label.\n- Renumbering: prefixes order pages. When inserting a page, pick the next\n number in the relevant group (subgroup numbers stay grouped).\n\n---\n\n## 3. Navigation \u2014 `docs/mkdocs.wiki.yml` is the source of truth\n\nEvery wiki page **must** be wired into the nav defined in\n`docs/mkdocs.wiki.yml`. If a page is not in the nav, it is orphaned.\n\n- The `nav:` block mirrors the directory tree; directories become nested\n groups.\n- When a section has many pages, group them **by theme** into nested\n subgroups. mongo-ops groups its use cases into:\n `Getting Started`, `Data &amp; Queries`, `Caching`, `Population`,\n `Advanced Usage`.\n- Keep `index.md`'s **Documentation Structure** table in sync with the nav \u2014\n it is the human-facing version of the same TOC. Every nav entry needs a row\n (or nested bullet group) there.\n- Nav label = human title (title case), not the filename slug.\n\n---\n\n## 4. Page anatomy\n\n### 4.1 `index.md` (Home)\n\n```\n# \ud83e\udde9 &lt;package&gt; \u2014 &lt;slogan&gt;\n&lt;one-paragraph pitch&gt;\n\n&gt; **Doc model:** \u2026 (see \u00a71)\n\n---\n\n## \ud83d\ude80 Key Features (bullet list, emoji per feature)\n## \ud83d\udce6 Installation (code blocks: internal PyPI, extras, local source)\n## \ud83d\udcc1 Documentation Structure (table = TOC, mirrors nav exactly)\n## \ud83d\udd17 Related Resources (bullets: source repo, internal PyPI, CI)\n---\n\u00a9 Aetoskia Internal \u2014 `&lt;package&gt;` &lt;version&gt;\n```\n\n### 4.2 Overview page (`01_*`)\n\n- Opens with `# Library Overview`, one sentence about what the library does,\n then a line stating the page builds the mental model.\n- Sections: `## \ud83c\udfd7\ufe0f Architecture` (ASCII diagram + numbered layer list),\n `## \ud83d\udd04 Lifecycle Rules` (table: step / call / why),\n `## \ud83e\udded Which \u2026 Should You Use?` (decision table).\n- Ends with `## \u27a1\ufe0f Read Next` (cross-links to the next pages to read).\n\n### 4.3 Components page (`02_*`)\n\n- Validated reference for the public API surface \u2014 describes what each\n component is for and how the pieces wire together. Keep it usage-level;\n exact signatures belong in `docs/lib/`.\n- Anatomy: numbered sections, one per component (`## 1. MongoConnectionManager`,\n `## 2. BaseDocument`, \u2026), with `### 8.1`-style sub-numbering for related\n types under a component (e.g. the cache layer's backend / stats / config /\n in-memory / redis implementations). Ends with `## Related`.\n\n### 4.4 Use-case page (the most common)\n\nStandard anatomy, in this order:\n\n```\n# Use Case N: &lt;Human Title&gt;\n\n**Scenario:** &lt;one sentence: the problem this recipe solves&gt;\n\n---\n\n## \ud83d\udce6 What's New? (table: Component | Description \u2014 new API used here)\n## \ud83d\ude80 Example (languaged code block, complete runnable-looking snippet)\n## \ud83d\udca1 Tips (bullets: gotchas, ordering, common mistakes)\n## Related (\u00a75)\n```\n\n### 4.5 Deep-dive / worked-example page\n\nFor intricate flows (population shapes, cache round-trips), use numbered\ndepth-first sections and comparison tables:\n\n```\n## 1. &lt;Write path&gt; (### 1a., ### 1b., \u2026 per sub-case)\n## 2. &lt;Read path&gt;\n## 3. &lt;Round trip / tricky bit&gt;\n## 4. When to use which (comparison table)\n## Related\n```\n\n### 4.6 Best Practices page (`04_*`)\n\n- Flat themed `##` sections (e.g. Layering, Lifecycle, Data &amp; Performance,\n Transactions &amp; Errors, Testing), each a short list of numbered conventions.\n- Pure prose \u2014 no large code blocks.\n\n### 4.7 Error Handling (`06_*`) / Testing pages\n\n- **Error Handling:** an exceptions table (`Exception | Source | Meaning / fix`),\n a `&gt; ` note on which failures are by design, a `## \ud83d\ude80 FastAPI Mapping Example`\n code block, then `## \ud83d\udca1 Tips` bullets, then `## Related`.\n- **Testing example (`07_*`):** `## \ud83d\ude80 Mock-Based Quickstart` (focused code\n block), `## \ud83d\udca1 Notes` tip list, `## Related`.\n\nCommon to all pages: no frontmatter, `---` between every major section, and a\n`## Related` (or variant) footer as the **last** section.\n\n---\n\n## 5. The `## Related` footer\n\nEvery page ends with a cross-link footer. Rules:\n\n- Always the **last** section, always preceded by a `---`.\n- Standard heading: `## Related` (no emoji).\n- One bullet line; links separated by ` \u00b7 ` (middle dot plus spaces).\n- Link label format: `[NN \u2013 Title](relative_path)` \u2014 en-dash, page number, title.\n- Paths are **relative**: same directory \u2192 `02_custom_repo.md`; parent \u2192\n `../01_overview.md`; child \u2192 `03_use_cases/01_basic_crud.md`.\n- Link order follows nav order (each `Related` points to related next/sibling\n pages, plus the overview/components anchor).\n\nExamples (from mongo-ops):\n\n```\n## Related\n- [02 \u2013 Custom repository](02_custom_repo.md) \u00b7 [04 \u2013 Pagination](04_pagination.md) \u00b7 [Overview](../01_overview.md)\n```\n\nVariants:\n\n- `## \u27a1\ufe0f Read Next` \u2014 used on the overview page (linear reading order).\n- `## \ud83d\udd17 Related Resources` \u2014 only on `index.md`, one bullet per external resource.\n\n---\n\n## 6. Tone &amp; formatting rules\n\n- **Written for humans**: short sentences, concrete examples, plain words.\n- Emoji-prefixed H2 headings for recognizable section types\n (`\ud83d\udce6 What's New?`, `\ud83d\ude80 Example`, `\ud83d\udca1 Tips`, `\ud83d\ude80 Key Features`).\n- `---` horizontal rule between every major section.\n- Code blocks always declare a language (```python, ```bash, etc.).\n- Use tables for comparisons and structured decisions; bullets for lists;\n ASCII diagrams for architecture.\n- Bold key terms inline. Use `inline code` for symbols/APIs.\n- Keep pages focused: one recipe/purpose per page. If a page balloons past\n ~10 KB, split it (add a numbered deep-dive page instead).\n- Match tone of existing pages in the repo before writing new ones.\n- Ground every `## \ud83d\ude80 Example`, `\ud83d\udca1 Tips`, and `\ud83d\udce6 What's New?` row in the\n library's actual source, tests, and its `docs/mcp` bundle \u2014 never invent\n APIs or behavior. Signatures and exceptions come from the code; gotchas\n come from the tests.\n\n---\n\n## 7. Build &amp; verify workflow\n\nAfter creating or editing wiki pages:\n\n```bash\n# 1. Build the wiki (from the repo root)\ndoc-forge build --wiki # wiki only\ndoc-forge build --wiki --mkdocs --module &lt;pkg&gt; # wiki + lib together\n\n# 2. Preview locally\ndoc-forge serve --wiki\n\n# 3. Collect into the hub (run from the docs/ service repo)\npython collect.py # copies site, regenerates index + nginx.conf\npython collect.py --dry-run # preview without writing\n```\n\nVerification checklist:\n\n- `doc-forge build --wiki` completes with no warnings about missing files.\n- Every new page is present in `docs/mkdocs.wiki.yml` **and** in the index\n Documentation Structure table.\n- Every page ends with a `## Related` block and no dead links (paths resolve).\n- After `collect.py`: the hub card links to both `/wiki/` and `/lib/` and the\n pages render (spot-check with the served site).\n- If code/docstrings changed (no change when wiki-only), run the repo gates:\n `black`, `ruff`, `mypy`, `pytest`.\n\n---\n\n## 8. Before/after checklist\n\n**Before creating a page:**\n\n- [ ] Confirm it is genuinely wiki material (how-to) and not API contract.\n- [ ] Find the right filename (`NN_snake_case.md`) and directory for its theme.\n- [ ] Outline the sections per \u00a74 anatomy that fits the content.\n\n**After creating/editing a page:**\n\n- [ ] Page wired into `docs/mkdocs.wiki.yml` nav (themed subgroup if needed).\n- [ ] `index.md` Documentation Structure table updated.\n- [ ] `## Related` footer present, relative links, nav order.\n- [ ] `---` separators consistent; no frontmatter; emoji headings where apt.\n- [ ] Build passes; collect run; hub shows `/wiki/` + `/lib/` links.\n- [ ] No orphaned files, no dead links.\n</code></pre></li> </ul> <p>\u00a9 Aetoskia Internal \u2014 <code>docforge</code> 1.0</p>"},{"location":"01_overview/","title":"Library Overview","text":"<p><code>docforge</code> turns GSDFC-compliant Python docstrings into maintainable reference documentation. It never edits source docstrings; it reads them, renders them, and assembles documentation sites from all available material.</p>"},{"location":"01_overview/#which-build-should-you-use","title":"\ud83e\udded Which Build Should You Use?","text":"Kind Source Output <code>lib</code> GSDFC docstrings <code>docs/lib/**</code> rendered markdown <code>api</code> OpenAPI JSON spec <code>docs/api/**</code> rendered markdown <code>wiki</code> Hand-written markdown <code>docs/wiki/**</code> (unchanged) <code>mcp</code> GSDFC docstrings + renderers <code>docs/mcp/**</code> structured JSON"},{"location":"01_overview/#architecture","title":"\ud83c\udfd7\ufe0f Architecture","text":"<p>Each enabled site kind produces its own MkDocs configuration and build:</p> <ol> <li><code>--mkdocs</code> (lib) writes <code>docs/mkdocs.lib.yml</code> and builds <code>site/lib/</code>.</li> <li><code>--api</code> writes <code>docs/mkdocs.api.yml</code> and builds <code>site/api/</code>.</li> <li><code>--wiki</code> writes <code>docs/mkdocs.wiki.yml</code> and builds <code>site/wiki/</code>.</li> </ol> <p>Every site is self-contained (own theme assets and search index) with navigation derived or scoped to that kind. Hand-written wiki content is never overwritten or regenerated \u2014 only its navigation is derived automatically.</p>"},{"location":"01_overview/#lifecycle-rules","title":"\ud83d\udd04 Lifecycle Rules","text":"<p><code>docs/mcp/**</code> is a self-contained, machine-readable reference generated from docforge's own GSDFC docstrings. <code>doc-forge serve --mcp --module docforge</code> serves it over MCP. See the MCP Guide.</p>"},{"location":"01_overview/#read-next","title":"\u27a1\ufe0f Read Next","text":"<ul> <li>02 \u2013 Components \u00b7 03 \u2013 Conventions</li> </ul>"},{"location":"02_components/","title":"Components","text":"<p><code>docforge</code> is split into four horizontal layers. Everything flows top to bottom through the CLI.</p>"},{"location":"02_components/#1-loaders-models","title":"1. Loaders &amp; Models","text":"<p>The <code>docforge/loaders</code> package wraps <code>griffe</code> to extract modules, functions, classes, and Google-style docstring sections. Loaded data is normalized into the object model under <code>docforge/models</code> (<code>Project</code>, <code>Module</code>, <code>DocObject</code>).</p>"},{"location":"02_components/#2-navigation","title":"2. Navigation","text":"<p><code>docforge/nav</code> parses <code>docforge.nav.yml</code> specs (<code>NavSpec</code>, <code>Resolver</code>, and the MkDocs nav emitter) and, since the wiki kind, derives wiki navigation from the file structure via <code>build_wiki_nav</code>.</p>"},{"location":"02_components/#3-renderers","title":"3. Renderers","text":"<p><code>docforge/renderers</code> turn model data into artifacts:</p> <ul> <li><code>MkDocsRenderer</code> \u2192 <code>docs/lib/**</code> reference markdown</li> <li><code>MCPRenderer</code> \u2192 <code>docs/mcp/**</code> structured documentation</li> </ul>"},{"location":"02_components/#4-servers","title":"4. Servers","text":"<p><code>docforge/servers</code> serves generated artifacts over live protocols:</p> <ul> <li><code>MCPServer</code> \u2192 serves a pre-generated <code>docs/mcp/**</code> bundle through MCP resources (<code>docs://index</code>, <code>docs://nav</code>, <code>docs://modules/{module}</code>)</li> </ul>"},{"location":"02_components/#5-cli","title":"5. CLI","text":"<p><code>docforge/cli</code> wires it all together:</p> <ul> <li><code>commands.py</code> \u2014 the <code>build</code> command and its <code>--mkdocs</code> / <code>--api</code> / <code>--wiki</code> / <code>--mcp</code> modes</li> <li><code>mkdocs_utils.py</code> \u2014 per-kind config generation (<code>docs/mkdocs.{lib,api,wiki}.yml</code>) with navigation re-rooted to each kind's <code>docs_dir</code></li> <li><code>api_utils.py</code> \u2014 OpenAPI loading and API docs generation</li> </ul>"},{"location":"02_components/#related","title":"Related","text":"<ul> <li>01 \u2013 Overview \u00b7 03 \u2013 Conventions</li> </ul>"},{"location":"03_conventions/","title":"Conventions","text":""},{"location":"03_conventions/#gsdfc-docstrings","title":"GSDFC docstrings","text":"<p>All documented source uses the Google-Styled Doc-Forge Convention (GSDFC): <code>Args:</code>, <code>Returns:</code>, <code>Raises:</code>, and <code>Attributes:</code> sections with properly typed signatures.</p> <p>The authoritative GSDFC specification lives in the <code>docforge/__init__.py</code> package docstring, which is exported verbatim into <code>docs/mcp/modules/docforge.json</code>, so the MCP bundle is self-documenting.</p> <p>Key rules:</p> <ol> <li>Use parenthesized types in prose entries (<code>name (Type):</code>) that match the signature types.</li> <li>Use <code># Summary</code>, <code># Examples</code>, and <code># Notes</code> sections at module level.</li> <li>Use <code>Args:</code>, <code>Returns:</code>, <code>Raises:</code>, <code>Yields:</code>, <code>Notes:</code>, and <code>Example:</code> sections at function and method level.</li> <li>Always update the matching <code>.pyi</code> stub alongside the <code>.py</code> implementation.</li> <li>Every distributable package ships a <code>py.typed</code> marker so type checkers consume the authored signatures instead of <code>Any</code>.</li> </ol>"},{"location":"03_conventions/#pyi-stubs-and-pytyped","title":"<code>.pyi</code> stubs and <code>py.typed</code>","text":"<p>Every module ships a matching <code>.pyi</code> stub kept in sync with the <code>.py</code> implementation. When signatures change, update both files. Packages expose a <code>py.typed</code> marker so consumers and type checkers use the authored signatures.</p>"},{"location":"03_conventions/#wiki-pages","title":"Wiki pages","text":"<ol> <li>Hand-written markdown lives in <code>docs/wiki/**</code> and is never generated.</li> <li>File names use a numeric prefix: <code>01_overview.md</code>, <code>02_components.md</code>.</li> <li>Nested directories become nested navigation groups: <code>05_development/01_environment.md</code> \u2192 group Development.</li> <li><code>index.md</code> is the site <code>Home</code> at the root, and a section root inside a directory.</li> <li>Navigation labels are derived by stripping the numeric prefix and applying title case on the remaining words.</li> </ol>"},{"location":"03_conventions/#templates","title":"Templates","text":"<p>MkDocs config fragments live in <code>docforge/templates</code>. The <code>mkdocs.wiki.yml</code> fragment carries only the <code>search</code> plugin, since wiki pages contain no mkdocstrings directives.</p>"},{"location":"03_conventions/#related","title":"Related","text":"<ul> <li>02 \u2013 Components \u00b7 04 \u2013 Iterative Workflow</li> </ul>"},{"location":"04_iterative_workflow/","title":"Iterative Workflow","text":"<p>A docs build runs through the CLI in a single pass.</p>"},{"location":"04_iterative_workflow/#build-commands","title":"\ud83d\ude80 Build commands","text":"<pre><code># Library reference only\ndoc-forge build --mkdocs --module docforge\n\n# Wiki + library (each an independent MkDocs build)\ndoc-forge build --wiki --mkdocs --module docforge\n\n# Wiki only \u2014 no module required\ndoc-forge build --wiki --site-name docforge\n\n# MCP structured bundle\ndoc-forge build --mcp --module docforge\n</code></pre>"},{"location":"04_iterative_workflow/#what-a-build-does","title":"\ud83d\udd04 What a build does","text":"<ol> <li>Validates the requested modes (<code>--mkdocs</code>, <code>--api</code>, <code>--wiki</code>, <code>--mcp</code>).</li> <li>Generates library sources under <code>docs/lib/**</code> with <code>MkDocsRenderer</code>.</li> <li>Generates API sources under <code>docs/api/**</code> when <code>--api</code> is given.</li> <li>Derives the wiki navigation from <code>docs/wiki/**</code>.</li> <li>Writes one MkDocs config per site kind (<code>docs/mkdocs.{lib,api,wiki}.yml</code>), re-rooting navigation paths to each kind's <code>docs_dir</code>.</li> <li>Runs <code>mkdocs build</code> once per config, emitting self-contained sites <code>site/lib/</code>, <code>site/api/</code>, and <code>site/wiki/</code>.</li> </ol>"},{"location":"04_iterative_workflow/#explore-the-sites","title":"\ud83e\udded Explore the sites","text":"<pre><code>doc-forge build --wiki --mkdocs --module docforge\ndoc-forge serve --wiki # serves site preview from docs/mkdocs.wiki.yml\ndoc-forge serve --lib\ndoc-forge serve --api\n# or target any config directly:\ndoc-forge serve --mkdocs --mkdocs-yml docs/mkdocs.wiki.yml\n</code></pre>"},{"location":"04_iterative_workflow/#serve-the-mcp-bundle","title":"\ud83d\udce6 Serve the MCP bundle","text":"<pre><code>doc-forge build --mcp --module docforge\ndoc-forge serve --mcp --module docforge\n</code></pre>"},{"location":"04_iterative_workflow/#related","title":"Related","text":"<ul> <li>03 \u2013 Conventions \u00b7 01 \u2013 Environment</li> </ul>"},{"location":"05_development/01_environment/","title":"Environment Setup","text":""},{"location":"05_development/01_environment/#create-the-environment","title":"\ud83d\ude80 Create the environment","text":"<pre><code>python -m venv .venv\n.venv\\Scripts\\activate\npip install -e .\n</code></pre> <p>Requires Python 3.10+ (per <code>pyproject.toml</code>).</p>"},{"location":"05_development/01_environment/#dependencies","title":"\ud83d\udce6 Dependencies","text":"<p>Development extras include:</p> <ul> <li><code>pytest</code>, <code>pytest-cov</code> \u2014 test suite and coverage</li> <li><code>ruff</code> \u2014 lint and format checking</li> <li><code>black</code> \u2014 auto-formatting</li> <li><code>mypy</code> \u2014 strict typing checks</li> <li><code>pydoclint</code> \u2014 docstring \u2194 signature consistency checks</li> </ul>"},{"location":"05_development/01_environment/#related","title":"Related","text":"<ul> <li>04 \u2013 Iterative Workflow \u00b7 02 \u2013 Quality Gates</li> </ul>"},{"location":"05_development/02_quality_gates/","title":"Quality Gates","text":"<p>Run all checks before pushing:</p>"},{"location":"05_development/02_quality_gates/#commands","title":"\ud83d\ude80 Commands","text":"<pre><code>.venv\\Scripts\\python.exe -m pytest\n.venv\\Scripts\\python.exe -m ruff check docforge tests\n.venv\\Scripts\\python.exe -m black --check docforge tests\n.venv\\Scripts\\python.exe -m mypy docforge\n.venv\\Scripts\\pydoclint.exe docforge\n</code></pre>"},{"location":"05_development/02_quality_gates/#test-layout","title":"\ud83d\udcc1 Test layout","text":"Path Covers <code>tests/nav/</code> Nav spec, resolver, wiki nav <code>tests/cli/</code> Build command flows and modes <code>tests/renderers/</code> MkDocs / MCP rendering <p>CLI tests use the <code>cli_runner</code> fixture with <code>mock_mkdocs_build</code> and <code>mock_mkdocs_load_config</code> so they exercise the full flow without invoking a real MkDocs build.</p>"},{"location":"05_development/02_quality_gates/#related","title":"Related","text":"<ul> <li>01 \u2013 Environment \u00b7 03 \u2013 GSDFC Guide</li> </ul>"},{"location":"05_development/03_gsdfc_guide/","title":"GSDFC Docstring Guide","text":"<p>This page is the practical companion to the authoritative GSDFC specification in the <code>docforge/__init__.py</code> package docstring. It describes how to write docstrings that render correctly in MkDocs and stay machine-parseable by doc-forge, MkDocs, and MCP clients.</p>"},{"location":"05_development/03_gsdfc_guide/#overview","title":"\ud83e\udded Overview","text":"<ul> <li>Docstrings are the single source of truth.</li> <li><code>doc-forge</code> compiles docstrings but never rewrites them.</li> <li>Every public symbol should have a complete, accurate docstring.</li> <li>Type hints live in signatures; prose entries repeat the type in parentheses and must match the signature.</li> </ul>"},{"location":"05_development/03_gsdfc_guide/#module-docstrings","title":"\ud83d\udce6 Module docstrings","text":"<p>Modules use Markdown headings and <code>---</code> separators.</p> <p>Recommended sections:</p> <ul> <li><code># Summary</code> \u2014 what the subsystem does</li> <li><code># Examples</code> \u2014 a representative usage snippet</li> <li><code># Notes</code> \u2014 guarantees, lifecycle, and thread-safety notes</li> </ul>"},{"location":"05_development/03_gsdfc_guide/#class-docstrings","title":"\ud83d\udce6 Class docstrings","text":"<p>Recommended sections, in order:</p> <ul> <li>summary line describing responsibility</li> <li><code>Attributes:</code> \u2014 instance attributes with <code>name (Type):</code> entries</li> <li><code>Notes:</code> \u2014 grouped subsections such as Guarantees, Lifecycle</li> <li><code>Example:</code> \u2014 indented <code>python</code> code block</li> </ul>"},{"location":"05_development/03_gsdfc_guide/#function-and-method-docstrings","title":"\ud83d\udce6 Function and method docstrings","text":"<p>Recommended section order:</p> <ol> <li><code>Args:</code></li> <li><code>Returns:</code></li> <li><code>Raises:</code></li> <li><code>Yields:</code></li> <li><code>Notes:</code></li> <li><code>Example:</code></li> </ol> <p>Formatting rules:</p> <ul> <li><code>Args:</code> entries are <code>name (Type):</code> followed by an indented description.</li> <li><code>Returns:</code> entries are <code>Type:</code> followed by an indented description.</li> <li><code>Raises:</code> entries are <code>ExceptionType:</code> followed by an indented condition.</li> <li><code>Yields:</code> replaces <code>Returns:</code> for generators.</li> <li>Summaries are written in the imperative mood.</li> <li>Fenced <code>python</code> blocks are allowed inside <code>Example:</code> sections, indented four spaces.</li> </ul>"},{"location":"05_development/03_gsdfc_guide/#property-docstrings","title":"\ud83d\udce6 Property docstrings","text":"<p>Properties document their return values with a <code>Returns:</code> section and, when meaningful, an <code>Example:</code>.</p>"},{"location":"05_development/03_gsdfc_guide/#example","title":"\ud83d\ude80 Example","text":"<pre><code>def process(foo: Foo, multiplier: int) -&gt; int:\n \"\"\"Process a Foo instance.\n\n Args:\n foo (Foo):\n Foo instance to process.\n\n multiplier (int):\n Value used to scale foo.\n\n Returns:\n int:\n Processed result.\n\n Raises:\n ValueError:\n If multiplier is negative.\n\n Example:\n Process foo:\n\n ```python\n foo = Foo(\"example\", value=10)\n result = process(foo, multiplier=2)\n print(result)\n ```\n \"\"\"\n</code></pre>"},{"location":"05_development/03_gsdfc_guide/#keeping-stubs-in-sync","title":"\ud83d\udd04 Keeping stubs in sync","text":"<p>Every <code>.py</code> module ships a matching <code>.pyi</code> stub. When a signature or a public symbol changes, update both files. Signature annotations in the stub must match the implementation.</p>"},{"location":"05_development/03_gsdfc_guide/#enforcement","title":"\ud83d\udee1\ufe0f Enforcement","text":"<p><code>pydoclint</code> (Google style) runs in CI and verifies that <code>Args:</code>/<code>Returns:</code> sections match function signatures, including types.</p> <ul> <li><code>allow-init-docstring = true</code> \u2014 <code>__init__</code> docstrings are allowed.</li> <li><code>skip-checking-raises = true</code> \u2014 <code>Raises:</code> sections are descriptive and are not required to map to literal <code>raise</code> statements.</li> <li><code>check-class-attributes = false</code> \u2014 <code>Attributes:</code> sections document instance attributes without class-level annotations.</li> </ul>"},{"location":"05_development/03_gsdfc_guide/#related","title":"Related","text":"<ul> <li>02 \u2013 Quality Gates \u00b7 04 \u2013 MCP Guide</li> </ul>"},{"location":"05_development/04_mcp_guide/","title":"MCP Guide","text":"<p>Doc-forge can export a machine-readable MCP bundle from a project's GSDFC docstrings and serve that bundle over the Model Context Protocol (MCP). The bundle is self-contained: readers can derive the full API reference \u2014 signatures, docstrings, and structure \u2014 for the documented project.</p>"},{"location":"05_development/04_mcp_guide/#building-the-bundle","title":"\ud83d\ude80 Building the bundle","text":"<pre><code>doc-forge build --mcp --module docforge\n</code></pre> <p>This writes structured JSON into <code>docs/mcp/</code>:</p> <ul> <li><code>index.json</code> \u2014 project metadata and module count</li> <li><code>nav.json</code> \u2014 module list with <code>docs://modules/{module}</code> resource URIs</li> <li><code>modules/{dotted.path}.json</code> \u2014 per-module serialized documentation</li> </ul>"},{"location":"05_development/04_mcp_guide/#serving-the-bundle","title":"\ud83d\ude80 Serving the bundle","text":"<pre><code>doc-forge serve --mcp --module docforge\n</code></pre> <p>The <code>MCPServer</code> (in <code>docforge/servers/mcp_server.py</code>) exposes:</p> Resource Description <code>docs://index</code> Project metadata <code>docs://nav</code> Navigation structure <code>docs://modules/{module}</code> Individual module documentation <p>The server also registers a single diagnostic tool, <code>ping</code>, and is read-only. Missing resources are returned as structured error dictionaries rather than exceptions. The default transport is <code>streamable-http</code>; <code>stdio</code> and <code>sse</code> are supported via <code>MCPServer.run</code>.</p>"},{"location":"05_development/04_mcp_guide/#bundle-contents","title":"\ud83d\udce6 Bundle contents","text":"<p>Each module resource contains:</p> <ul> <li><code>path</code> \u2014 dotted module path</li> <li><code>docstring</code> \u2014 the raw GSDFC module docstring</li> <li><code>objects</code> \u2014 a recursive mapping of public symbols with <code>name</code>, <code>kind</code>, <code>path</code>, <code>signature</code>, and <code>docstring</code>, plus nested <code>members</code></li> </ul> <p>Because the bundle is generated from docstrings, the quality of the bundle equals the quality of the project's GSDFC docstrings. For docforge itself, the GSDFC specification is carried in <code>modules/docforge.json</code> via the <code>docforge/__init__.py</code> package docstring, making the bundle self-documenting.</p>"},{"location":"05_development/04_mcp_guide/#related","title":"Related","text":"<ul> <li>03 \u2013 GSDFC Guide \u00b7 05 \u2013 MkDocs Configs</li> </ul>"},{"location":"05_development/05_mkdocs_configs/","title":"MkDocs Configuration Model","text":"<p>Each documentation kind (lib, api, wiki) is built by its own MkDocs site. A repo that documents kind <code>{kind}</code> carries a config at <code>docs/mkdocs.{kind}.yml</code> that sets <code>docs_dir</code> to the kind's source directory and <code>site_dir</code> to <code>../site/{kind}</code>.</p>"},{"location":"05_development/05_mkdocs_configs/#file-wins","title":"\ud83d\udcc4 File wins","text":"<p><code>docs/mkdocs.{kind}.yml</code> is a repo-owned file, not a build byproduct:</p> <ul> <li>Absent \u2014 <code>doc-forge build --{kind}</code> materializes a copy from the packaged templates (see below) and then builds <code>site/{kind}</code>.</li> <li>Present \u2014 the build uses the file verbatim. Edits to the theme, palette, plugins, markdown extensions, nav, or <code>site_dir</code> are respected as-is.</li> <li><code>--refresh</code> \u2014 force-regenerates the file from the templates, replacing any local changes.</li> </ul> <p>Because a present file is never rewritten, rerunning a build is a no-op for versioned configs: the working tree stays clean.</p>"},{"location":"05_development/05_mkdocs_configs/#templates","title":"\ud83e\udde9 Templates","text":"<p>The built-in defaults live in <code>docforge/templates/</code>:</p> File Role <code>mkdocs.common.yml</code> Shared theme + markdown extensions <code>mkdocs.lib.yml</code> <code>mkdocstrings</code> handler for library reference <code>mkdocs.api.yml</code> Swagger/OpenAPI plugins and API-side features <code>mkdocs.wiki.yml</code> Wiki look: horizontal <code>navigation.tabs</code> header, blue grey/teal palette, Roboto <p>A per-kind config is generated by deep-merging the common template with the kind fragment, then filling in generation-time values (<code>site_name</code>, <code>docs_dir</code>, <code>site_dir</code>, <code>nav</code>, API <code>site_description</code>/<code>site_author</code>, and the theme <code>icon</code> from <code>docforge.nav.yml</code>). Pass <code>--template &lt;path&gt;</code> to replace the built-in templates entirely.</p>"},{"location":"05_development/05_mkdocs_configs/#supported-layouts","title":"\ud83c\udfd7\ufe0f Supported layouts","text":"<ul> <li>Per-kind config \u2014 the standard layout; each kind builds to <code>site/{kind}</code> and is served under <code>/&lt;repo&gt;/{kind}/</code>.</li> <li>Legacy root config \u2014 a repo with a single kind may instead author root <code>mkdocs.yml</code> (for example mongo-ops, whose wiki uses <code>docs_dir: docs/wiki</code>). doc-forge never reads or writes root <code>mkdocs.yml</code>; the docs service maps the kind to the root <code>site/</code> dir in this case.</li> </ul> <p>Commit <code>docs/mkdocs.{kind}.yml</code> so served docs are reproducible from source.</p>"},{"location":"05_development/05_mkdocs_configs/#related","title":"Related","text":"<ul> <li>04 \u2013 MCP Guide</li> </ul>"}]}