Skip to main content

Living Documentation: link docs to code and check freshness when signatures change

Project description

LiveDoc — Living Documentation for Code

Living Documentation Check PyPI Python License: MIT

LiveDoc links Markdown documentation to code symbols and warns when the linked code changes.

When a function, method, interface, type alias, or Go symbol changes, LiveDoc identifies the related documentation fragment and marks it as possibly outdated. This helps teams keep documentation close to the code and verify documentation freshness in local development, pre-commit hooks, and CI.

Why LiveDoc?

Documentation often becomes outdated after code changes. Tests can verify behavior, but they usually cannot tell whether a README, guide, or API description still matches the current function signature.

LiveDoc adds an explicit link between a Markdown section and a code symbol:

<!-- livedoc: code_id = "mymodule.calc:add" -->
## `add`

Adds two numbers and returns the result.

On the first run, LiveDoc stores the current code signatures. On later runs, it compares the current code with the stored baseline and reports documentation connected to changed symbols.

Features

  • Links Markdown sections to code through invisible HTML comment anchors
  • Detects signature changes that may make documentation outdated
  • Validates that every documented code_id exists in the scanned project
  • Reports the source file and line of changed symbols
  • Detects duplicate code_id values
  • Supports text and JSON output
  • Supports project configuration through .livedoc.json
  • Supports path exclusions through .livedocignore and --ignore
  • Works locally, in pre-commit hooks, and in CI
  • Has no required runtime dependencies

Supported Languages

  • Python: functions, async functions, instance methods, class methods, static methods, positional-only and keyword-only parameters, *args, **kwargs, type annotations, default values, and return annotations
  • TypeScript/JavaScript: functions, arrow functions, classes, methods, overload implementations, interfaces, and type aliases in .ts, .tsx, .js, and .jsx files
  • Go: functions and methods, including pointer and value receivers

LiveDoc excludes common generated, dependency, build, and test paths by default. Additional paths can be excluded through configuration or command-line options.

Installation

Install the latest release from PyPI:

pip install living-doc

To pin this release:

pip install "living-doc==0.1.8"

Check the installed version:

livedoc --version

You can also run LiveDoc as a Python module:

python -m livedoc --version

LiveDoc requires Python 3.10 or newer.

Quick Start

1. Add an anchor to Markdown

Create a documentation file under docs/ and place a LiveDoc anchor before the section it describes:

<!-- livedoc: code_id = "mymodule.calc:add" -->
## `add`

Adds two numbers and returns an integer.

2. Run LiveDoc for the first time

From the project root:

livedoc . --docs docs

The first run creates:

.livedoc/code_signatures.json

Commit this file to the repository. It is the baseline that future runs compare against.

3. Change the linked code

For example:

def add(a: int, b: int, clamp: bool = False) -> int:
    ...

Run LiveDoc again:

livedoc . --docs docs

LiveDoc reports the linked documentation section as possibly outdated and shows what changed.

4. Update the baseline after reviewing the docs

After intentionally changing the API and updating its documentation:

livedoc . --docs docs --update

Commit the updated .livedoc/code_signatures.json file together with the code and documentation changes.

Anchor Format

LiveDoc anchors are HTML comments, so they do not appear in rendered Markdown.

One symbol

<!-- livedoc: code_id = "package.module:function_name" -->
## Function documentation

Multiple symbols

<!-- livedoc: code_id = "package.module:func_a", "package.module:func_b" -->
## Related functions

An anchor can be written across multiple lines:

<!-- livedoc:
     code_id = "package.module:Service.create"
-->
## Creating a service

The anchor applies to the following Markdown section.

For the complete mapping specification, see spec/code-doc-mapping.md.

code_id Examples

Python

mymodule.calc:add
mymodule.service:UserService.create

Format:

module.path:function_name
module.path:ClassName.method_name

TypeScript and JavaScript

src.utils:add
src.services.user:UserService.create
src.models:User

Format:

path.to.file:symbol
path.to.file:ClassName.methodName

Go

calculator:Add
service:(*UserService).Create
service:UserService.Validate

Format:

package:FunctionName
package:(*Type).Method
package:Type.Method

Configuration

Create .livedoc.json in the project root:

{
  "docs": "docs",
  "ignore": ["build", "generated"],
  "ignore_code_ids": ["generated.client:*"],
  "format": "text"
}

Supported keys:

Key Type Description
docs string Documentation directory relative to the project root
ignore array of strings Additional ignored path segments or glob patterns
ignore_code_ids array of strings Symbol patterns excluded from validation and freshness checks
format text or json Default output format

Command-line options override configuration values where applicable.

.livedocignore

Create .livedocignore in the project root to exclude paths, one pattern per line:

# Generated files
build
generated
scripts/vendor

Empty lines and lines beginning with # are ignored.

Command-Line Usage

usage: livedoc [-h] [--version] [--docs DOCS] [--update]
               [--ignore PATTERN] [--format {text,json}] [--quiet]
               [path]

Common commands:

# Scan the current project using docs/
livedoc .

# Use a custom documentation directory
livedoc . --docs documentation

# Add ignored paths
livedoc . --ignore tests --ignore generated

# Produce machine-readable output
livedoc . --format json

# Reduce non-essential output in CI
livedoc . --quiet

# Accept reviewed code and documentation changes
livedoc . --update

Exit Codes

Code Meaning
0 Documentation is up to date, or the first baseline was created successfully
1 Possibly outdated documentation or unknown anchor references were found
2 Configuration, parsing, filesystem, baseline, or duplicate-symbol error

Reports

Text output

Text reports include:

  • the affected documentation fragment
  • the Markdown file and approximate line
  • the change reason
  • the previous and current signatures
  • the current code location

Example:

Possibly outdated documentation (code changed):

  * docs/api.md#add
    File: docs/api.md, line ~1
    Section: add
    Reason: param default changed
    [mymodule.calc:add]  add(a: int, b: int) -> int  ->  add(a: int, b: int = 0) -> int
    Code: mymodule/calc.py:4

JSON output

Use:

livedoc . --format json

The JSON report contains:

  • ok
  • outdated
  • unknown_anchors
  • signature differences
  • parameter-level change details when available
  • code file and line information

JSON output is intended for CI integrations and other developer tools.

GitHub Actions

Before enabling CI:

  1. Add LiveDoc anchors to the Markdown files.
  2. Run LiveDoc locally once.
  3. Commit .livedoc/code_signatures.json.

Create .github/workflows/livedoc.yml:

name: Living documentation

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

permissions:
  contents: read

jobs:
  livedoc:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"
          cache: pip

      - name: Install LiveDoc
        run: python -m pip install "living-doc==0.1.8"

      - name: Check documentation freshness
        run: livedoc . --docs docs --quiet

Replace docs if the project uses a different documentation directory. You can also set the directory in .livedoc.json and run livedoc . --quiet.

Pre-commit

Add a local hook to .pre-commit-config.yaml:

repos:
  - repo: local
    hooks:
      - id: livedoc
        name: LiveDoc
        entry: python -m livedoc
        language: system
        pass_filenames: false

Install the hook:

pip install pre-commit
pre-commit install

Run it manually:

pre-commit run livedoc --all-files

Using LiveDoc in This Repository

Install the project with development dependencies:

python -m pip install -e ".[dev]"

Run the quality checks:

python -m ruff check .
python -m pytest -q
python -m livedoc examples --docs docs

Check the version:

python -m livedoc --version

Repository Structure

LiveDoc/
├── .github/workflows/       # CI workflows
├── examples/                # Python, TypeScript, and Go examples
├── spec/                    # Code-to-documentation mapping specification
├── src/livedoc/
│   ├── core/                # Link graph and signature comparison
│   ├── parsers/             # Python, TypeScript/JavaScript, Go, and Markdown parsers
│   ├── report/              # Text and JSON report generation
│   ├── cli.py               # Command-line interface
│   └── config.py            # Project configuration loader
├── tests/                   # Automated tests
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
└── pyproject.toml

Development

See CONTRIBUTING.md for the development setup, testing commands, coding guidelines, and pull request checklist.

The main local checks are:

python -m ruff check .
python -m pytest -q
python -m build
python -m twine check dist/*

Publishing to PyPI

Build and validate the distributions:

python -m build
python -m twine check dist/*

Upload the release:

python -m twine upload dist/*

PyPI token authentication uses __token__ as the username and the API token as the password.

Roadmap

Possible future improvements:

  • easier project initialization and symbol discovery commands
  • richer pull-request annotations
  • additional language parsers
  • IDE and LSP integration
  • generated documentation views with outdated-section highlighting
  • optional automatic documentation update suggestions

Contributing

Contributions, bug reports, and feature requests are welcome. See CONTRIBUTING.md before opening a pull request.

License

LiveDoc is distributed under the MIT License. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

living_doc-0.1.8.tar.gz (35.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

living_doc-0.1.8-py3-none-any.whl (28.1 kB view details)

Uploaded Python 3

File details

Details for the file living_doc-0.1.8.tar.gz.

File metadata

  • Download URL: living_doc-0.1.8.tar.gz
  • Upload date:
  • Size: 35.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for living_doc-0.1.8.tar.gz
Algorithm Hash digest
SHA256 b4b3b2270ec97f4c1470b518e2e0de9271505400763510e1e44ce0a49dc0c5d9
MD5 ea6c8ee1eaa3361880fd58839a5f1f58
BLAKE2b-256 3065c005e0ac96edbeedd6db0ee3b0fdc9be202398c7e90a5a3e6d1fcaa8229a

See more details on using hashes here.

File details

Details for the file living_doc-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: living_doc-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 28.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for living_doc-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 52d1aecdc70c48e5c50fd2596374483042ea642758efcf37f1596cb8d4c93310
MD5 284624b77821b161273accf50e2f9fd8
BLAKE2b-256 586405d72982a36bdcf996b140c0541a46d72f1fee7f3a45d582c516a679d7fe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page