@yawlabs/ctxlint 0.9.2 → 0.9.4
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 +31 -2
- package/agent-session-lint-rules.json +16 -8
- package/context-lint-rules.json +165 -48
- package/dist/index.js +1547 -1294
- package/mcp-config-lint-rules.json +189 -44
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -205,10 +205,11 @@ Session checks are **opt-in** because they access files outside the project dire
|
|
|
205
205
|
| **Stale memory** | Memory entries referencing file paths that no longer exist |
|
|
206
206
|
| **Duplicate memory** | Near-duplicate memory entries across projects (>60% overlap) |
|
|
207
207
|
| **Loop detection** | Agent stuck in a loop — 3+ consecutive identical commands, or cyclic A,B,A,B patterns |
|
|
208
|
+
| **Memory index overflow** | `MEMORY.md` exceeds Claude Code's documented 200-line / 25KB session-load cap, so entries past the cap are invisible to the agent |
|
|
208
209
|
|
|
209
210
|
### Session Linting Specification
|
|
210
211
|
|
|
211
|
-
- **[`AGENT_SESSION_LINT_SPEC.md`](./AGENT_SESSION_LINT_SPEC.md)** —
|
|
212
|
+
- **[`AGENT_SESSION_LINT_SPEC.md`](./AGENT_SESSION_LINT_SPEC.md)** — 8 lint rules, the agent session data landscape across 8 agents, sibling detection strategy, and implementation guidance.
|
|
212
213
|
- **[`agent-session-lint-rules.json`](./agent-session-lint-rules.json)** — Machine-readable rule catalog.
|
|
213
214
|
|
|
214
215
|
## Example Output
|
|
@@ -287,7 +288,15 @@ Re-lints automatically when any context file, MCP config, or `package.json` chan
|
|
|
287
288
|
run: npx @yawlabs/ctxlint --strict
|
|
288
289
|
```
|
|
289
290
|
|
|
290
|
-
|
|
291
|
+
### Exit Codes
|
|
292
|
+
|
|
293
|
+
| Code | Meaning |
|
|
294
|
+
|---|---|
|
|
295
|
+
| `0` | Success — no issues, or issues below the strict threshold |
|
|
296
|
+
| `1` | Strict mode caught at least one error or warning (`--strict` is set) |
|
|
297
|
+
| `2` | Config error, invalid CLI option, or internal failure |
|
|
298
|
+
|
|
299
|
+
In non-strict mode ctxlint always exits `0` — it's a reporting tool by default. Pass `--strict` to enforce in CI.
|
|
291
300
|
|
|
292
301
|
### GitHub Action
|
|
293
302
|
|
|
@@ -370,6 +379,26 @@ Create a `.ctxlintrc` or `.ctxlintrc.json` in your project root:
|
|
|
370
379
|
|
|
371
380
|
The `contextFiles` array adds custom file patterns to scan alongside the built-in list. Useful for project-specific context files like `CONVENTIONS.md`.
|
|
372
381
|
|
|
382
|
+
### Config Reference
|
|
383
|
+
|
|
384
|
+
| Field | Type | Default | Meaning |
|
|
385
|
+
|---|---|---|---|
|
|
386
|
+
| `checks` | `string[]` | all checks | Checks to run. Check names include `paths`, `commands`, `tokens`, `tier-tokens`, `redundancy`, `contradictions`, `frontmatter`, `staleness`, `ci-coverage`, `ci-secrets`, plus any `mcp-*` / `session-*`. |
|
|
387
|
+
| `ignore` | `string[]` | `[]` | Checks to skip, evaluated after `checks`. |
|
|
388
|
+
| `strict` | `boolean` | `false` | Exit non-zero on any warning or error. |
|
|
389
|
+
| `tokenThresholds` | `object` | see below | Per-file and cross-file token thresholds. |
|
|
390
|
+
| `tokenThresholds.info` | `number` | `1000` | Per-file info threshold for `tokens/info`. |
|
|
391
|
+
| `tokenThresholds.warning` | `number` | `3000` | Per-file warning threshold for `tokens/large`. |
|
|
392
|
+
| `tokenThresholds.error` | `number` | `8000` | Per-file error threshold for `tokens/excessive`. |
|
|
393
|
+
| `tokenThresholds.aggregate` | `number` | `5000` | Cross-file total threshold for `tokens/aggregate`. |
|
|
394
|
+
| `tokenThresholds.tierBreakdown` | `number` | `1000` | Always-loaded file threshold for `tier-tokens/section-breakdown`. |
|
|
395
|
+
| `tokenThresholds.tierAggregate` | `number` | `4000` | Combined always-loaded threshold for `tier-tokens/aggregate`. |
|
|
396
|
+
| `contextFiles` | `string[]` | `[]` | Extra glob patterns to scan alongside the built-in list. |
|
|
397
|
+
| `mcp` | `boolean` | `false` | Enable MCP config checks by default (same as `--mcp`). |
|
|
398
|
+
| `mcpGlobal` | `boolean` | `false` | Also scan user/global MCP configs (same as `--mcp-global`). |
|
|
399
|
+
|
|
400
|
+
Config file resolution order: `.ctxlintrc` → `.ctxlintrc.json` in the project root. Use `--config <path>` to point elsewhere. CLI flags override config fields.
|
|
401
|
+
|
|
373
402
|
CLI flags override config file settings. Use `--config <path>` to load a config from a custom location.
|
|
374
403
|
|
|
375
404
|
## Use as MCP Server
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"description": "GitHub secret set on sibling repos but not this project.",
|
|
22
22
|
"trigger": "gh secret set command found in agent history for 2+ siblings but not current project.",
|
|
23
23
|
"message": "Secret \"{name}\" is set on {count} sibling repos but not this project",
|
|
24
|
-
"fixable": false
|
|
24
|
+
"fixable": false,
|
|
25
|
+
"stability": "stable"
|
|
25
26
|
},
|
|
26
27
|
{
|
|
27
28
|
"id": "session/diverged-file",
|
|
@@ -40,7 +41,8 @@
|
|
|
40
41
|
".eslintrc.json",
|
|
41
42
|
"tsconfig.json",
|
|
42
43
|
".gitignore"
|
|
43
|
-
]
|
|
44
|
+
],
|
|
45
|
+
"stability": "stable"
|
|
44
46
|
},
|
|
45
47
|
{
|
|
46
48
|
"id": "session/missing-workflow",
|
|
@@ -49,7 +51,8 @@
|
|
|
49
51
|
"description": "GitHub Actions workflow missing from this project.",
|
|
50
52
|
"trigger": "Workflow file exists in 2+ siblings but not current project (which has .github).",
|
|
51
53
|
"message": "Workflow \"{workflow}\" exists in {count} sibling repos but not this project",
|
|
52
|
-
"fixable": false
|
|
54
|
+
"fixable": false,
|
|
55
|
+
"stability": "stable"
|
|
53
56
|
},
|
|
54
57
|
{
|
|
55
58
|
"id": "session/stale-memory",
|
|
@@ -58,7 +61,8 @@
|
|
|
58
61
|
"description": "Memory file references paths that no longer exist.",
|
|
59
62
|
"trigger": "Claude Code memory file contains path references to files that have been deleted or moved.",
|
|
60
63
|
"message": "Memory references \"{path}\" which no longer exists",
|
|
61
|
-
"fixable": false
|
|
64
|
+
"fixable": false,
|
|
65
|
+
"stability": "stable"
|
|
62
66
|
},
|
|
63
67
|
{
|
|
64
68
|
"id": "session/duplicate-memory",
|
|
@@ -67,7 +71,8 @@
|
|
|
67
71
|
"description": "Near-duplicate memory entries across projects.",
|
|
68
72
|
"trigger": "Two memory files from different projects have >60% line overlap.",
|
|
69
73
|
"message": "\"{file1}\" and \"{file2}\" have {overlap}% content overlap",
|
|
70
|
-
"fixable": false
|
|
74
|
+
"fixable": false,
|
|
75
|
+
"stability": "stable"
|
|
71
76
|
},
|
|
72
77
|
{
|
|
73
78
|
"id": "session/consecutive-repeat",
|
|
@@ -76,7 +81,8 @@
|
|
|
76
81
|
"description": "Same command run 3+ times consecutively in agent history.",
|
|
77
82
|
"trigger": "Agent history for the current project shows the same display string 3+ times in a row.",
|
|
78
83
|
"message": "Command run {count} times consecutively: \"{command}\"",
|
|
79
|
-
"fixable": false
|
|
84
|
+
"fixable": false,
|
|
85
|
+
"stability": "experimental"
|
|
80
86
|
},
|
|
81
87
|
{
|
|
82
88
|
"id": "session/cyclic-pattern",
|
|
@@ -85,7 +91,8 @@
|
|
|
85
91
|
"description": "Cyclic command pattern detected in agent history.",
|
|
86
92
|
"trigger": "Agent history shows a repeating sequence of 2-3 commands (e.g. A,B,A,B) repeated 2+ times.",
|
|
87
93
|
"message": "Cyclic pattern repeated {count} times: {cycle}",
|
|
88
|
-
"fixable": false
|
|
94
|
+
"fixable": false,
|
|
95
|
+
"stability": "experimental"
|
|
89
96
|
},
|
|
90
97
|
{
|
|
91
98
|
"id": "session/memory-index-overflow",
|
|
@@ -95,7 +102,8 @@
|
|
|
95
102
|
"trigger": "~/.claude/projects/<encoded-project>/memory/MEMORY.md exceeds 200 lines OR 25,600 bytes.",
|
|
96
103
|
"message": "MEMORY.md has {N} lines — only the first 200 are loaded. {excess} lines are effectively invisible.",
|
|
97
104
|
"fixable": false,
|
|
98
|
-
"source": "code.claude.com/docs/en/memory"
|
|
105
|
+
"source": "code.claude.com/docs/en/memory",
|
|
106
|
+
"stability": "stable"
|
|
99
107
|
}
|
|
100
108
|
],
|
|
101
109
|
"dataSources": [
|
package/context-lint-rules.json
CHANGED
|
@@ -75,7 +75,8 @@
|
|
|
75
75
|
"trigger": "Path reference in context file resolves to a non-existent file or directory.",
|
|
76
76
|
"message": "{path} does not exist",
|
|
77
77
|
"fixable": true,
|
|
78
|
-
"fixDescription": "Replace broken path with suggestion from git rename detection or fuzzy matching."
|
|
78
|
+
"fixDescription": "Replace broken path with suggestion from git rename detection or fuzzy matching.",
|
|
79
|
+
"stability": "stable"
|
|
79
80
|
},
|
|
80
81
|
{
|
|
81
82
|
"id": "paths/glob-no-match",
|
|
@@ -84,7 +85,8 @@
|
|
|
84
85
|
"description": "Glob pattern matches zero files in the project.",
|
|
85
86
|
"trigger": "Path contains wildcard characters (*, ?) but matches no files.",
|
|
86
87
|
"message": "{pattern} matches no files",
|
|
87
|
-
"fixable": false
|
|
88
|
+
"fixable": false,
|
|
89
|
+
"stability": "stable"
|
|
88
90
|
},
|
|
89
91
|
{
|
|
90
92
|
"id": "paths/directory-not-found",
|
|
@@ -93,7 +95,8 @@
|
|
|
93
95
|
"description": "Referenced directory does not exist.",
|
|
94
96
|
"trigger": "Path ending with / does not resolve to an existing directory.",
|
|
95
97
|
"message": "{path} directory does not exist",
|
|
96
|
-
"fixable": false
|
|
98
|
+
"fixable": false,
|
|
99
|
+
"stability": "stable"
|
|
97
100
|
},
|
|
98
101
|
{
|
|
99
102
|
"id": "commands/script-not-found",
|
|
@@ -102,7 +105,8 @@
|
|
|
102
105
|
"description": "Package manager script name is not found in package.json scripts.",
|
|
103
106
|
"trigger": "npm run, pnpm, yarn, or bun script reference does not match a key in package.json#scripts.",
|
|
104
107
|
"message": "\"{cmd}\" — script \"{name}\" not found in package.json",
|
|
105
|
-
"fixable": false
|
|
108
|
+
"fixable": false,
|
|
109
|
+
"stability": "stable"
|
|
106
110
|
},
|
|
107
111
|
{
|
|
108
112
|
"id": "commands/make-target-not-found",
|
|
@@ -111,7 +115,8 @@
|
|
|
111
115
|
"description": "Make target is not found in Makefile.",
|
|
112
116
|
"trigger": "make command references a target not declared in the project's Makefile.",
|
|
113
117
|
"message": "\"{cmd}\" — target \"{name}\" not found in Makefile",
|
|
114
|
-
"fixable": false
|
|
118
|
+
"fixable": false,
|
|
119
|
+
"stability": "stable"
|
|
115
120
|
},
|
|
116
121
|
{
|
|
117
122
|
"id": "commands/no-makefile",
|
|
@@ -120,7 +125,8 @@
|
|
|
120
125
|
"description": "Make command used but no Makefile exists in the project.",
|
|
121
126
|
"trigger": "Context file references a make command but no Makefile is found at the project root.",
|
|
122
127
|
"message": "\"{cmd}\" — no Makefile found in project",
|
|
123
|
-
"fixable": false
|
|
128
|
+
"fixable": false,
|
|
129
|
+
"stability": "stable"
|
|
124
130
|
},
|
|
125
131
|
{
|
|
126
132
|
"id": "commands/npx-not-in-deps",
|
|
@@ -129,7 +135,8 @@
|
|
|
129
135
|
"description": "npx package is not in project dependencies.",
|
|
130
136
|
"trigger": "npx package is not in package.json dependencies/devDependencies and not in node_modules/.bin.",
|
|
131
137
|
"message": "\"{cmd}\" — \"{pkg}\" not found in dependencies",
|
|
132
|
-
"fixable": false
|
|
138
|
+
"fixable": false,
|
|
139
|
+
"stability": "stable"
|
|
133
140
|
},
|
|
134
141
|
{
|
|
135
142
|
"id": "commands/tool-not-found",
|
|
@@ -138,7 +145,19 @@
|
|
|
138
145
|
"description": "Common development tool is not in project dependencies.",
|
|
139
146
|
"trigger": "Tool name (vitest, jest, eslint, prettier, tsc, etc.) not found in dependencies or node_modules/.bin.",
|
|
140
147
|
"message": "\"{cmd}\" — \"{tool}\" not found in dependencies or node_modules/.bin",
|
|
141
|
-
"fixable": false
|
|
148
|
+
"fixable": false,
|
|
149
|
+
"stability": "stable"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "commands/npm-auth-trap",
|
|
153
|
+
"category": "commands",
|
|
154
|
+
"severity": "info",
|
|
155
|
+
"description": "Context file documents an npm write operation (deprecate, unpublish, dist-tag, access, owner) as a local CLI command. Under WebAuthn-only 2FA (no TOTP authenticator), these commands return 422 because npm treats CLI web-auth tokens as not-2FA-authenticated for writes. The npm website settings UI is the only path that works; CI-driven workflows are the scalable alternative.",
|
|
156
|
+
"trigger": "Context file references `npm deprecate`, `npm unpublish`, `npm dist-tag add/rm/set`, `npm access grant/revoke/2fa`, or `npm owner add/rm` as a command.",
|
|
157
|
+
"message": "\"{cmd}\" — npm {op} requires a 2FA-authenticated session; CLI returns 422 under WebAuthn-only auth",
|
|
158
|
+
"fixable": false,
|
|
159
|
+
"stability": "experimental",
|
|
160
|
+
"source": "https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification"
|
|
142
161
|
},
|
|
143
162
|
{
|
|
144
163
|
"id": "staleness/stale",
|
|
@@ -147,7 +166,8 @@
|
|
|
147
166
|
"description": "Context file has not been updated in 30+ days while referenced code has changed.",
|
|
148
167
|
"trigger": "File last modified 30+ days ago AND paths it references have git commits since.",
|
|
149
168
|
"message": "Last updated {days} days ago. {path} has {N} commits since.",
|
|
150
|
-
"fixable": false
|
|
169
|
+
"fixable": false,
|
|
170
|
+
"stability": "stable"
|
|
151
171
|
},
|
|
152
172
|
{
|
|
153
173
|
"id": "staleness/aging",
|
|
@@ -156,7 +176,8 @@
|
|
|
156
176
|
"description": "Context file has not been updated in 14-30 days while referenced code has changed.",
|
|
157
177
|
"trigger": "File last modified 14-30 days ago AND paths it references have git commits since.",
|
|
158
178
|
"message": "Last updated {days} days ago. {path} has {N} commits since.",
|
|
159
|
-
"fixable": false
|
|
179
|
+
"fixable": false,
|
|
180
|
+
"stability": "stable"
|
|
160
181
|
},
|
|
161
182
|
{
|
|
162
183
|
"id": "tokens/excessive",
|
|
@@ -167,7 +188,8 @@
|
|
|
167
188
|
"message": "{N} tokens — consumes significant context window space",
|
|
168
189
|
"fixable": false,
|
|
169
190
|
"configurable": true,
|
|
170
|
-
"defaultThreshold": 8000
|
|
191
|
+
"defaultThreshold": 8000,
|
|
192
|
+
"stability": "stable"
|
|
171
193
|
},
|
|
172
194
|
{
|
|
173
195
|
"id": "tokens/large",
|
|
@@ -178,7 +200,8 @@
|
|
|
178
200
|
"message": "{N} tokens — large context file",
|
|
179
201
|
"fixable": false,
|
|
180
202
|
"configurable": true,
|
|
181
|
-
"defaultThreshold": 3000
|
|
203
|
+
"defaultThreshold": 3000,
|
|
204
|
+
"stability": "stable"
|
|
182
205
|
},
|
|
183
206
|
{
|
|
184
207
|
"id": "tokens/info",
|
|
@@ -189,7 +212,8 @@
|
|
|
189
212
|
"message": "Uses ~{N} tokens per session",
|
|
190
213
|
"fixable": false,
|
|
191
214
|
"configurable": true,
|
|
192
|
-
"defaultThreshold": 1000
|
|
215
|
+
"defaultThreshold": 1000,
|
|
216
|
+
"stability": "stable"
|
|
193
217
|
},
|
|
194
218
|
{
|
|
195
219
|
"id": "tokens/aggregate",
|
|
@@ -200,7 +224,8 @@
|
|
|
200
224
|
"message": "{count} context files consume {N} tokens combined",
|
|
201
225
|
"fixable": false,
|
|
202
226
|
"configurable": true,
|
|
203
|
-
"defaultThreshold": 5000
|
|
227
|
+
"defaultThreshold": 5000,
|
|
228
|
+
"stability": "stable"
|
|
204
229
|
},
|
|
205
230
|
{
|
|
206
231
|
"id": "tier-tokens/section-breakdown",
|
|
@@ -212,7 +237,8 @@
|
|
|
212
237
|
"fixable": false,
|
|
213
238
|
"configurable": true,
|
|
214
239
|
"configKey": "tokenThresholds.tierBreakdown",
|
|
215
|
-
"defaultThreshold": 1000
|
|
240
|
+
"defaultThreshold": 1000,
|
|
241
|
+
"stability": "stable"
|
|
216
242
|
},
|
|
217
243
|
{
|
|
218
244
|
"id": "tier-tokens/aggregate",
|
|
@@ -224,7 +250,8 @@
|
|
|
224
250
|
"fixable": false,
|
|
225
251
|
"configurable": true,
|
|
226
252
|
"configKey": "tokenThresholds.tierAggregate",
|
|
227
|
-
"defaultThreshold": 4000
|
|
253
|
+
"defaultThreshold": 4000,
|
|
254
|
+
"stability": "stable"
|
|
228
255
|
},
|
|
229
256
|
{
|
|
230
257
|
"id": "tier-tokens/hard-enforcement-missing",
|
|
@@ -234,7 +261,8 @@
|
|
|
234
261
|
"trigger": "Line in an always-loaded file matches NEVER|ALWAYS|DO NOT|MUST NOT with a backticked command, and .claude/settings.json / ~/.claude/settings.json does not contain a matching PreToolUse hook or permissions.deny entry.",
|
|
235
262
|
"message": "Inviolable framing without a hook to back it up",
|
|
236
263
|
"fixable": false,
|
|
237
|
-
"source": "code.claude.com/docs/en/hooks-guide"
|
|
264
|
+
"source": "code.claude.com/docs/en/hooks-guide",
|
|
265
|
+
"stability": "experimental"
|
|
238
266
|
},
|
|
239
267
|
{
|
|
240
268
|
"id": "redundancy/tech-mention",
|
|
@@ -243,7 +271,8 @@
|
|
|
243
271
|
"description": "Context file mentions a technology that is already in package.json dependencies.",
|
|
244
272
|
"trigger": "File contains phrases like 'use React' or 'built with Express' and that package is in dependencies.",
|
|
245
273
|
"message": "\"{tech}\" is in package.json {depType} — agent can infer this",
|
|
246
|
-
"fixable": false
|
|
274
|
+
"fixable": false,
|
|
275
|
+
"stability": "stable"
|
|
247
276
|
},
|
|
248
277
|
{
|
|
249
278
|
"id": "redundancy/discoverable-dir",
|
|
@@ -252,7 +281,8 @@
|
|
|
252
281
|
"description": "Context file describes the location of a directory that the agent can discover by listing files.",
|
|
253
282
|
"trigger": "File says files 'are in' or 'go in' a directory that exists in the project.",
|
|
254
283
|
"message": "Directory \"{dir}\" exists and is discoverable — agent can find this by listing files",
|
|
255
|
-
"fixable": false
|
|
284
|
+
"fixable": false,
|
|
285
|
+
"stability": "stable"
|
|
256
286
|
},
|
|
257
287
|
{
|
|
258
288
|
"id": "redundancy/duplicate-content",
|
|
@@ -261,7 +291,8 @@
|
|
|
261
291
|
"description": "Two context files have significant content overlap.",
|
|
262
292
|
"trigger": "Two files share 60%+ of their lines (by trimmed content, lines >10 chars).",
|
|
263
293
|
"message": "{file1} and {file2} have {N}% content overlap",
|
|
264
|
-
"fixable": false
|
|
294
|
+
"fixable": false,
|
|
295
|
+
"stability": "stable"
|
|
265
296
|
},
|
|
266
297
|
{
|
|
267
298
|
"id": "contradictions/conflict",
|
|
@@ -280,7 +311,8 @@
|
|
|
280
311
|
"naming convention",
|
|
281
312
|
"CSS approach",
|
|
282
313
|
"state management"
|
|
283
|
-
]
|
|
314
|
+
],
|
|
315
|
+
"stability": "stable"
|
|
284
316
|
},
|
|
285
317
|
{
|
|
286
318
|
"id": "frontmatter/missing",
|
|
@@ -290,7 +322,12 @@
|
|
|
290
322
|
"trigger": "Cursor .mdc, Copilot instruction, or Windsurf rule file has no --- frontmatter block.",
|
|
291
323
|
"message": "{format} file is missing frontmatter",
|
|
292
324
|
"fixable": false,
|
|
293
|
-
"appliesTo": [
|
|
325
|
+
"appliesTo": [
|
|
326
|
+
"cursor-mdc",
|
|
327
|
+
"copilot-instructions",
|
|
328
|
+
"windsurf-rules"
|
|
329
|
+
],
|
|
330
|
+
"stability": "stable"
|
|
294
331
|
},
|
|
295
332
|
{
|
|
296
333
|
"id": "frontmatter/missing-field",
|
|
@@ -300,7 +337,12 @@
|
|
|
300
337
|
"trigger": "Frontmatter exists but is missing a key field (description for Cursor, applyTo for Copilot, trigger for Windsurf).",
|
|
301
338
|
"message": "Missing \"{field}\" field in {format} frontmatter",
|
|
302
339
|
"fixable": false,
|
|
303
|
-
"appliesTo": [
|
|
340
|
+
"appliesTo": [
|
|
341
|
+
"cursor-mdc",
|
|
342
|
+
"copilot-instructions",
|
|
343
|
+
"windsurf-rules"
|
|
344
|
+
],
|
|
345
|
+
"stability": "stable"
|
|
304
346
|
},
|
|
305
347
|
{
|
|
306
348
|
"id": "frontmatter/invalid-value",
|
|
@@ -310,7 +352,11 @@
|
|
|
310
352
|
"trigger": "alwaysApply is not true/false, trigger is not a valid enum value, globs doesn't look like a pattern.",
|
|
311
353
|
"message": "Invalid {field} value: \"{value}\"",
|
|
312
354
|
"fixable": false,
|
|
313
|
-
"appliesTo": [
|
|
355
|
+
"appliesTo": [
|
|
356
|
+
"cursor-mdc",
|
|
357
|
+
"windsurf-rules"
|
|
358
|
+
],
|
|
359
|
+
"stability": "stable"
|
|
314
360
|
},
|
|
315
361
|
{
|
|
316
362
|
"id": "frontmatter/no-activation",
|
|
@@ -320,7 +366,10 @@
|
|
|
320
366
|
"trigger": "Cursor .mdc has frontmatter with neither globs nor alwaysApply set.",
|
|
321
367
|
"message": "No activation field — rule may not be applied automatically",
|
|
322
368
|
"fixable": false,
|
|
323
|
-
"appliesTo": [
|
|
369
|
+
"appliesTo": [
|
|
370
|
+
"cursor-mdc"
|
|
371
|
+
],
|
|
372
|
+
"stability": "stable"
|
|
324
373
|
},
|
|
325
374
|
{
|
|
326
375
|
"id": "ci/no-release-docs",
|
|
@@ -329,7 +378,8 @@
|
|
|
329
378
|
"description": "Release/deploy CI workflow exists but no context file documents the process.",
|
|
330
379
|
"trigger": ".github/workflows/ contains release/deploy/publish workflow but no context file mentions the release process.",
|
|
331
380
|
"message": "Release workflow found but no context file documents the release process",
|
|
332
|
-
"fixable": false
|
|
381
|
+
"fixable": false,
|
|
382
|
+
"stability": "stable"
|
|
333
383
|
},
|
|
334
384
|
{
|
|
335
385
|
"id": "ci/undocumented-secret",
|
|
@@ -338,14 +388,19 @@
|
|
|
338
388
|
"description": "CI workflow references a secret not mentioned in any context file.",
|
|
339
389
|
"trigger": "${{ secrets.NAME }} found in workflow YAML but NAME not mentioned in any context file. GitHub-provided secrets (GITHUB_TOKEN, etc.) are excluded.",
|
|
340
390
|
"message": "CI secret \"{name}\" is used in {workflow} but not mentioned in any context file",
|
|
341
|
-
"fixable": false
|
|
391
|
+
"fixable": false,
|
|
392
|
+
"stability": "stable"
|
|
342
393
|
}
|
|
343
394
|
],
|
|
344
395
|
"formats": [
|
|
345
396
|
{
|
|
346
397
|
"id": "claude-code",
|
|
347
398
|
"client": "Claude Code",
|
|
348
|
-
"patterns": [
|
|
399
|
+
"patterns": [
|
|
400
|
+
"CLAUDE.md",
|
|
401
|
+
"CLAUDE.local.md",
|
|
402
|
+
".claude/rules/*.md"
|
|
403
|
+
],
|
|
349
404
|
"type": "markdown",
|
|
350
405
|
"frontmatter": "none",
|
|
351
406
|
"scope": "project-wide and rule-based"
|
|
@@ -353,7 +408,11 @@
|
|
|
353
408
|
{
|
|
354
409
|
"id": "aaif",
|
|
355
410
|
"client": "AAIF / Multi-agent standard",
|
|
356
|
-
"patterns": [
|
|
411
|
+
"patterns": [
|
|
412
|
+
"AGENTS.md",
|
|
413
|
+
"AGENT.md",
|
|
414
|
+
"AGENTS.override.md"
|
|
415
|
+
],
|
|
357
416
|
"type": "markdown",
|
|
358
417
|
"frontmatter": "none",
|
|
359
418
|
"scope": "project-wide"
|
|
@@ -361,42 +420,77 @@
|
|
|
361
420
|
{
|
|
362
421
|
"id": "cursor",
|
|
363
422
|
"client": "Cursor",
|
|
364
|
-
"patterns": [
|
|
423
|
+
"patterns": [
|
|
424
|
+
".cursorrules",
|
|
425
|
+
".cursor/rules/*.md",
|
|
426
|
+
".cursor/rules/*.mdc",
|
|
427
|
+
".cursor/rules/*/RULE.md"
|
|
428
|
+
],
|
|
365
429
|
"type": "markdown",
|
|
366
430
|
"frontmatter": "required for .mdc",
|
|
367
431
|
"frontmatterFields": {
|
|
368
|
-
"description": {
|
|
369
|
-
|
|
370
|
-
|
|
432
|
+
"description": {
|
|
433
|
+
"required": true,
|
|
434
|
+
"type": "string"
|
|
435
|
+
},
|
|
436
|
+
"globs": {
|
|
437
|
+
"required": false,
|
|
438
|
+
"type": "string or string[]"
|
|
439
|
+
},
|
|
440
|
+
"alwaysApply": {
|
|
441
|
+
"required": false,
|
|
442
|
+
"type": "boolean"
|
|
443
|
+
}
|
|
371
444
|
},
|
|
372
445
|
"scope": "project-wide and rule-based"
|
|
373
446
|
},
|
|
374
447
|
{
|
|
375
448
|
"id": "copilot",
|
|
376
449
|
"client": "GitHub Copilot",
|
|
377
|
-
"patterns": [
|
|
450
|
+
"patterns": [
|
|
451
|
+
".github/copilot-instructions.md",
|
|
452
|
+
".github/instructions/*.md",
|
|
453
|
+
".github/git-commit-instructions.md"
|
|
454
|
+
],
|
|
378
455
|
"type": "markdown",
|
|
379
456
|
"frontmatter": "optional",
|
|
380
457
|
"frontmatterFields": {
|
|
381
|
-
"applyTo": {
|
|
458
|
+
"applyTo": {
|
|
459
|
+
"required": false,
|
|
460
|
+
"type": "string (glob)"
|
|
461
|
+
}
|
|
382
462
|
},
|
|
383
463
|
"scope": "project-wide and scoped"
|
|
384
464
|
},
|
|
385
465
|
{
|
|
386
466
|
"id": "windsurf",
|
|
387
467
|
"client": "Windsurf",
|
|
388
|
-
"patterns": [
|
|
468
|
+
"patterns": [
|
|
469
|
+
".windsurfrules",
|
|
470
|
+
".windsurf/rules/*.md"
|
|
471
|
+
],
|
|
389
472
|
"type": "markdown",
|
|
390
473
|
"frontmatter": "recommended for rules",
|
|
391
474
|
"frontmatterFields": {
|
|
392
|
-
"trigger": {
|
|
475
|
+
"trigger": {
|
|
476
|
+
"required": true,
|
|
477
|
+
"type": "enum",
|
|
478
|
+
"values": [
|
|
479
|
+
"always_on",
|
|
480
|
+
"glob",
|
|
481
|
+
"manual",
|
|
482
|
+
"model"
|
|
483
|
+
]
|
|
484
|
+
}
|
|
393
485
|
},
|
|
394
486
|
"scope": "project-wide and rule-based"
|
|
395
487
|
},
|
|
396
488
|
{
|
|
397
489
|
"id": "gemini",
|
|
398
490
|
"client": "Gemini CLI",
|
|
399
|
-
"patterns": [
|
|
491
|
+
"patterns": [
|
|
492
|
+
"GEMINI.md"
|
|
493
|
+
],
|
|
400
494
|
"type": "markdown",
|
|
401
495
|
"frontmatter": "none",
|
|
402
496
|
"scope": "project-wide"
|
|
@@ -404,7 +498,9 @@
|
|
|
404
498
|
{
|
|
405
499
|
"id": "cline",
|
|
406
500
|
"client": "Cline",
|
|
407
|
-
"patterns": [
|
|
501
|
+
"patterns": [
|
|
502
|
+
".clinerules"
|
|
503
|
+
],
|
|
408
504
|
"type": "plain text",
|
|
409
505
|
"frontmatter": "none",
|
|
410
506
|
"scope": "project-wide"
|
|
@@ -412,7 +508,9 @@
|
|
|
412
508
|
{
|
|
413
509
|
"id": "aider",
|
|
414
510
|
"client": "Aider",
|
|
415
|
-
"patterns": [
|
|
511
|
+
"patterns": [
|
|
512
|
+
".aiderules"
|
|
513
|
+
],
|
|
416
514
|
"type": "plain text",
|
|
417
515
|
"frontmatter": "none",
|
|
418
516
|
"scope": "project-wide"
|
|
@@ -420,7 +518,9 @@
|
|
|
420
518
|
{
|
|
421
519
|
"id": "aide",
|
|
422
520
|
"client": "Aide / Codestory",
|
|
423
|
-
"patterns": [
|
|
521
|
+
"patterns": [
|
|
522
|
+
".aide/rules/*.md"
|
|
523
|
+
],
|
|
424
524
|
"type": "markdown",
|
|
425
525
|
"frontmatter": "none",
|
|
426
526
|
"scope": "rule-based"
|
|
@@ -428,7 +528,9 @@
|
|
|
428
528
|
{
|
|
429
529
|
"id": "amazonq",
|
|
430
530
|
"client": "Amazon Q Developer",
|
|
431
|
-
"patterns": [
|
|
531
|
+
"patterns": [
|
|
532
|
+
".amazonq/rules/*.md"
|
|
533
|
+
],
|
|
432
534
|
"type": "markdown",
|
|
433
535
|
"frontmatter": "none",
|
|
434
536
|
"scope": "rule-based"
|
|
@@ -436,7 +538,10 @@
|
|
|
436
538
|
{
|
|
437
539
|
"id": "goose",
|
|
438
540
|
"client": "Goose (Block)",
|
|
439
|
-
"patterns": [
|
|
541
|
+
"patterns": [
|
|
542
|
+
".goose/instructions.md",
|
|
543
|
+
".goosehints"
|
|
544
|
+
],
|
|
440
545
|
"type": "markdown",
|
|
441
546
|
"frontmatter": "none",
|
|
442
547
|
"scope": "project-wide"
|
|
@@ -444,7 +549,10 @@
|
|
|
444
549
|
{
|
|
445
550
|
"id": "junie",
|
|
446
551
|
"client": "JetBrains Junie",
|
|
447
|
-
"patterns": [
|
|
552
|
+
"patterns": [
|
|
553
|
+
".junie/guidelines.md",
|
|
554
|
+
".junie/AGENTS.md"
|
|
555
|
+
],
|
|
448
556
|
"type": "markdown",
|
|
449
557
|
"frontmatter": "none",
|
|
450
558
|
"scope": "project-wide"
|
|
@@ -452,7 +560,9 @@
|
|
|
452
560
|
{
|
|
453
561
|
"id": "jetbrains-ai",
|
|
454
562
|
"client": "JetBrains AI Assistant",
|
|
455
|
-
"patterns": [
|
|
563
|
+
"patterns": [
|
|
564
|
+
".aiassistant/rules/*.md"
|
|
565
|
+
],
|
|
456
566
|
"type": "markdown",
|
|
457
567
|
"frontmatter": "none",
|
|
458
568
|
"scope": "rule-based"
|
|
@@ -460,7 +570,10 @@
|
|
|
460
570
|
{
|
|
461
571
|
"id": "continue",
|
|
462
572
|
"client": "Continue",
|
|
463
|
-
"patterns": [
|
|
573
|
+
"patterns": [
|
|
574
|
+
".continuerules",
|
|
575
|
+
".continue/rules/*.md"
|
|
576
|
+
],
|
|
464
577
|
"type": "markdown",
|
|
465
578
|
"frontmatter": "none",
|
|
466
579
|
"scope": "project-wide and rule-based"
|
|
@@ -468,7 +581,9 @@
|
|
|
468
581
|
{
|
|
469
582
|
"id": "zed",
|
|
470
583
|
"client": "Zed",
|
|
471
|
-
"patterns": [
|
|
584
|
+
"patterns": [
|
|
585
|
+
".rules"
|
|
586
|
+
],
|
|
472
587
|
"type": "plain text",
|
|
473
588
|
"frontmatter": "none",
|
|
474
589
|
"scope": "project-wide"
|
|
@@ -476,7 +591,9 @@
|
|
|
476
591
|
{
|
|
477
592
|
"id": "replit",
|
|
478
593
|
"client": "Replit",
|
|
479
|
-
"patterns": [
|
|
594
|
+
"patterns": [
|
|
595
|
+
"replit.md"
|
|
596
|
+
],
|
|
480
597
|
"type": "markdown",
|
|
481
598
|
"frontmatter": "none",
|
|
482
599
|
"scope": "project-wide"
|