Metadata-Version: 2.5
Name: guidelines-for-all
Version: 1.3.1
Summary: Generate coding guidelines from linter configurations
Project-URL: Homepage, https://github.com/coreyt/guidelines-for-all
Project-URL: Documentation, https://github.com/coreyt/guidelines-for-all#readme
Project-URL: Repository, https://github.com/coreyt/guidelines-for-all
Project-URL: Issues, https://github.com/coreyt/guidelines-for-all/issues
Author: Guidelines for All contributors
License-Expression: Elastic-2.0
License-File: LICENSE
Keywords: coding-guidelines,documentation,eslint,linting,ruff
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Requires-Dist: click>=8.1.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyjson5>=1.6.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: ruamel-yaml>=0.18.0
Requires-Dist: toml>=0.10.0
Requires-Dist: tomlkit>=0.13.0
Provides-Extra: dev
Requires-Dist: jsonschema>=4.0.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.5; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.12.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.2.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Requires-Dist: types-toml>=0.10.0; extra == 'dev'
Provides-Extra: similarity
Requires-Dist: sentence-transformers>=2.2.0; extra == 'similarity'
Provides-Extra: tui
Requires-Dist: textual>=0.47.0; extra == 'tui'
Description-Content-Type: text/markdown

# Guidelines for All (`g4a`)

**Guidelines for All** turns your linter configurations into readable coding standards, and helps you set up and maintain those configurations. The command is `g4a`.

Coding guidelines usually live in a wiki that nobody reads and that drifts out of sync with what the linters actually enforce. Guidelines for All works backward from the tools your team already runs, so the guidelines stay accurate and are available to everyone who touches the code, not just the people who wrote the lint config.

## What it does

1. **Generates coding standards from linter configs.** g4a reads ESLint, Prettier, Ruff, Pyright, Roslyn, Checkstyle, PMD, SpotBugs and 16 more tools, then writes a coding-standards document (Markdown or Word) with each rule's upstream documentation.
2. **Helps you manage the configs.** It can scan a codebase for the conventions your team already follows and write matching linter configs, find rules that conflict across tools, and generate a script that runs every linter.

Because the document is generated from the configs, it changes when the configs change.

### Features

- **Coding standards document** — A front section (purpose, scope, definitions, tooling) followed by one appendix per tool, as Markdown or Word. Use the built-in templates or your own.
- **Rules your tools enforce by default** — Rules a tool turns on by itself or through a preset the config selects (Clippy's default groups, Ruff's default set, Pyright's type-checking mode, TypeScript `strict`, `eslint:recommended`, ...) are documented too, each with its source.
- **Convention discovery** — `g4a discover` scans Python, JavaScript, TypeScript, Rust and Go source and writes linter configs that match what the code already does.
- **Rule interference detection** — Finds rules that conflict across tools, such as ESLint `semi` and Prettier `semi`.
- **Lint runner** — `g4a generate-script` writes a bash script that runs every configured linter in check or fix mode.
- **AI-friendly export** — `g4a export-rules` writes the enforced rules as JSON, YAML or Markdown for coding assistants.
- **Terminal UI** — Browse rules, run the discover wizard and check interference interactively.

## Status

**v1.3.1** (released 2026-10-29), beta. See [CHANGELOG.md](CHANGELOG.md) for what changed.

## Installation

```bash
pip install guidelines-for-all
g4a --version
```

`pip install g4a` installs the same package. Optional extras, which need the full package name:

```bash
pip install "guidelines-for-all[tui]"         # terminal UI (g4a tui)
pip install "guidelines-for-all[similarity]"  # semantic interference detection (large download)
```

### Requirements

| Need | When |
|------|------|
| Python 3.10 or later | Always |
| A GitHub token in `GITHUB_TOKEN` | Recommended. Rule documentation comes from GitHub, which allows 60 requests an hour without a token and 5,000 with one. A first `g4a sync` often needs more than 60. See [GitHub token](#github-token). |
| [Pandoc](https://pandoc.org/installing.html) | Word output only. See [Word output](#word-output). |
| Node.js, and `eslint` installed in the project | ESLint flat configs (`eslint.config.js` and similar), which g4a asks ESLint to evaluate |
| `markdownlint-cli2` (npm) | `g4a build --lint` |
| `pymarkdownlnt` (pip) | The optional `pymarkdown_lint` check of generated Markdown |

### From source

For unreleased features or development:

```bash
git clone https://github.com/coreyt/guidelines-for-all.git
cd guidelines-for-all
pip install -e .
g4a --version
```

## Quick start

### Fastest: one command

In a project that has linter configs:

```bash
g4a --auto
```

This detects the tools, fetches their rule documentation and writes `generated/coding-standards.md`. It does not create a `g4a.yaml`; use the steps below when you want to keep settings.

### You already have linter configs

```bash
g4a init     # Detect linter configs and write g4a.yaml
g4a sync     # Fetch rule documentation from GitHub into .g4a-cache/
g4a build    # Write docs/guidelines/coding-standards.md
```

What each step creates:

| Step | Creates |
|------|---------|
| `g4a init` | `g4a.yaml` (the tools found and where output goes) and a `.gitignore` entry for `.g4a-cache/` |
| `g4a sync` | `.g4a-cache/`, one file per rule, kept for 7 days. `build` fetches anything missing, so `sync` is optional. |
| `g4a build` | `docs/guidelines/coding-standards.md`: the front section followed by one appendix per tool |

Other forms of `build`:

```bash
g4a build --markdown-only      # one Markdown file per tool instead of one document
g4a build --appendix-only      # only the appendices, to paste into an existing document
g4a build --format docx        # Word document (needs Pandoc and a template)
g4a build -o out/              # another output directory
```

Edit `g4a.yaml` to change the project name, add or remove tools, or point at config files g4a did not find. Run `g4a check` to validate it.

### Starting without linter configs

`g4a discover` scans your source code, reports the conventions it finds, and can write linter configs that match them.

```bash
g4a discover                # Report detected conventions (writes nothing)
g4a discover --dry-run      # Show the config files it would write
g4a discover --apply        # Write the linter configs and g4a.yaml
g4a check-interference      # Look for rules that conflict across tools
g4a build                   # Write generated/coding-standards.md
```

`discover --apply` writes `g4a.yaml` without an output setting, so `build` writes to `generated/`. Add `output: {markdown: {output_dir: docs/guidelines}}` to `g4a.yaml` to change that, and add `.g4a-cache/` to `.gitignore`.

## The generated document

`g4a build` writes one document with three parts:

```
┌─────────────────────────────────────┐
│  Front section                      │  ← Purpose, scope, definitions, tooling
├─────────────────────────────────────┤
│  How to read the appendices         │
├─────────────────────────────────────┤
│  Appendix A: ESLint Rules           │
│  Appendix B: Prettier Rules         │  ← One per tool, from its config
│  ...                                │
└─────────────────────────────────────┘
```

- **Templates.** `--template-preset minimal|standard|enterprise` (or `document.template_preset` in `g4a.yaml`) picks how much front matter you get; `standard` is the default. To write your own front section, set `document.stub` to a Markdown file.
- **Markdown dialect.** The document uses `[[_TOC_]]` for its table of contents and `\pagebreak` for page breaks. GitLab and Azure DevOps render the table of contents and Pandoc honours both; on GitHub they appear as plain text.
- **Rules from defaults and presets**. Rules the config names get a full section. Rules a tool enables by default or through a preset are listed in one table per tool. Set `output.markdown.default_rules` to `full` for full sections or `omit` for a count only.

### Word output

```bash
g4a build --format docx
g4a build --format docx --docx-template path/to/template.docx
```

Word output needs [Pandoc](https://pandoc.org/installing.html). g4a includes a plain Word template with the styles it uses, so no template of your own is needed. To use your organization's template, pass `--docx-template`, set `output.docx.template` in `g4a.yaml`, or place a file named `docx-template.docx` in the project directory or the current directory; g4a checks them in that order. Your template must define the styles g4a uses: `TableCompact`, `Bullet List 1`–`3`, `Ordered List 1`–`3`, `GrayBlock Header`, `GrayBlock Text` and `GrayBlock Bullet List 1`–`3`. `--format all` writes both Markdown and Word.

## Commands

| Command | What it does |
|---------|--------------|
| `g4a init` | Detect linter configs and write `g4a.yaml` |
| `g4a sync` | Fetch rule documentation into the cache |
| `g4a build` | Generate the coding-standards document |
| `g4a check` | Validate `g4a.yaml` and the linter configs |
| `g4a list-rules` | List each tool's rules and whether they are applied |
| `g4a check-interference` | Find rules that conflict across tools |
| `g4a discover` | Detect conventions in source code; write matching configs with `--apply` |
| `g4a generate-script` | Write a bash script that runs every configured linter |
| `g4a export-rules` | Export the enforced rules as JSON, YAML or Markdown |
| `g4a init-practices` | Add a best-practices section from a preset |
| `g4a cache` | Show (`--status`) or clear (`--clear`) the rule cache |
| `g4a tui` | Interactive terminal UI (needs the `tui` extra) |
| `g4a wake-export` | Send lint constraints to [wake](https://github.com/coreyt/wake), a Claude Code context tool |

Run `g4a <command> --help` for each command's options.

Options that go before the command:

| Option | Meaning |
|--------|---------|
| `-c`, `--config PATH` | Use this `g4a.yaml` (default: `./g4a.yaml`) |
| `-d`, `--directory PATH` | Run as if started in this directory |
| `-v`, `--verbose` | Show details, including pre-flight warnings such as a linter that is not installed |
| `-q`, `--quiet` | Show errors only |
| `--auto` | Zero-config mode: detect, fetch and build without `g4a.yaml` |
| `-V`, `--version` | Show the version |

### Using g4a in CI

| Exit code | Meaning |
|-----------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Configuration error |
| 3 | Network error |
| 4 | Pre-flight check failed |
| 5 | Rule interference found (with `--fail-on-conflict`, or `interference.on_conflict: error` during `build`) |

```bash
g4a check
g4a check-interference --fail-on-conflict
g4a build
```

Set `GITHUB_TOKEN` in the CI environment, and cache `.g4a-cache/` between runs to avoid refetching.

## Supported tools

24 tools. g4a finds these config files automatically; any other path can be set with `config_path` in `g4a.yaml`.

### TypeScript/JavaScript
| Tool | Config files detected |
|------|----------------------|
| ESLint | `eslint.config.{js,mjs,cjs,ts}` (flat config), `.eslintrc.json`, `.eslintrc`, `.eslintrc.yaml`, `.eslintrc.yml` |
| TypeScript-ESLint | `.eslintrc.json`, `.eslintrc`, `.eslintrc.yaml`, `.eslintrc.yml` (`@typescript-eslint/*` rules) |
| TSConfig | `tsconfig.json` |

### Python
| Tool | Config files detected |
|------|----------------------|
| Ruff | `ruff.toml`, `.ruff.toml`, `pyproject.toml` |
| Pyright | `pyrightconfig.json`, `pyproject.toml` |
| mypy | `mypy.ini`, `.mypy.ini`, `setup.cfg`, `pyproject.toml` |

### C#/.NET
| Tool | Config files detected |
|------|----------------------|
| Roslyn analyzers | `.editorconfig`, `.globalconfig` |
| StyleCop Analyzers | `stylecop.json`, `.stylecop.json`, `.editorconfig` (SA* rules) |

`dotnet format` enforces `.editorconfig` settings through the Roslyn analyzers, so its IDE* rules are covered by the Roslyn adapter.

### Java
| Tool | Config files detected |
|------|----------------------|
| Checkstyle | `checkstyle.xml`, `config/checkstyle/checkstyle.xml`, `checkstyle-config.xml`, `.checkstyle.xml` |
| PMD | `pmd.xml`, `ruleset.xml`, `pmd-ruleset.xml`, `.pmd.xml`, `pmd-rules.xml` |
| SpotBugs | `spotbugs-exclude.xml`, `spotbugs-include.xml`, `spotbugs.xml`, and the `findbugs-*.xml` equivalents |

### C/C++
| Tool | Config files detected |
|------|----------------------|
| Clang-Tidy | `.clang-tidy` |
| clang-format | `.clang-format`, `_clang-format` |

### Rust
| Tool | Config files detected |
|------|----------------------|
| rustc | `Cargo.toml` (compiler lints; `[lints.rust]`) |
| Clippy | `Cargo.toml` (`[lints.clippy]`) |
| rustfmt | `rustfmt.toml`, `.rustfmt.toml` |

### Go
| Tool | Config files detected |
|------|----------------------|
| golangci-lint | `.golangci.yml`, `.golangci.yaml`, `.golangci.json`, `.golangci.toml` |

### Lua
| Tool | Config files detected |
|------|----------------------|
| Luacheck | `.luacheckrc`, `.luacheck` |

### Markdown
| Tool | Config files detected |
|------|----------------------|
| Markdownlint | `.markdownlint-cli2.{jsonc,yaml}`, `.markdownlint.{jsonc,json,yaml,yml}` |
| PyMarkdown | `.pymarkdown`, `.pymarkdown.{json,yml,yaml}` |

### Multi-language
| Tool | Config files detected |
|------|----------------------|
| Prettier | `.prettierrc`, `.prettierrc.{json,yaml,yml,toml}` |
| Semgrep | `.semgrep.yaml`, `.semgrep.yml`, `semgrep.yaml`, `semgrep.yml`, `.semgrep` (rules document themselves) |
| SonarQube | Quality Profile XML export: `sonar-quality-profile.xml`, `quality-profile.xml`, `sonar-profile.xml`, `sonar-profile-backup.xml`, `sonarqube-profile.xml`. Known issue: upstream rule text is not fetched; appendices list rule keys, severities and parameters |
| Lookout | `lookout.toml`, `[tool.lookout]` in `pyproject.toml`, `.lookout-rules/`, `.lookout-baseline.json` (architectural rules) |

The front section of the document is written for the project's main ecosystem: JavaScript/TypeScript, Python, C#/.NET, Java, C/C++, Rust, Go, Lua or Markdown. g4a picks it from the enabled tools; set `document.ecosystem` in `g4a.yaml` to choose it yourself.

## Configuration

`g4a init` writes `g4a.yaml`. A typical file:

```yaml
project:
  name: "My Project"

tools:
  ruff:
    enabled: true
    config_path: pyproject.toml
  markdownlint:
    enabled: true
    config_path: .markdownlint.json

output:
  markdown:
    output_dir: ./docs/guidelines   # default when the key is absent: ./generated

document:
  template_preset: standard         # minimal, standard or enterprise
  appendices:
    style: alpha                    # A, B, C (or numeric: 1, 2, 3)
    prefix: Appendix

interference:
  on_conflict: warn                 # or error: build exits with code 5
  ignore:
    - "eslint/semi:prettier/semi"   # pairs you enforce in both tools on purpose

cache:
  ttl_days: 7
```

g4a ignores keys it does not know, so a misspelled key has no effect. `g4a check` and the pre-flight checks name each such key in a warning. Check spelling against the [configuration reference](docs/usage-guide.md#configuration-reference).

## Rule interference

g4a looks for rules that conflict across tools, for example:

- ESLint `semi` and Prettier `semi`
- ESLint `quotes` and Prettier `singleQuote`
- ESLint `no-unused-vars` and TypeScript-ESLint `no-unused-vars`

```bash
g4a check-interference                     # report conflicts
g4a check-interference --format json       # as JSON
g4a check-interference --fail-on-conflict  # exit code 5 when conflicts are found
```

`g4a build` runs the same check. List pairs you enforce in both tools on purpose under `interference.ignore`.

## Checking the generated Markdown

- `g4a build --lint` runs `markdownlint-cli2` on the output (install it with npm).
- The `pymarkdown_lint` setting runs PyMarkdown (`pip install pymarkdownlnt`) with a preset for where the document will be read:

```yaml
pymarkdown_lint:
  enabled: true
  preset: pandoc          # or gfm
  fail_on_error: false
```

| Check | `pandoc` preset | `gfm` preset |
|-------|-----------------|--------------|
| Line length | Not checked | 80 characters |
| Inline HTML | Allowed | `br`, `details`, `summary`, `kbd`, `sub`, `sup` only |
| Code block language | Optional | Required |
| Consecutive blank lines | Up to 2 | 1 |
| Duplicate headings | Allowed | Not allowed |

## GitHub token

Rule documentation is fetched from GitHub. Without a token the limit is 60 requests an hour; with one it is 5,000.

1. Create a token at [GitHub settings → Developer settings → Personal access tokens](https://github.com/settings/tokens). A classic token with no scopes is enough, because g4a only reads public repositories.
2. Set it before running g4a:

```bash
export GITHUB_TOKEN=ghp_your_token_here
```

Add that line to your shell profile (`~/.bashrc`, `~/.zshrc`) to keep it, or use a tool such as [direnv](https://direnv.net/) for per-project settings. Never commit the token. `g4a check` reports whether a token was found.

Fetched documentation is cached in `.g4a-cache/` for 7 days (`cache.ttl_days`), so later builds work offline.

## Documentation

- [Usage guide](docs/usage-guide.md) - Every command and setting, with examples
- [Codebase analyzer](docs/14-codebase-analyzer.md) - How `g4a discover` detects conventions
- [Adding linter adapters](docs/10-adding-linter-adapters.md) - Supporting another tool
- [Changelog](CHANGELOG.md) - Release history
- [Roadmap](ROADMAP.md) - What is planned next
- [Contributing](CONTRIBUTING.md) - Development setup, tests and project layout

## License

Licensed under the [Elastic License 2.0](LICENSE) (ELv2). ELv2 is a source-available license; it is not an OSI-approved open-source license.

In plain terms (the [LICENSE](LICENSE) text is what governs), you may use, copy, modify and redistribute the software, including inside your company and in your CI pipelines, but you may not:

- provide it to third parties as a hosted or managed service that gives them access to a substantial part of its features;
- move, change, disable or circumvent any license-key functionality;
- alter, remove or obscure licensing, copyright or other notices.

### License history

- Up to and including **v1.0.0** (January 2026): MIT. Anyone who received v1.0.0 keeps the MIT rights to that version.
- From the March 2026 relicense onward (v1.2.0 and later): Elastic License 2.0.
