clean-slop 2.0.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 ADDED
@@ -0,0 +1,849 @@
1
+ # clean-slop
2
+
3
+ **A production readiness engine for modern JavaScript and TypeScript projects.**
4
+
5
+ clean-slop answers one question: **should this code be merged into production?**
6
+
7
+ It combines AI-generated code quality analysis, static security analysis, reliability analysis, maintainability analysis, and production readiness checks into a single professional tool with a clear score and actionable output.
8
+
9
+ ```bash
10
+ npm install -D clean-slop
11
+ npx clean-slop scan
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Why clean-slop
17
+
18
+ AI code generation tools produce code that passes tests and compiles cleanly but contains patterns that silently fail in production: empty catch blocks that hide errors, hardcoded secrets that get committed to version control, SQL queries built with string concatenation, debug flags left active, and validation functions that always return true.
19
+
20
+ Standard linters catch syntax errors and style violations. clean-slop catches the patterns that indicate code that was never properly reviewed, never properly secured, and was never actually intended to run in production.
21
+
22
+ ---
23
+
24
+ ## Features
25
+
26
+ - **22 built-in rules** across 5 categories
27
+ - **Clear production readiness score** (0–100) with letter grade
28
+ - **Multiple output formats**: terminal, JSON, HTML, Markdown, SARIF 2.1.0
29
+ - **GitHub Code Scanning integration** via SARIF upload
30
+ - **Watch mode** for continuous feedback during development
31
+ - **CI-ready exit codes** with configurable thresholds
32
+ - **Plugin architecture** for custom rules
33
+ - **Public API** for programmatic use in build tools and scripts
34
+ - **TypeScript-first** with full type definitions
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ # As a dev dependency (recommended)
42
+ npm install -D clean-slop
43
+
44
+ # Global installation
45
+ npm install -g clean-slop
46
+
47
+ # No installation required
48
+ npx clean-slop scan
49
+ ```
50
+
51
+ **Requirements:** Node.js >= 18.0.0
52
+
53
+ ---
54
+
55
+ ## Quick Start
56
+
57
+ **Scan the current directory:**
58
+
59
+ ```bash
60
+ npx clean-slop scan
61
+ ```
62
+
63
+ **Scan a specific directory:**
64
+
65
+ ```bash
66
+ npx clean-slop scan ./src
67
+ ```
68
+
69
+ **Generate an HTML report:**
70
+
71
+ ```bash
72
+ npx clean-slop report --reporter html --output ./reports/clean-slop.html
73
+ ```
74
+
75
+ **CI gate (exit 1 if not production ready):**
76
+
77
+ ```bash
78
+ npx clean-slop check
79
+ ```
80
+
81
+ **Initialize a config file:**
82
+
83
+ ```bash
84
+ npx clean-slop init
85
+ ```
86
+
87
+ ---
88
+
89
+ ## CLI Reference
90
+
91
+ ### `clean-slop scan [directory]`
92
+
93
+ Scan a directory for issues. This is the default command.
94
+
95
+ ```
96
+ Options:
97
+ -c, --config <path> Path to configuration file
98
+ --reporter <name> Reporter: text, json, html, markdown, sarif [default: text]
99
+ -o, --output <file> Write report to a file instead of stdout
100
+ --fail-threshold <score> Minimum score before exiting with code 1 [default: 70]
101
+ --max-critical <n> Maximum allowed critical issues [default: 0]
102
+ --max-high <n> Maximum allowed high issues
103
+ --no-ai-slop Disable AI slop rules
104
+ --no-security Disable security rules
105
+ --no-reliability Disable reliability rules
106
+ --no-maintainability Disable maintainability rules
107
+ --no-production-readiness Disable production readiness rules
108
+ --verbose Print full issue details including snippets and fixes
109
+ --quiet Only print the score summary
110
+ --ci CI mode: machine-readable output, no color
111
+ ```
112
+
113
+ **Examples:**
114
+
115
+ ```bash
116
+ # Scan src/ with verbose output
117
+ clean-slop scan src --verbose
118
+
119
+ # Scan and fail if any critical issues found
120
+ clean-slop scan --max-critical 0
121
+
122
+ # Output SARIF for GitHub Code Scanning
123
+ clean-slop scan --reporter sarif --output results.sarif
124
+
125
+ # Disable security rules for a legacy scan
126
+ clean-slop scan --no-security
127
+ ```
128
+
129
+ ---
130
+
131
+ ### `clean-slop check [directory]`
132
+
133
+ Quick pass/fail check for use in CI pipelines. Prints PASS or FAIL with the score.
134
+
135
+ ```
136
+ Options:
137
+ -c, --config <path> Path to configuration file
138
+ --fail-threshold <score> Minimum passing score [default: 70]
139
+ --max-critical <n> Maximum critical issues allowed [default: 0]
140
+ ```
141
+
142
+ Exit codes:
143
+ - `0` — production ready (score above threshold, critical issues within limit)
144
+ - `1` — not production ready
145
+
146
+ ---
147
+
148
+ ### `clean-slop watch [directory]`
149
+
150
+ Watch for file changes and re-scan automatically. Useful during active development.
151
+
152
+ ```bash
153
+ clean-slop watch src --verbose
154
+ ```
155
+
156
+ ---
157
+
158
+ ### `clean-slop report [directory]`
159
+
160
+ Generate a report from a fresh scan and write it to a file.
161
+
162
+ ```bash
163
+ # Generate an HTML report
164
+ clean-slop report --reporter html --output ./reports/clean-slop.html
165
+
166
+ # Generate a Markdown report for GitHub PR comments
167
+ clean-slop report --reporter markdown --output ./clean-slop.md
168
+ ```
169
+
170
+ ---
171
+
172
+ ### `clean-slop doctor`
173
+
174
+ Diagnose the current environment. Reports Node.js version, configuration status, git repository presence, and loaded rules.
175
+
176
+ ```bash
177
+ clean-slop doctor
178
+ ```
179
+
180
+ ---
181
+
182
+ ### `clean-slop init`
183
+
184
+ Generate a `clean-slop.config.js` in the current directory with all options documented.
185
+
186
+ ```bash
187
+ clean-slop init
188
+ clean-slop init --force # Overwrite existing config
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Configuration
194
+
195
+ clean-slop uses [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig) for configuration discovery. Configuration is loaded from the first match of:
196
+
197
+ - `clean-slop.config.js`
198
+ - `clean-slop.config.ts`
199
+ - `clean-slop.config.mjs`
200
+ - `clean-slop.config.cjs`
201
+ - `.clean-slop.js`
202
+ - `.clean-slop.json`
203
+ - `.clean-slop.yaml`
204
+ - `package.json` (`"clean-slop"` key)
205
+
206
+ ### Full Configuration Reference
207
+
208
+ ```javascript
209
+ /** @type {import('clean-slop').UserConfig} */
210
+ export default {
211
+ // Glob patterns of files to scan
212
+ include: [
213
+ '**/*.js',
214
+ '**/*.jsx',
215
+ '**/*.ts',
216
+ '**/*.tsx',
217
+ '**/*.mjs',
218
+ '**/*.cjs',
219
+ ],
220
+
221
+ // Glob patterns to exclude
222
+ exclude: [
223
+ '**/node_modules/**',
224
+ '**/dist/**',
225
+ '**/build/**',
226
+ '**/.next/**',
227
+ '**/coverage/**',
228
+ '**/*.min.js',
229
+ '**/*.generated.*',
230
+ '**/__generated__/**',
231
+ ],
232
+
233
+ // Enable or disable entire rule categories
234
+ categories: {
235
+ 'ai-slop': true,
236
+ 'security': true,
237
+ 'reliability': true,
238
+ 'maintainability': true,
239
+ 'production-readiness': true,
240
+ },
241
+
242
+ // Per-rule severity overrides
243
+ // Value: 'critical' | 'high' | 'medium' | 'low' | 'info' | 'off'
244
+ rules: {
245
+ // Disable a rule entirely
246
+ 'ai-slop/empty-catch': 'off',
247
+
248
+ // Escalate a rule to critical
249
+ 'security/hardcoded-secrets': 'critical',
250
+
251
+ // Downgrade a rule severity
252
+ 'production-readiness/no-console-log': 'info',
253
+ },
254
+
255
+ // Minimum overall score before CI exits with code 1
256
+ failThreshold: 70,
257
+
258
+ // Maximum issues per severity (scan fails if exceeded)
259
+ maxIssues: {
260
+ critical: 0, // Zero critical issues allowed
261
+ high: 5,
262
+ },
263
+
264
+ // Reporter: 'text' | 'json' | 'html' | 'markdown' | 'sarif'
265
+ reporter: 'text',
266
+
267
+ // Output file path (null = stdout)
268
+ output: null,
269
+
270
+ // Verbose output (show snippets, fixes, docs links)
271
+ verbose: false,
272
+
273
+ // Additional ignore patterns (on top of .gitignore)
274
+ ignorePatterns: ['src/legacy/**'],
275
+
276
+ // Plugins to load
277
+ plugins: [],
278
+ };
279
+ ```
280
+
281
+ ---
282
+
283
+ ## Rule Reference
284
+
285
+ ### AI Slop (`ai-slop`)
286
+
287
+ Rules that detect patterns characteristic of unreviewed AI-generated code.
288
+
289
+ | Rule ID | Severity | Description |
290
+ |---------|----------|-------------|
291
+ | `ai-slop/empty-catch` | high | Catch blocks that silently swallow errors |
292
+ | `ai-slop/todo-implementation` | high | TODO/FIXME comments and placeholder throw statements |
293
+ | `ai-slop/giant-function` | medium | Functions exceeding 80 lines |
294
+ | `ai-slop/excessive-nesting` | medium | Control flow nesting deeper than 4 levels |
295
+ | `ai-slop/fake-validation` | high | Validation functions that unconditionally return true |
296
+ | `ai-slop/high-complexity` | medium | Cyclomatic complexity exceeding 10 |
297
+ | `ai-slop/dead-code` | medium | Unreachable code after return/throw/break/continue |
298
+
299
+ ---
300
+
301
+ ### Security (`security`)
302
+
303
+ Rules that detect common vulnerability patterns.
304
+
305
+ | Rule ID | Severity | Description |
306
+ |---------|----------|-------------|
307
+ | `security/unsafe-eval` | critical | Use of eval() and new Function() |
308
+ | `security/hardcoded-secrets` | critical | API keys, passwords, tokens in source |
309
+ | `security/sql-injection` | critical | SQL built with string concatenation or template literals |
310
+ | `security/command-injection` | critical | child_process calls with dynamic arguments |
311
+ | `security/path-traversal` | critical | File system operations with dynamic paths |
312
+ | `security/prototype-pollution` | high | Dynamic property assignment and unsafe merge |
313
+ | `security/weak-crypto` | high | MD5, SHA1, ECB mode, Math.random() for secrets |
314
+ | `security/dangerous-cors` | high | Wildcard CORS, insecure cookie configuration |
315
+
316
+ ---
317
+
318
+ ### Reliability (`reliability`)
319
+
320
+ Rules that detect code likely to fail under load or in production conditions.
321
+
322
+ | Rule ID | Severity | Description |
323
+ |---------|----------|-------------|
324
+ | `reliability/unhandled-promise` | high | Fire-and-forget async calls with no error handling |
325
+ | `reliability/missing-await` | high | Async functions returning un-awaited Promises |
326
+ | `reliability/infinite-loop` | high | while(true) and for(;;) with no exit condition |
327
+
328
+ ---
329
+
330
+ ### Maintainability (`maintainability`)
331
+
332
+ Rules that identify structural problems affecting long-term code health.
333
+
334
+ | Rule ID | Severity | Description |
335
+ |---------|----------|-------------|
336
+ | `maintainability/giant-file` | medium | Source files exceeding 400 lines |
337
+ | `maintainability/circular-imports` | medium | Import patterns that commonly cause circular dependencies |
338
+
339
+ ---
340
+
341
+ ### Production Readiness (`production-readiness`)
342
+
343
+ Rules that detect development artifacts left in production code.
344
+
345
+ | Rule ID | Severity | Description |
346
+ |---------|----------|-------------|
347
+ | `production-readiness/no-console-log` | low | console.log and debug console methods |
348
+ | `production-readiness/no-localhost-urls` | medium | Localhost URLs, debug flags, mock implementations |
349
+
350
+ ---
351
+
352
+ ## Output Formats
353
+
354
+ ### Text (default)
355
+
356
+ Color-coded terminal output with file grouping, severity labels, and optional verbose mode.
357
+
358
+ ### JSON
359
+
360
+ Machine-readable full scan result. Includes every issue, score breakdown, file list, config, and metadata.
361
+
362
+ ```bash
363
+ clean-slop scan --reporter json --output scan.json
364
+ ```
365
+
366
+ ### HTML
367
+
368
+ Self-contained single-file interactive report with filtering by severity. Suitable for CI artifacts and sharing with non-technical stakeholders.
369
+
370
+ ```bash
371
+ clean-slop report --reporter html --output ./reports/scan.html
372
+ ```
373
+
374
+ ### Markdown
375
+
376
+ GitHub-flavored Markdown report suitable for posting as a PR comment or including in CI artifact summaries.
377
+
378
+ ```bash
379
+ clean-slop report --reporter markdown --output ./clean-slop.md
380
+ ```
381
+
382
+ ### SARIF 2.1.0
383
+
384
+ Static Analysis Results Interchange Format. Compatible with GitHub Code Scanning, Azure DevOps, and VS Code SARIF Viewer.
385
+
386
+ ```bash
387
+ clean-slop scan --reporter sarif --output results.sarif
388
+ ```
389
+
390
+ ---
391
+
392
+ ## JavaScript / TypeScript API
393
+
394
+ clean-slop exposes a full programmatic API for integration with build tools, scripts, and other tooling.
395
+
396
+ ```typescript
397
+ import { scanDirectory, loadConfig, generateReport } from 'clean-slop';
398
+
399
+ // Simple usage
400
+ const result = await scanDirectory('./src');
401
+ console.log(`Score: ${result.score.overall}/100`);
402
+ console.log(`Issues: ${result.issues.length}`);
403
+
404
+ // With configuration
405
+ const config = await loadConfig(process.cwd());
406
+ const result = await scanDirectory('./src', {
407
+ categories: { security: true },
408
+ failThreshold: 80,
409
+ });
410
+
411
+ // Generate a report
412
+ const html = generateReport(result, 'html');
413
+ ```
414
+
415
+ ### API Reference
416
+
417
+ #### `scanDirectory(directory, config?)`
418
+
419
+ Scan a directory and return a `ScanResult`.
420
+
421
+ ```typescript
422
+ async function scanDirectory(
423
+ directory: string,
424
+ config?: UserConfig
425
+ ): Promise<ScanResult>
426
+ ```
427
+
428
+ #### `loadConfig(cwd, configPath?)`
429
+
430
+ Load and resolve configuration from the filesystem.
431
+
432
+ ```typescript
433
+ async function loadConfig(
434
+ cwd: string,
435
+ configPath?: string
436
+ ): Promise<ResolvedConfig>
437
+ ```
438
+
439
+ #### `generateReport(result, reporter)`
440
+
441
+ Generate a report string from a scan result.
442
+
443
+ ```typescript
444
+ function generateReport(
445
+ result: ScanResult,
446
+ reporter: 'text' | 'json' | 'html' | 'markdown' | 'sarif'
447
+ ): string
448
+ ```
449
+
450
+ ---
451
+
452
+ ## CI/CD Integration
453
+
454
+ ### GitHub Actions
455
+
456
+ Add clean-slop as a required check in your CI pipeline:
457
+
458
+ ```yaml
459
+ # .github/workflows/quality.yml
460
+ name: Code Quality
461
+
462
+ on: [push, pull_request]
463
+
464
+ jobs:
465
+ clean-slop:
466
+ name: Production Readiness Check
467
+ runs-on: ubuntu-latest
468
+
469
+ steps:
470
+ - uses: actions/checkout@v4
471
+
472
+ - uses: actions/setup-node@v4
473
+ with:
474
+ node-version: 20
475
+
476
+ - run: npm ci
477
+
478
+ - name: Scan with clean-slop
479
+ run: |
480
+ npx clean-slop scan src \
481
+ --reporter sarif \
482
+ --output clean-slop-results.sarif \
483
+ --fail-threshold 70 \
484
+ --max-critical 0
485
+
486
+ - name: Upload to GitHub Code Scanning
487
+ if: always()
488
+ uses: github/codeql-action/upload-sarif@v3
489
+ with:
490
+ sarif_file: clean-slop-results.sarif
491
+ ```
492
+
493
+ ### npm scripts
494
+
495
+ ```json
496
+ {
497
+ "scripts": {
498
+ "quality": "clean-slop scan src",
499
+ "quality:ci": "clean-slop check src --fail-threshold 70",
500
+ "quality:report": "clean-slop report --reporter html --output reports/quality.html"
501
+ }
502
+ }
503
+ ```
504
+
505
+ ### Pre-commit hook
506
+
507
+ Using [husky](https://typicode.github.io/husky/):
508
+
509
+ ```bash
510
+ npx husky add .husky/pre-commit "npx clean-slop check src --fail-threshold 60"
511
+ ```
512
+
513
+ ---
514
+
515
+ ## Plugin Development
516
+
517
+ clean-slop supports custom plugins that add new rules.
518
+
519
+ ### Creating a Plugin
520
+
521
+ ```typescript
522
+ import type { Plugin, Rule, RuleContext } from 'clean-slop';
523
+
524
+ const myRule: Rule = {
525
+ meta: {
526
+ id: 'my-plugin/no-deprecated-api',
527
+ name: 'No Deprecated API',
528
+ category: 'maintainability',
529
+ severity: 'medium',
530
+ confidence: 'high',
531
+ description: 'Detects usage of deprecated internal APIs.',
532
+ rationale: 'Deprecated APIs will be removed in the next major release.',
533
+ docsUrl: 'https://myteam.dev/docs/rules/no-deprecated-api',
534
+ fixable: false,
535
+ },
536
+
537
+ create(context: RuleContext) {
538
+ // Use the traverse utility or work with context.ast directly
539
+ const ast = context.ast;
540
+
541
+ // Report an issue
542
+ context.report({
543
+ message: 'Usage of deprecated API detected.',
544
+ explanation: 'The legacyClient API will be removed in v3.0.',
545
+ impact: 'This call will throw at runtime after the upgrade.',
546
+ location: {
547
+ file: context.filePath,
548
+ line: 10,
549
+ column: 0,
550
+ },
551
+ fix: {
552
+ description: 'Replace legacyClient with modernClient.',
553
+ code: "import { modernClient } from '@myorg/client';",
554
+ },
555
+ });
556
+ },
557
+ };
558
+
559
+ const plugin: Plugin = {
560
+ name: 'my-plugin',
561
+ version: '1.0.0',
562
+ rules: [myRule],
563
+ };
564
+
565
+ export default plugin;
566
+ ```
567
+
568
+ ### Registering a Plugin
569
+
570
+ ```javascript
571
+ // clean-slop.config.js
572
+ export default {
573
+ plugins: ['./my-plugin.js', 'clean-slop-plugin-nestjs'],
574
+ };
575
+ ```
576
+
577
+ ---
578
+
579
+ ## Architecture Overview
580
+
581
+ ```
582
+ clean-slop/
583
+ ├── src/
584
+ │ ├── cli/ # Commander-based CLI and command implementations
585
+ │ │ ├── bin.ts # Entry point (#!/usr/bin/env node)
586
+ │ │ ├── index.ts # Command registration
587
+ │ │ └── commands/ # scan, check, watch, report, doctor, init
588
+ │ ├── config/ # cosmiconfig loader and config resolution
589
+ │ ├── parsers/ # @typescript-eslint/typescript-estree AST parser
590
+ │ ├── rules/ # Rule engine and all built-in rules
591
+ │ │ ├── engine.ts # RuleEngine class
592
+ │ │ ├── index.ts # BUILT_IN_RULES registry
593
+ │ │ ├── ai-slop/ # AI slop detection rules
594
+ │ │ ├── security/ # Security rules
595
+ │ │ ├── reliability/ # Reliability rules
596
+ │ │ ├── maintainability/ # Maintainability rules
597
+ │ │ └── production-readiness/ # Production readiness rules
598
+ │ ├── scanners/ # File discovery and orchestration
599
+ │ ├── reporters/ # text, json, html, markdown, sarif reporters
600
+ │ ├── utils/ # AST traversal, constants, shared utilities
601
+ │ ├── types.ts # All shared TypeScript interfaces
602
+ │ ├── version.ts # Package version constant
603
+ │ └── index.ts # Public API exports
604
+ ├── tests/
605
+ │ ├── unit/ # Per-rule unit tests
606
+ │ ├── integration/ # Full scan pipeline tests
607
+ │ └── fixtures/ # Deliberately bad code for testing
608
+ └── .github/workflows/ # CI and release automation
609
+ ```
610
+
611
+ **Data flow:**
612
+
613
+ 1. CLI parses arguments → loads config
614
+ 2. Scanner discovers files matching include/exclude globs
615
+ 3. Parser converts each file to an AST using `@typescript-eslint/typescript-estree`
616
+ 4. Rule engine iterates rules, calls `rule.create(context)` for each file
617
+ 5. Rules call `context.report()` to record issues
618
+ 6. Scanner computes per-category scores and overall score
619
+ 7. Reporter generates output in the requested format
620
+ 8. CLI exits with appropriate code based on score and maxIssues thresholds
621
+
622
+ ---
623
+
624
+ ## Security Philosophy
625
+
626
+ clean-slop treats security as a first-class concern. The security rule category is always enabled by default and cannot be silently bypassed.
627
+
628
+ Key principles:
629
+
630
+ **Detect at the pattern level.** Most static analysis requires full data-flow tracking, which is expensive and complex. clean-slop detects high-signal structural patterns that reliably indicate vulnerability classes even without full data-flow.
631
+
632
+ **Report false positives, not false negatives.** When a pattern is ambiguous, clean-slop reports it with an appropriate confidence level rather than silently ignoring it. A false positive in a security tool is a minor annoyance. A false negative is a breach.
633
+
634
+ **Explain why it matters.** Every security issue includes an `impact` field that explains what an attacker can do if the issue is exploited. Security issues are not academic.
635
+
636
+ **Never disable critical rules in config.** The `failThreshold` and `maxIssues` configuration allows teams to tune the gate, but rules themselves can only be downgraded or turned off explicitly by ID in configuration. There is no way to globally disable security checks.
637
+
638
+ ---
639
+
640
+ ## AI Slop Philosophy
641
+
642
+ AI code generation tools are productivity multipliers. They are also pattern completion engines that produce syntactically correct, test-passable code without any understanding of production requirements.
643
+
644
+ The AI slop category detects specific patterns that AI generators produce systematically:
645
+
646
+ - **Empty catch blocks** — the generator handles the error path syntactically but not semantically. The exception vanishes.
647
+ - **Fake validation** — the generator names the function `validateEmail` to make the code look complete, but the body is `return true`.
648
+ - **TODO/placeholder throws** — the generator creates the skeleton of a feature and marks everything unimplemented. The feature is never implemented.
649
+ - **Giant functions** — the generator places all logic in a single function without decomposing it into maintainable units.
650
+ - **High complexity** — the generator combines multiple responsibilities into one function, creating code with too many paths to test.
651
+
652
+ clean-slop does not penalize AI-assisted development. It penalizes AI-generated code that was never reviewed.
653
+
654
+ ---
655
+
656
+ ## Contributing
657
+
658
+ Contributions are welcome. The project is structured so that adding a new rule requires only creating a single file in the appropriate category directory and adding the import to `src/rules/index.ts`.
659
+
660
+ ### Development Setup
661
+
662
+ ```bash
663
+ git clone https://github.com/clean-slop/clean-slop
664
+ cd clean-slop
665
+ npm install
666
+ npm run build
667
+ npm test
668
+ ```
669
+
670
+ ### Adding a Rule
671
+
672
+ 1. Create `src/rules/<category>/<rule-name>.ts`
673
+ 2. Implement the `Rule` interface (see existing rules for examples)
674
+ 3. Add the import and export to `src/rules/index.ts`
675
+ 4. Add unit tests to `tests/unit/`
676
+ 5. Add a fixture case to `tests/fixtures/` if needed
677
+
678
+ ### Rule Implementation Template
679
+
680
+ ```typescript
681
+ import type { Rule } from '../../types.js';
682
+ import { traverse, getLocation } from '../../utils/ast.js';
683
+ import type { ASTNode } from '../../utils/ast.js';
684
+
685
+ const rule: Rule = {
686
+ meta: {
687
+ id: 'category/rule-name',
688
+ name: 'Human Readable Rule Name',
689
+ category: 'security', // ai-slop | security | reliability | maintainability | production-readiness
690
+ severity: 'high',
691
+ confidence: 'high',
692
+ description: 'One sentence description.',
693
+ rationale: 'Why this matters and what it indicates.',
694
+ docsUrl: 'https://clean-slop.dev/docs/rules/category/rule-name',
695
+ fixable: false,
696
+ },
697
+
698
+ create(context) {
699
+ traverse(context.ast, {
700
+ CallExpression(node: ASTNode) {
701
+ // Detection logic here
702
+ context.report({
703
+ message: 'Short description of what was found.',
704
+ explanation: 'Full explanation of the issue.',
705
+ impact: 'What happens in production if this is not fixed.',
706
+ location: getLocation(node, context.filePath),
707
+ fix: {
708
+ description: 'How to fix this.',
709
+ code: '// Example fix code',
710
+ },
711
+ });
712
+ },
713
+ });
714
+ },
715
+ };
716
+
717
+ export default rule;
718
+ ```
719
+
720
+ ### Testing Guide
721
+
722
+ ```bash
723
+ # Run all tests
724
+ npm test
725
+
726
+ # Run tests in watch mode
727
+ npm run test:watch
728
+
729
+ # Run with coverage
730
+ npm run test:coverage
731
+
732
+ # Run a specific test file
733
+ npx vitest run tests/unit/security-rules.test.ts
734
+ ```
735
+
736
+ ### Commit Convention
737
+
738
+ This project follows [Conventional Commits](https://www.conventionalcommits.org/):
739
+
740
+ ```
741
+ feat: add new rule security/jwt-none-algorithm
742
+ fix: correct false positive in ai-slop/fake-validation
743
+ docs: update CLI reference for watch command
744
+ test: add coverage for path-traversal rule
745
+ refactor: extract AST traversal utilities
746
+ ```
747
+
748
+ ---
749
+
750
+ ## Release Guide
751
+
752
+ Releases are automated via GitHub Actions on tag push.
753
+
754
+ ```bash
755
+ # Bump version
756
+ npm version patch # 1.0.0 → 1.0.1
757
+ npm version minor # 1.0.0 → 1.1.0
758
+ npm version major # 1.0.0 → 2.0.0
759
+
760
+ # Push with tag
761
+ git push origin main --follow-tags
762
+ ```
763
+
764
+ The release workflow will:
765
+ 1. Run tests
766
+ 2. Build the package
767
+ 3. Publish to npm with provenance
768
+ 4. Create a GitHub Release with auto-generated release notes
769
+
770
+ ---
771
+
772
+ ## Troubleshooting
773
+
774
+ **Parse errors on valid files**
775
+
776
+ clean-slop uses `@typescript-eslint/typescript-estree` for parsing. Experimental syntax (decorators, certain JSX patterns) may require a `tsconfig.json`. Run `clean-slop doctor` to verify the environment.
777
+
778
+ **False positives in generated code**
779
+
780
+ Add generated files to the `exclude` array in configuration:
781
+
782
+ ```javascript
783
+ exclude: ['**/__generated__/**', '**/*.generated.ts', '**/graphql-types.ts'],
784
+ ```
785
+
786
+ **Score is lower than expected**
787
+
788
+ Run with `--verbose` to see the full explanation for each issue. Check which category is pulling the score down and use `--no-<category>` flags or per-rule `'off'` configuration to tune the results.
789
+
790
+ **CI exits with code 1**
791
+
792
+ The process exits with code 1 when the score is below `failThreshold` or when `maxIssues` limits are exceeded. Run `clean-slop scan --verbose` locally to see exactly which issues are causing the failure.
793
+
794
+ ---
795
+
796
+ ## FAQ
797
+
798
+ **Does clean-slop replace ESLint?**
799
+
800
+ No. ESLint and clean-slop serve different purposes. ESLint is a style and correctness linter. clean-slop analyzes production readiness patterns, security vulnerabilities, and AI-generated code quality. They are complementary.
801
+
802
+ **Can I use clean-slop with JavaScript (not TypeScript)?**
803
+
804
+ Yes. clean-slop supports plain `.js`, `.jsx`, `.mjs`, and `.cjs` files.
805
+
806
+ **Does clean-slop modify my code?**
807
+
808
+ No. clean-slop is a read-only analysis tool. It reports issues and suggests fixes but never modifies files. The `fix` field in each issue contains suggested remediation, but applying it is always a manual action.
809
+
810
+ **What is the performance profile?**
811
+
812
+ On a typical 50,000 line TypeScript project, clean-slop completes a full scan in 2–5 seconds on modern hardware.
813
+
814
+ **How is the score calculated?**
815
+
816
+ Each category starts at 100. Issues deduct points based on severity: critical (-20), high (-10), medium (-4), low (-1). Each category score is floored at 0. The overall score is the average of all 5 category scores.
817
+
818
+ **Can teams add custom rules?**
819
+
820
+ Yes, via the plugin system. See the Plugin Development section above.
821
+
822
+ ---
823
+
824
+ ## Roadmap
825
+
826
+ - [ ] Additional security rules: JWT algorithm validation, ReDoS detection, insecure deserialization
827
+ - [ ] React-specific rules: missing key props, unsafe innerHTML, useEffect cleanup
828
+ - [ ] Next.js rules: server-side data exposure, missing authentication on API routes
829
+ - [ ] NestJS rules: missing guards, exposed internal routes
830
+ - [ ] Dependency health analysis (known vulnerabilities via OSV)
831
+ - [ ] Duplicate code detection (AST-based similarity)
832
+ - [ ] VS Code extension
833
+ - [ ] GitHub App for automated PR comments
834
+
835
+ ---
836
+
837
+ ## License
838
+
839
+ MIT — see [LICENSE](./LICENSE)
840
+
841
+ ---
842
+
843
+ ## Code of Conduct
844
+
845
+ This project follows the [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct. Be respectful, constructive, and professional in all interactions.
846
+
847
+ ---
848
+
849
+ *clean-slop is built for teams that ship production software and need confidence that what they merge is actually ready for production.*