bulk-docstring-addition

Add Google-style docstrings to all public functions and classes in a Python package. Uses AST parsing for precise gap detection, priority ranking by coverage ratio, and multi-file patching.

5 stars

Best use case

bulk-docstring-addition is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Add Google-style docstrings to all public functions and classes in a Python package. Uses AST parsing for precise gap detection, priority ranking by coverage ratio, and multi-file patching.

Teams using bulk-docstring-addition should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/bulk-docstring-addition/SKILL.md --create-dirs "https://raw.githubusercontent.com/vamseeachanta/workspace-hub/main/.agents/skills/software-development/bulk-docstring-addition/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/bulk-docstring-addition/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How bulk-docstring-addition Compares

Feature / Agentbulk-docstring-additionStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Add Google-style docstrings to all public functions and classes in a Python package. Uses AST parsing for precise gap detection, priority ranking by coverage ratio, and multi-file patching.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Bulk Docstring Addition

## When to Use
- User asks to add/improve docstrings across a Python package
- Documentation coverage audit reveals gaps
- Pre-release documentation cleanup

## Key Principle
**Only add docstrings — never change logic or signatures.** This is a pure documentation task.

## Step 1: Rough Coverage Scan (optional, for prioritization)

Use grep-based ratio to rank files by docstring coverage. Lower ratio = worse coverage:

```bash
cd <package_root>
for f in $(find . -name "*.py" | sort); do
  defs=$(grep -c "^\s*def \|^\s*class " "$f" 2>/dev/null || echo 0)
  docs=$(grep -c '"""' "$f" 2>/dev/null || echo 0)
  if [ "$defs" -gt 0 ]; then
    ratio=$(echo "scale=2; $docs / ($defs * 2)" | bc 2>/dev/null)
    echo "$f | defs=$defs | docs=$docs | ratio=$ratio"
  fi
done | sort -t'=' -k4 -n
```

Files with ratio < 0.70 need the most attention.

## Step 2: Precise Gap Detection with AST

This is the **critical step** — use Python's `ast` module for exact identification. Grep ratios are rough; AST parsing is authoritative.

```python
# Run via terminal heredoc (python3 << 'PYEOF' ... PYEOF)
import ast, os

base = '.'
missing = []
for root, dirs, files in os.walk(base):
    for f in files:
        if f.endswith('.py'):
            fp = os.path.join(root, f)
            try:
                with open(fp) as fh:
                    tree = ast.parse(fh.read())
            except:
                continue
            for node in ast.walk(tree):
                if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
                    name = node.name
                    # Skip private methods (keep dunder methods like __init__)
                    if name.startswith('_') and not name.startswith('__'):
                        continue
                    docstring = ast.get_docstring(node)
                    if not docstring:
                        kind = 'class' if isinstance(node, ast.ClassDef) else 'def'
                        missing.append((fp, node.lineno, kind, name))

print(f'Total public defs/classes missing docstrings: {len(missing)}')
for fp, line, kind, name in missing:
    print(f'{fp}:{line} {kind} {name}')
```

## Step 3: Read Files and Apply Docstrings

### Strategy
1. **Read each file** that has missing docstrings (use `read_file`)
2. **Batch by file** — use multi-file `patch` mode when possible (V4A patches)
3. **Use Google-style format** with Args, Returns, Raises, Examples sections

### Google-Style Docstring Format

```python
def function_name(arg1: str, arg2: int = 0) -> dict:
    """One-line summary of what this function does.

    Extended description if needed — explain the algorithm,
    context, or non-obvious behavior.

    Args:
        arg1: Description of arg1.
        arg2: Description of arg2.

    Returns:
        Dictionary with keys ``key1`` and ``key2`` containing
        the computed results.

    Raises:
        ValueError: If arg1 is empty.

    Examples:
        >>> result = function_name("hello", 42)
        >>> print(result["key1"])
    """
```

### Patching Approach
- Use `patch` tool in `replace` mode for targeted insertions
- For `__init__` methods: add docstring right after `def __init__(...):`
- For inner `Config` classes (Pydantic): one-line docstring is sufficient
- For inner functions (closures): brief one-liner is fine
- **Always verify** the patch tool reports lint: ok

## Step 4: Verify Zero Gaps Remain

Re-run the AST scanner from Step 2. Target: `Total public defs/classes missing docstrings: 0`

## Scaling: Parallel Subagents for Large Packages

When total file count across target packages exceeds ~50, use `delegate_task` with parallel subagents:

1. **Pre-triage first** — Quick coverage scan (Step 1) to identify which packages actually need work. Skip packages already at 100% coverage (e.g. a 2-file package with full docstrings).
2. **One subagent per package** — Up to 3 in parallel via `delegate_task(tasks=[...])`. Each subagent gets an isolated context with clear instructions.
3. **Scope by gap size** — Subagents hit iteration limits (~50 tool calls). A package with 165 files and 43 needing docstrings will only complete ~19 files before exhaustion. For large packages, tell the subagent to prioritize files with ZERO docstrings first, then lowest coverage ratio.
4. **Commit per package** — After subagents return, commit each package separately for clean git history.

### Subagent prompt template:
```
goal: Add Google-style docstrings to all public functions/classes in <pkg>/
context: Path is <full_path>. <N> files, <M> defs, <D> existing docstring markers.
         Focus on files MISSING docstrings — skip files with good coverage.
         Do NOT modify logic/imports/signatures. Only add docstrings.
toolsets: ["terminal", "file"]
```

### Lesson: Iteration budget planning
- Reading a file + patching it = ~2-3 tool calls per file
- A subagent with 50 iterations can process ~15-20 files with docstrings
- For packages with 40+ files needing work, create a follow-up issue for the remainder

## Pitfalls

1. **grep ratios mislead** — A file can have ratio=0.84 but still have missing docstrings (e.g. module-level docstrings inflate the count). Always use AST for truth.
2. **`python3 -c` with quotes** — Complex Python one-liners with nested quotes get blocked by terminal. Use heredoc (`python3 << 'PYEOF'`) or `uv run python << 'PYEOF'` instead. Some sandboxes block `python -c` with semicolons entirely.
3. **Duplicate files** — Packages often have copied/mirrored modules (e.g. `marine_analysis/` and `marine_engineering/` with identical catenary solvers). Don't forget the copies.
4. **Pydantic inner Config classes** — These are real classes that AST detects. A one-line `"""Pydantic configuration for ModelName."""` suffices.
5. **Closure/inner functions** — AST detects these too (e.g. `def run_spectrum():` inside a method). One-liner docstrings are appropriate.
6. **Non-unique match in patch** — When multiple `class Config:` or similar exist in one file, use `replace` mode with enough surrounding context to disambiguate, rather than V4A patch mode.
7. **Empty __init__.py files** — These count as files but just need a one-line module docstring. Subagents can bulk-write these with `write_file` instead of patching.

Related Skills

sphinx-1-docstring-style-guide

5
from vamseeachanta/workspace-hub

Sub-skill of sphinx: 1. Docstring Style Guide (+3).

test-oversized-skill

5
from vamseeachanta/workspace-hub

A test fixture skill that exceeds 200 lines with multiple H2/H3 sections for split testing.

interactive-report-generator

5
from vamseeachanta/workspace-hub

Generate interactive HTML reports with Plotly visualizations from data analysis results. Supports dashboards, charts, and professional styling.

data-validation-reporter

5
from vamseeachanta/workspace-hub

Generate interactive validation reports with quality scoring, missing data analysis, and type checking. Combines Pandas validation, Plotly visualization, and YAML configuration for comprehensive data quality reporting.

agent-os-framework

5
from vamseeachanta/workspace-hub

Generate standardized .agent-os directory structure with product documentation, mission, tech-stack, roadmap, and decision records. Enables AI-native workflows.

OrcaFlex Specialist Skill

5
from vamseeachanta/workspace-hub

```yaml

repo-ecosystem-hygiene

5
from vamseeachanta/workspace-hub

Interpret the daily read-only repo ecosystem hygiene audit and route remediation through approved workflows.

domain-knowledge-sweep

5
from vamseeachanta/workspace-hub

Systematic multi-source research of an engineering domain. Spawns parent issue → 6 research subissues (Standards, Academic, Industry, LinkedIn-marketing, Code-audit, Synthesis) → gap implementation subissues. Replaces LinkedIn-only extraction with defensible comprehensive sourcing.

subagent-write-verification

5
from vamseeachanta/workspace-hub

Independently verify subagent-claimed file writes with filesystem and git checks before treating the artifact as real, before committing it, and before referencing the path in downstream prompts.

git-operation-serialization-preflight

5
from vamseeachanta/workspace-hub

Before any commit, stash, merge, reset, rebase, or checkout in a multi-agent or shared-checkout environment, run a bounded preflight to detect active git writers and stale index/config locks, then serialize the mutating step under a single-writer guarantee.

public-knowledge-graph-governance

5
from vamseeachanta/workspace-hub

Maintain public-safe knowledge graph artifacts for llm-wiki and similar markdown knowledge bases. Use when changing graph generators, validators, schema docs, weekly freshness checks, or public/private source-scope boundaries.

llm-wiki-weekly-freshness

5
from vamseeachanta/workspace-hub

Class-level governance workflow for keeping llm-wiki-style markdown knowledge bases current, public-safe, graph/index-valid, and useful for code development. Use when reviewing llm-wiki architecture/content, scanning new LLM concepts, maintaining public knowledge graphs, producing an issue roadmap, or running recurring freshness cadence.