@yawlabs/ctxlint 0.2.2 → 0.4.0
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.
- package/README.md +109 -24
- package/dist/chunk-WEYNMCAH.js +1562 -0
- package/dist/cli-VYWAONGX.js +354 -0
- package/dist/index.js +5 -1275
- package/dist/mcp/server.js +669 -123
- package/dist/server-7C2IQ7VV.js +202 -0
- package/package.json +11 -3
package/README.md
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
# ctxlint
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@yawlabs/ctxlint)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://github.com/YawLabs/ctxlint/stargazers)
|
|
6
|
+
[](https://github.com/YawLabs/ctxlint/actions/workflows/ci.yml)
|
|
7
|
+
|
|
8
|
+
**Lint your AI agent context files against your actual codebase.** 7 checks, 21+ formats, auto-fix. Works as a CLI, CI step, pre-commit hook, or MCP server.
|
|
4
9
|
|
|
5
10
|
Your `CLAUDE.md` is lying to your agent. ctxlint catches it.
|
|
6
11
|
|
|
12
|
+
## Why ctxlint?
|
|
13
|
+
|
|
14
|
+
Context files rot fast. You rename a file, change a build script, or switch from Jest to Vitest — and your `CLAUDE.md` still says the old thing. Your agent follows those instructions faithfully, then fails.
|
|
15
|
+
|
|
16
|
+
- **Catches real problems** — broken paths, wrong commands, stale references, contradictions across files
|
|
17
|
+
- **Smart suggestions** — detects git renames and fuzzy-matches to suggest the right path
|
|
18
|
+
- **Auto-fix** — `--fix` rewrites broken paths automatically using git history
|
|
19
|
+
- **Token-aware** — shows how much context window your files consume and flags redundant content
|
|
20
|
+
- **Every AI tool** — supports Claude Code, Cursor, Copilot, Windsurf, Gemini, Cline, Aider, and 14 more
|
|
21
|
+
- **Multiple outputs** — text, JSON, and SARIF (GitHub Code Scanning)
|
|
22
|
+
- **MCP server** — 4 tools for IDE/agent integration with tool annotations for auto-approval
|
|
23
|
+
|
|
7
24
|
## Install
|
|
8
25
|
|
|
9
26
|
```bash
|
|
@@ -21,34 +38,38 @@ npx @yawlabs/ctxlint
|
|
|
21
38
|
| Check | What it finds |
|
|
22
39
|
|-------|--------------|
|
|
23
40
|
| **Broken paths** | File references in context that don't exist in your project |
|
|
24
|
-
| **Wrong commands** | Build/test commands that don't match your package.json scripts |
|
|
41
|
+
| **Wrong commands** | Build/test commands that don't match your package.json scripts or Makefile targets |
|
|
25
42
|
| **Stale context** | Context files not updated after recent code changes |
|
|
26
43
|
| **Token waste** | How much context window your files consume per session |
|
|
27
44
|
| **Redundancy** | Content the agent can already infer (e.g. "We use React" when react is in package.json) |
|
|
45
|
+
| **Contradictions** | Conflicting directives across context files (e.g. "use Jest" in one, "use Vitest" in another) |
|
|
46
|
+
| **Frontmatter** | Invalid or missing YAML frontmatter in Cursor .mdc, Copilot instructions, and Windsurf rules |
|
|
28
47
|
|
|
29
48
|
## Supported Context Files
|
|
30
49
|
|
|
31
50
|
| File | Tool |
|
|
32
51
|
|------|------|
|
|
33
|
-
| `CLAUDE.md`, `CLAUDE.local.md` | Claude Code |
|
|
34
|
-
| `AGENTS.md` | Multi-agent |
|
|
35
|
-
| `.cursorrules`, `.cursor/rules/*.md`, `.cursor/rules/*.mdc` | Cursor |
|
|
36
|
-
|
|
|
52
|
+
| `CLAUDE.md`, `CLAUDE.local.md`, `.claude/rules/*.md` | Claude Code |
|
|
53
|
+
| `AGENTS.md`, `AGENT.md`, `AGENTS.override.md` | AAIF / Multi-agent standard |
|
|
54
|
+
| `.cursorrules`, `.cursor/rules/*.md`, `.cursor/rules/*.mdc`, `.cursor/rules/*/RULE.md` | Cursor |
|
|
55
|
+
| `.github/copilot-instructions.md`, `.github/instructions/*.md`, `.github/git-commit-instructions.md` | GitHub Copilot |
|
|
37
56
|
| `.windsurfrules`, `.windsurf/rules/*.md` | Windsurf |
|
|
38
|
-
| `GEMINI.md` | Gemini |
|
|
39
|
-
| `JULES.md` | Jules |
|
|
57
|
+
| `GEMINI.md` | Gemini CLI |
|
|
40
58
|
| `.clinerules` | Cline |
|
|
41
|
-
| `CODEX.md` | OpenAI Codex CLI |
|
|
42
59
|
| `.aiderules` | Aider |
|
|
43
60
|
| `.aide/rules/*.md` | Aide / Codestory |
|
|
44
61
|
| `.amazonq/rules/*.md` | Amazon Q Developer |
|
|
45
|
-
| `.goose/instructions.md` | Goose by Block |
|
|
46
|
-
|
|
|
62
|
+
| `.goose/instructions.md`, `.goosehints` | Goose by Block |
|
|
63
|
+
| `.junie/guidelines.md`, `.junie/AGENTS.md` | JetBrains Junie |
|
|
64
|
+
| `.aiassistant/rules/*.md` | JetBrains AI Assistant |
|
|
65
|
+
| `.continuerules`, `.continue/rules/*.md` | Continue |
|
|
66
|
+
| `.rules` | Zed |
|
|
67
|
+
| `replit.md` | Replit |
|
|
47
68
|
|
|
48
69
|
## Example Output
|
|
49
70
|
|
|
50
71
|
```
|
|
51
|
-
ctxlint v0.
|
|
72
|
+
ctxlint v0.3.0
|
|
52
73
|
|
|
53
74
|
Scanning /Users/you/my-app...
|
|
54
75
|
|
|
@@ -61,9 +82,10 @@ CLAUDE.md
|
|
|
61
82
|
→ Did you mean src/middleware/auth.ts? (renamed 14 days ago)
|
|
62
83
|
✗ Line 8: "pnpm test" — script "test" not found in package.json
|
|
63
84
|
⚠ Last updated 47 days ago. src/routes/ has 8 commits since.
|
|
85
|
+
⚠ testing framework conflict: "Vitest" in CLAUDE.md vs "Jest" in AGENTS.md
|
|
64
86
|
ℹ Line 3: "Express" is in package.json dependencies — agent can infer this
|
|
65
87
|
|
|
66
|
-
Summary: 2 errors,
|
|
88
|
+
Summary: 2 errors, 2 warnings, 1 info
|
|
67
89
|
Token usage: 1,203 tokens per agent session
|
|
68
90
|
Estimated waste: ~55 tokens (redundant content)
|
|
69
91
|
```
|
|
@@ -78,12 +100,16 @@ Arguments:
|
|
|
78
100
|
|
|
79
101
|
Options:
|
|
80
102
|
--strict Exit code 1 on any warning or error (for CI)
|
|
81
|
-
--checks <list> Comma-separated: paths, commands, staleness, tokens, redundancy
|
|
103
|
+
--checks <list> Comma-separated: paths, commands, staleness, tokens, redundancy, contradictions, frontmatter
|
|
82
104
|
--ignore <list> Comma-separated checks to skip
|
|
83
105
|
--fix Auto-fix broken paths using git history and fuzzy matching
|
|
84
|
-
--format
|
|
106
|
+
--format <fmt> Output format: text, json, or sarif (default: text)
|
|
85
107
|
--tokens Show token breakdown per file
|
|
86
108
|
--verbose Show passing checks too
|
|
109
|
+
--quiet Suppress all output (exit code only, for scripts)
|
|
110
|
+
--config <path> Path to config file (default: .ctxlintrc in project root)
|
|
111
|
+
--depth <n> Max subdirectory depth to scan (default: 2)
|
|
112
|
+
--mcp Start the MCP server instead of running the linter
|
|
87
113
|
-V, --version Output the version number
|
|
88
114
|
-h, --help Display help
|
|
89
115
|
|
|
@@ -100,6 +126,18 @@ Commands:
|
|
|
100
126
|
|
|
101
127
|
Exits with code 1 if any errors or warnings are found.
|
|
102
128
|
|
|
129
|
+
### SARIF Output (GitHub Code Scanning)
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
- name: Lint context files
|
|
133
|
+
run: npx @yawlabs/ctxlint --format sarif > ctxlint.sarif
|
|
134
|
+
|
|
135
|
+
- name: Upload SARIF
|
|
136
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
137
|
+
with:
|
|
138
|
+
sarif_file: ctxlint.sarif
|
|
139
|
+
```
|
|
140
|
+
|
|
103
141
|
## Auto-fix
|
|
104
142
|
|
|
105
143
|
```bash
|
|
@@ -110,19 +148,33 @@ When a broken path was renamed in git or has a close match in the project, `--fi
|
|
|
110
148
|
|
|
111
149
|
## Pre-commit Hook
|
|
112
150
|
|
|
151
|
+
### Built-in
|
|
152
|
+
|
|
113
153
|
```bash
|
|
114
154
|
npx @yawlabs/ctxlint init
|
|
115
155
|
```
|
|
116
156
|
|
|
117
157
|
Sets up a git pre-commit hook that runs `ctxlint --strict` before each commit.
|
|
118
158
|
|
|
159
|
+
### pre-commit framework
|
|
160
|
+
|
|
161
|
+
Add to your `.pre-commit-config.yaml`:
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
repos:
|
|
165
|
+
- repo: https://github.com/yawlabs/ctxlint
|
|
166
|
+
rev: v0.3.0
|
|
167
|
+
hooks:
|
|
168
|
+
- id: ctxlint
|
|
169
|
+
```
|
|
170
|
+
|
|
119
171
|
## Config File
|
|
120
172
|
|
|
121
173
|
Create a `.ctxlintrc` or `.ctxlintrc.json` in your project root:
|
|
122
174
|
|
|
123
175
|
```json
|
|
124
176
|
{
|
|
125
|
-
"checks": ["paths", "commands", "tokens"],
|
|
177
|
+
"checks": ["paths", "commands", "tokens", "contradictions", "frontmatter"],
|
|
126
178
|
"ignore": ["redundancy"],
|
|
127
179
|
"strict": true,
|
|
128
180
|
"tokenThresholds": {
|
|
@@ -130,22 +182,55 @@ Create a `.ctxlintrc` or `.ctxlintrc.json` in your project root:
|
|
|
130
182
|
"warning": 2000,
|
|
131
183
|
"error": 5000,
|
|
132
184
|
"aggregate": 4000
|
|
133
|
-
}
|
|
185
|
+
},
|
|
186
|
+
"contextFiles": ["CONVENTIONS.md", "docs/ai-rules.md"]
|
|
134
187
|
}
|
|
135
188
|
```
|
|
136
189
|
|
|
137
|
-
|
|
190
|
+
The `contextFiles` array adds custom file patterns to scan alongside the built-in list. Useful for project-specific context files like `CONVENTIONS.md`.
|
|
191
|
+
|
|
192
|
+
CLI flags override config file settings. Use `--config <path>` to load a config from a custom location.
|
|
138
193
|
|
|
139
194
|
## Use as MCP Server
|
|
140
195
|
|
|
141
|
-
ctxlint ships with an MCP server that exposes four tools (`ctxlint_audit`, `ctxlint_validate_path`, `ctxlint_token_report`, `ctxlint_fix`)
|
|
196
|
+
ctxlint ships with an MCP server that exposes four tools (`ctxlint_audit`, `ctxlint_validate_path`, `ctxlint_token_report`, `ctxlint_fix`). All tools declare annotations so MCP clients can skip confirmation dialogs for read-only operations.
|
|
142
197
|
|
|
143
|
-
|
|
144
|
-
# Claude Code
|
|
145
|
-
claude mcp add ctxlint -- node node_modules/@yawlabs/ctxlint/dist/mcp/server.js
|
|
198
|
+
### With `.mcp.json` (Cursor, Windsurf, and other MCP clients)
|
|
146
199
|
|
|
147
|
-
|
|
148
|
-
|
|
200
|
+
Create `.mcp.json` in your project root:
|
|
201
|
+
|
|
202
|
+
macOS / Linux / WSL:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"mcpServers": {
|
|
207
|
+
"ctxlint": {
|
|
208
|
+
"command": "npx",
|
|
209
|
+
"args": ["-y", "@yawlabs/ctxlint", "--mcp"]
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Windows:
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"mcpServers": {
|
|
220
|
+
"ctxlint": {
|
|
221
|
+
"command": "cmd",
|
|
222
|
+
"args": ["/c", "npx", "-y", "@yawlabs/ctxlint", "--mcp"]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
> **Tip:** This file is safe to commit — it contains no secrets.
|
|
229
|
+
|
|
230
|
+
### With Claude Code
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
claude mcp add ctxlint -- npx -y @yawlabs/ctxlint --mcp
|
|
149
234
|
```
|
|
150
235
|
|
|
151
236
|
## JSON Output
|