instruction-lint 0.1.0__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.
- instruction_lint-0.1.0/.gitignore +18 -0
- instruction_lint-0.1.0/.pre-commit-hooks.yaml +9 -0
- instruction_lint-0.1.0/CHANGELOG.md +84 -0
- instruction_lint-0.1.0/LICENSE +21 -0
- instruction_lint-0.1.0/PKG-INFO +267 -0
- instruction_lint-0.1.0/README.md +236 -0
- instruction_lint-0.1.0/action.yml +37 -0
- instruction_lint-0.1.0/agentlint/__init__.py +9 -0
- instruction_lint-0.1.0/agentlint/adapters/__init__.py +6 -0
- instruction_lint-0.1.0/agentlint/adapters/base.py +58 -0
- instruction_lint-0.1.0/agentlint/adapters/copilot.py +63 -0
- instruction_lint-0.1.0/agentlint/adapters/cursor.py +57 -0
- instruction_lint-0.1.0/agentlint/adapters/windsurf.py +57 -0
- instruction_lint-0.1.0/agentlint/checks/__init__.py +15 -0
- instruction_lint-0.1.0/agentlint/checks/dispatch_coverage.py +77 -0
- instruction_lint-0.1.0/agentlint/checks/file_references.py +92 -0
- instruction_lint-0.1.0/agentlint/checks/forbidden_patterns.py +52 -0
- instruction_lint-0.1.0/agentlint/checks/number_sourcing.py +81 -0
- instruction_lint-0.1.0/agentlint/checks/trigger_overlap.py +115 -0
- instruction_lint-0.1.0/agentlint/cli.py +178 -0
- instruction_lint-0.1.0/agentlint/config.py +147 -0
- instruction_lint-0.1.0/agentlint/models.py +77 -0
- instruction_lint-0.1.0/agentlint/report.py +170 -0
- instruction_lint-0.1.0/agentlint/templates/SKILL_HEALTH_CHECK.md +244 -0
- instruction_lint-0.1.0/pyproject.toml +54 -0
- instruction_lint-0.1.0/tests/__init__.py +0 -0
- instruction_lint-0.1.0/tests/conftest.py +71 -0
- instruction_lint-0.1.0/tests/test_cli.py +322 -0
- instruction_lint-0.1.0/tests/test_dispatch_coverage.py +88 -0
- instruction_lint-0.1.0/tests/test_file_references.py +242 -0
- instruction_lint-0.1.0/tests/test_forbidden_patterns.py +64 -0
- instruction_lint-0.1.0/tests/test_number_sourcing.py +80 -0
- instruction_lint-0.1.0/tests/test_report.py +276 -0
- instruction_lint-0.1.0/tests/test_trigger_overlap.py +79 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.egg-info/
|
|
4
|
+
dist/
|
|
5
|
+
build/
|
|
6
|
+
.venv/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
*.db
|
|
9
|
+
*.db-journal
|
|
10
|
+
|
|
11
|
+
# Temporary audit/test helpers (not part of the package)
|
|
12
|
+
_smoke_test.py
|
|
13
|
+
_check_wheel.py
|
|
14
|
+
|
|
15
|
+
# Internal release process docs — not for public repo
|
|
16
|
+
PUBLISH_AGENT.md
|
|
17
|
+
QUALITY_AUDIT.md
|
|
18
|
+
AGENT_STATE.md
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
- id: agentlint
|
|
2
|
+
name: agentlint
|
|
3
|
+
description: Audit AI coding assistant instruction files (Copilot skills, Cursor rules, Windsurf rules)
|
|
4
|
+
language: python
|
|
5
|
+
entry: agentlint
|
|
6
|
+
pass_filenames: false
|
|
7
|
+
always_run: false
|
|
8
|
+
types: [markdown]
|
|
9
|
+
stages: [pre-commit]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to agentlint are documented here.
|
|
4
|
+
|
|
5
|
+
## [Unreleased] — pre-release additions (2026-04-02)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Windsurf adapter** — detects and lints `.windsurfrules` (DISPATCH) and
|
|
9
|
+
`.windsurf/rules/*.md` (SKILL) files. `--adapter windsurf` and auto-detection both
|
|
10
|
+
supported. (`agentlint/adapters/windsurf.py`)
|
|
11
|
+
- **`--format sarif`** — emits SARIF 2.1.0 JSON for direct ingestion by GitHub Code
|
|
12
|
+
Scanning and other SAST platforms. (`agentlint/report.py`, `agentlint/cli.py`)
|
|
13
|
+
- **AL-F01 fuzzy suggestions** — when a referenced file path is not found on disk, the
|
|
14
|
+
fix hint now checks for similarly-named files using `difflib.get_close_matches` and
|
|
15
|
+
suggests the closest match (e.g. `Did you mean 'src/utils/validator.ts'?`).
|
|
16
|
+
(`agentlint/checks/file_references.py`)
|
|
17
|
+
- 10 new tests covering all three features above (`tests/test_cli.py`,
|
|
18
|
+
`tests/test_file_references.py`). Test count: 51 → 67 → 77.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **UnicodeEncodeError on Windows** — `✖` and `⚠` characters in the text output caused a
|
|
22
|
+
crash on Windows terminals using cp1252 encoding. Fixed with `io.TextIOWrapper` fallback
|
|
23
|
+
in `cli.py`.
|
|
24
|
+
- **Raw traceback on invalid `.agentlint.yml`** — a malformed config file produced a full
|
|
25
|
+
Python stack trace instead of a friendly error message. Fixed with `try/except
|
|
26
|
+
yaml.YAMLError` in `config.py`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- PyPI distribution name changed from `agentlint` to `agentlint-cli` (the name `agentlint`
|
|
30
|
+
was already registered on PyPI by an unrelated package). Python module name, CLI binary,
|
|
31
|
+
and import paths are unchanged.
|
|
32
|
+
- `action.yml` adapter description updated to include `windsurf`.
|
|
33
|
+
- `action.yml` format description updated to include `sarif`.
|
|
34
|
+
- `.pre-commit-hooks.yaml` description updated to mention Windsurf.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## [0.1.0-rc] — pre-release fixes (found during internal audit, 2026-04-01)
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- **BUG-01** `--adapter cursor` (or any explicit adapter) on a repo that does not match that
|
|
42
|
+
adapter's `detect()` heuristics now exits with code 2 instead of silently scanning 0 files
|
|
43
|
+
and exiting 0. (`agentlint/cli.py`)
|
|
44
|
+
- **BUG-02** AL-F01 no longer fires on file-path strings that appear inside fenced code
|
|
45
|
+
blocks (` ``` … ``` `). (`agentlint/checks/file_references.py`)
|
|
46
|
+
- **BUG-04** `templates/SKILL_HEALTH_CHECK.md` is now bundled inside the `agentlint/`
|
|
47
|
+
package directory so `--init` works after `pip install`. (`agentlint/__init__.py`)
|
|
48
|
+
- **BUG-05** Removed dead `_CHECK_REGISTRY` list and the misleading
|
|
49
|
+
`skill-dispatch-coverage` toggle key from `Config.checks`. (`agentlint/config.py`)
|
|
50
|
+
- **BUG-06** `--config /path/to/custom.yml` now loads the specified file directly via
|
|
51
|
+
`Config._from_file()`. (`agentlint/cli.py`, `agentlint/config.py`)
|
|
52
|
+
- **action.yml / CLI mismatch** Added `--fail-on-warnings` as an explicit CLI flag.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- README CLI reference block updated to match current `--help` output.
|
|
56
|
+
- README grade table rewritten with accurate descriptions from the scoring formula.
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
- `LICENSE` file (MIT).
|
|
60
|
+
- `tests/test_file_references.py` — 11 tests for AL-F01.
|
|
61
|
+
- `tests/test_cli.py` — 13 integration tests covering all exit codes and flags.
|
|
62
|
+
- `tests/test_report.py` — 25 tests for `format_text()`, `format_json()`, and `grade()`.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## [0.1.0] — 2026-04-01
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
- **AL-D01** Detect skill paths in dispatch table that don't exist on disk.
|
|
70
|
+
- **AL-D02** Detect skill files on disk that are missing from the dispatch table.
|
|
71
|
+
- **AL-F01** Detect source-file references in skill files that don't exist on disk.
|
|
72
|
+
- **AL-N01** Detect threshold/percentage numbers in skill files without a source pointer,
|
|
73
|
+
with look-back awareness for table rows and blockquotes.
|
|
74
|
+
- **AL-T01** Detect overlapping trigger descriptions between skills using Jaccard similarity.
|
|
75
|
+
- **AL-P01** (built-in default) Detect hardcoded test counts.
|
|
76
|
+
- Configurable forbidden patterns via `.agentlint.yml`.
|
|
77
|
+
- **GitHub Copilot adapter** — parses `copilot-instructions.md` + `.github/skills/**/SKILL.md`.
|
|
78
|
+
- **Cursor adapter** — parses `.cursorrules` + `.cursor/rules/*.mdc`.
|
|
79
|
+
- Auto-detection: both adapters can be active simultaneously.
|
|
80
|
+
- `--format json` for CI dashboards and PR annotations.
|
|
81
|
+
- A–F health grade based on violation density.
|
|
82
|
+
- `--init` flag copies `SKILL_HEALTH_CHECK.md` behavioral test template.
|
|
83
|
+
- Pre-commit hook support (`.pre-commit-hooks.yaml`).
|
|
84
|
+
- GitHub Action wrapper (`action.yml`).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 agentlint
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: instruction-lint
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The ESLint of AI coding assistant instructions — audit, validate, and fix your Copilot skills, Cursor rules, and agent instruction files.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Mr-afroverse/agentlint
|
|
6
|
+
Project-URL: Repository, https://github.com/Mr-afroverse/agentlint
|
|
7
|
+
Project-URL: Issues, https://github.com/Mr-afroverse/agentlint/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/Mr-afroverse/agentlint/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: agentlint <hello@agentlint.dev>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agent,ai,cursor,github-copilot,instructions,lint,skills,windsurf
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: click>=8.0
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# agentlint
|
|
33
|
+
|
|
34
|
+
**The ESLint of AI coding assistant instructions.**
|
|
35
|
+
|
|
36
|
+
Audit, validate, and keep your GitHub Copilot skills, Cursor rules, and agent instruction files consistent with your actual codebase.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Why
|
|
41
|
+
|
|
42
|
+
AI coding assistants are only as good as their instructions. Instruction files drift silently:
|
|
43
|
+
|
|
44
|
+
- A skill references a file that was renamed six months ago.
|
|
45
|
+
- A threshold is hardcoded in a SKILL.md but the constant changed in source code.
|
|
46
|
+
- Two skills have overlapping triggers — the agent picks randomly.
|
|
47
|
+
- A skill was added to disk but never wired into the dispatch table.
|
|
48
|
+
|
|
49
|
+
None of this gets caught by `markdownlint` or `yamllint`. These are **codebase-aware problems** that require **codebase-aware checks**.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install instruction-lint
|
|
57
|
+
cd your-project
|
|
58
|
+
agentlint
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or as a **pre-commit hook** (recommended — runs on every commit, zero maintenance):
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
# .pre-commit-config.yaml
|
|
65
|
+
repos:
|
|
66
|
+
- repo: https://github.com/Mr-afroverse/agentlint
|
|
67
|
+
rev: v0.1.0
|
|
68
|
+
hooks:
|
|
69
|
+
- id: agentlint
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## What it checks
|
|
75
|
+
|
|
76
|
+
| ID | Check | Severity | Zero-config |
|
|
77
|
+
|----|-------|----------|-------------|
|
|
78
|
+
| AL-D01 | Skill path in dispatch table → exists on disk | Error | ✓ |
|
|
79
|
+
| AL-D02 | Skill file on disk → referenced in dispatch table | Error | ✓ |
|
|
80
|
+
| AL-F01 | Source-file paths in skill files → exist on disk | Warning | ✓ |
|
|
81
|
+
| AL-N01 | Threshold numbers → have a source pointer | Warning | ✓ |
|
|
82
|
+
| AL-T01 | Trigger descriptions → no significant overlap | Warning | ✓ |
|
|
83
|
+
| AL-P* | Forbidden patterns (built-in defaults + configurable) | Error | ✓ |
|
|
84
|
+
|
|
85
|
+
All six checks work out of the box with no configuration.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Supported assistants
|
|
90
|
+
|
|
91
|
+
| Assistant | Format detected |
|
|
92
|
+
|-----------|----------------|
|
|
93
|
+
| **GitHub Copilot** | `.github/copilot-instructions.md` + `.github/skills/**/SKILL.md` |
|
|
94
|
+
| **Cursor** | `.cursorrules` + `.cursor/rules/*.mdc` |
|
|
95
|
+
| **Windsurf** | `.windsurfrules` + `.windsurf/rules/*.md` |
|
|
96
|
+
|
|
97
|
+
Multiple formats can be active at once. `agentlint` auto-detects which are present.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Example output
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
[agentlint] 2 error(s), 1 warning(s) across 8 file(s). Grade: C
|
|
105
|
+
|
|
106
|
+
.github/skills/gps-scorer/SKILL.md
|
|
107
|
+
✖ [AL-D02]:1 Skill `gps-scorer` is not referenced in the dispatch file.
|
|
108
|
+
Fix → Add an entry for `.github/skills/gps-scorer/SKILL.md` in the dispatch table.
|
|
109
|
+
|
|
110
|
+
.github/copilot-instructions.md
|
|
111
|
+
✖ [AL-D01]:14 Skill path not found on disk: `.github/skills/old-scorer/SKILL.md`
|
|
112
|
+
Fix → Create the file or correct the path in the dispatch table.
|
|
113
|
+
|
|
114
|
+
.github/skills/eudr-standards/SKILL.md
|
|
115
|
+
⚠ [AL-N01]:48 Threshold number without source pointer: `| GREEN ≥ 90% |`
|
|
116
|
+
Fix → Add '(Source: constants.py)' or a regulatory article reference.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Health scoring
|
|
122
|
+
|
|
123
|
+
Every run produces a **grade** (A–F) based on error and warning density across scanned files. Use it to track skill health over time in your CI dashboard.
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Grade: A → no violations, or up to 2 warnings per file
|
|
127
|
+
Grade: B → up to 3–4 warnings per file, or 1 error in a large repo
|
|
128
|
+
Grade: C → 6 warnings per file, or 1 error per small file
|
|
129
|
+
Grade: D → 2 errors per file, or many warnings
|
|
130
|
+
Grade: F → 3+ errors per file, or high combined density
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The score formula is `100 − (errors_per_file × 20) − (warnings_per_file × 5)`. Grades A–F map to score bands 90 / 80 / 70 / 60 / below 60.
|
|
134
|
+
|
|
135
|
+
Pipe `--format json` into your CI annotation step:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
agentlint --format json | tee agentlint-report.json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Or emit **SARIF** for GitHub Code Scanning:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
agentlint --format sarif | tee agentlint.sarif
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Configuration
|
|
150
|
+
|
|
151
|
+
`agentlint` works with zero config. Add `.agentlint.yml` to extend or override defaults:
|
|
152
|
+
|
|
153
|
+
```yaml
|
|
154
|
+
# .agentlint.yml
|
|
155
|
+
|
|
156
|
+
# Add project-specific forbidden patterns (extends built-in defaults)
|
|
157
|
+
forbidden_patterns:
|
|
158
|
+
- id: MY001
|
|
159
|
+
pattern: '\b8-stage pipeline\b'
|
|
160
|
+
reason: "Pipeline has 7 stages — this count will drift."
|
|
161
|
+
fix: "Use '7-stage' and add a pointer to orchestrator.py."
|
|
162
|
+
severity: error
|
|
163
|
+
|
|
164
|
+
# Adjust trigger-overlap sensitivity (0.0–1.0, default 0.5)
|
|
165
|
+
trigger_overlap_threshold: 0.6
|
|
166
|
+
|
|
167
|
+
# Add extra source-root directories for file-reference resolution
|
|
168
|
+
source_roots: [".", "src", "backend"]
|
|
169
|
+
|
|
170
|
+
# Add project-specific source markers (extends built-in list)
|
|
171
|
+
source_markers:
|
|
172
|
+
- "my_constants\\.py"
|
|
173
|
+
- "REGULATORY_GATES"
|
|
174
|
+
|
|
175
|
+
# Disable specific checks
|
|
176
|
+
checks:
|
|
177
|
+
trigger-overlap: false
|
|
178
|
+
|
|
179
|
+
# Fail the run when warnings are present (default: only errors fail)
|
|
180
|
+
fail_on_warnings: true
|
|
181
|
+
|
|
182
|
+
# Paths to skip (substring match on the file path)
|
|
183
|
+
ignore_paths:
|
|
184
|
+
- "archive/"
|
|
185
|
+
- "docs/health/"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Replace built-in forbidden patterns entirely
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
forbidden_patterns_mode: replace
|
|
192
|
+
forbidden_patterns:
|
|
193
|
+
- id: PROJ001
|
|
194
|
+
pattern: '\blegacy_mode\b'
|
|
195
|
+
reason: "legacy_mode was removed in v2."
|
|
196
|
+
fix: "Delete the flag entirely."
|
|
197
|
+
severity: error
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Layer 2: Behavioral testing
|
|
203
|
+
|
|
204
|
+
The checks above are **static** — they analyse files without running the agent. To test whether your skills actually fire correctly and produce sound guidance, use the included behavioral test sheet:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
agentlint --init # copies SKILL_HEALTH_CHECK.md into .github/skills/
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The template contains 10 ready-to-run prompts with explicit PASS/FAIL criteria covering trigger accuracy, over-firing prevention, source-pointer discipline, multi-skill invocation, and more.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## GitHub Action
|
|
215
|
+
|
|
216
|
+
```yaml
|
|
217
|
+
# .github/workflows/agentlint.yml
|
|
218
|
+
name: agentlint
|
|
219
|
+
on: [push, pull_request]
|
|
220
|
+
|
|
221
|
+
jobs:
|
|
222
|
+
agentlint:
|
|
223
|
+
runs-on: ubuntu-latest
|
|
224
|
+
steps:
|
|
225
|
+
- uses: actions/checkout@v4
|
|
226
|
+
- uses: Mr-afroverse/agentlint@v0.1.0
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## CLI reference
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
Usage: agentlint [OPTIONS] [PATH]
|
|
235
|
+
|
|
236
|
+
agentlint — audit AI coding assistant instruction files.
|
|
237
|
+
|
|
238
|
+
Options:
|
|
239
|
+
-V, --version Show the version and exit.
|
|
240
|
+
--format [text|json|sarif] Output format (default: text).
|
|
241
|
+
--config PATH Path to .agentlint.yml config file.
|
|
242
|
+
--adapter [copilot|cursor|windsurf|auto]
|
|
243
|
+
Force a specific adapter (default: auto-
|
|
244
|
+
detect).
|
|
245
|
+
--fail-on-warnings Exit 1 when warnings are present (overrides
|
|
246
|
+
config).
|
|
247
|
+
--init Copy SKILL_HEALTH_CHECK.md template into
|
|
248
|
+
.github/skills/.
|
|
249
|
+
-h, --help Show this message and exit.
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Development
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
git clone https://github.com/Mr-afroverse/agentlint
|
|
258
|
+
cd agentlint
|
|
259
|
+
pip install -e ".[dev]" # or: pip install instruction-lint
|
|
260
|
+
pytest
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# agentlint
|
|
2
|
+
|
|
3
|
+
**The ESLint of AI coding assistant instructions.**
|
|
4
|
+
|
|
5
|
+
Audit, validate, and keep your GitHub Copilot skills, Cursor rules, and agent instruction files consistent with your actual codebase.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
AI coding assistants are only as good as their instructions. Instruction files drift silently:
|
|
12
|
+
|
|
13
|
+
- A skill references a file that was renamed six months ago.
|
|
14
|
+
- A threshold is hardcoded in a SKILL.md but the constant changed in source code.
|
|
15
|
+
- Two skills have overlapping triggers — the agent picks randomly.
|
|
16
|
+
- A skill was added to disk but never wired into the dispatch table.
|
|
17
|
+
|
|
18
|
+
None of this gets caught by `markdownlint` or `yamllint`. These are **codebase-aware problems** that require **codebase-aware checks**.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install instruction-lint
|
|
26
|
+
cd your-project
|
|
27
|
+
agentlint
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or as a **pre-commit hook** (recommended — runs on every commit, zero maintenance):
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
# .pre-commit-config.yaml
|
|
34
|
+
repos:
|
|
35
|
+
- repo: https://github.com/Mr-afroverse/agentlint
|
|
36
|
+
rev: v0.1.0
|
|
37
|
+
hooks:
|
|
38
|
+
- id: agentlint
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## What it checks
|
|
44
|
+
|
|
45
|
+
| ID | Check | Severity | Zero-config |
|
|
46
|
+
|----|-------|----------|-------------|
|
|
47
|
+
| AL-D01 | Skill path in dispatch table → exists on disk | Error | ✓ |
|
|
48
|
+
| AL-D02 | Skill file on disk → referenced in dispatch table | Error | ✓ |
|
|
49
|
+
| AL-F01 | Source-file paths in skill files → exist on disk | Warning | ✓ |
|
|
50
|
+
| AL-N01 | Threshold numbers → have a source pointer | Warning | ✓ |
|
|
51
|
+
| AL-T01 | Trigger descriptions → no significant overlap | Warning | ✓ |
|
|
52
|
+
| AL-P* | Forbidden patterns (built-in defaults + configurable) | Error | ✓ |
|
|
53
|
+
|
|
54
|
+
All six checks work out of the box with no configuration.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Supported assistants
|
|
59
|
+
|
|
60
|
+
| Assistant | Format detected |
|
|
61
|
+
|-----------|----------------|
|
|
62
|
+
| **GitHub Copilot** | `.github/copilot-instructions.md` + `.github/skills/**/SKILL.md` |
|
|
63
|
+
| **Cursor** | `.cursorrules` + `.cursor/rules/*.mdc` |
|
|
64
|
+
| **Windsurf** | `.windsurfrules` + `.windsurf/rules/*.md` |
|
|
65
|
+
|
|
66
|
+
Multiple formats can be active at once. `agentlint` auto-detects which are present.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Example output
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
[agentlint] 2 error(s), 1 warning(s) across 8 file(s). Grade: C
|
|
74
|
+
|
|
75
|
+
.github/skills/gps-scorer/SKILL.md
|
|
76
|
+
✖ [AL-D02]:1 Skill `gps-scorer` is not referenced in the dispatch file.
|
|
77
|
+
Fix → Add an entry for `.github/skills/gps-scorer/SKILL.md` in the dispatch table.
|
|
78
|
+
|
|
79
|
+
.github/copilot-instructions.md
|
|
80
|
+
✖ [AL-D01]:14 Skill path not found on disk: `.github/skills/old-scorer/SKILL.md`
|
|
81
|
+
Fix → Create the file or correct the path in the dispatch table.
|
|
82
|
+
|
|
83
|
+
.github/skills/eudr-standards/SKILL.md
|
|
84
|
+
⚠ [AL-N01]:48 Threshold number without source pointer: `| GREEN ≥ 90% |`
|
|
85
|
+
Fix → Add '(Source: constants.py)' or a regulatory article reference.
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Health scoring
|
|
91
|
+
|
|
92
|
+
Every run produces a **grade** (A–F) based on error and warning density across scanned files. Use it to track skill health over time in your CI dashboard.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
Grade: A → no violations, or up to 2 warnings per file
|
|
96
|
+
Grade: B → up to 3–4 warnings per file, or 1 error in a large repo
|
|
97
|
+
Grade: C → 6 warnings per file, or 1 error per small file
|
|
98
|
+
Grade: D → 2 errors per file, or many warnings
|
|
99
|
+
Grade: F → 3+ errors per file, or high combined density
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The score formula is `100 − (errors_per_file × 20) − (warnings_per_file × 5)`. Grades A–F map to score bands 90 / 80 / 70 / 60 / below 60.
|
|
103
|
+
|
|
104
|
+
Pipe `--format json` into your CI annotation step:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
agentlint --format json | tee agentlint-report.json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Or emit **SARIF** for GitHub Code Scanning:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
agentlint --format sarif | tee agentlint.sarif
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Configuration
|
|
119
|
+
|
|
120
|
+
`agentlint` works with zero config. Add `.agentlint.yml` to extend or override defaults:
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
# .agentlint.yml
|
|
124
|
+
|
|
125
|
+
# Add project-specific forbidden patterns (extends built-in defaults)
|
|
126
|
+
forbidden_patterns:
|
|
127
|
+
- id: MY001
|
|
128
|
+
pattern: '\b8-stage pipeline\b'
|
|
129
|
+
reason: "Pipeline has 7 stages — this count will drift."
|
|
130
|
+
fix: "Use '7-stage' and add a pointer to orchestrator.py."
|
|
131
|
+
severity: error
|
|
132
|
+
|
|
133
|
+
# Adjust trigger-overlap sensitivity (0.0–1.0, default 0.5)
|
|
134
|
+
trigger_overlap_threshold: 0.6
|
|
135
|
+
|
|
136
|
+
# Add extra source-root directories for file-reference resolution
|
|
137
|
+
source_roots: [".", "src", "backend"]
|
|
138
|
+
|
|
139
|
+
# Add project-specific source markers (extends built-in list)
|
|
140
|
+
source_markers:
|
|
141
|
+
- "my_constants\\.py"
|
|
142
|
+
- "REGULATORY_GATES"
|
|
143
|
+
|
|
144
|
+
# Disable specific checks
|
|
145
|
+
checks:
|
|
146
|
+
trigger-overlap: false
|
|
147
|
+
|
|
148
|
+
# Fail the run when warnings are present (default: only errors fail)
|
|
149
|
+
fail_on_warnings: true
|
|
150
|
+
|
|
151
|
+
# Paths to skip (substring match on the file path)
|
|
152
|
+
ignore_paths:
|
|
153
|
+
- "archive/"
|
|
154
|
+
- "docs/health/"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Replace built-in forbidden patterns entirely
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
forbidden_patterns_mode: replace
|
|
161
|
+
forbidden_patterns:
|
|
162
|
+
- id: PROJ001
|
|
163
|
+
pattern: '\blegacy_mode\b'
|
|
164
|
+
reason: "legacy_mode was removed in v2."
|
|
165
|
+
fix: "Delete the flag entirely."
|
|
166
|
+
severity: error
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Layer 2: Behavioral testing
|
|
172
|
+
|
|
173
|
+
The checks above are **static** — they analyse files without running the agent. To test whether your skills actually fire correctly and produce sound guidance, use the included behavioral test sheet:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
agentlint --init # copies SKILL_HEALTH_CHECK.md into .github/skills/
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The template contains 10 ready-to-run prompts with explicit PASS/FAIL criteria covering trigger accuracy, over-firing prevention, source-pointer discipline, multi-skill invocation, and more.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## GitHub Action
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
# .github/workflows/agentlint.yml
|
|
187
|
+
name: agentlint
|
|
188
|
+
on: [push, pull_request]
|
|
189
|
+
|
|
190
|
+
jobs:
|
|
191
|
+
agentlint:
|
|
192
|
+
runs-on: ubuntu-latest
|
|
193
|
+
steps:
|
|
194
|
+
- uses: actions/checkout@v4
|
|
195
|
+
- uses: Mr-afroverse/agentlint@v0.1.0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## CLI reference
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
Usage: agentlint [OPTIONS] [PATH]
|
|
204
|
+
|
|
205
|
+
agentlint — audit AI coding assistant instruction files.
|
|
206
|
+
|
|
207
|
+
Options:
|
|
208
|
+
-V, --version Show the version and exit.
|
|
209
|
+
--format [text|json|sarif] Output format (default: text).
|
|
210
|
+
--config PATH Path to .agentlint.yml config file.
|
|
211
|
+
--adapter [copilot|cursor|windsurf|auto]
|
|
212
|
+
Force a specific adapter (default: auto-
|
|
213
|
+
detect).
|
|
214
|
+
--fail-on-warnings Exit 1 when warnings are present (overrides
|
|
215
|
+
config).
|
|
216
|
+
--init Copy SKILL_HEALTH_CHECK.md template into
|
|
217
|
+
.github/skills/.
|
|
218
|
+
-h, --help Show this message and exit.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Development
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
git clone https://github.com/Mr-afroverse/agentlint
|
|
227
|
+
cd agentlint
|
|
228
|
+
pip install -e ".[dev]" # or: pip install instruction-lint
|
|
229
|
+
pytest
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: agentlint
|
|
2
|
+
description: Audit AI coding assistant instruction files for drift, broken references, and structural issues.
|
|
3
|
+
author: agentlint
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
path:
|
|
7
|
+
description: Directory to scan (default: repo root)
|
|
8
|
+
required: false
|
|
9
|
+
default: "."
|
|
10
|
+
format:
|
|
11
|
+
description: Output format — "text", "json", or "sarif"
|
|
12
|
+
required: false
|
|
13
|
+
default: "text"
|
|
14
|
+
adapter:
|
|
15
|
+
description: Force adapter — "copilot", "cursor", "windsurf", or "auto"
|
|
16
|
+
required: false
|
|
17
|
+
default: "auto"
|
|
18
|
+
fail-on-warnings:
|
|
19
|
+
description: Exit 1 when warnings are present (default false)
|
|
20
|
+
required: false
|
|
21
|
+
default: "false"
|
|
22
|
+
|
|
23
|
+
runs:
|
|
24
|
+
using: composite
|
|
25
|
+
steps:
|
|
26
|
+
- name: Install agentlint
|
|
27
|
+
shell: bash
|
|
28
|
+
run: pip install instruction-lint
|
|
29
|
+
|
|
30
|
+
- name: Run agentlint
|
|
31
|
+
shell: bash
|
|
32
|
+
run: |
|
|
33
|
+
ARGS="${{ inputs.path }} --format ${{ inputs.format }} --adapter ${{ inputs.adapter }}"
|
|
34
|
+
if [ "${{ inputs.fail-on-warnings }}" = "true" ]; then
|
|
35
|
+
ARGS="$ARGS --fail-on-warnings"
|
|
36
|
+
fi
|
|
37
|
+
agentlint $ARGS
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from agentlint.adapters.base import BaseAdapter
|
|
2
|
+
from agentlint.adapters.copilot import CopilotAdapter
|
|
3
|
+
from agentlint.adapters.cursor import CursorAdapter
|
|
4
|
+
from agentlint.adapters.windsurf import WindsurfAdapter
|
|
5
|
+
|
|
6
|
+
__all__ = ["BaseAdapter", "CopilotAdapter", "CursorAdapter", "WindsurfAdapter"]
|