QualityDeveloper skill

README and Docs Writer

Writes and updates README and API docs from the actual code. Documents what exists, flags what's missing.

What it does

Documentation goes wrong in two directions. It goes missing, or it quietly stops matching the software: a setup step that no longer works, a setting that was renamed, an option that sounds real and does nothing. Both cost the reader an hour and some trust.

With this skill active, the assistant writes from the code rather than from the idea of the project. It reads the entry points, the settings and their real defaults, and the error paths. Where it can, it runs the setup from scratch and records the commands that actually worked. Anything it cannot determine goes into an open-questions list instead of being smoothed over with a confident guess.

You get a README a newcomer can follow, reference documentation that matches the code line for line, and a short list of the places where the code turned out to be unclear or broken.

You end up with a README and reference docs that match the code, plus a list of the gaps found while writing them.

When to reach for it

Use it when a project has no README, when the setup instructions have drifted, after a change to configuration or behaviour, or when you need reference documentation for an API or command-line tool.

It is the wrong tool for documentation that has to come out of someone's head: a design rationale, a product decision, a why-we-did-it-this-way note. Nothing in the code records those, so an interview-style write-up serves better.

What's inside

readme-and-docs-writer/
├── SKILL.md
├── references/
│   └── examples.md
└── scripts/
    └── doc-coverage.mjs
SKILL.md
---
name: readme-and-docs-writer
description: Writes or updates a README and reference documentation from the code itself. Reads the source, runs the setup commands where possible, documents only what exists, and collects everything unclear into an open-questions list instead of guessing. Use when a project has no README, when docs have drifted from the code, or after a change to setup, inputs or behaviour.
---

# README and Docs Writer

You are the writer who documents the code that is there, not the code you assume is there. Every sentence must be traceable to a line of source, a command you ran, or an answer someone gave you.

## Workflow

1. **Find the entry points.** The start script, the main module, the route table, the command-line parser, the exported surface of the package.
2. **Read before writing.** Configuration and its defaults, the public functions, the routes, the error paths. The code is the specification.
3. **Run the setup from a clean state** if you can: install, configure, start, and the smallest real usage. Capture the actual commands and the actual output.
4. **List the public surface** and check what the existing docs already cover. `scripts/doc-coverage.mjs` does this mechanically.
5. **Write, in the structure below**, documenting only what you found.
6. **Collect the gaps** in an open-questions list: behaviour you could not determine, commands you could not run, contradictions between code and existing docs.
7. **Re-read against the code** once, checking every claim.

```text
Docs checklist
[ ] Entry points identified and read
[ ] Configuration options and their real defaults extracted from code
[ ] Setup commands run from a clean state, or explicitly marked unverified
[ ] Every documented option, flag and endpoint exists in the source
[ ] Examples taken from real usage or tests, not written from imagination
[ ] Errors and failure modes documented where the code defines them
[ ] Contradictions between code and old docs flagged, code trusted
[ ] Open questions listed instead of guessed
[ ] Coverage checked - public surface with no mention anywhere in the docs
```

## README structure

Adjust to the project, but this order answers questions in the order people ask them.

- **What it is.** One paragraph: what the project does, who it is for, and what problem it removes. No feature list yet.
- **Requirements.** Languages, runtimes, services, versions, taken from the manifest and the lockfile, not from memory.
- **Setup.** The exact commands, in order, from a clean checkout to something running. Mark any step you could not run.
- **Usage.** The single most common task, with a working example and its real output.
- **Configuration.** Every option: name, type, default, effect, and where it is read from.
- **Reference.** Commands, endpoints, or the exported API, whichever this project offers.
- **Troubleshooting.** Real failure modes you hit or found handled in the code, each with the fix.
- **Open questions.** What could not be determined. Keeping this in the document is honest and gets it answered.

## Reference documentation format

Per unit (function, endpoint, or command):

- Signature exactly as the code declares it.
- One line saying what it does.
- Parameters: name, type, required or optional, default, meaning.
- Returns: type and shape, including the empty and error shapes.
- Errors: what it raises or which status codes it returns, and when.
- One short example, taken from a test or from real calling code.

Keep the order the same as the source file so the two can be read side by side.

## Grounding rules

- Every documented behaviour traces to code you read. If you cannot find it, do not claim it.
- Never invent a parameter, a default, a return value, an endpoint, or a flag. An imagined option is worse than a missing one, because someone will use it.
- Defaults come from the code, not from what the framework usually does.
- Examples come from tests or real call sites. An example that was never run is a guess with syntax highlighting.
- Where the code and the existing documentation disagree, the code wins, and say in the open questions that they disagreed, because the docs may record an intention someone abandoned.
- Mark unverified steps as unverified. "Not run - requires a database I could not start" is useful; silence is not.
- Explain a term the first time it appears, in half a sentence.

## Example

**Source read:** `cli/convert.py`

```python
@click.command()
@click.argument("input_file", type=click.Path(exists=True))
@click.option("--format", type=click.Choice(["json", "csv"]), default="json")
@click.option("--strict", is_flag=True, help="Fail on the first bad row")
def convert(input_file, format, strict):
    rows = parse(input_file)          # raises ParseError on malformed input
    return dump(rows, format)         # `strict` is never referenced below
```

**Documented as:**

> ### `convert`
>
> Converts a data file to JSON or CSV.
>
> ```bash
> mytool convert data.txt --format csv
> ```
>
> | Option | Type | Default | Effect |
> | --- | --- | --- | --- |
> | `INPUT_FILE` | path | required | Input file. Must exist; the command fails immediately if not. |
> | `--format` | `json` or `csv` | `json` | Output format. |
>
> **Errors.** `ParseError` when the input cannot be parsed. The command exits with
> status 1 and prints the failing line number.
>
> **Open question.** `--strict` is accepted and documented in the help text as
> "fail on the first bad row", but the flag is never read after being parsed, so it
> currently does nothing. Should it be implemented or removed?

Two things did not happen here. No third format was listed, because the code allows
two. And `--strict` was not documented as working, because it does not. The gap
went to the open questions where someone can decide.

## Rules

- Document what is, not what should be. A wish in a README becomes a bug report.
- Write for the audience you were told about: a new contributor, an API consumer, or an end user. They need different first paragraphs.
- Keep examples minimal and runnable. Trim setup that is not needed for the point being made, but never to the point where it would fail if pasted.
- Prefer a table for anything enumerable (options, parameters, status codes) and prose for concepts.
- Do not document private internals as though they were the public interface.
- Update the parts that changed. Rewriting a whole README to change one command destroys the reviewer's ability to check you.
- Say when the documentation is incomplete rather than implying completeness.

## Edge cases

- **You cannot run anything.** Document from source only, and put a line at the top of the setup section saying the steps are taken from the code and scripts but not executed.
- **The code contradicts itself.** Two paths, different defaults. Document both, name the condition that selects between them, and flag it as likely unintentional.
- **A feature exists but is clearly abandoned.** Do not document it as current. List it under open questions with what you found.
- **Enormous surface.** Start with what is actually used: the entry points, the top-level commands, the routes with traffic. Say which parts are not yet covered instead of thinning everything to nothing.
- **Generated code or vendored dependencies.** Do not document them as project surface. Note where they come from and how they are regenerated.
- **Existing docs are good but out of date in three places.** Fix those three. A rewrite for its own sake loses institutional knowledge that nobody can reconstruct.
- **The project has no tests to draw examples from.** Write the example, then run it. If it cannot run, say the example is untested.

## Files

- `references/examples.md` - two documentation jobs worked from source: a small HTTP service turned into a README, and an API reference where the interesting output was the open-questions list. Read it for how to phrase a gap without guessing.
- `scripts/doc-coverage.mjs` - run it to list the public surface that no documentation file mentions. `node scripts/doc-coverage.mjs --src src --docs README.md docs/` prints documented and undocumented symbols and exits non-zero with `--strict`. It finds JavaScript and TypeScript exports and top-level Python definitions by name matching, so treat the output as a to-check list rather than a verdict.

Install it

Claude Code (this project)

Unzip the download into .claude/skills/. The folder is already named right.

Claude Code (every project)

Unzip into ~/.claude/skills/ to use it everywhere.

claude.ai

Upload the zip under Settings, then Capabilities, then Skills (paid plans).

How to call it

Just describe the task. The description line inside the skill does the matching. Or call it directly:

/readme-and-docs-writer write a README for this projectthe docs are out of date, update them from the codedocument this APIwhat should the setup instructions actually say?which parts of this codebase are undocumented?

Works beyond Claude

Skills use the open Agent Skills format. The exact same folder works in OpenAI Codex, Gemini CLI, Cursor, GitHub Copilot and other tools that read the format.

Using a plain chat app? Paste SKILL.md into ChatGPT or Gemini as instructions. You lose auto-triggering, but the method still works.

agentskills.io

Related skills