# tldr-maintenance reduces the tldr-pages backlog to a file per metric

> A maintenance repository that computes per-language quality metrics for the tldr command pages and writes each one to a plain text file, with a summary tracked in a single GitHub issue. Several metrics are known to produce false positives, which the README says out loud.

**tldr-pages/tldr-maintenance** — Calculates metrics about the current state of the tldr pages 👷.

- Repository: https://github.com/tldr-pages/tldr-maintenance
- Stars: 23 · Forks: 7
- Language: Python
- License: not declared
- Published: 2026-08-24 · Updated: 2026-08-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/tldr-pages-tldr-maintenance

## Each metric becomes a text file per language

The metrics are defined in one file, `scripts/metrics.tsv`, and every script reads that definition. Calculation is per language, and results land in two places: `check-pages/<metric>.txt` for English, and `check-pages.<language>/<metric>.txt` for each translated language.

The flat file layout is what makes this usable inside a contribution workflow. A file listing page names can be read directly, piped into other tooling, or opened as a checklist, without parsing JSON or querying an API. The file naming matches the metric identifiers in the table, such as `inconsistent-filenames` or `lint-errors`.

Not every metric applies to English. The ones that compare a translated page against the English page have no meaning for the source language itself, since there is nothing to compare it to, and those are marked as not for English in the metric list.

## Most metrics compare a translated page against its English original

The comparison metrics come in several flavours and they are not interchangeable. A mismatched page title is a translated `# ...` heading that differs from the English title. Outdated pages based on command count, command contents and header line count each look at a different slice of the page: the number of commands, the commands themselves with everything between `{{...}}`, `<...>`, `(...)`, `"..."` and `'...'` stripped out, and the number of `>` header lines.

The see also family is the most intricate. A malformed see also mention is one whose translated `> See also: ...` line does not match the template format, and an outdated one names different pages than the English page names. Missing see also mentions apply only to pages whose English page carries a see also line as the second to last line of the description, and a mention in the wrong position counts as missing.

More information links are checked against the template for format and against the English page for currency, so a translated link can be well formed and still be wrong.

## Three metrics are flagged as generating false positives

The README states plainly that results need to be checked by hand. The named cause is that running `set-alias-page.py` and `wrong-filename.py` generates false positives.

Three metrics carry that warning explicitly: missing alias pages, which fires when the English page is an alias page and the translated page does not exist; outdated alias pages, which fires when the translated alias does not match the alias template or refers to another command; and inconsistent filenames, which fires when a filename does not match the page title.

This is a design decision worth reading correctly. A tool that reported only certain results would be easier to trust and less useful, because the alias scripts generate pages in bulk and a strict checker would either reject their output or ignore those pages. The cost of coverage is a list a human has to read.

The stated remedy is CODEOWNERS, where each maintainer watches the output for the language they own to see whether changes are needed.

## Missing pages are found by following references rather than by listing directories

Three metrics detect absence, and they do it by resolving references instead of enumerating files.

A missing TLDR page is a page referenced by another page, for example through `tldr example`, where the referenced page does not exist yet in that language. A missing see also page is the same idea applied to the first translated `> See also: ...` line. A misplaced page is one that is not inside a folder from the list of supported platforms.

Three more catch structural gaps between languages: a missing English page is a translated filename that cannot be found as an English page, a missing translated page is an English page that cannot be found as a translation, and both of those are excluded for English by definition.

Several of these point at the same external tool as a cross-check, the tldr translation page at lukwebsforge.github.io/tldri18n, which shows the same missing and misplaced information implicitly. Having two views of the same backlog is the point: one is generated from the repository, the other is not.

## Lint errors come from two tools, with some checks skipped for translations

The `lint-errors` metric collects errors from `markdownlint` and `tldr-lint`. For translations, some `tldr-lint` checks are ignored, and the specifics are in the `lint` function inside `scripts/check-pages.sh`.

The ignored checks are named: `TLDR104`, which is about the English tense, and checks on capital letters and punctuation for some languages. The reason follows from the nature of a translation, since an English tense rule has no counterpart in most other languages and capitalization conventions differ.

This is the one metric that runs tools rather than diffing pages, and it is the one that depends on the repository's own Node dependencies. The manifest pins `markdownlint-cli` at `^0.49.1` and `tldr-lint` at `^0.0.23`, with husky at `^9.1.7` as a dev dependency for commit hooks. The Python side is just two tools, black at `26.3.1` and flake8 at `7.1.1`.

## The summary lands in a tracked issue and in a release asset

Per-language files are the working output. The aggregate view is a summary appended to `metrics-log.md`, which is published as a release asset under the tag named latest, and it is also written to `summary.tsv`.

The tsv carries a number of results, a total and a percentage for each language plus a `total` row across all languages. Most totals include a percentage rounded down to one decimal, calculated against the sum of the totals for the relevant languages.

The whole summary is tracked in one GitHub issue, issue 25, along with the metrics per translation. Keeping the backlog in a single issue is what makes it usable as a work queue: a contributor opens the issue, sees which language has the largest count on a given metric, and knows where to look without querying anything.

The rounding is worth noting if you are diffing these numbers over time. A percentage rounded down will not recover a value that lost a fraction at an earlier point in the same run.

## The entry points are npm scripts wrapping shell and Python

The manifest is marked private and exposes the workflow as npm scripts, so nothing here is published to a registry. `calculate-metrics` runs `bash scripts/calculate-metrics.sh`, `check-codeowners` and `check-maintainers` are Python scripts, and `prepare` installs husky.

Linting is split three ways and chained together by `lint`: `lint-markdown` runs markdownlint over the markdown files, `lint-python` runs black in check mode over scripts followed by flake8 over scripts, and `lint-bash` runs shellcheck over `scripts/*.sh`.

The top level also holds `.flake8`, `.markdownlint.json`, `.lycheeignore` and `.editorconfig`, so the shell, Python and Markdown sides are each linted against a committed configuration rather than defaults. The `tldr` entry at the root and the presence of `.gitmodules` indicate the pages repository is pulled in as a submodule, which is how the metrics scripts reach the pages they measure. A GitHub Actions workflow badge covers metrics calculation and another covers link checking.

## Conclusion

This is a maintainer tool for the tldr-pages project rather than something end users install, and its value is in making a translation backlog countable. Two things to know before you read its output. Several metrics are documented as producing false positives, so a non-empty result file is a prompt to look, not a verdict, and CODEOWNERS is meant to use these results only as a hint about their own language. Also check what your reporting baseline is: the summary carries totals and percentages per language, and the repository has a single release named latest, so the tracked issue is the place to compare against rather than any version number.

## FAQ

### What does TLDR stand for in the tldr-maintenance context?

The README does not spell out the acronym, but it describes what the pages contain: a title, example commands written as command lines, a description, More information links, See also mentions and optional alias pages. The metrics measure translation consistency between those pages.

### What does TLDR mean in work, according to tldr-maintenance?

In this repository the term names a collection of short command pages rather than a workplace abbreviation. What the tool contributes is a way to see which of those pages are incomplete, misnamed or out of date with their English original, per language.

### Is tldr-maintenance still relevant for active translation work?

The repository is not archived and its last push landed on 2026-09-30. The metrics exist to show contributors whether work remains on maintenance and quality, and the tracked issue 25 holds the current per-language totals.

## Sources

- [Official README](https://github.com/tldr-pages/tldr-maintenance#readme)
- [Project repository](https://github.com/tldr-pages/tldr-maintenance)
- [Release notes](https://github.com/tldr-pages/tldr-maintenance/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tldr-pages-tldr-maintenance
