Agent Skills Framework Extension
Code Documentation Patterns Skill
When to Use This Skill
Use this skill when implementing code documentation patterns patterns in your codebase.
How to Use This Skill
- Review the patterns and examples below
- Apply the relevant patterns to your implementation
- Follow the best practices outlined in this skill
API documentation, inline comments, JSDoc/TSDoc standards, automated doc generation, and comprehensive reference documentation.
Core Capabilities
- API Documentation - OpenAPI, JSDoc, TSDoc, docstrings
- Inline Comments - Explanatory comments, TODOs, complex logic documentation
- Auto-Generation - Sphinx, Doxygen, TypeDoc, API reference generation
- Documentation Standards - Style guides, completeness checks, validation
- Code Examples - Usage examples, integration guides, tutorials
JSDoc/TSDoc Standards
/**
* User authentication service handling login, logout, and session management.
*
* @example
* ```typescript
* const authService = new AuthService(config);
* const result = await authService.login('user@example.com', 'password');
*
* if (result.success) {
* console.log('Login successful:', result.user);
* }
* ```
*
* @see {@link SessionManager} for session handling
* @see {@link UserRepository} for user data access
*/
export class AuthService {
/**
* Authenticates a user with email and password.
*
* @param email - User's email address
* @param password - User's password (will be hashed)
* @returns Promise resolving to authentication result
* @throws {AuthenticationError} If credentials are invalid
* @throws {RateLimitError} If too many failed attempts
*
* @example
* ```typescript
* try {
* const result = await authService.login('user@example.com', 'pass123');
* console.log('User:', result.user);
* } catch (error) {
* if (error instanceof AuthenticationError) {
* console.error('Invalid credentials');
* }
* }
* ```
*/
async login(email: string, password: string): Promise<AuthResult> {
// Implementation
}
/**
* Validates a JWT token and returns the associated user.
*
* @param token - JWT access token
* @returns Promise resolving to user if token is valid, null otherwise
*
* @remarks
* This method verifies:
* - Token signature
* - Expiration time
* - User still exists and is active
*
* @internal
* Uses RS256 algorithm for signature verification
*/
async validateToken(token: string): Promise<User | null> {
// Implementation
}
}
/**
* Result of authentication attempt.
*
* @property success - Whether authentication succeeded
* @property user - Authenticated user (only if success=true)
* @property token - JWT access token (only if success=true)
* @property refreshToken - JWT refresh token (only if success=true)
* @property error - Error message (only if success=false)
*/
export interface AuthResult {
success: boolean;
user?: User;
token?: string;
refreshToken?: string;
error?: string;
}
Python Docstrings (Google Style)
"""User authentication and authorization module.
This module provides classes and functions for:
- User authentication (login, logout)
- Session management
- Permission checking
- Password hashing and verification
Example:
Basic usage of AuthService::
from app.auth import AuthService
auth = AuthService(config)
result = auth.login('user@example.com', 'password')
if result.success:
print(f"Welcome, {result.user.name}!")
See Also:
- :class:`SessionManager`: Session handling
- :class:`UserRepository`: User data access
"""
from typing import Optional, Dict, Any
from dataclasses import dataclass
@dataclass
class AuthResult:
"""Result of authentication attempt.
Attributes:
success: Whether authentication succeeded.
user: Authenticated user (only if success=True).
token: JWT access token (only if success=True).
error: Error message (only if success=False).
Example:
>>> result = auth.login('user@example.com', 'password')
>>> if result.success:
... print(result.user.name)
"""
success: bool
user: Optional['User'] = None
token: Optional[str] = None
error: Optional[str] = None
class AuthService:
"""Handles user authentication and session management.
This class provides methods for:
- User login and logout
- Token validation
- Session management
- Password verification
Args:
config: Authentication configuration.
db: Database connection.
cache: Redis cache for session storage.
Attributes:
config: Current authentication configuration.
session_timeout: Session timeout in seconds (default: 3600).
Example:
>>> auth = AuthService(config, db, cache)
>>> result = auth.login('user@example.com', 'password')
>>> if result.success:
... print('Login successful')
Note:
This class is thread-safe and can be used concurrently.
Sessions are stored in Redis for scalability.
Warning:
Always use HTTPS in production to protect credentials.
"""
def __init__(self, config: Dict[str, Any], db, cache):
"""Initialize AuthService with config and dependencies."""
self.config = config
self.db = db
self.cache = cache
self.session_timeout = config.get('session_timeout', 3600)
def login(self, email: str, password: str) -> AuthResult:
"""Authenticate user with email and password.
Verifies credentials against database and creates new session
if authentication succeeds.
Args:
email: User's email address.
password: User's plaintext password (will be hashed).
Returns:
AuthResult object with success status and user/token if successful.
Raises:
AuthenticationError: If credentials are invalid.
RateLimitError: If too many failed login attempts.
DatabaseError: If database query fails.
Example:
>>> result = auth.login('user@example.com', 'password123')
>>> if result.success:
... print(f'Welcome, {result.user.name}')
... else:
... print(f'Login failed: {result.error}')
Note:
Failed login attempts are rate-limited to prevent brute force attacks.
After 5 failed attempts, the account is temporarily locked for 15 minutes.
See Also:
:meth:`logout`: End user session
:meth:`validate_token`: Verify JWT token
"""
# Implementation
pass
def validate_token(self, token: str) -> Optional['User']:
"""Validate JWT token and return associated user.
Verifies token signature, expiration, and user status.
Args:
token: JWT access token to validate.
Returns:
User object if token is valid, None otherwise.
Example:
>>> user = auth.validate_token(token)
>>> if user:
... print(f'Token valid for {user.email}')
Technical Details:
Uses RS256 algorithm for signature verification.
Checks:
1. Token signature (RSA public key)
2. Expiration time (exp claim)
3. User exists and is active
4. User permissions haven't changed
See Also:
JWT RFC: https://tools.ietf.org/html/rfc7519
"""
# Implementation
pass
Documentation Generator Script
# scripts/generate_api_docs.py
import ast
import json
from pathlib import Path
from typing import List, Dict, Optional
from dataclasses import dataclass, asdict
@dataclass
class DocItem:
"""Documented code element."""
type: str # 'class', 'function', 'method'
name: str
signature: str
docstring: Optional[str]
params: List[Dict[str, str]]
returns: Optional[Dict[str, str]]
raises: List[Dict[str, str]]
examples: List[str]
see_also: List[str]
file: str
line: int
class APIDocGenerator:
"""Generate API documentation from source code."""
def __init__(self, source_path: str):
self.source = Path(source_path)
self.docs: List[DocItem] = []
def generate(self, output_format: str = 'markdown') -> str:
"""Generate complete API documentation."""
# Extract documentation from source files
for py_file in self.source.rglob('*.py'):
if not self._should_document(py_file):
continue
file_docs = self._extract_file_docs(py_file)
self.docs.extend(file_docs)
# Sort by type and name
self.docs.sort(key=lambda d: (d.type, d.name))
# Generate output
if output_format == 'markdown':
return self._generate_markdown()
elif output_format == 'json':
return self._generate_json()
elif output_format == 'html':
return self._generate_html()
def _extract_file_docs(self, file_path: Path) -> List[DocItem]:
"""Extract documentation from Python file."""
docs = []
with open(file_path, 'r') as f:
content = f.read()
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.ClassDef):
docs.append(self._extract_class_doc(node, file_path))
# Extract method docs
for item in node.body:
if isinstance(item, ast.FunctionDef):
docs.append(self._extract_method_doc(item, node.name, file_path))
elif isinstance(node, ast.FunctionDef):
docs.append(self._extract_function_doc(node, file_path))
return docs
def _extract_class_doc(self, node: ast.ClassDef, file_path: Path) -> DocItem:
"""Extract class documentation."""
docstring = ast.get_docstring(node)
params, returns, raises, examples, see_also = self._parse_docstring(docstring)
return DocItem(
type='class',
name=node.name,
signature=f'class {node.name}',
docstring=docstring,
params=params,
returns=returns,
raises=raises,
examples=examples,
see_also=see_also,
file=str(file_path),
line=node.lineno
)
def _parse_docstring(self, docstring: Optional[str]) -> tuple:
"""Parse Google-style docstring into components."""
if not docstring:
return [], None, [], [], []
params = []
returns = None
raises = []
examples = []
see_also = []
sections = self._split_docstring_sections(docstring)
# Parse Args section
if 'Args' in sections:
params = self._parse_params_section(sections['Args'])
# Parse Returns section
if 'Returns' in sections:
returns = {'description': sections['Returns'].strip()}
# Parse Raises section
if 'Raises' in sections:
raises = self._parse_raises_section(sections['Raises'])
# Parse Example section
if 'Example' in sections or 'Examples' in sections:
examples_text = sections.get('Example') or sections.get('Examples')
examples = [examples_text.strip()]
# Parse See Also section
if 'See Also' in sections:
see_also = [line.strip() for line in sections['See Also'].split('\n') if line.strip()]
return params, returns, raises, examples, see_also
def _generate_markdown(self) -> str:
"""Generate Markdown documentation."""
output = "# API Reference\n\n"
# Group by type
classes = [d for d in self.docs if d.type == 'class']
functions = [d for d in self.docs if d.type == 'function']
if classes:
output += "## Classes\n\n"
for doc in classes:
output += f"### {doc.name}\n\n"
if doc.docstring:
output += f"{doc.docstring}\n\n"
if doc.params:
output += "**Parameters:**\n\n"
for param in doc.params:
output += f"- `{param['name']}`: {param['description']}\n"
output += "\n"
if doc.examples:
output += "**Example:**\n\n```python\n"
output += doc.examples[0]
output += "\n```\n\n"
if functions:
output += "## Functions\n\n"
for doc in functions:
output += f"### {doc.name}\n\n"
output += f"`{doc.signature}`\n\n"
if doc.docstring:
output += f"{doc.docstring}\n\n"
return output
# Usage
generator = APIDocGenerator('src/')
markdown_docs = generator.generate('markdown')
print(markdown_docs)
Usage Examples
Generate API Documentation
Apply code-documentation-patterns skill to generate complete API reference documentation in Markdown format
Validate Documentation Completeness
Apply code-documentation-patterns skill to check all public APIs have docstrings and examples
Generate JSDoc/TSDoc
Apply code-documentation-patterns skill to add JSDoc comments to all exported functions and classes
Integration Points
- documentation-quality - Quality validation and standards enforcement
- code-review-patterns - Documentation review as part of PR
- comprehensive-review-patterns - Multi-dimensional documentation analysis
Success Output
When successful, this skill MUST output:
✅ SKILL COMPLETE: code-documentation-patterns
Completed:
- [x] Documentation format selected ({format}: JSDoc/TSDoc/Docstring/OpenAPI)
- [x] {count} functions/classes documented
- [x] All parameters documented with types
- [x] Return values documented
- [x] Examples added to {count} items
- [x] Error cases documented
Outputs:
- Documentation coverage: {percentage}% of public API
- Format: {format} (JSDoc/TSDoc/Python/etc.)
- Files modified: {file_list}
Quality Metrics:
- Completeness: {percentage}% (params, returns, examples)
- Examples included: {count}/{total} items
Completion Checklist
Before marking this skill as complete, verify:
- Documentation format appropriate for language (JSDoc for TS, docstrings for Python)
- All public functions/classes have documentation
- Parameter types and descriptions provided
- Return values documented with types
- At least one usage example per major function/class
- Error conditions and exceptions documented
- See Also references added for related functions
- Code examples are valid and tested
- Documentation follows language conventions (Google style for Python, JSDoc for JS/TS)
- Auto-generated docs build successfully (if using Sphinx/TypeDoc)
Failure Indicators
This skill has FAILED if:
- ❌ Documentation format incompatible with language (JSDoc for Python, etc.)
- ❌ Public APIs missing documentation
- ❌ Parameters documented without types
- ❌ No usage examples provided
- ❌ Code examples contain syntax errors
- ❌ Documentation build fails (Sphinx, TypeDoc, etc.)
- ❌ Incomplete parameter descriptions ("TODO", "TBD")
- ❌ Documentation inconsistent with actual function signatures
When NOT to Use
Do NOT use this skill when:
- Code is still in prototype/experimental phase - Documentation overhead slows iteration
- Private/internal functions only - Focus documentation on public API first
- Auto-generated code (from protobuf, GraphQL schemas) - Use schema-first documentation
- Test files - Tests serve as documentation through examples
- Legacy code scheduled for removal - Don't document code being deleted
- Simple getters/setters - Obvious functionality doesn't need verbose docs
Use alternative approaches instead:
- Prototypes → Add minimal inline comments only
- Internal code → Add brief inline comments, defer full docs
- Generated code → Document schemas/contracts, not generated output
- Test files → Write descriptive test names and arrange-act-assert structure
- Legacy code → Mark as deprecated, point to replacement
Anti-Patterns (Avoid)
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Copy-paste documentation | Duplicate docs across similar functions | Use @see references, document base/abstract once |
| Documentation lies | Docs don't match implementation | Update docs when code changes (test with examples) |
| Excessive verbosity | Multi-paragraph docs for simple functions | Keep simple functions documented simply (1-2 sentences) |
| No examples | Theory without practice | Include at least one working example per major function |
| Type-only documentation | "param x: string" with no description | Explain purpose, constraints, validation rules |
| Undocumented exceptions | No @throws or Raises section | Document all possible exceptions/errors |
| TODO documentation | "TODO: document this later" | Either document now or omit until ready |
| Documenting private APIs first | Internal code documented, public API not | Prioritize public API documentation |
Principles
This skill embodies CODITECT principles:
- #5 Eliminate Ambiguity - Clear parameter descriptions, unambiguous types
- #6 Clear, Understandable, Explainable - Examples show usage, not just theory
- #8 No Assumptions - Document edge cases, error conditions, constraints
- First Principles - Understand documentation serves readers, not writers
- Separation of Concerns - API docs separate from implementation details
- Keep It Simple - Simple functions get simple docs, complex functions get examples
Related Standards: