@yawlabs/ctxlint 0.9.2 → 0.9.3

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 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)** — 7 lint rules, the agent session data landscape across 8 agents, sibling detection strategy, and implementation guidance.
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
- Exits with code 1 if any errors or warnings are found.
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": [
@@ -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,8 @@
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"
142
150
  },
143
151
  {
144
152
  "id": "staleness/stale",
@@ -147,7 +155,8 @@
147
155
  "description": "Context file has not been updated in 30+ days while referenced code has changed.",
148
156
  "trigger": "File last modified 30+ days ago AND paths it references have git commits since.",
149
157
  "message": "Last updated {days} days ago. {path} has {N} commits since.",
150
- "fixable": false
158
+ "fixable": false,
159
+ "stability": "stable"
151
160
  },
152
161
  {
153
162
  "id": "staleness/aging",
@@ -156,7 +165,8 @@
156
165
  "description": "Context file has not been updated in 14-30 days while referenced code has changed.",
157
166
  "trigger": "File last modified 14-30 days ago AND paths it references have git commits since.",
158
167
  "message": "Last updated {days} days ago. {path} has {N} commits since.",
159
- "fixable": false
168
+ "fixable": false,
169
+ "stability": "stable"
160
170
  },
161
171
  {
162
172
  "id": "tokens/excessive",
@@ -167,7 +177,8 @@
167
177
  "message": "{N} tokens — consumes significant context window space",
168
178
  "fixable": false,
169
179
  "configurable": true,
170
- "defaultThreshold": 8000
180
+ "defaultThreshold": 8000,
181
+ "stability": "stable"
171
182
  },
172
183
  {
173
184
  "id": "tokens/large",
@@ -178,7 +189,8 @@
178
189
  "message": "{N} tokens — large context file",
179
190
  "fixable": false,
180
191
  "configurable": true,
181
- "defaultThreshold": 3000
192
+ "defaultThreshold": 3000,
193
+ "stability": "stable"
182
194
  },
183
195
  {
184
196
  "id": "tokens/info",
@@ -189,7 +201,8 @@
189
201
  "message": "Uses ~{N} tokens per session",
190
202
  "fixable": false,
191
203
  "configurable": true,
192
- "defaultThreshold": 1000
204
+ "defaultThreshold": 1000,
205
+ "stability": "stable"
193
206
  },
194
207
  {
195
208
  "id": "tokens/aggregate",
@@ -200,7 +213,8 @@
200
213
  "message": "{count} context files consume {N} tokens combined",
201
214
  "fixable": false,
202
215
  "configurable": true,
203
- "defaultThreshold": 5000
216
+ "defaultThreshold": 5000,
217
+ "stability": "stable"
204
218
  },
205
219
  {
206
220
  "id": "tier-tokens/section-breakdown",
@@ -212,7 +226,8 @@
212
226
  "fixable": false,
213
227
  "configurable": true,
214
228
  "configKey": "tokenThresholds.tierBreakdown",
215
- "defaultThreshold": 1000
229
+ "defaultThreshold": 1000,
230
+ "stability": "stable"
216
231
  },
217
232
  {
218
233
  "id": "tier-tokens/aggregate",
@@ -224,7 +239,8 @@
224
239
  "fixable": false,
225
240
  "configurable": true,
226
241
  "configKey": "tokenThresholds.tierAggregate",
227
- "defaultThreshold": 4000
242
+ "defaultThreshold": 4000,
243
+ "stability": "stable"
228
244
  },
229
245
  {
230
246
  "id": "tier-tokens/hard-enforcement-missing",
@@ -234,7 +250,8 @@
234
250
  "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
251
  "message": "Inviolable framing without a hook to back it up",
236
252
  "fixable": false,
237
- "source": "code.claude.com/docs/en/hooks-guide"
253
+ "source": "code.claude.com/docs/en/hooks-guide",
254
+ "stability": "experimental"
238
255
  },
239
256
  {
240
257
  "id": "redundancy/tech-mention",
@@ -243,7 +260,8 @@
243
260
  "description": "Context file mentions a technology that is already in package.json dependencies.",
244
261
  "trigger": "File contains phrases like 'use React' or 'built with Express' and that package is in dependencies.",
245
262
  "message": "\"{tech}\" is in package.json {depType} — agent can infer this",
246
- "fixable": false
263
+ "fixable": false,
264
+ "stability": "stable"
247
265
  },
248
266
  {
249
267
  "id": "redundancy/discoverable-dir",
@@ -252,7 +270,8 @@
252
270
  "description": "Context file describes the location of a directory that the agent can discover by listing files.",
253
271
  "trigger": "File says files 'are in' or 'go in' a directory that exists in the project.",
254
272
  "message": "Directory \"{dir}\" exists and is discoverable — agent can find this by listing files",
255
- "fixable": false
273
+ "fixable": false,
274
+ "stability": "stable"
256
275
  },
257
276
  {
258
277
  "id": "redundancy/duplicate-content",
@@ -261,7 +280,8 @@
261
280
  "description": "Two context files have significant content overlap.",
262
281
  "trigger": "Two files share 60%+ of their lines (by trimmed content, lines >10 chars).",
263
282
  "message": "{file1} and {file2} have {N}% content overlap",
264
- "fixable": false
283
+ "fixable": false,
284
+ "stability": "stable"
265
285
  },
266
286
  {
267
287
  "id": "contradictions/conflict",
@@ -280,7 +300,8 @@
280
300
  "naming convention",
281
301
  "CSS approach",
282
302
  "state management"
283
- ]
303
+ ],
304
+ "stability": "stable"
284
305
  },
285
306
  {
286
307
  "id": "frontmatter/missing",
@@ -290,7 +311,12 @@
290
311
  "trigger": "Cursor .mdc, Copilot instruction, or Windsurf rule file has no --- frontmatter block.",
291
312
  "message": "{format} file is missing frontmatter",
292
313
  "fixable": false,
293
- "appliesTo": ["cursor-mdc", "copilot-instructions", "windsurf-rules"]
314
+ "appliesTo": [
315
+ "cursor-mdc",
316
+ "copilot-instructions",
317
+ "windsurf-rules"
318
+ ],
319
+ "stability": "stable"
294
320
  },
295
321
  {
296
322
  "id": "frontmatter/missing-field",
@@ -300,7 +326,12 @@
300
326
  "trigger": "Frontmatter exists but is missing a key field (description for Cursor, applyTo for Copilot, trigger for Windsurf).",
301
327
  "message": "Missing \"{field}\" field in {format} frontmatter",
302
328
  "fixable": false,
303
- "appliesTo": ["cursor-mdc", "copilot-instructions", "windsurf-rules"]
329
+ "appliesTo": [
330
+ "cursor-mdc",
331
+ "copilot-instructions",
332
+ "windsurf-rules"
333
+ ],
334
+ "stability": "stable"
304
335
  },
305
336
  {
306
337
  "id": "frontmatter/invalid-value",
@@ -310,7 +341,11 @@
310
341
  "trigger": "alwaysApply is not true/false, trigger is not a valid enum value, globs doesn't look like a pattern.",
311
342
  "message": "Invalid {field} value: \"{value}\"",
312
343
  "fixable": false,
313
- "appliesTo": ["cursor-mdc", "windsurf-rules"]
344
+ "appliesTo": [
345
+ "cursor-mdc",
346
+ "windsurf-rules"
347
+ ],
348
+ "stability": "stable"
314
349
  },
315
350
  {
316
351
  "id": "frontmatter/no-activation",
@@ -320,7 +355,10 @@
320
355
  "trigger": "Cursor .mdc has frontmatter with neither globs nor alwaysApply set.",
321
356
  "message": "No activation field — rule may not be applied automatically",
322
357
  "fixable": false,
323
- "appliesTo": ["cursor-mdc"]
358
+ "appliesTo": [
359
+ "cursor-mdc"
360
+ ],
361
+ "stability": "stable"
324
362
  },
325
363
  {
326
364
  "id": "ci/no-release-docs",
@@ -329,7 +367,8 @@
329
367
  "description": "Release/deploy CI workflow exists but no context file documents the process.",
330
368
  "trigger": ".github/workflows/ contains release/deploy/publish workflow but no context file mentions the release process.",
331
369
  "message": "Release workflow found but no context file documents the release process",
332
- "fixable": false
370
+ "fixable": false,
371
+ "stability": "stable"
333
372
  },
334
373
  {
335
374
  "id": "ci/undocumented-secret",
@@ -338,14 +377,19 @@
338
377
  "description": "CI workflow references a secret not mentioned in any context file.",
339
378
  "trigger": "${{ secrets.NAME }} found in workflow YAML but NAME not mentioned in any context file. GitHub-provided secrets (GITHUB_TOKEN, etc.) are excluded.",
340
379
  "message": "CI secret \"{name}\" is used in {workflow} but not mentioned in any context file",
341
- "fixable": false
380
+ "fixable": false,
381
+ "stability": "stable"
342
382
  }
343
383
  ],
344
384
  "formats": [
345
385
  {
346
386
  "id": "claude-code",
347
387
  "client": "Claude Code",
348
- "patterns": ["CLAUDE.md", "CLAUDE.local.md", ".claude/rules/*.md"],
388
+ "patterns": [
389
+ "CLAUDE.md",
390
+ "CLAUDE.local.md",
391
+ ".claude/rules/*.md"
392
+ ],
349
393
  "type": "markdown",
350
394
  "frontmatter": "none",
351
395
  "scope": "project-wide and rule-based"
@@ -353,7 +397,11 @@
353
397
  {
354
398
  "id": "aaif",
355
399
  "client": "AAIF / Multi-agent standard",
356
- "patterns": ["AGENTS.md", "AGENT.md", "AGENTS.override.md"],
400
+ "patterns": [
401
+ "AGENTS.md",
402
+ "AGENT.md",
403
+ "AGENTS.override.md"
404
+ ],
357
405
  "type": "markdown",
358
406
  "frontmatter": "none",
359
407
  "scope": "project-wide"
@@ -361,42 +409,77 @@
361
409
  {
362
410
  "id": "cursor",
363
411
  "client": "Cursor",
364
- "patterns": [".cursorrules", ".cursor/rules/*.md", ".cursor/rules/*.mdc", ".cursor/rules/*/RULE.md"],
412
+ "patterns": [
413
+ ".cursorrules",
414
+ ".cursor/rules/*.md",
415
+ ".cursor/rules/*.mdc",
416
+ ".cursor/rules/*/RULE.md"
417
+ ],
365
418
  "type": "markdown",
366
419
  "frontmatter": "required for .mdc",
367
420
  "frontmatterFields": {
368
- "description": {"required": true, "type": "string"},
369
- "globs": {"required": false, "type": "string or string[]"},
370
- "alwaysApply": {"required": false, "type": "boolean"}
421
+ "description": {
422
+ "required": true,
423
+ "type": "string"
424
+ },
425
+ "globs": {
426
+ "required": false,
427
+ "type": "string or string[]"
428
+ },
429
+ "alwaysApply": {
430
+ "required": false,
431
+ "type": "boolean"
432
+ }
371
433
  },
372
434
  "scope": "project-wide and rule-based"
373
435
  },
374
436
  {
375
437
  "id": "copilot",
376
438
  "client": "GitHub Copilot",
377
- "patterns": [".github/copilot-instructions.md", ".github/instructions/*.md", ".github/git-commit-instructions.md"],
439
+ "patterns": [
440
+ ".github/copilot-instructions.md",
441
+ ".github/instructions/*.md",
442
+ ".github/git-commit-instructions.md"
443
+ ],
378
444
  "type": "markdown",
379
445
  "frontmatter": "optional",
380
446
  "frontmatterFields": {
381
- "applyTo": {"required": false, "type": "string (glob)"}
447
+ "applyTo": {
448
+ "required": false,
449
+ "type": "string (glob)"
450
+ }
382
451
  },
383
452
  "scope": "project-wide and scoped"
384
453
  },
385
454
  {
386
455
  "id": "windsurf",
387
456
  "client": "Windsurf",
388
- "patterns": [".windsurfrules", ".windsurf/rules/*.md"],
457
+ "patterns": [
458
+ ".windsurfrules",
459
+ ".windsurf/rules/*.md"
460
+ ],
389
461
  "type": "markdown",
390
462
  "frontmatter": "recommended for rules",
391
463
  "frontmatterFields": {
392
- "trigger": {"required": true, "type": "enum", "values": ["always_on", "glob", "manual", "model"]}
464
+ "trigger": {
465
+ "required": true,
466
+ "type": "enum",
467
+ "values": [
468
+ "always_on",
469
+ "glob",
470
+ "manual",
471
+ "model"
472
+ ]
473
+ }
393
474
  },
394
475
  "scope": "project-wide and rule-based"
395
476
  },
396
477
  {
397
478
  "id": "gemini",
398
479
  "client": "Gemini CLI",
399
- "patterns": ["GEMINI.md"],
480
+ "patterns": [
481
+ "GEMINI.md"
482
+ ],
400
483
  "type": "markdown",
401
484
  "frontmatter": "none",
402
485
  "scope": "project-wide"
@@ -404,7 +487,9 @@
404
487
  {
405
488
  "id": "cline",
406
489
  "client": "Cline",
407
- "patterns": [".clinerules"],
490
+ "patterns": [
491
+ ".clinerules"
492
+ ],
408
493
  "type": "plain text",
409
494
  "frontmatter": "none",
410
495
  "scope": "project-wide"
@@ -412,7 +497,9 @@
412
497
  {
413
498
  "id": "aider",
414
499
  "client": "Aider",
415
- "patterns": [".aiderules"],
500
+ "patterns": [
501
+ ".aiderules"
502
+ ],
416
503
  "type": "plain text",
417
504
  "frontmatter": "none",
418
505
  "scope": "project-wide"
@@ -420,7 +507,9 @@
420
507
  {
421
508
  "id": "aide",
422
509
  "client": "Aide / Codestory",
423
- "patterns": [".aide/rules/*.md"],
510
+ "patterns": [
511
+ ".aide/rules/*.md"
512
+ ],
424
513
  "type": "markdown",
425
514
  "frontmatter": "none",
426
515
  "scope": "rule-based"
@@ -428,7 +517,9 @@
428
517
  {
429
518
  "id": "amazonq",
430
519
  "client": "Amazon Q Developer",
431
- "patterns": [".amazonq/rules/*.md"],
520
+ "patterns": [
521
+ ".amazonq/rules/*.md"
522
+ ],
432
523
  "type": "markdown",
433
524
  "frontmatter": "none",
434
525
  "scope": "rule-based"
@@ -436,7 +527,10 @@
436
527
  {
437
528
  "id": "goose",
438
529
  "client": "Goose (Block)",
439
- "patterns": [".goose/instructions.md", ".goosehints"],
530
+ "patterns": [
531
+ ".goose/instructions.md",
532
+ ".goosehints"
533
+ ],
440
534
  "type": "markdown",
441
535
  "frontmatter": "none",
442
536
  "scope": "project-wide"
@@ -444,7 +538,10 @@
444
538
  {
445
539
  "id": "junie",
446
540
  "client": "JetBrains Junie",
447
- "patterns": [".junie/guidelines.md", ".junie/AGENTS.md"],
541
+ "patterns": [
542
+ ".junie/guidelines.md",
543
+ ".junie/AGENTS.md"
544
+ ],
448
545
  "type": "markdown",
449
546
  "frontmatter": "none",
450
547
  "scope": "project-wide"
@@ -452,7 +549,9 @@
452
549
  {
453
550
  "id": "jetbrains-ai",
454
551
  "client": "JetBrains AI Assistant",
455
- "patterns": [".aiassistant/rules/*.md"],
552
+ "patterns": [
553
+ ".aiassistant/rules/*.md"
554
+ ],
456
555
  "type": "markdown",
457
556
  "frontmatter": "none",
458
557
  "scope": "rule-based"
@@ -460,7 +559,10 @@
460
559
  {
461
560
  "id": "continue",
462
561
  "client": "Continue",
463
- "patterns": [".continuerules", ".continue/rules/*.md"],
562
+ "patterns": [
563
+ ".continuerules",
564
+ ".continue/rules/*.md"
565
+ ],
464
566
  "type": "markdown",
465
567
  "frontmatter": "none",
466
568
  "scope": "project-wide and rule-based"
@@ -468,7 +570,9 @@
468
570
  {
469
571
  "id": "zed",
470
572
  "client": "Zed",
471
- "patterns": [".rules"],
573
+ "patterns": [
574
+ ".rules"
575
+ ],
472
576
  "type": "plain text",
473
577
  "frontmatter": "none",
474
578
  "scope": "project-wide"
@@ -476,7 +580,9 @@
476
580
  {
477
581
  "id": "replit",
478
582
  "client": "Replit",
479
- "patterns": ["replit.md"],
583
+ "patterns": [
584
+ "replit.md"
585
+ ],
480
586
  "type": "markdown",
481
587
  "frontmatter": "none",
482
588
  "scope": "project-wide"