Compare commits
7 Commits
0.0.5
...
b5379cd82e
| Author | SHA1 | Date | |
|---|---|---|---|
| b5379cd82e | |||
| caeda0ad5c | |||
| 7643e27358 | |||
| 04db9f44d8 | |||
| 6c8da4b43b | |||
| 066e710dee | |||
| ed0fac8b3d |
@@ -1,86 +1,270 @@
|
|||||||
"""
|
"""
|
||||||
# doc-forge
|
Renderer-agnostic Python documentation compiler that converts docstrings into
|
||||||
|
structured documentation for both humans (MkDocs) and machines (MCP / AI agents).
|
||||||
|
|
||||||
`doc-forge` is a renderer-agnostic Python documentation compiler designed for
|
`doc-forge` statically analyzes your source code, builds a semantic model of
|
||||||
speed, flexibility, and beautiful output. It decouples the introspection of
|
modules and objects, and renders that model into documentation outputs without
|
||||||
your code from the rendering process, allowing you to generate documentation
|
executing your code.
|
||||||
for various platforms (starting with MkDocs) from a single internal models.
|
---
|
||||||
|
|
||||||
## Core Philosophy
|
# Core Philosophy
|
||||||
|
|
||||||
`doc-forge` operates on two fundamental principles:
|
`doc-forge` follows a compiler architecture:
|
||||||
|
|
||||||
1. **The Atomic Unit is a Python Import Path**: Documentation is organized around the semantic structure of your code (e.g., `mypackage.utils`), not the filesystem.
|
1. **Front-end (Introspection)**
|
||||||
2. **The Documentation Compiler Paradigm**: We separate documentation into three distinct phases:
|
Static analysis of modules, classes, functions, signatures, and docstrings.
|
||||||
- **Front-end (Introspection)**: Static analysis of source code and docstrings.
|
|
||||||
- **Middle-end (Semantic Model)**: A renderer-neutral internal representation.
|
|
||||||
- **Back-end (Renderers)**: Generation of human-facing (MkDocs) or machine-facing (MCP) outputs.
|
|
||||||
|
|
||||||
## Documentation Design
|
2. **Middle-end (Semantic Model)**
|
||||||
|
Renderer-neutral structured representation of your API.
|
||||||
|
|
||||||
`doc-forge` is an "AI-Native" documentation compiler. To get the most out of it, design your docstrings with both humans and LLMs in mind:
|
3. **Back-end (Renderers)**
|
||||||
|
|
||||||
### For Humans (Readability & Structure)
|
* MkDocs → human documentation
|
||||||
- **`__init__.py` as Landing Pages**: Use the docstring of your package's `__init__.py` as the home page. Include overviews, installation instructions, and high-level examples here.
|
* MCP JSON → AI-readable documentation
|
||||||
- **Single Source of Truth**: Keep all technical details in docstrings. This ensures your MkDocs/Sphinx sites stay in sync with the code.
|
---
|
||||||
- **Semantic Hierarchy**: Use standard Markdown headers to structure complex module documentation.
|
|
||||||
|
|
||||||
### For LLMs (AI-Native Knowledge)
|
# Docstring Writing Standard
|
||||||
- **Model Context Protocol (MCP)**: `doc-forge` exports your docs as structured JSON. This allows AI agents to "understand" your API surface area without layout noise.
|
|
||||||
- **Canonical Paths**: Use dotted import paths as primary identifiers. AI tools use these to link code usage to documentation.
|
|
||||||
- **Type Annotations**: While not in docstrings, `doc-forge` (via Griffe) extracts signatures. Clean type hints dramatically improve an LLM's ability to generate correct code using your library.
|
|
||||||
## Available Commands
|
|
||||||
|
|
||||||
- **build**: Build documentation (MkDocs site or MCP resources).
|
Docstrings are the single source of truth. `doc-forge` does not generate content.
|
||||||
- **serve**: Serve documentation (MkDocs or MCP).
|
It compiles and renders what you write.
|
||||||
- **tree**: Visualize the introspected project structure.
|
|
||||||
|
|
||||||
## Installation
|
Documentation follows the Python import hierarchy.
|
||||||
|
---
|
||||||
|
|
||||||
Install using `pip` with the optional `mkdocs` dependencies for a complete setup:
|
# Package docstring (`package/__init__.py`) — Full user guide
|
||||||
|
|
||||||
|
This is the landing page. A developer must be able to install and use the
|
||||||
|
package after reading only this docstring.
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
|
||||||
|
'''
|
||||||
|
Short description of what this package provides.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install doc-forge
|
pip install my-package
|
||||||
```
|
```
|
||||||
|
|
||||||
## Quick Start
|
# Quick start
|
||||||
|
|
||||||
|
```python
|
||||||
|
from my_package.foo import Bar
|
||||||
|
|
||||||
|
bar = Bar()
|
||||||
|
result = bar.process("example")
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
# Core concepts
|
||||||
|
|
||||||
|
## Bar
|
||||||
|
- Primary object exposed by the package.
|
||||||
|
|
||||||
|
## foo module
|
||||||
|
- Provides core functionality.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Typical workflow
|
||||||
|
|
||||||
|
1. Import public objects
|
||||||
|
2. Initialize objects
|
||||||
|
3. Call methods
|
||||||
|
---
|
||||||
|
|
||||||
|
# Public API
|
||||||
|
|
||||||
|
foo.Bar
|
||||||
|
foo.helper_function
|
||||||
|
---
|
||||||
|
'''
|
||||||
|
---
|
||||||
|
|
||||||
|
# Submodule docstring (`package/foo/__init__.py`) — Subsystem guide
|
||||||
|
|
||||||
|
Explains a specific subsystem.
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
|
||||||
|
'''
|
||||||
|
Provides core functionality.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```python
|
||||||
|
from my_package.foo import Bar
|
||||||
|
|
||||||
|
bar = Bar()
|
||||||
|
bar.process("example")
|
||||||
|
```
|
||||||
|
---
|
||||||
|
'''
|
||||||
|
---
|
||||||
|
|
||||||
|
# Class docstring — Object contract
|
||||||
|
|
||||||
|
Defines responsibility and behavior.
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Bar:
|
||||||
|
'''
|
||||||
|
Performs processing on input data.
|
||||||
|
|
||||||
|
Instances may be reused across multiple calls.
|
||||||
|
---
|
||||||
|
'''
|
||||||
|
```
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* Responsibility
|
||||||
|
* Lifecycle expectations
|
||||||
|
* Thread safety (if relevant)
|
||||||
|
* Performance characteristics (if relevant)
|
||||||
|
---
|
||||||
|
|
||||||
|
# Function and method docstrings — API specification
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def process(
|
||||||
|
self,
|
||||||
|
value1: str,
|
||||||
|
value2: str | None = "default value",
|
||||||
|
value3: str | None = None,
|
||||||
|
) -> str:
|
||||||
|
'''
|
||||||
|
Process an input value.
|
||||||
|
---
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
value1 : str
|
||||||
|
required: True
|
||||||
|
value to be processed
|
||||||
|
Example:
|
||||||
|
'string'
|
||||||
|
|
||||||
|
value2 : str
|
||||||
|
required: False
|
||||||
|
default: "default value"
|
||||||
|
value to be processed
|
||||||
|
Example:
|
||||||
|
'string'
|
||||||
|
|
||||||
|
value3 : str
|
||||||
|
required: False
|
||||||
|
value to be processed
|
||||||
|
Example:
|
||||||
|
'string'
|
||||||
|
---
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
processed value : str
|
||||||
|
result after processing value
|
||||||
|
---
|
||||||
|
|
||||||
|
Behavior
|
||||||
|
--------
|
||||||
|
- behaviour 1
|
||||||
|
- behaviour 2
|
||||||
|
---
|
||||||
|
'''
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
# Attribute docstrings (optional)
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Class
|
||||||
|
'''
|
||||||
|
attribute1 : str
|
||||||
|
required: True
|
||||||
|
default: "default value"
|
||||||
|
attribute description
|
||||||
|
|
||||||
|
attribute2 : str
|
||||||
|
required: False
|
||||||
|
attribute description
|
||||||
|
|
||||||
|
attribute2 : str
|
||||||
|
required: False
|
||||||
|
default: "default value"
|
||||||
|
attribute description
|
||||||
|
'''
|
||||||
|
|
||||||
|
attribute1: str = "default value"
|
||||||
|
attribute2: str | None = None
|
||||||
|
attribute3: str | None = "default value"
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
# Writing Rules
|
||||||
|
|
||||||
|
**Heading hierarchy**
|
||||||
|
|
||||||
|
Module docstring
|
||||||
|
|
||||||
|
- Examples
|
||||||
|
- Usage
|
||||||
|
- Core concepts
|
||||||
|
- Public API
|
||||||
|
|
||||||
|
Class docstring
|
||||||
|
|
||||||
|
- Attributes
|
||||||
|
- Execution contract
|
||||||
|
- Lifecycle
|
||||||
|
- Thread safety
|
||||||
|
- Notes
|
||||||
|
|
||||||
|
Method docstring
|
||||||
|
|
||||||
|
- Parameters
|
||||||
|
- Returns
|
||||||
|
- Raises
|
||||||
|
- Yields
|
||||||
|
- Behavior
|
||||||
|
|
||||||
|
**Required**
|
||||||
|
|
||||||
|
* Use Markdown headings
|
||||||
|
* Use Markdown line separator `---`
|
||||||
|
* Line separator should be followed by a blank line
|
||||||
|
* Provide real import examples
|
||||||
|
* Document all public APIs
|
||||||
|
* Keep descriptions precise and factual
|
||||||
|
|
||||||
|
**Avoid**
|
||||||
|
|
||||||
|
* Plain-text separators like `====`
|
||||||
|
* Duplicate external documentation
|
||||||
|
* Informal or conversational language
|
||||||
|
---
|
||||||
|
|
||||||
|
# How doc-forge uses these docstrings
|
||||||
|
|
||||||
|
## Build MkDocs site:
|
||||||
|
|
||||||
1. **Build Documentation**:
|
|
||||||
Introspect your package and generate documentation in one step:
|
|
||||||
```bash
|
```bash
|
||||||
# Build MkDocs site
|
doc-forge build --mkdocs --module my_package
|
||||||
doc-forge build --mkdocs --module my_package --site-name "My Docs"
|
```
|
||||||
|
|
||||||
# Build MCP resources
|
## Build MCP documentation:
|
||||||
|
|
||||||
|
```bash
|
||||||
doc-forge build --mcp --module my_package
|
doc-forge build --mcp --module my_package
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Define Navigation**:
|
Both outputs are generated directly from docstrings.
|
||||||
Create a `docforge.nav.yml` to organize your documentation:
|
---
|
||||||
```yaml
|
|
||||||
home: my_package/index.md
|
|
||||||
groups:
|
|
||||||
Core API:
|
|
||||||
- my_package/core/*.md
|
|
||||||
Utilities:
|
|
||||||
- my_package/utils.md
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Preview**:
|
|
||||||
```bash
|
|
||||||
# Serve MkDocs site
|
|
||||||
doc-forge serve --mkdocs
|
|
||||||
|
|
||||||
# Serve MCP documentation
|
|
||||||
doc-forge serve --mcp
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
- `docforge.loaders`: Introspects source code using static analysis (`griffe`).
|
|
||||||
- `docforge.models`: The internal representation of your project, modules, and objects.
|
|
||||||
- `docforge.renderers`: Converters that turn the models into physical files.
|
|
||||||
- `docforge.nav`: Managers for logical-to-physical path mapping and navigation.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .loaders import GriffeLoader, discover_module_paths
|
from .loaders import GriffeLoader, discover_module_paths
|
||||||
|
|||||||
@@ -31,3 +31,8 @@ plugins:
|
|||||||
annotations_path: brief
|
annotations_path: brief
|
||||||
show_root_heading: true
|
show_root_heading: true
|
||||||
group_by_category: true
|
group_by_category: true
|
||||||
|
|
||||||
|
markdown_extensions:
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.tabbed:
|
||||||
|
alternate_style: true
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"module": "docforge",
|
"module": "docforge",
|
||||||
"content": {
|
"content": {
|
||||||
"path": "docforge",
|
"path": "docforge",
|
||||||
"docstring": "# doc-forge\n\n`doc-forge` is a renderer-agnostic Python documentation compiler designed for\nspeed, flexibility, and beautiful output. It decouples the introspection of\nyour code from the rendering process, allowing you to generate documentation\nfor various platforms (starting with MkDocs) from a single internal models.\n\n## Core Philosophy\n\n`doc-forge` operates on two fundamental principles:\n\n1. **The Atomic Unit is a Python Import Path**: Documentation is organized around the semantic structure of your code (e.g., `mypackage.utils`), not the filesystem.\n2. **The Documentation Compiler Paradigm**: We separate documentation into three distinct phases:\n - **Front-end (Introspection)**: Static analysis of source code and docstrings.\n - **Middle-end (Semantic Model)**: A renderer-neutral internal representation.\n - **Back-end (Renderers)**: Generation of human-facing (MkDocs) or machine-facing (MCP) outputs.\n\n## Documentation Design\n\n`doc-forge` is an \"AI-Native\" documentation compiler. To get the most out of it, design your docstrings with both humans and LLMs in mind:\n\n### For Humans (Readability & Structure)\n- **`__init__.py` as Landing Pages**: Use the docstring of your package's `__init__.py` as the home page. Include overviews, installation instructions, and high-level examples here.\n- **Single Source of Truth**: Keep all technical details in docstrings. This ensures your MkDocs/Sphinx sites stay in sync with the code.\n- **Semantic Hierarchy**: Use standard Markdown headers to structure complex module documentation.\n\n### For LLMs (AI-Native Knowledge)\n- **Model Context Protocol (MCP)**: `doc-forge` exports your docs as structured JSON. This allows AI agents to \"understand\" your API surface area without layout noise.\n- **Canonical Paths**: Use dotted import paths as primary identifiers. AI tools use these to link code usage to documentation.\n- **Type Annotations**: While not in docstrings, `doc-forge` (via Griffe) extracts signatures. Clean type hints dramatically improve an LLM's ability to generate correct code using your library.\n## Available Commands\n\n- **build**: Build documentation (MkDocs site or MCP resources).\n- **serve**: Serve documentation (MkDocs or MCP).\n- **tree**: Visualize the introspected project structure.\n\n## Installation\n\nInstall using `pip` with the optional `mkdocs` dependencies for a complete setup:\n\n```bash\npip install doc-forge\n```\n\n## Quick Start\n\n1. **Build Documentation**:\n Introspect your package and generate documentation in one step:\n ```bash\n # Build MkDocs site\n doc-forge build --mkdocs --module my_package --site-name \"My Docs\"\n\n # Build MCP resources\n doc-forge build --mcp --module my_package\n ```\n\n2. **Define Navigation**:\n Create a `docforge.nav.yml` to organize your documentation:\n ```yaml\n home: my_package/index.md\n groups:\n Core API:\n - my_package/core/*.md\n Utilities:\n - my_package/utils.md\n ```\n\n3. **Preview**:\n ```bash\n # Serve MkDocs site\n doc-forge serve --mkdocs\n\n # Serve MCP documentation\n doc-forge serve --mcp\n ```\n\n## Project Structure\n\n- `docforge.loaders`: Introspects source code using static analysis (`griffe`).\n- `docforge.models`: The internal representation of your project, modules, and objects.\n- `docforge.renderers`: Converters that turn the models into physical files.\n- `docforge.nav`: Managers for logical-to-physical path mapping and navigation.",
|
"docstring": "Renderer-agnostic Python documentation compiler that converts docstrings into\nstructured documentation for both humans (MkDocs) and machines (MCP / AI agents).\n\n`doc-forge` statically analyzes your source code, builds a semantic model of\nmodules and objects, and renders that model into documentation outputs without\nexecuting your code.\n---\n\n# Core Philosophy\n\n`doc-forge` follows a compiler architecture:\n\n1. **Front-end (Introspection)**\n Static analysis of modules, classes, functions, signatures, and docstrings.\n\n2. **Middle-end (Semantic Model)**\n Renderer-neutral structured representation of your API.\n\n3. **Back-end (Renderers)**\n\n * MkDocs → human documentation\n * MCP JSON → AI-readable documentation\n---\n\n# Docstring Writing Standard\n\nDocstrings are the single source of truth. `doc-forge` does not generate content.\nIt compiles and renders what you write.\n\nDocumentation follows the Python import hierarchy.\n---\n\n# Package docstring (`package/__init__.py`) — Full user guide\n\nThis is the landing page. A developer must be able to install and use the\npackage after reading only this docstring.\n\n## Example:\n\n '''\n Short description of what this package provides.\n\n # Installation\n\n ```bash\n pip install my-package\n ```\n\n # Quick start\n\n ```python\n from my_package.foo import Bar\n\n bar = Bar()\n result = bar.process(\"example\")\n ```\n ---\n\n # Core concepts\n\n ## Bar\n - Primary object exposed by the package.\n\n ## foo module\n - Provides core functionality.\n ---\n\n # Typical workflow\n\n 1. Import public objects\n 2. Initialize objects\n 3. Call methods\n ---\n\n # Public API\n\n foo.Bar\n foo.helper_function\n ---\n '''\n---\n\n# Submodule docstring (`package/foo/__init__.py`) — Subsystem guide\n\nExplains a specific subsystem.\n\n## Example:\n\n '''\n Provides core functionality.\n\n # Usage\n\n ```python\n from my_package.foo import Bar\n\n bar = Bar()\n bar.process(\"example\")\n ```\n ---\n '''\n---\n\n# Class docstring — Object contract\n\nDefines responsibility and behavior.\n\n## Example:\n\n```python\nclass Bar:\n '''\n Performs processing on input data.\n\n Instances may be reused across multiple calls.\n ---\n '''\n```\n\nInclude:\n\n* Responsibility\n* Lifecycle expectations\n* Thread safety (if relevant)\n* Performance characteristics (if relevant)\n---\n\n# Function and method docstrings — API specification\n\n## Example:\n\n```python\ndef process(\n self,\n value1: str,\n value2: str | None = \"default value\",\n value3: str | None = None,\n) -> str:\n '''\n Process an input value.\n ---\n\n Parameters\n ----------\n value1 : str\n required: True\n value to be processed\n Example:\n 'string'\n\n value2 : str\n required: False\n default: \"default value\"\n value to be processed\n Example:\n 'string'\n\n value3 : str\n required: False\n value to be processed\n Example:\n 'string'\n ---\n\n Returns\n -------\n processed value : str\n result after processing value\n ---\n\n Behavior\n --------\n - behaviour 1\n - behaviour 2\n ---\n '''\n```\n---\n\n# Attribute docstrings (optional)\n\n## Example:\n\n```python\nclass Class\n '''\n attribute1 : str\n required: True\n default: \"default value\"\n attribute description\n\n attribute2 : str\n required: False\n attribute description\n\n attribute2 : str\n required: False\n default: \"default value\"\n attribute description\n '''\n\n attribute1: str = \"default value\"\n attribute2: str | None = None\n attribute3: str | None = \"default value\"\n```\n---\n\n# Writing Rules\n\n**Heading hierarchy**\n\nModule docstring\n\n- Examples\n- Usage\n- Core concepts\n- Public API\n\nClass docstring\n\n- Attributes\n- Execution contract\n- Lifecycle\n- Thread safety\n- Notes\n\nMethod docstring\n\n- Parameters\n- Returns\n- Raises\n- Yields\n- Behavior\n\n**Required**\n\n* Use Markdown headings\n* Use Markdown line separator `---`\n* Line separator should be followed by a blank line\n* Provide real import examples\n* Document all public APIs\n* Keep descriptions precise and factual\n\n**Avoid**\n\n* Plain-text separators like `====`\n* Duplicate external documentation\n* Informal or conversational language\n---\n\n# How doc-forge uses these docstrings\n\n## Build MkDocs site:\n\n```bash\ndoc-forge build --mkdocs --module my_package\n```\n\n## Build MCP documentation:\n\n```bash\ndoc-forge build --mcp --module my_package\n```\n\nBoth outputs are generated directly from docstrings.\n---",
|
||||||
"objects": {
|
"objects": {
|
||||||
"GriffeLoader": {
|
"GriffeLoader": {
|
||||||
"name": "GriffeLoader",
|
"name": "GriffeLoader",
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ plugins:
|
|||||||
annotations_path: brief
|
annotations_path: brief
|
||||||
show_root_heading: true
|
show_root_heading: true
|
||||||
group_by_category: true
|
group_by_category: true
|
||||||
|
markdown_extensions:
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.tabbed:
|
||||||
|
alternate_style: true
|
||||||
site_name: docforge
|
site_name: docforge
|
||||||
nav:
|
nav:
|
||||||
- Home: index.md
|
- Home: index.md
|
||||||
|
|||||||
Reference in New Issue
Block a user