@eduardbar/drift 0.9.1 → 1.1.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.
Files changed (129) hide show
  1. package/.github/actions/drift-scan/README.md +61 -0
  2. package/.github/actions/drift-scan/action.yml +65 -0
  3. package/.github/workflows/publish-vscode.yml +78 -0
  4. package/AGENTS.md +83 -23
  5. package/README.md +69 -2
  6. package/ROADMAP.md +130 -98
  7. package/dist/analyzer.d.ts +8 -38
  8. package/dist/analyzer.js +181 -1526
  9. package/dist/badge.js +40 -22
  10. package/dist/ci.js +32 -18
  11. package/dist/cli.js +125 -4
  12. package/dist/config.js +1 -1
  13. package/dist/diff.d.ts +0 -7
  14. package/dist/diff.js +26 -25
  15. package/dist/fix.d.ts +17 -0
  16. package/dist/fix.js +132 -0
  17. package/dist/git/blame.d.ts +22 -0
  18. package/dist/git/blame.js +227 -0
  19. package/dist/git/helpers.d.ts +36 -0
  20. package/dist/git/helpers.js +152 -0
  21. package/dist/git/trend.d.ts +21 -0
  22. package/dist/git/trend.js +81 -0
  23. package/dist/git.d.ts +0 -13
  24. package/dist/git.js +27 -21
  25. package/dist/index.d.ts +5 -1
  26. package/dist/index.js +3 -0
  27. package/dist/map.d.ts +3 -0
  28. package/dist/map.js +103 -0
  29. package/dist/metrics.d.ts +4 -0
  30. package/dist/metrics.js +176 -0
  31. package/dist/plugins.d.ts +6 -0
  32. package/dist/plugins.js +74 -0
  33. package/dist/printer.js +20 -0
  34. package/dist/report.js +654 -293
  35. package/dist/reporter.js +85 -2
  36. package/dist/review.d.ts +15 -0
  37. package/dist/review.js +80 -0
  38. package/dist/rules/comments.d.ts +4 -0
  39. package/dist/rules/comments.js +45 -0
  40. package/dist/rules/complexity.d.ts +4 -0
  41. package/dist/rules/complexity.js +51 -0
  42. package/dist/rules/coupling.d.ts +4 -0
  43. package/dist/rules/coupling.js +19 -0
  44. package/dist/rules/magic.d.ts +4 -0
  45. package/dist/rules/magic.js +33 -0
  46. package/dist/rules/nesting.d.ts +5 -0
  47. package/dist/rules/nesting.js +82 -0
  48. package/dist/rules/phase0-basic.d.ts +11 -0
  49. package/dist/rules/phase0-basic.js +183 -0
  50. package/dist/rules/phase1-complexity.d.ts +7 -0
  51. package/dist/rules/phase1-complexity.js +8 -0
  52. package/dist/rules/phase2-crossfile.d.ts +23 -0
  53. package/dist/rules/phase2-crossfile.js +135 -0
  54. package/dist/rules/phase3-arch.d.ts +23 -0
  55. package/dist/rules/phase3-arch.js +151 -0
  56. package/dist/rules/phase3-configurable.d.ts +6 -0
  57. package/dist/rules/phase3-configurable.js +97 -0
  58. package/dist/rules/phase5-ai.d.ts +8 -0
  59. package/dist/rules/phase5-ai.js +262 -0
  60. package/dist/rules/phase8-semantic.d.ts +17 -0
  61. package/dist/rules/phase8-semantic.js +110 -0
  62. package/dist/rules/promise.d.ts +4 -0
  63. package/dist/rules/promise.js +24 -0
  64. package/dist/rules/shared.d.ts +7 -0
  65. package/dist/rules/shared.js +27 -0
  66. package/dist/snapshot.d.ts +19 -0
  67. package/dist/snapshot.js +119 -0
  68. package/dist/types.d.ts +69 -0
  69. package/dist/utils.d.ts +2 -1
  70. package/dist/utils.js +1 -0
  71. package/docs/AGENTS.md +146 -0
  72. package/docs/PRD.md +208 -0
  73. package/package.json +8 -3
  74. package/packages/eslint-plugin-drift/src/index.ts +1 -1
  75. package/packages/vscode-drift/.vscodeignore +9 -0
  76. package/packages/vscode-drift/LICENSE +21 -0
  77. package/packages/vscode-drift/README.md +64 -0
  78. package/packages/vscode-drift/images/icon.png +0 -0
  79. package/packages/vscode-drift/images/icon.svg +30 -0
  80. package/packages/vscode-drift/package-lock.json +485 -0
  81. package/packages/vscode-drift/package.json +119 -0
  82. package/packages/vscode-drift/src/analyzer.ts +40 -0
  83. package/packages/vscode-drift/src/diagnostics.ts +55 -0
  84. package/packages/vscode-drift/src/extension.ts +135 -0
  85. package/packages/vscode-drift/src/statusbar.ts +55 -0
  86. package/packages/vscode-drift/src/treeview.ts +110 -0
  87. package/packages/vscode-drift/tsconfig.json +18 -0
  88. package/packages/vscode-drift/vscode-drift-0.1.0.vsix +0 -0
  89. package/packages/vscode-drift/vscode-drift-0.1.1.vsix +0 -0
  90. package/src/analyzer.ts +248 -1765
  91. package/src/badge.ts +38 -16
  92. package/src/ci.ts +38 -17
  93. package/src/cli.ts +143 -4
  94. package/src/config.ts +1 -1
  95. package/src/diff.ts +36 -30
  96. package/src/fix.ts +178 -0
  97. package/src/git/blame.ts +279 -0
  98. package/src/git/helpers.ts +198 -0
  99. package/src/git/trend.ts +117 -0
  100. package/src/git.ts +33 -24
  101. package/src/index.ts +16 -1
  102. package/src/map.ts +117 -0
  103. package/src/metrics.ts +200 -0
  104. package/src/plugins.ts +76 -0
  105. package/src/printer.ts +20 -0
  106. package/src/report.ts +666 -296
  107. package/src/reporter.ts +95 -2
  108. package/src/review.ts +98 -0
  109. package/src/rules/comments.ts +56 -0
  110. package/src/rules/complexity.ts +57 -0
  111. package/src/rules/coupling.ts +23 -0
  112. package/src/rules/magic.ts +38 -0
  113. package/src/rules/nesting.ts +88 -0
  114. package/src/rules/phase0-basic.ts +194 -0
  115. package/src/rules/phase1-complexity.ts +8 -0
  116. package/src/rules/phase2-crossfile.ts +177 -0
  117. package/src/rules/phase3-arch.ts +183 -0
  118. package/src/rules/phase3-configurable.ts +132 -0
  119. package/src/rules/phase5-ai.ts +292 -0
  120. package/src/rules/phase8-semantic.ts +136 -0
  121. package/src/rules/promise.ts +29 -0
  122. package/src/rules/shared.ts +39 -0
  123. package/src/snapshot.ts +175 -0
  124. package/src/types.ts +75 -1
  125. package/src/utils.ts +3 -1
  126. package/tests/helpers.ts +45 -0
  127. package/tests/new-features.test.ts +153 -0
  128. package/tests/rules.test.ts +1269 -0
  129. package/vitest.config.ts +15 -0
@@ -0,0 +1,61 @@
1
+ # drift-scan Action
2
+
3
+ Scan your TypeScript project for AI-generated technical debt in CI.
4
+
5
+ ## Usage
6
+
7
+ ```yaml
8
+ - name: Check drift score
9
+ uses: eduardbar/drift@v1
10
+ with:
11
+ path: ./src
12
+ min-score: 60
13
+ ```
14
+
15
+ ## Inputs
16
+
17
+ | Input | Description | Default |
18
+ |-------|-------------|---------|
19
+ | `path` | Path to scan | `.` |
20
+ | `min-score` | Fail if score exceeds this | `80` |
21
+ | `fail-on-threshold` | Whether to fail on threshold | `true` |
22
+ | `version` | drift version to use | `latest` |
23
+
24
+ ## Outputs
25
+
26
+ | Output | Description |
27
+ |--------|-------------|
28
+ | `score` | Project drift score (0-100) |
29
+ | `grade` | Grade: CLEAN / LOW / MODERATE / HIGH / CRITICAL |
30
+
31
+ ## Example: PR gate
32
+
33
+ ```yaml
34
+ name: Drift Check
35
+ on: [pull_request]
36
+
37
+ jobs:
38
+ drift:
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ - uses: eduardbar/drift@v1
43
+ with:
44
+ path: ./src
45
+ min-score: 60
46
+ fail-on-threshold: true
47
+ ```
48
+
49
+ ## Example: capture outputs
50
+
51
+ ```yaml
52
+ - name: Scan drift
53
+ id: drift
54
+ uses: eduardbar/drift@v1
55
+ with:
56
+ path: ./src
57
+ fail-on-threshold: false
58
+
59
+ - name: Print results
60
+ run: echo "Score ${{ steps.drift.outputs.score }}/100 — ${{ steps.drift.outputs.grade }}"
61
+ ```
@@ -0,0 +1,65 @@
1
+ name: 'Drift — Technical Debt Scanner'
2
+ description: 'Scan TypeScript projects for AI-generated technical debt and enforce score thresholds'
3
+ author: 'eduardbar'
4
+
5
+ branding:
6
+ icon: 'activity'
7
+ color: 'purple'
8
+
9
+ inputs:
10
+ path:
11
+ description: 'Path to scan'
12
+ required: false
13
+ default: '.'
14
+ min-score:
15
+ description: 'Fail if project score exceeds this threshold (0-100)'
16
+ required: false
17
+ default: '80'
18
+ fail-on-threshold:
19
+ description: 'Whether to fail the action if threshold is exceeded'
20
+ required: false
21
+ default: 'true'
22
+ version:
23
+ description: 'Version of @eduardbar/drift to use'
24
+ required: false
25
+ default: 'latest'
26
+
27
+ outputs:
28
+ score:
29
+ description: 'The overall drift score (0-100)'
30
+ value: ${{ steps.scan.outputs.score }}
31
+ grade:
32
+ description: 'The drift grade (CLEAN / LOW / MODERATE / HIGH / CRITICAL)'
33
+ value: ${{ steps.scan.outputs.grade }}
34
+
35
+ runs:
36
+ using: 'composite'
37
+ steps:
38
+ - name: Install drift
39
+ shell: bash
40
+ run: npm install -g @eduardbar/drift@${{ inputs.version }}
41
+
42
+ - name: Run drift scan
43
+ id: scan
44
+ shell: bash
45
+ run: |
46
+ TMPFILE=$(mktemp)
47
+
48
+ # Run scan — write JSON to tmp, progress to stderr (already separate)
49
+ drift scan ${{ inputs.path }} --ai > "$TMPFILE" 2>/dev/null || true
50
+
51
+ # Extract score and grade from AIOutput JSON
52
+ SCORE=$(node -e "const d=JSON.parse(require('fs').readFileSync('$TMPFILE','utf8')); console.log(d.summary.score)")
53
+ GRADE=$(node -e "const d=JSON.parse(require('fs').readFileSync('$TMPFILE','utf8')); console.log(d.summary.grade)")
54
+
55
+ rm "$TMPFILE"
56
+
57
+ echo "score=$SCORE" >> "$GITHUB_OUTPUT"
58
+ echo "grade=$GRADE" >> "$GITHUB_OUTPUT"
59
+
60
+ echo "Drift Score: $SCORE/100 ($GRADE)"
61
+
62
+ if [ "${{ inputs.fail-on-threshold }}" = "true" ] && [ "$SCORE" -gt "${{ inputs.min-score }}" ]; then
63
+ echo "::error::Drift score $SCORE/100 exceeds threshold of ${{ inputs.min-score }}"
64
+ exit 1
65
+ fi
@@ -0,0 +1,78 @@
1
+ name: Publish VS Code Extension
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ tags:
7
+ - 'vscode-v*'
8
+ workflow_dispatch:
9
+ inputs:
10
+ version:
11
+ description: 'Version to publish (e.g. 0.1.1)'
12
+ required: true
13
+ type: string
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ publish:
20
+ runs-on: ubuntu-latest
21
+ defaults:
22
+ run:
23
+ working-directory: packages/vscode-drift
24
+
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@v4
28
+ with:
29
+ ref: ${{ github.event_name == 'release' && github.ref || github.event.repository.default_branch }}
30
+
31
+ - name: Setup Node.js
32
+ uses: actions/setup-node@v4
33
+ with:
34
+ node-version: '20'
35
+ cache: 'npm'
36
+ cache-dependency-path: packages/vscode-drift/package-lock.json
37
+
38
+ - name: Verify version matches tag
39
+ if: github.event_name == 'release'
40
+ run: |
41
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
42
+ TAG_VERSION="${{ inputs.version }}"
43
+ else
44
+ TAG_VERSION="${GITHUB_REF#refs/tags/vscode-v}"
45
+ fi
46
+ PKG_VERSION=$(node -p "require('./package.json').version")
47
+ if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
48
+ echo "Error: Tag version ($TAG_VERSION) does not match package.json version ($PKG_VERSION)"
49
+ exit 1
50
+ fi
51
+ echo "Version check passed: $PKG_VERSION"
52
+
53
+ - name: Check if version already published
54
+ run: |
55
+ PKG_VERSION=$(node -p "require('./package.json').version")
56
+ PUBLISHED=$(npx @vscode/vsce show eduardbar.vscode-drift 2>&1 | grep "Version:" | awk '{print $2}' || echo "none")
57
+ if [ "$PUBLISHED" = "$PKG_VERSION" ]; then
58
+ echo "Version $PKG_VERSION already published on Marketplace. Skipping."
59
+ echo "skip_publish=true" >> $GITHUB_ENV
60
+ fi
61
+
62
+ - name: Install dependencies
63
+ if: env.skip_publish != 'true'
64
+ run: npm ci
65
+
66
+ - name: Build extension
67
+ if: env.skip_publish != 'true'
68
+ run: npm run build
69
+
70
+ - name: Package extension
71
+ if: env.skip_publish != 'true'
72
+ run: npx @vscode/vsce package --no-dependencies
73
+
74
+ - name: Publish to VS Code Marketplace
75
+ if: env.skip_publish != 'true'
76
+ run: npx @vscode/vsce publish --no-dependencies
77
+ env:
78
+ VSCE_PAT: ${{ secrets.VSCE_PAT }}
package/AGENTS.md CHANGED
@@ -20,6 +20,7 @@ Publicado en npm como `@eduardbar/drift`. MIT.
20
20
  | `kleur ^4` | Colores en consola (sin dependencias) |
21
21
  | `typescript ^5.9` | Dev — compilación |
22
22
  | `@types/node ^25` | Dev — tipos Node.js |
23
+ | `vitest ^4` | Testing |
23
24
 
24
25
  **Runtime:** Node.js 18+, ES Modules (`"type": "module"`).
25
26
 
@@ -32,18 +33,47 @@ drift/
32
33
  ├── bin/
33
34
  │ └── drift.js ← wrapper cross-platform (Windows npx fix)
34
35
  ├── src/
35
- │ ├── types.ts interfaces: DriftIssue, FileReport, DriftReport, AIOutput
36
- │ ├── analyzer.ts motor AST + 10 reglas de detección + drift-ignore
37
- │ ├── reporter.ts ← buildReport(), formatMarkdown(), formatAIOutput()
38
- │ ├── printer.ts ← salida consola con colores y score bar ASCII
39
- │ ├── utils.ts ← scoreToGrade, severityIcon, scoreBar
40
- │ ├── index.ts ← re-exports públicos (librería)
41
- └── cli.ts ← entry point Commander.js
42
- ├── assets/
43
- │ ├── og.svg / og.pngimagen OG original
44
- │ ├── og-v030-linkedin.svg/png imagen post LinkedIn v0.3.0
45
- └── og-v030-x.svg/png imagen hilo X v0.3.0
36
+ │ ├── analyzer.ts motor AST + 26 reglas + drift-ignore
37
+ │ ├── types.ts interfaces: DriftIssue, FileReport, DriftReport, AIOutput
38
+ │ ├── reporter.ts ← buildReport(), formatMarkdown(), formatAIOutput()
39
+ │ ├── printer.ts ← salida consola con colores y score bar ASCII
40
+ │ ├── utils.ts ← scoreToGrade, severityIcon, scoreBar
41
+ │ ├── index.ts ← re-exports públicos (librería)
42
+ ├── cli.ts ← entry point Commander.js
43
+ ├── config.ts ← drift.config.ts support
44
+ │ ├── fix.tsdrift fix command
45
+ │ ├── ci.ts drift ci command
46
+ ├── diff.ts drift diff command
47
+ │ ├── report.ts ← drift report command
48
+ │ ├── badge.ts ← drift badge command
49
+ │ ├── snapshot.ts ← drift snapshot command
50
+ │ ├── git.ts ← re-exports git analyzers
51
+ │ ├── git/
52
+ │ │ ├── trend.ts ← drift trend (historial de scores)
53
+ │ │ ├── blame.ts ← drift blame (atribución de deuda)
54
+ │ │ └── helpers.ts
55
+ │ └── rules/ ← reglas modularizadas por fase
56
+ │ ├── phase0-basic.ts
57
+ │ ├── phase1-complexity.ts
58
+ │ ├── phase2-crossfile.ts ← dead-file, unused-export, unused-dependency
59
+ │ ├── phase3-arch.ts ← circular-dependency, layer-violation
60
+ │ ├── phase5-ai.ts
61
+ │ ├── phase8-semantic.ts ← semantic-duplication
62
+ │ ├── complexity.ts
63
+ │ ├── coupling.ts
64
+ │ ├── nesting.ts
65
+ │ ├── promise.ts
66
+ │ ├── magic.ts
67
+ │ ├── comments.ts
68
+ │ └── shared.ts
69
+ ├── packages/
70
+ │ ├── eslint-plugin-drift/ ← ESLint plugin oficial
71
+ │ └── vscode-drift/ ← VS Code extension
46
72
  ├── dist/ ← output tsc (no editar a mano)
73
+ ├── assets/
74
+ │ ├── og.svg / og.png
75
+ │ ├── og-v030-linkedin.svg/png
76
+ │ └── og-v030-x.svg/png
47
77
  ├── .github/workflows/publish.yml
48
78
  ├── package.json
49
79
  ├── tsconfig.json
@@ -58,6 +88,8 @@ drift/
58
88
  npm run build # tsc — compila src/ → dist/
59
89
  npm run dev # tsc --watch
60
90
  npm start # node dist/cli.js (desarrollo local)
91
+ npm test # vitest run
92
+ npm run test:watch # vitest (watch mode)
61
93
  ```
62
94
 
63
95
  **Pre-publicación:** `prepublishOnly` corre `build` automáticamente.
@@ -88,18 +120,35 @@ npx @eduardbar/drift scan ./src -o report.md # exportar Markdown
88
120
 
89
121
  ## Reglas del analyzer
90
122
 
91
- | Regla | Severidad | Peso | Qué detecta |
92
- |-------|-----------|------|-------------|
93
- | `large-file` | error | 20 | Archivos > 300 líneas |
94
- | `large-function` | error | 15 | Funciones > 50 líneas |
95
- | `duplicate-function-name` | error | 18 | Nombres de función duplicados (case-insensitive) |
96
- | `debug-leftover` | warning | 10 | `console.log/warn/error` + `TODO/FIXME/HACK/XXX/TEMP` |
97
- | `catch-swallow` | warning | 10 | Bloques `catch {}` vacíos |
98
- | `dead-code` | warning | 8 | Imports nombrados sin usar |
99
- | `any-abuse` | warning | 8 | Uso explícito de `any` como tipo |
100
- | `comment-contradiction` | warning | 12 | (reservado — definido en RULE_WEIGHTS) |
101
- | `no-return-type` | info | 5 | Funciones sin tipo de retorno explícito |
102
- | `magic-number` | info | 3 | (reservado — definido en RULE_WEIGHTS) |
123
+ | Regla | Severidad | Peso |
124
+ |-------|-----------|------|
125
+ | `large-file` | error | 20 |
126
+ | `large-function` | error | 15 |
127
+ | `duplicate-function-name` | error | 18 |
128
+ | `high-complexity` | error | 15 |
129
+ | `circular-dependency` | error | 14 |
130
+ | `layer-violation` | error | 16 |
131
+ | `comment-contradiction` | warning | 12 |
132
+ | `deep-nesting` | warning | 12 |
133
+ | `semantic-duplication` | warning | 12 |
134
+ | `debug-leftover` | warning | 10 |
135
+ | `catch-swallow` | warning | 10 |
136
+ | `high-coupling` | warning | 10 |
137
+ | `dead-file` | warning | 10 |
138
+ | `hardcoded-config` | warning | 10 |
139
+ | `cross-boundary-import` | warning | 10 |
140
+ | `dead-code` | warning | 8 |
141
+ | `any-abuse` | warning | 8 |
142
+ | `too-many-params` | warning | 8 |
143
+ | `unused-export` | warning | 8 |
144
+ | `inconsistent-error-handling` | warning | 8 |
145
+ | `promise-style-mix` | warning | 7 |
146
+ | `unnecessary-abstraction` | warning | 7 |
147
+ | `naming-inconsistency` | warning | 6 |
148
+ | `unused-dependency` | warning | 6 |
149
+ | `no-return-type` | info | 5 |
150
+ | `over-commented` | info | 4 |
151
+ | `magic-number` | info | 3 |
103
152
 
104
153
  **Score = suma de pesos capped a 100. Score del proyecto = promedio de archivos.**
105
154
 
@@ -199,6 +248,7 @@ Sin esto, Windows no ejecuta el shebang correctamente con ES modules.
199
248
 
200
249
  | Versión | Cambios principales |
201
250
  |---------|---------------------|
251
+ | **1.0.0** | 26 reglas, 131 tests, modular rules, JS/JSX, drift fix/report/diff/ci/badge/trend/blame, VS Code extension |
202
252
  | **0.3.0** | `--ai` (LLM-optimized JSON output) + `--fix` (inline suggestions) |
203
253
  | **0.2.3** | Fix: bin wrapper para compatibilidad Windows npx |
204
254
  | **0.2.2** | Refactor: `formatMarkdown` dividido en helpers + fix CI doble publish |
@@ -208,6 +258,16 @@ Sin esto, Windows no ejecuta el shebang correctamente con ES modules.
208
258
 
209
259
  ---
210
260
 
261
+ ## Estado actual (feb 2026)
262
+
263
+ - **Versión publicada:** `1.0.0`
264
+ - **Branch:** `master`, sincronizado con `origin`
265
+ - **Self-scan score:** 5/100 (LOW)
266
+ - **Top issues:** 51× magic-number, 2× deep-nesting, 2× catch-swallow
267
+ - **26 reglas activas** organizadas en fases
268
+
269
+ ---
270
+
211
271
  ## Convenciones de código
212
272
 
213
273
  - Todo en TypeScript — sin `any` explícito (drift se corre sobre sí mismo)
package/README.md CHANGED
@@ -10,7 +10,7 @@ Detect technical debt in AI-generated TypeScript code. One command. Zero config.
10
10
  ![ts-morph](https://img.shields.io/badge/powered%20by-ts--morph-6366f1.svg)
11
11
  ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
12
12
 
13
- [Why](#why) · [Installation](#installation) · [Commands](#commands) · [Rules](#rules) · [Score](#score) · [Configuration](#configuration) · [CI Integration](#ci-integration) · [drift-ignore](#drift-ignore) · [Contributing](#contributing)
13
+ [Why](#why) · [Installation](#installation) · [Product Docs](#product-docs) · [Commands](#commands) · [Rules](#rules) · [Score](#score) · [Configuration](#configuration) · [CI Integration](#ci-integration) · [drift-ignore](#drift-ignore) · [Contributing](#contributing)
14
14
 
15
15
  ---
16
16
 
@@ -47,6 +47,13 @@ npm install --save-dev @eduardbar/drift
47
47
 
48
48
  ---
49
49
 
50
+ ## Product Docs
51
+
52
+ - Product requirements and roadmap: [`docs/PRD.md`](./docs/PRD.md)
53
+ - Contributor/agent workflow guide: [`docs/AGENTS.md`](./docs/AGENTS.md)
54
+
55
+ ---
56
+
50
57
  ## Commands
51
58
 
52
59
  ### `drift scan [path]`
@@ -121,6 +128,42 @@ Shows score delta, issues introduced, and issues resolved since the given ref.
121
128
 
122
129
  ---
123
130
 
131
+ ### `drift review`
132
+
133
+ Review drift against a git base ref and output a PR-ready markdown comment.
134
+
135
+ ```bash
136
+ drift review --base origin/main
137
+ drift review --base main --comment
138
+ drift review --base HEAD~3 --json
139
+ drift review --base origin/main --fail-on 5
140
+ ```
141
+
142
+ | Flag | Description |
143
+ |------|-------------|
144
+ | `--base <ref>` | Git base ref to compare against (default: `origin/main`) |
145
+ | `--json` | Output structured review JSON |
146
+ | `--comment` | Print only the markdown body for PR comments |
147
+ | `--fail-on <n>` | Exit code 1 when score delta is greater than or equal to `n` |
148
+
149
+ ---
150
+
151
+ ### `drift map [path]`
152
+
153
+ Generate an `architecture.svg` map with inferred layer dependencies.
154
+
155
+ ```bash
156
+ drift map
157
+ drift map ./src
158
+ drift map ./src --output docs/architecture.svg
159
+ ```
160
+
161
+ | Flag | Description |
162
+ |------|-------------|
163
+ | `--output <file>` | Output path for the SVG file (default: `architecture.svg`) |
164
+
165
+ ---
166
+
124
167
  ### `drift report [path]`
125
168
 
126
169
  Generate a self-contained HTML report. No server required — open in any browser.
@@ -220,6 +263,24 @@ drift blame file --top 10
220
263
 
221
264
  ---
222
265
 
266
+ ### `drift fix [path]`
267
+
268
+ Auto-fix safe issues with explicit preview/write modes.
269
+
270
+ ```bash
271
+ drift fix ./src --preview
272
+ drift fix ./src --write
273
+ drift fix ./src --dry-run # alias of --preview
274
+ ```
275
+
276
+ | Flag | Description |
277
+ |------|-------------|
278
+ | `--preview` | Preview before/after without writing files |
279
+ | `--write` | Apply fixes to disk |
280
+ | `--dry-run` | Backward-compatible alias for preview mode |
281
+
282
+ ---
283
+
223
284
  ## Rules
224
285
 
225
286
  26 rules across three severity levels. All run automatically unless marked as requiring configuration.
@@ -277,6 +338,12 @@ drift runs with zero configuration. Architectural rules (`layer-violation`, `cro
277
338
  import type { DriftConfig } from '@eduardbar/drift'
278
339
 
279
340
  export default {
341
+ plugins: ['drift-plugin-example'],
342
+ architectureRules: {
343
+ controllerNoDb: true,
344
+ serviceNoHttp: true,
345
+ maxFunctionLines: 80,
346
+ },
280
347
  layers: [
281
348
  { name: 'domain', patterns: ['src/domain/**'], canImportFrom: [] },
282
349
  { name: 'app', patterns: ['src/app/**'], canImportFrom: ['domain'] },
@@ -418,7 +485,7 @@ See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) before participating.
418
485
  | [`commander`](https://github.com/tj/commander.js) | CLI commands and flags |
419
486
  | [`kleur`](https://github.com/lukeed/kleur) | Terminal colors (zero dependencies) |
420
487
 
421
- **Runtime:** Node.js 18+ · TypeScript 5.x · ES Modules
488
+ **Runtime:** Node.js 18+ · TypeScript 5.x · ES Modules · Supports TypeScript (`.ts`, `.tsx`) and JavaScript (`.js`, `.jsx`) files
422
489
 
423
490
  ---
424
491