From cogapp-markdown
Auto-generate and keep markdown documentation in sync with code using cogapp. Use when user says "keep docs in sync", "regenerate readme", "embed --help output", "run cog -r", "documentation is out of date", "sync CLI help into README", or when documentation should be derived from code rather than maintained by hand.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cogapp-markdown:cogapp-markdownThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use [cogapp](https://github.com/nedbat/cog) to auto-generate sections of markdown files. Cog lets you embed Python code in markdown that produces output inline — the generated content lives in the file alongside the code that created it. Running `cog -r` regenerates the output, keeping docs in sync with code.
Use cogapp to auto-generate sections of markdown files. Cog lets you embed Python code in markdown that produces output inline — the generated content lives in the file alongside the code that created it. Running cog -r regenerates the output, keeping docs in sync with code.
uv add --dev cogapp
Or add "cogapp" to your [dependency-groups] dev dependencies in pyproject.toml.
Use HTML comments as cog markers so the Python code is invisible when the markdown is rendered:
<!-- [[[cog
import cog
cog.outl("This content is generated by cog.")
]]] -->
This content is generated by cog.
<!-- [[[end]]] -->
The pattern is:
<!-- [[[cog — opens the Python code block (hidden in rendered markdown)cog.out() or cog.outl() to produce output]]] --> — closes the Python code block<!-- [[[end]]] --> — marks the end of the generated regionRegenerate all cog blocks in-place:
cog -r docs/*.md
Or without installing — use uv run --with to run cog in a temporary environment:
uv run --with cogapp cog -r docs/*.md
The -r flag replaces file contents in-place. Without it, cog writes to stdout.
The most common use is keeping CLI documentation in sync with actual --help output.
For Click-based CLIs, use CliRunner to capture help output directly (no subprocess needed):
<!-- [[[cog
import cog
from mypackage import cli
from click.testing import CliRunner
runner = CliRunner()
result = runner.invoke(cli.cli, ["mycommand", "--help"])
help = result.output.replace("Usage: cli", "Usage: mypackage")
cog.out(
"```\n{}\n```\n".format(help.strip())
)
]]] -->
<!-- [[[end]]] -->
The replace("Usage: cli", "Usage: mypackage") is needed because CliRunner reports the command name as cli instead of the real entry point name.
For argparse or other CLIs, use subprocess:
<!-- [[[cog
import cog
import subprocess
result = subprocess.run(["mycommand", "--help"], capture_output=True, text=True)
cog.out(
"```\n{}\n```\n".format(result.stdout.strip())
)
]]] -->
<!-- [[[end]]] -->
Add a step to your test workflow that checks all cog blocks are up to date. This fails CI if someone changes CLI behavior but forgets to regenerate the docs:
- name: Check if cog needs to be run
run: |
cog --check docs/*.md
cog --check exits with code 1 if any file would change. It does not modify files.
Use --check-fail-msg to tell developers how to fix it:
- name: Check if cog needs to be run
run: |
cog --check --check-fail-msg='Run "cog -r docs/*.md" to update' docs/*.md
If the project uses uv and cogapp is not a declared dependency, use uv run --with:
- name: Check if cog needs to be run
run: |
uv run --with cogapp cog --check docs/*.md
<!-- [[[cog
import cog
headers = ["Name", "Type", "Description"]
rows = [
["id", "int", "Primary key"],
["name", "str", "User name"],
]
cog.outl("| " + " | ".join(headers) + " |")
cog.outl("| " + " | ".join(["---"] * len(headers)) + " |")
for row in rows:
cog.outl("| " + " | ".join(row) + " |")
]]] -->
<!-- [[[end]]] -->
<!-- [[[cog
import cog
import json
data = {"key": "value", "count": 42}
cog.out("```json\n")
cog.outl(json.dumps(data, indent=2))
cog.out("```\n")
]]] -->
<!-- [[[end]]] -->
Each cog block is independent. You can have many blocks in one file — each gets its own <!-- [[[cog ... ]]] --> and <!-- [[[end]]] --> pair. Imports are shared across blocks within the same file.
cog -r FILE — regenerate in-placecog --check FILE — check without modifying (for CI)cog --check --diff FILE — show what would changecog -P FILE — use print() instead of cog.outl() in code blocksnpx claudepluginhub fblissjr/fb-claude-skills --plugin cogapp-markdownProvides best practices for Markdown technical documentation and READMEs, including structure, organization, linking, writing style, code examples, and admonitions.
Generates and maintains README, API docs, changelogs, and architecture docs. Provides docstring and generator commands for JavaScript, Python, and Go projects.