611 lines
19 KiB
Markdown
611 lines
19 KiB
Markdown
---
|
|
name: Code Documenter
|
|
description: Add comprehensive inline documentation to code including docstrings, comments, and API documentation (OpenAPI/Swagger). Use when the user wants to document functions, classes, APIs, add docstrings, generate API specs, or mentions improving code documentation, adding comments, or creating OpenAPI/Swagger documentation.
|
|
---
|
|
|
|
# Code Documenter
|
|
|
|
A specialized skill for adding comprehensive inline documentation to code across multiple programming languages and frameworks. This skill focuses on improving code maintainability through clear, consistent documentation.
|
|
|
|
## Instructions
|
|
|
|
### Core Workflow
|
|
|
|
1. **Gather documentation requirements**
|
|
- Ask for target files or directories to document
|
|
- **Prompt for docstring format preference**:
|
|
- Python: Google, NumPy, Sphinx, or reStructuredText style?
|
|
- JavaScript/TypeScript: JSDoc format?
|
|
- Other languages: Default to language conventions
|
|
- **Ask about file exclusions**:
|
|
- Should test files be excluded?
|
|
- Should generated code be excluded?
|
|
- Should vendor/third-party code be excluded?
|
|
- Are there specific paths or patterns to exclude?
|
|
- **Ask about special documentation needs**:
|
|
- Do any files need different documentation styles?
|
|
- Are there specific modules that need more detailed docs?
|
|
- Should examples be included for complex functions?
|
|
|
|
2. **Identify project type and framework**
|
|
- Detect programming language(s)
|
|
- Identify web framework (if API documentation needed)
|
|
- Determine appropriate documentation strategy
|
|
|
|
3. **Analyze existing documentation**
|
|
- Use Grep to find undocumented functions/classes
|
|
- Assess current documentation quality
|
|
- Identify inconsistencies in style
|
|
|
|
4. **Document code systematically**
|
|
- Start with public APIs and exported functions
|
|
- Document classes and their methods
|
|
- Document complex private functions
|
|
- Add module-level documentation
|
|
- Follow user's preferred style consistently
|
|
|
|
5. **Generate API documentation (if applicable)**
|
|
- Apply framework-specific API documentation strategy
|
|
- See API Documentation Strategy section below
|
|
|
|
6. **Verify and validate**
|
|
- Ensure all public APIs are documented
|
|
- Verify documentation accuracy
|
|
- Check for consistency in style
|
|
- Run documentation linters if available
|
|
|
|
7. **Generate documentation report**
|
|
- Create summary of changes
|
|
- Report coverage metrics (before/after)
|
|
- List files modified
|
|
- Provide recommendations for ongoing documentation practices
|
|
|
|
### API Documentation Strategy
|
|
|
|
Different frameworks have different approaches to API documentation. Apply the appropriate strategy based on the detected framework:
|
|
|
|
#### Django / Django REST Framework
|
|
**Strategy**: Leverage built-in schema generation
|
|
- Django REST Framework auto-generates OpenAPI schemas
|
|
- Add docstrings to viewsets and serializers
|
|
- Use `schema` parameter in `@api_view` decorator for additional details
|
|
- Install `drf-spectacular` for enhanced automatic documentation
|
|
- **Minimal manual OpenAPI work needed** - focus on clear docstrings
|
|
|
|
Example:
|
|
```python
|
|
class UserViewSet(viewsets.ModelViewSet):
|
|
"""
|
|
API endpoint for managing users.
|
|
|
|
list: Return a list of all users.
|
|
create: Create a new user.
|
|
retrieve: Return a specific user by ID.
|
|
update: Update an existing user.
|
|
destroy: Delete a user.
|
|
"""
|
|
queryset = User.objects.all()
|
|
serializer_class = UserSerializer
|
|
```
|
|
|
|
#### FastAPI
|
|
**Strategy**: Leverage automatic Swagger generation from type hints
|
|
- FastAPI auto-generates OpenAPI/Swagger docs from Python type hints
|
|
- Use Pydantic models for request/response schemas
|
|
- Add docstrings to path operations for descriptions
|
|
- Use `response_model` parameter for response documentation
|
|
- Use `status_code` and `responses` parameters for detailed responses
|
|
- **Type hints are the primary documentation mechanism**
|
|
|
|
Example:
|
|
```python
|
|
@app.post("/users/", response_model=UserResponse, status_code=201)
|
|
async def create_user(user: UserCreate) -> UserResponse:
|
|
"""
|
|
Create a new user.
|
|
|
|
Args:
|
|
user: User data including name, email, and password
|
|
|
|
Returns:
|
|
UserResponse: Created user with generated ID
|
|
|
|
Raises:
|
|
HTTPException: 400 if email already exists
|
|
"""
|
|
# Implementation
|
|
```
|
|
|
|
#### NestJS (TypeScript)
|
|
**Strategy**: Add OpenAPI decorators to controllers and DTOs
|
|
- Install `@nestjs/swagger` package
|
|
- Use `@ApiTags()`, `@ApiOperation()`, `@ApiResponse()` on controllers
|
|
- Use `@ApiProperty()` on DTO classes
|
|
- Use `@ApiParam()`, `@ApiQuery()`, `@ApiBody()` for parameters
|
|
- **Requires manual OpenAPI decorators**
|
|
|
|
Example:
|
|
```typescript
|
|
@ApiTags('users')
|
|
@Controller('users')
|
|
export class UsersController {
|
|
@Post()
|
|
@ApiOperation({ summary: 'Create a new user' })
|
|
@ApiResponse({ status: 201, description: 'User created successfully', type: UserDto })
|
|
@ApiResponse({ status: 400, description: 'Invalid input data' })
|
|
@ApiBody({ type: CreateUserDto })
|
|
async create(@Body() createUserDto: CreateUserDto): Promise<UserDto> {
|
|
// Implementation
|
|
}
|
|
}
|
|
|
|
export class CreateUserDto {
|
|
@ApiProperty({ description: 'User email address', example: 'user@example.com' })
|
|
@IsEmail()
|
|
email: string;
|
|
|
|
@ApiProperty({ description: 'User full name', example: 'John Doe' })
|
|
@IsString()
|
|
name: string;
|
|
}
|
|
```
|
|
|
|
#### Go (Gin, Echo, Chi, Gorilla Mux)
|
|
**Strategy**: Use swag annotations or manual OpenAPI spec
|
|
- Option 1: Use `swaggo/swag` for annotation-based documentation
|
|
- Option 2: Write OpenAPI spec manually in YAML/JSON
|
|
- **Requires manual documentation** - Go doesn't auto-generate from types
|
|
|
|
With swag annotations:
|
|
```go
|
|
// CreateUser godoc
|
|
// @Summary Create a new user
|
|
// @Description Create a new user with the provided information
|
|
// @Tags users
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param user body CreateUserRequest true "User data"
|
|
// @Success 201 {object} UserResponse
|
|
// @Failure 400 {object} ErrorResponse
|
|
// @Router /users [post]
|
|
func (h *UserHandler) CreateUser(c *gin.Context) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Express.js (Node.js)
|
|
**Strategy**: Use swagger-jsdoc with JSDoc comments
|
|
- Install `swagger-jsdoc` and `swagger-ui-express`
|
|
- Add JSDoc comments with OpenAPI schema
|
|
- **Requires manual JSDoc OpenAPI annotations**
|
|
|
|
Example:
|
|
```javascript
|
|
/**
|
|
* @swagger
|
|
* /users:
|
|
* post:
|
|
* summary: Create a new user
|
|
* tags: [Users]
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* required:
|
|
* - email
|
|
* - name
|
|
* properties:
|
|
* email:
|
|
* type: string
|
|
* format: email
|
|
* name:
|
|
* type: string
|
|
* responses:
|
|
* 201:
|
|
* description: User created successfully
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/User'
|
|
* 400:
|
|
* description: Invalid input
|
|
*/
|
|
router.post('/users', createUser);
|
|
```
|
|
|
|
#### ASP.NET Core (C#)
|
|
**Strategy**: Use XML comments with Swashbuckle
|
|
- Add XML documentation comments
|
|
- Configure Swashbuckle to include XML comments
|
|
- Use attributes like `[ProducesResponseType]` for responses
|
|
|
|
Example:
|
|
```csharp
|
|
/// <summary>
|
|
/// Creates a new user
|
|
/// </summary>
|
|
/// <param name="request">User creation request</param>
|
|
/// <returns>Created user</returns>
|
|
/// <response code="201">User created successfully</response>
|
|
/// <response code="400">Invalid input data</response>
|
|
[HttpPost]
|
|
[ProducesResponseType(typeof(UserResponse), StatusCodes.Status201Created)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
|
|
{
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
### Language-Specific Documentation Formats
|
|
|
|
#### Python
|
|
**Google Style** (default recommendation):
|
|
```python
|
|
def calculate_total(items: list[Item], tax_rate: float = 0.0) -> float:
|
|
"""Calculate the total cost including tax.
|
|
|
|
Args:
|
|
items: List of items to calculate total for
|
|
tax_rate: Tax rate as decimal (e.g., 0.08 for 8%). Defaults to 0.0
|
|
|
|
Returns:
|
|
Total cost including tax
|
|
|
|
Raises:
|
|
ValueError: If tax_rate is negative or items list is empty
|
|
|
|
Example:
|
|
>>> items = [Item(price=10.0), Item(price=20.0)]
|
|
>>> calculate_total(items, tax_rate=0.08)
|
|
32.4
|
|
"""
|
|
```
|
|
|
|
**NumPy Style**:
|
|
```python
|
|
def calculate_total(items, tax_rate=0.0):
|
|
"""
|
|
Calculate the total cost including tax.
|
|
|
|
Parameters
|
|
----------
|
|
items : list of Item
|
|
List of items to calculate total for
|
|
tax_rate : float, optional
|
|
Tax rate as decimal (e.g., 0.08 for 8%), by default 0.0
|
|
|
|
Returns
|
|
-------
|
|
float
|
|
Total cost including tax
|
|
|
|
Raises
|
|
------
|
|
ValueError
|
|
If tax_rate is negative or items list is empty
|
|
"""
|
|
```
|
|
|
|
**Sphinx Style**:
|
|
```python
|
|
def calculate_total(items, tax_rate=0.0):
|
|
"""
|
|
Calculate the total cost including tax.
|
|
|
|
:param items: List of items to calculate total for
|
|
:type items: list[Item]
|
|
:param tax_rate: Tax rate as decimal, defaults to 0.0
|
|
:type tax_rate: float, optional
|
|
:return: Total cost including tax
|
|
:rtype: float
|
|
:raises ValueError: If tax_rate is negative or items list is empty
|
|
"""
|
|
```
|
|
|
|
#### JavaScript/TypeScript (JSDoc)
|
|
```javascript
|
|
/**
|
|
* Calculate the total cost including tax
|
|
*
|
|
* @param {Item[]} items - List of items to calculate total for
|
|
* @param {number} [taxRate=0.0] - Tax rate as decimal (e.g., 0.08 for 8%)
|
|
* @returns {number} Total cost including tax
|
|
* @throws {Error} If tax_rate is negative or items array is empty
|
|
*
|
|
* @example
|
|
* const items = [{ price: 10.0 }, { price: 20.0 }];
|
|
* const total = calculateTotal(items, 0.08);
|
|
* console.log(total); // 32.4
|
|
*/
|
|
function calculateTotal(items, taxRate = 0.0) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
TypeScript with type annotations:
|
|
```typescript
|
|
/**
|
|
* Calculate the total cost including tax
|
|
*
|
|
* @param items - List of items to calculate total for
|
|
* @param taxRate - Tax rate as decimal (e.g., 0.08 for 8%)
|
|
* @returns Total cost including tax
|
|
* @throws {Error} If tax_rate is negative or items array is empty
|
|
*/
|
|
function calculateTotal(items: Item[], taxRate: number = 0.0): number {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Java (Javadoc)
|
|
```java
|
|
/**
|
|
* Calculate the total cost including tax
|
|
*
|
|
* @param items List of items to calculate total for
|
|
* @param taxRate Tax rate as decimal (e.g., 0.08 for 8%)
|
|
* @return Total cost including tax
|
|
* @throws IllegalArgumentException if tax_rate is negative or items list is empty
|
|
*
|
|
* @see Item
|
|
* @since 1.0
|
|
*/
|
|
public double calculateTotal(List<Item> items, double taxRate) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Go
|
|
```go
|
|
// CalculateTotal calculates the total cost including tax.
|
|
//
|
|
// Parameters:
|
|
// - items: Slice of items to calculate total for
|
|
// - taxRate: Tax rate as decimal (e.g., 0.08 for 8%)
|
|
//
|
|
// Returns:
|
|
// - Total cost including tax
|
|
// - Error if tax_rate is negative or items slice is empty
|
|
//
|
|
// Example:
|
|
//
|
|
// items := []Item{{Price: 10.0}, {Price: 20.0}}
|
|
// total, err := CalculateTotal(items, 0.08)
|
|
func CalculateTotal(items []Item, taxRate float64) (float64, error) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Rust (Rustdoc)
|
|
```rust
|
|
/// Calculate the total cost including tax
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `items` - Vector of items to calculate total for
|
|
/// * `tax_rate` - Tax rate as decimal (e.g., 0.08 for 8%)
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Total cost including tax
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns `Err` if tax_rate is negative or items vector is empty
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// let items = vec![Item { price: 10.0 }, Item { price: 20.0 }];
|
|
/// let total = calculate_total(&items, 0.08)?;
|
|
/// assert_eq!(total, 32.4);
|
|
/// ```
|
|
pub fn calculate_total(items: &[Item], tax_rate: f64) -> Result<f64, String> {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### C/C++ (Doxygen)
|
|
```c
|
|
/**
|
|
* @brief Calculate the total cost including tax
|
|
*
|
|
* @param items Array of items to calculate total for
|
|
* @param count Number of items in the array
|
|
* @param tax_rate Tax rate as decimal (e.g., 0.08 for 8%)
|
|
* @return double Total cost including tax, or -1.0 on error
|
|
*
|
|
* @note Returns -1.0 if tax_rate is negative or count is 0
|
|
* @see Item
|
|
*/
|
|
double calculate_total(const Item* items, size_t count, double tax_rate) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### PHP (PHPDoc)
|
|
```php
|
|
/**
|
|
* Calculate the total cost including tax
|
|
*
|
|
* @param Item[] $items List of items to calculate total for
|
|
* @param float $taxRate Tax rate as decimal (e.g., 0.08 for 8%)
|
|
* @return float Total cost including tax
|
|
* @throws InvalidArgumentException if tax_rate is negative or items array is empty
|
|
*
|
|
* @example
|
|
* $items = [new Item(10.0), new Item(20.0)];
|
|
* $total = calculateTotal($items, 0.08);
|
|
* echo $total; // 32.4
|
|
*/
|
|
function calculateTotal(array $items, float $taxRate = 0.0): float {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
#### Ruby (YARD)
|
|
```ruby
|
|
# Calculate the total cost including tax
|
|
#
|
|
# @param items [Array<Item>] List of items to calculate total for
|
|
# @param tax_rate [Float] Tax rate as decimal (e.g., 0.08 for 8%)
|
|
# @return [Float] Total cost including tax
|
|
# @raise [ArgumentError] if tax_rate is negative or items array is empty
|
|
#
|
|
# @example Calculate total with tax
|
|
# items = [Item.new(10.0), Item.new(20.0)]
|
|
# calculate_total(items, 0.08) #=> 32.4
|
|
def calculate_total(items, tax_rate = 0.0)
|
|
# Implementation
|
|
end
|
|
```
|
|
|
|
### Documentation Report Structure
|
|
|
|
Generate a report named `{project_name}_documentation_report.md` with these sections:
|
|
|
|
1. **Documentation Coverage**
|
|
- Before: X% of functions/classes documented
|
|
- After: Y% of functions/classes documented
|
|
- Files analyzed: N
|
|
- Functions/classes documented: M
|
|
|
|
2. **Files Modified**
|
|
- List of all files with added/updated documentation
|
|
- Number of functions/classes documented per file
|
|
|
|
3. **Documentation Standards Applied**
|
|
- Docstring format used (e.g., Google style for Python)
|
|
- API documentation strategy (e.g., FastAPI auto-generation)
|
|
- Any custom conventions followed
|
|
|
|
4. **API Documentation**
|
|
- Framework detected
|
|
- Strategy applied
|
|
- OpenAPI/Swagger endpoint (if applicable)
|
|
- Additional setup required (if any)
|
|
|
|
5. **Recommendations**
|
|
- Suggestions for maintaining documentation quality
|
|
- Tools to install for documentation linting
|
|
- CI/CD integration suggestions (e.g., enforce docstring coverage)
|
|
- Areas that need manual review or additional detail
|
|
|
|
## Critical Rules
|
|
|
|
### Always Do
|
|
- Prompt user for docstring format preference before starting
|
|
- Ask about file exclusions and special documentation needs
|
|
- Detect framework for appropriate API documentation strategy
|
|
- Ensure documentation is accurate based on code analysis
|
|
- Document all parameters and return values
|
|
- Include error/exception documentation
|
|
- Follow language and framework conventions consistently
|
|
- Generate comprehensive documentation report
|
|
|
|
### Never Do
|
|
- Never assume docstring format - always ask the user
|
|
- Never document without analyzing the code first
|
|
- Never write inaccurate or misleading documentation
|
|
- Never ignore user's exclusion preferences
|
|
- Never apply the wrong API documentation strategy for the framework
|
|
- Never forget to document exceptions/errors
|
|
- Never skip the documentation report
|
|
|
|
## Knowledge Base
|
|
|
|
- **Docstring Formats**: Expert in Google, NumPy, Sphinx, JSDoc, Javadoc, PHPDoc, YARD, Rustdoc, Doxygen
|
|
- **API Documentation**: Expert in OpenAPI/Swagger, framework-specific strategies
|
|
- **Frameworks**: Django, FastAPI, NestJS, Express.js, ASP.NET Core, Gin, Echo
|
|
- **Languages**: Python, JavaScript/TypeScript, Java, Go, Ruby, C/C++, Rust, PHP
|
|
- **Documentation Tools**: Sphinx, JSDoc, Swagger, Doxygen, Rustdoc, godoc
|
|
|
|
## Integration with Other Skills
|
|
|
|
- **Receives from**: Spec Miner (code analysis to inform documentation)
|
|
- **Works with**: Fullstack Guardian (can document during implementation)
|
|
- **Outputs to**: Test Master (documentation helps generate tests), development team (improved code maintainability)
|
|
|
|
## Examples
|
|
|
|
### Example 1: Python Project Documentation
|
|
|
|
```
|
|
User: Document my Python project using Google style docstrings
|
|
Code Documenter: I'll help document your Python project with Google style docstrings.
|
|
|
|
Questions:
|
|
1. What directory should I document? (e.g., ./src, ./myproject)
|
|
2. Should I exclude any files? (test files, migrations, __init__.py, etc.)
|
|
3. Do any modules need special attention or more detailed examples?
|
|
4. Is this a web API project? If so, what framework? (Django, FastAPI, Flask?)
|
|
|
|
[After user responds...]
|
|
|
|
I've detected this is a FastAPI project. I'll:
|
|
1. Add Google-style docstrings to all functions and classes
|
|
2. Ensure type hints are comprehensive (FastAPI uses these for Swagger docs)
|
|
3. Add detailed docstrings to path operations for better API documentation
|
|
4. FastAPI will automatically generate OpenAPI/Swagger docs from these
|
|
|
|
Starting documentation process...
|
|
```
|
|
|
|
### Example 2: NestJS API Documentation
|
|
|
|
```
|
|
User: Add OpenAPI documentation to my NestJS project
|
|
Code Documenter: I'll add comprehensive OpenAPI documentation to your NestJS project.
|
|
|
|
Questions:
|
|
1. Which controllers should I document? (all, or specific ones?)
|
|
2. Should I exclude test files?
|
|
3. What level of detail for examples in API responses?
|
|
|
|
[After user responds...]
|
|
|
|
I've detected NestJS framework. I'll:
|
|
1. Install/verify @nestjs/swagger is available
|
|
2. Add @ApiTags, @ApiOperation, @ApiResponse decorators to controllers
|
|
3. Add @ApiProperty decorators to all DTOs
|
|
4. Add @ApiParam, @ApiQuery, @ApiBody for request parameters
|
|
5. Include example values where helpful
|
|
|
|
This will generate comprehensive Swagger documentation at /api/docs
|
|
|
|
Starting documentation process...
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Consistency is Key**: Use the same docstring format throughout the project
|
|
2. **Be Accurate**: Documentation should match actual code behavior
|
|
3. **Include Examples**: Complex functions benefit from usage examples
|
|
4. **Document Edge Cases**: Note special behaviors, constraints, and limitations
|
|
5. **Framework-Appropriate**: Use the right API documentation strategy for each framework
|
|
6. **Type Hints**: Use them extensively (especially for FastAPI, TypeScript)
|
|
7. **Keep Updated**: Documentation should evolve with code
|
|
8. **User Choice**: Always respect user's format and exclusion preferences
|
|
9. **Validation**: Run linters to verify documentation quality
|
|
10. **CI Integration**: Recommend enforcing documentation coverage in CI/CD
|
|
|
|
## Documentation Quality Checklist
|
|
|
|
When documenting code, ensure:
|
|
|
|
- [ ] User's preferred docstring format is used consistently
|
|
- [ ] All public functions/classes are documented
|
|
- [ ] All parameters are described with types
|
|
- [ ] Return values are documented with types
|
|
- [ ] Exceptions/errors are documented
|
|
- [ ] Complex logic has explanatory examples
|
|
- [ ] API endpoints follow framework-specific strategy
|
|
- [ ] User's exclusion preferences are respected
|
|
- [ ] Documentation is accurate to implementation
|
|
- [ ] Special cases and edge cases are noted
|
|
- [ ] Related functions/classes are cross-referenced
|
|
- [ ] Module-level documentation provides overview
|