readability-cli 0.7.0__tar.gz → 0.8.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {readability_cli-0.7.0 → readability_cli-0.8.1}/.github/workflows/ci.yml +9 -0
  2. {readability_cli-0.7.0 → readability_cli-0.8.1}/PKG-INFO +156 -57
  3. readability_cli-0.8.1/README.md +360 -0
  4. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/cppguide.md +3 -3
  5. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/tsguide.md +2 -2
  6. {readability_cli-0.7.0 → readability_cli-0.8.1}/pyproject.toml +1 -1
  7. {readability_cli-0.7.0 → readability_cli-0.8.1}/readability.py +643 -238
  8. {readability_cli-0.7.0 → readability_cli-0.8.1}/test_readability.py +822 -155
  9. {readability_cli-0.7.0 → readability_cli-0.8.1}/uv.lock +1 -1
  10. readability_cli-0.7.0/README.md +0 -261
  11. {readability_cli-0.7.0 → readability_cli-0.8.1}/.github/workflows/publish.yml +0 -0
  12. {readability_cli-0.7.0 → readability_cli-0.8.1}/.github/workflows/update-guides.yml +0 -0
  13. {readability_cli-0.7.0 → readability_cli-0.8.1}/.gitignore +0 -0
  14. {readability_cli-0.7.0 → readability_cli-0.8.1}/.python-version +0 -0
  15. {readability_cli-0.7.0 → readability_cli-0.8.1}/LICENSE +0 -0
  16. {readability_cli-0.7.0 → readability_cli-0.8.1}/configs/pyrefly.toml +0 -0
  17. {readability_cli-0.7.0 → readability_cli-0.8.1}/configs/ruff.toml +0 -0
  18. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/Rguide.md +0 -0
  19. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/csharp-style.md +0 -0
  20. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/docguide-style.md +0 -0
  21. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/go-guide.md +0 -0
  22. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/htmlcssguide.md +0 -0
  23. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/javaguide.md +0 -0
  24. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/jsguide.md +0 -0
  25. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/jsoncstyleguide.md +0 -0
  26. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/objcguide.md +0 -0
  27. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/pyguide.md +0 -0
  28. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/shellguide.md +0 -0
  29. {readability_cli-0.7.0 → readability_cli-0.8.1}/guides/vimscriptguide.md +0 -0
@@ -29,3 +29,12 @@ jobs:
29
29
 
30
30
  - name: Run tests
31
31
  run: uv run pytest
32
+
33
+ # Runs the tool against itself, which is the only place tool
34
+ # resolution is exercised for real: the unit tests reach it with
35
+ # shutil.which mocked, so they cannot tell whether a resolved command
36
+ # actually starts. ruff comes from the synced environment and pyrefly
37
+ # is not a dependency at all, so this covers both the PATH branch and
38
+ # the uvx runner, on a machine that has neither installed.
39
+ - name: Check this repository with the tool itself
40
+ run: uv run readability check .
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: readability-cli
3
- Version: 0.7.0
3
+ Version: 0.8.1
4
4
  Summary: A CLI to lint, format, and type-check code with Google-style defaults, and pull Google style guides in markdown format.
5
5
  Project-URL: Homepage, https://github.com/owahltinez/readability
6
6
  Project-URL: Repository, https://github.com/owahltinez/readability
@@ -28,7 +28,8 @@ and quick access to style conventions without browsing HTML pages.
28
28
  Pyrefly are used automatically when a project does not define its own.
29
29
  - **Style Guides**: A `guide` command that fetches the latest Google style
30
30
  guides (Python, Shell, C++, Java, JS/TS, Go, etc.) converted to Markdown,
31
- navigable by outline and by section rather than read whole.
31
+ and outlines, addresses, and searches them by section rather than serving
32
+ 200 KB to be read whole.
32
33
  - **Offline Mode**: Local caching of style guides for fast, offline access,
33
34
  kept fresh with a single `sync` command.
34
35
 
@@ -40,8 +41,9 @@ You can run the tool directly without installing it using `uvx`:
40
41
  # Check and fix formatting for the current directory
41
42
  uvx --from readability-cli readability check . --fix
42
43
 
43
- # Get the Python style guide
44
+ # Outline the Python style guide, then read one of its sections
44
45
  uvx --from readability-cli readability guide python
46
+ uvx --from readability-cli readability guide python 2.2
45
47
  ```
46
48
 
47
49
  ## Installation
@@ -92,17 +94,77 @@ readability check . --fix
92
94
 
93
95
  ### Supported Tools
94
96
 
95
- | Tool | Supported Extensions | Trigger Files |
96
- |------|----------------------|---------------|
97
- | **Ruff** | `.py` | `pyproject.toml`, `ruff.toml`, `.ruff.toml` |
98
- | **Pyrefly** | `.py` | `pyproject.toml`, `pyrefly.toml` |
99
- | **Biome** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.jsonc`, `.css`, `.html` | `biome.json`, `biome.jsonc` |
100
- | **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` | `.prettierrc*`, `prettier.config.*` |
101
- | **gofmt** | `.go` | `go.mod` |
97
+ | Tool | Supported Extensions | Config Needed | Fetched By |
98
+ |------|----------------------|---------------|------------|
99
+ | **Ruff** | `.py` | none, bundled | `uvx` |
100
+ | **Pyrefly** | `.py` | none, bundled | `uvx` |
101
+ | **Biome** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.jsonc`, `.css`, `.html` | `biome.json` or `biome.jsonc` | `npx` |
102
+ | **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` | `.prettierrc*` or `prettier.config.*` | `npx` |
103
+ | **gofmt** | `.go` | `go.mod` | — |
104
+
105
+ **You do not need to install any of these.** Each is resolved in order: a
106
+ project-local install (`node_modules/.bin`, `.venv/bin`) first, then whatever
107
+ is on your `PATH`, and only then fetched by `uvx` or `npx`. The runners cache
108
+ what they download, so the fetch happens once per machine and later runs are
109
+ served from disk and work offline.
110
+
111
+ That keeps this package at ~4 MB rather than the ~54 MB it would take to
112
+ carry Ruff and Pyrefly itself — a cost that would fall on everyone using only
113
+ `guide`. An installed copy always wins over a fetched one, so a project that
114
+ pinned a version is linted against the rules it chose.
115
+
116
+ Fetched tools carry a minimum version, enough to understand the bundled
117
+ configurations, and no maximum. A ceiling would freeze anyone who installed
118
+ nothing at whatever was current when this package shipped, and tie its
119
+ releases to Ruff's — which has published seventeen minor series, roughly one
120
+ every six weeks. If you need a fixed version, install it: an installed tool
121
+ always wins over a fetched one.
122
+
123
+ Set `UV_OFFLINE=1` to forbid fetching. A tool that then cannot be reached
124
+ fails the run rather than passing it.
125
+
126
+ Ruff and Pyrefly ship with bundled configurations, so they run on any file
127
+ they handle without the project arranging anything. Biome, Prettier and gofmt
128
+ bring no defaults here, so they wait until the project asks with a config
129
+ file.
130
+
131
+ A tool that could not be reached at all is never skipped quietly:
102
132
 
103
- The command will only run a tool if its trigger file exists in the current
104
- working directory and the tool is available in your `PATH`. For `biome` and
105
- `prettier`, it attempts to run them via `npx`.
133
+ ```bash
134
+ # Some tools ran, so the result stands, but coverage was partial
135
+ $ readability check src/
136
+ Warning: not installed, so not run: prettier.
137
+ No findings in 1 path(s) (ruff, pyrefly).
138
+
139
+ # Nothing ran, so there is no result to report
140
+ $ readability check src/
141
+ Error: Every tool for 1 path(s) is missing, so nothing was verified.
142
+ ```
143
+
144
+ That second case needs neither the tool nor a runner to be present, which is
145
+ the state a container image is usually in.
146
+
147
+ `check` exits non-zero on findings and on having verified nothing, so it can
148
+ gate CI without a clean exit ever meaning "the tools were absent".
149
+
150
+ ### Python API
151
+
152
+ Use `check_paths` to run the same checks without the command's status messages
153
+ or exit-code decisions:
154
+
155
+ ```python
156
+ from pathlib import Path
157
+
158
+ from readability import check_paths
159
+
160
+ report = check_paths(["src", Path("tests")], project_root=Path.cwd())
161
+ if report.findings or report.failed or not report.ran:
162
+ handle_failed_check(report)
163
+ ```
164
+
165
+ The returned `CheckReport` records only whether findings occurred and which
166
+ tools ran, were skipped, or failed. Detailed tool findings are still written
167
+ as each tool runs.
106
168
 
107
169
  ### Default Configurations
108
170
 
@@ -116,59 +178,64 @@ project-level configuration takes full precedence over the bundled defaults.
116
178
 
117
179
  ## Style Guides
118
180
 
119
- The `guide` command prints a Google style guide as Markdown, using the local
120
- cache when available:
181
+ The `guide` command reads a Google style guide, using the local cache when
182
+ available. It has four forms:
121
183
 
122
184
  ```bash
123
- # Get the Python style guide (uses local cache if available)
124
- readability guide python
185
+ # Which languages have a guide, and which are cached
186
+ readability guide
125
187
 
126
- # Force fetching the latest version from the web
127
- readability guide python --remote
128
-
129
- # Save a style guide to a file
130
- readability guide cpp --output cpp-style.md
188
+ # The outline of one: every heading, a few KB where the guide is 200
189
+ readability guide python
131
190
 
132
- # Search a guide without printing it: the pipe carries it, you see matches
133
- readability guide python | grep -n "f-string"
191
+ # One section, by index, heading text, or a parent-scoped path
192
+ readability guide cpp 10.4
193
+ readability guide shell "Function Comments"
194
+ readability guide python "Imports > Decision"
134
195
 
135
- # Synchronize all supported style guides to the local cache
136
- readability sync
196
+ # The whole guide, for grepping or when you really do want all of it
197
+ readability guide cpp --full
198
+ readability guide python --full | grep -i f-string
137
199
  ```
138
200
 
139
- A guide can exceed 100 KB, so printing one whole is rarely what you want.
140
- `--outline` and `--section` below cover navigating to a rule; piping to
141
- `grep` covers finding wording that no heading names. Neither leaves a copy
142
- behind, which is what a coding agent should do rather than redirecting a
143
- guide into the repository it is working on.
201
+ A guide can exceed 200 KB, so the outline is what a bare invocation prints:
202
+ listing the sections and fetching the one you need beats reading the lot.
203
+ Nothing is written to disk, which is what a coding agent should do rather
204
+ than redirecting a guide into the repository it is working on use a shell
205
+ redirect if you do want a copy.
206
+
207
+ `REF` and `--full` cannot be combined; that is refused rather than resolved
208
+ by a precedence rule you would have to know.
144
209
 
145
210
  ### Navigating a Guide
146
211
 
147
- `--outline` lists a guide's headings and `--section` prints just one of them,
148
- which turns "read 200 KB" into "list the sections, fetch the one you need":
212
+ The outline gives each section an index to fetch it by, and flags the ones
213
+ large enough to be worth knowing about first:
149
214
 
150
215
  ```bash
151
- # List every heading, with the index to pass to --section
152
- readability guide cpp --outline
153
-
154
- # Only the top two levels, for a bird's eye view of a large guide
155
- readability guide cpp --outline --depth 2
156
-
157
- # Print one section: its heading and everything nested under it
158
- readability guide shell --section "Function Comments"
159
- readability guide cpp --section 10.4
160
-
161
- # Sections can be saved like whole guides can
162
- readability guide python --section "Imports" --output imports.md
216
+ $ readability guide cpp
217
+ Google C++ Style Guide
218
+ 1 Background
219
+ 1.1 Goals of the Style Guide
220
+ 2 C++ Version
221
+ 3 Header Files (1.7k words)
222
+ 3.1 Self-contained Headers
223
+ ...
224
+ # 140 sections · print one: readability guide cpp 4.5.1
163
225
  ```
164
226
 
227
+ Sizes appear only at 1200 words and above — the 4% of sections expensive
228
+ enough that you would want warning. They include subsections, since that is
229
+ what the reference returns. The trailing line goes to stderr, so it never
230
+ contaminates a piped outline.
231
+
165
232
  A section reference can be any of the following:
166
233
 
167
234
  | Reference | Example |
168
235
  |-----------|---------|
169
- | Section index, as shown by `--outline` | `--section 2.2.4` |
170
- | Heading text, case-insensitive, or its slug | `--section "function comments"` |
171
- | A parent-scoped path, spaces around the `>` | `--section "Imports > Decision"` |
236
+ | Section index, as shown by the outline | `2.2.4` |
237
+ | Heading text, case-insensitive, or its slug | `"function comments"` |
238
+ | A parent-scoped path, spaces around the `>` | `"Imports > Decision"` |
172
239
 
173
240
  Whole matches are preferred; a reference that matches nothing in full is
174
241
  retried as a substring of the heading text.
@@ -187,28 +254,50 @@ printed section number or the heading text over a positional index, since
187
254
  positional indices shift when an unnumbered guide is re-synced.
188
255
 
189
256
  A reference that matches several headings is reported rather than guessed at,
190
- listing the index and path of every candidate on stderr:
257
+ listing every candidate on stderr:
191
258
 
192
259
  ```bash
193
- $ readability guide python --section Decision
260
+ $ readability guide python Decision
194
261
  Error: 'Decision' matches 19 headings in the 'python' guide. Repeat with one of:
195
- --section 2.1.4 (Python Language Rules > Lint > Decision)
196
- --section 2.2.4 (Python Language Rules > Imports > Decision)
262
+ 2.1.4 (Python Language Rules > Lint > Decision)
263
+ 2.2.4 (Python Language Rules > Imports > Decision)
197
264
  ...
198
265
  ```
199
266
 
200
- Content goes to stdout and diagnostics to stderr, so both flags are safe to
267
+ ### When a Reference Misses
268
+
269
+ A guide discusses plenty that no heading is named after, so a reference that
270
+ matches nothing is usually a vocabulary mismatch rather than a mistake. The
271
+ sections that mention the words are reported, which turns the miss into the
272
+ next command:
273
+
274
+ ```bash
275
+ $ readability guide python f-string
276
+ Error: Found no heading matching 'f-string' in the 'python' guide.
277
+ It appears in these sections:
278
+ 3.10 Python Style Rules > Strings
279
+ 3.10.1 Python Style Rules > Strings > Logging
280
+ ```
281
+
282
+ This locates a rule; it does not search text. For that, pipe `--full` to
283
+ `grep`, which you already know and which brings its own `-i`, `-A`, `-c` and
284
+ the rest:
285
+
286
+ ```bash
287
+ readability guide python --full | grep -in -A2 "f-string"
288
+ ```
289
+
290
+ Content goes to stdout and diagnostics to stderr, so every form is safe to
201
291
  pipe. Headings inside fenced code blocks are ignored, which matters for the
202
292
  Shell and Python guides where `#` starts a comment.
203
293
 
204
294
  ### Supported Languages
205
295
 
206
- Use `readability languages` to see a full list of supported languages and
207
- their aliases. This command also indicates which guides are currently
208
- available in the local cache with a `[cached]` label:
296
+ Run `readability guide` with no language for the full list and which guides
297
+ are cached:
209
298
 
210
299
  ```bash
211
- $ readability languages
300
+ $ readability guide
212
301
  Supported languages and their aliases:
213
302
  - r [cached]
214
303
  - c++, cpp [cached]
@@ -226,6 +315,16 @@ Supported languages and their aliases:
226
315
  - vim [cached]
227
316
  ```
228
317
 
318
+ Refresh the cache with `sync`, which takes languages or refetches everything:
319
+
320
+ ```bash
321
+ # Refetch one guide, or a few
322
+ readability sync python shell
323
+
324
+ # Refetch all of them
325
+ readability sync
326
+ ```
327
+
229
328
  ### Offline Mode
230
329
 
231
330
  The tool stores local copies of the style guides in the `guides/` directory
@@ -0,0 +1,360 @@
1
+ # Readability
2
+
3
+ A CLI tool that keeps code aligned with Google style conventions. It runs the
4
+ right linters, formatters, and type checkers for your project with sensible
5
+ defaults, and serves the official Google style guides in Markdown format. This
6
+ is ideal for AI agents or developers who want consistent code quality checks
7
+ and quick access to style conventions without browsing HTML pages.
8
+
9
+ ## Features
10
+
11
+ - **Linting & Formatting**: A `check` command that automatically detects and
12
+ runs relevant tools (Ruff, Pyrefly, Biome, Prettier, gofmt) for your project.
13
+ - **Sensible Defaults**: Bundled Google-style configurations for Ruff and
14
+ Pyrefly are used automatically when a project does not define its own.
15
+ - **Style Guides**: A `guide` command that fetches the latest Google style
16
+ guides (Python, Shell, C++, Java, JS/TS, Go, etc.) converted to Markdown,
17
+ and outlines, addresses, and searches them by section rather than serving
18
+ 200 KB to be read whole.
19
+ - **Offline Mode**: Local caching of style guides for fast, offline access,
20
+ kept fresh with a single `sync` command.
21
+
22
+ ## Quick Start
23
+
24
+ You can run the tool directly without installing it using `uvx`:
25
+
26
+ ```bash
27
+ # Check and fix formatting for the current directory
28
+ uvx --from readability-cli readability check . --fix
29
+
30
+ # Outline the Python style guide, then read one of its sections
31
+ uvx --from readability-cli readability guide python
32
+ uvx --from readability-cli readability guide python 2.2
33
+ ```
34
+
35
+ ## Installation
36
+
37
+ Install it as a global tool with `uv`:
38
+
39
+ ```bash
40
+ # Install the readability tool
41
+ uv tool install readability-cli
42
+
43
+ # Use it anywhere
44
+ readability check .
45
+ readability guide python
46
+ ```
47
+
48
+ ### For Development
49
+
50
+ This project uses `uv` for dependency management:
51
+
52
+ ```bash
53
+ # Clone the repository
54
+ git clone https://github.com/owahltinez/readability.git
55
+ cd readability
56
+
57
+ # Install dependencies and create a virtual environment
58
+ uv sync
59
+
60
+ # (Optional) Populate the local cache for offline use
61
+ uv run readability sync
62
+ ```
63
+
64
+ ## Checking and Formatting
65
+
66
+ The `check` command identifies and runs relevant linting and formatting tools
67
+ based on file extensions and the presence of configuration files (triggers) in
68
+ your project root:
69
+
70
+ ```bash
71
+ # Run checks on the current directory
72
+ readability check .
73
+
74
+ # Check specific files or directories
75
+ readability check src/ tests/ main.py
76
+
77
+ # Automatically fix and format files
78
+ readability check . --fix
79
+ ```
80
+
81
+ ### Supported Tools
82
+
83
+ | Tool | Supported Extensions | Config Needed | Fetched By |
84
+ |------|----------------------|---------------|------------|
85
+ | **Ruff** | `.py` | none, bundled | `uvx` |
86
+ | **Pyrefly** | `.py` | none, bundled | `uvx` |
87
+ | **Biome** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.jsonc`, `.css`, `.html` | `biome.json` or `biome.jsonc` | `npx` |
88
+ | **Prettier** | `.js`, `.ts`, `.jsx`, `.tsx`, `.json`, `.css`, `.scss`, `.html`, `.md`, `.yml`, `.yaml` | `.prettierrc*` or `prettier.config.*` | `npx` |
89
+ | **gofmt** | `.go` | `go.mod` | — |
90
+
91
+ **You do not need to install any of these.** Each is resolved in order: a
92
+ project-local install (`node_modules/.bin`, `.venv/bin`) first, then whatever
93
+ is on your `PATH`, and only then fetched by `uvx` or `npx`. The runners cache
94
+ what they download, so the fetch happens once per machine and later runs are
95
+ served from disk and work offline.
96
+
97
+ That keeps this package at ~4 MB rather than the ~54 MB it would take to
98
+ carry Ruff and Pyrefly itself — a cost that would fall on everyone using only
99
+ `guide`. An installed copy always wins over a fetched one, so a project that
100
+ pinned a version is linted against the rules it chose.
101
+
102
+ Fetched tools carry a minimum version, enough to understand the bundled
103
+ configurations, and no maximum. A ceiling would freeze anyone who installed
104
+ nothing at whatever was current when this package shipped, and tie its
105
+ releases to Ruff's — which has published seventeen minor series, roughly one
106
+ every six weeks. If you need a fixed version, install it: an installed tool
107
+ always wins over a fetched one.
108
+
109
+ Set `UV_OFFLINE=1` to forbid fetching. A tool that then cannot be reached
110
+ fails the run rather than passing it.
111
+
112
+ Ruff and Pyrefly ship with bundled configurations, so they run on any file
113
+ they handle without the project arranging anything. Biome, Prettier and gofmt
114
+ bring no defaults here, so they wait until the project asks with a config
115
+ file.
116
+
117
+ A tool that could not be reached at all is never skipped quietly:
118
+
119
+ ```bash
120
+ # Some tools ran, so the result stands, but coverage was partial
121
+ $ readability check src/
122
+ Warning: not installed, so not run: prettier.
123
+ No findings in 1 path(s) (ruff, pyrefly).
124
+
125
+ # Nothing ran, so there is no result to report
126
+ $ readability check src/
127
+ Error: Every tool for 1 path(s) is missing, so nothing was verified.
128
+ ```
129
+
130
+ That second case needs neither the tool nor a runner to be present, which is
131
+ the state a container image is usually in.
132
+
133
+ `check` exits non-zero on findings and on having verified nothing, so it can
134
+ gate CI without a clean exit ever meaning "the tools were absent".
135
+
136
+ ### Python API
137
+
138
+ Use `check_paths` to run the same checks without the command's status messages
139
+ or exit-code decisions:
140
+
141
+ ```python
142
+ from pathlib import Path
143
+
144
+ from readability import check_paths
145
+
146
+ report = check_paths(["src", Path("tests")], project_root=Path.cwd())
147
+ if report.findings or report.failed or not report.ran:
148
+ handle_failed_check(report)
149
+ ```
150
+
151
+ The returned `CheckReport` records only whether findings occurred and which
152
+ tools ran, were skipped, or failed. Detailed tool findings are still written
153
+ as each tool runs.
154
+
155
+ ### Default Configurations
156
+
157
+ For Ruff and Pyrefly, bundled defaults based on the
158
+ [Google Python style guide](https://google.github.io/styleguide/pyguide.html)
159
+ (80-column lines, Google docstring convention, import ordering, full type
160
+ checking) are applied when the project does not define its own configuration.
161
+ To override them, add a `[tool.ruff]` or `[tool.pyrefly]` section to your
162
+ `pyproject.toml` (or a dedicated `ruff.toml` / `pyrefly.toml`) — any
163
+ project-level configuration takes full precedence over the bundled defaults.
164
+
165
+ ## Style Guides
166
+
167
+ The `guide` command reads a Google style guide, using the local cache when
168
+ available. It has four forms:
169
+
170
+ ```bash
171
+ # Which languages have a guide, and which are cached
172
+ readability guide
173
+
174
+ # The outline of one: every heading, a few KB where the guide is 200
175
+ readability guide python
176
+
177
+ # One section, by index, heading text, or a parent-scoped path
178
+ readability guide cpp 10.4
179
+ readability guide shell "Function Comments"
180
+ readability guide python "Imports > Decision"
181
+
182
+ # The whole guide, for grepping or when you really do want all of it
183
+ readability guide cpp --full
184
+ readability guide python --full | grep -i f-string
185
+ ```
186
+
187
+ A guide can exceed 200 KB, so the outline is what a bare invocation prints:
188
+ listing the sections and fetching the one you need beats reading the lot.
189
+ Nothing is written to disk, which is what a coding agent should do rather
190
+ than redirecting a guide into the repository it is working on — use a shell
191
+ redirect if you do want a copy.
192
+
193
+ `REF` and `--full` cannot be combined; that is refused rather than resolved
194
+ by a precedence rule you would have to know.
195
+
196
+ ### Navigating a Guide
197
+
198
+ The outline gives each section an index to fetch it by, and flags the ones
199
+ large enough to be worth knowing about first:
200
+
201
+ ```bash
202
+ $ readability guide cpp
203
+ Google C++ Style Guide
204
+ 1 Background
205
+ 1.1 Goals of the Style Guide
206
+ 2 C++ Version
207
+ 3 Header Files (1.7k words)
208
+ 3.1 Self-contained Headers
209
+ ...
210
+ # 140 sections · print one: readability guide cpp 4.5.1
211
+ ```
212
+
213
+ Sizes appear only at 1200 words and above — the 4% of sections expensive
214
+ enough that you would want warning. They include subsections, since that is
215
+ what the reference returns. The trailing line goes to stderr, so it never
216
+ contaminates a piped outline.
217
+
218
+ A section reference can be any of the following:
219
+
220
+ | Reference | Example |
221
+ |-----------|---------|
222
+ | Section index, as shown by the outline | `2.2.4` |
223
+ | Heading text, case-insensitive, or its slug | `"function comments"` |
224
+ | A parent-scoped path, spaces around the `>` | `"Imports > Decision"` |
225
+
226
+ Whole matches are preferred; a reference that matches nothing in full is
227
+ retried as a substring of the heading text.
228
+
229
+ Three of the shipped guides — Python, JavaScript, and Java — number their own
230
+ sections, and those numbers are the index. A rule cited from the outline then
231
+ matches the published guide exactly, including where the guide skips a
232
+ number: the Python guide has no 2.15 at all, so its 2.16 is listed as 2.16
233
+ rather than renumbered. The other eleven guides number nothing, so their
234
+ index comes from each heading's position in the tree.
235
+
236
+ Either way the index is unique, which is what makes a repeated heading
237
+ addressable — `Definition`, `Pros`, `Cons`, and `Decision` appear under every
238
+ rule in the Python guide. For a reference stored and used later, prefer a
239
+ printed section number or the heading text over a positional index, since
240
+ positional indices shift when an unnumbered guide is re-synced.
241
+
242
+ A reference that matches several headings is reported rather than guessed at,
243
+ listing every candidate on stderr:
244
+
245
+ ```bash
246
+ $ readability guide python Decision
247
+ Error: 'Decision' matches 19 headings in the 'python' guide. Repeat with one of:
248
+ 2.1.4 (Python Language Rules > Lint > Decision)
249
+ 2.2.4 (Python Language Rules > Imports > Decision)
250
+ ...
251
+ ```
252
+
253
+ ### When a Reference Misses
254
+
255
+ A guide discusses plenty that no heading is named after, so a reference that
256
+ matches nothing is usually a vocabulary mismatch rather than a mistake. The
257
+ sections that mention the words are reported, which turns the miss into the
258
+ next command:
259
+
260
+ ```bash
261
+ $ readability guide python f-string
262
+ Error: Found no heading matching 'f-string' in the 'python' guide.
263
+ It appears in these sections:
264
+ 3.10 Python Style Rules > Strings
265
+ 3.10.1 Python Style Rules > Strings > Logging
266
+ ```
267
+
268
+ This locates a rule; it does not search text. For that, pipe `--full` to
269
+ `grep`, which you already know and which brings its own `-i`, `-A`, `-c` and
270
+ the rest:
271
+
272
+ ```bash
273
+ readability guide python --full | grep -in -A2 "f-string"
274
+ ```
275
+
276
+ Content goes to stdout and diagnostics to stderr, so every form is safe to
277
+ pipe. Headings inside fenced code blocks are ignored, which matters for the
278
+ Shell and Python guides where `#` starts a comment.
279
+
280
+ ### Supported Languages
281
+
282
+ Run `readability guide` with no language for the full list and which guides
283
+ are cached:
284
+
285
+ ```bash
286
+ $ readability guide
287
+ Supported languages and their aliases:
288
+ - r [cached]
289
+ - c++, cpp [cached]
290
+ - c#, csharp [cached]
291
+ - docguide, markdown [cached]
292
+ - go [cached]
293
+ - css, html [cached]
294
+ - java [cached]
295
+ - javascript, js [cached]
296
+ - json [cached]
297
+ - objc, objective-c [cached]
298
+ - python [cached]
299
+ - shell [cached]
300
+ - ts, typescript [cached]
301
+ - vim [cached]
302
+ ```
303
+
304
+ Refresh the cache with `sync`, which takes languages or refetches everything:
305
+
306
+ ```bash
307
+ # Refetch one guide, or a few
308
+ readability sync python shell
309
+
310
+ # Refetch all of them
311
+ readability sync
312
+ ```
313
+
314
+ ### Offline Mode
315
+
316
+ The tool stores local copies of the style guides in the `guides/` directory
317
+ and the `guide` command uses these local files when they exist. The bundled
318
+ copies are automatically synchronized weekly from the official
319
+ [Google Style Guides](https://google.github.io/styleguide/) repository via
320
+ GitHub Actions, and you can refresh your local cache at any time with the
321
+ `sync` command.
322
+
323
+ You can override the default `guides/` directory by setting the
324
+ `READABILITY_CACHE` environment variable. This is useful if you want to store
325
+ the guides in a specific location or share them across different
326
+ installations:
327
+
328
+ ```bash
329
+ export READABILITY_CACHE=/path/to/my/guides
330
+ readability guide python
331
+ ```
332
+
333
+ ## Development
334
+
335
+ Run tests with `pytest`:
336
+
337
+ ```bash
338
+ uv run pytest
339
+ ```
340
+
341
+ Check code style with `ruff`:
342
+
343
+ ```bash
344
+ uv run ruff check .
345
+ uv run ruff format .
346
+ ```
347
+
348
+ ### Releasing
349
+
350
+ Releases are published to PyPI as
351
+ [`readability-cli`](https://pypi.org/project/readability-cli/) via trusted
352
+ publishing: pushing a `v*` tag triggers the `publish.yml` GitHub Actions
353
+ workflow, which builds the package with `uv build` and uploads it.
354
+
355
+ ```bash
356
+ # 1. Bump the version in pyproject.toml, commit, and push
357
+ # 2. Tag the release and push the tag
358
+ git tag v0.4.1
359
+ git push origin v0.4.1
360
+ ```