@eduardbar/drift 0.9.1 → 1.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/.github/workflows/publish-vscode.yml +76 -0
- package/AGENTS.md +30 -12
- package/README.md +1 -1
- package/ROADMAP.md +130 -98
- package/dist/analyzer.d.ts +4 -38
- package/dist/analyzer.js +85 -1543
- package/dist/cli.js +47 -4
- package/dist/config.js +1 -1
- package/dist/fix.d.ts +13 -0
- package/dist/fix.js +120 -0
- package/dist/git/blame.d.ts +22 -0
- package/dist/git/blame.js +227 -0
- package/dist/git/helpers.d.ts +36 -0
- package/dist/git/helpers.js +152 -0
- package/dist/git/trend.d.ts +21 -0
- package/dist/git/trend.js +80 -0
- package/dist/git.d.ts +0 -4
- package/dist/git.js +2 -2
- package/dist/report.js +620 -293
- package/dist/rules/phase0-basic.d.ts +11 -0
- package/dist/rules/phase0-basic.js +176 -0
- package/dist/rules/phase1-complexity.d.ts +31 -0
- package/dist/rules/phase1-complexity.js +277 -0
- package/dist/rules/phase2-crossfile.d.ts +27 -0
- package/dist/rules/phase2-crossfile.js +122 -0
- package/dist/rules/phase3-arch.d.ts +31 -0
- package/dist/rules/phase3-arch.js +148 -0
- package/dist/rules/phase5-ai.d.ts +8 -0
- package/dist/rules/phase5-ai.js +262 -0
- package/dist/rules/phase8-semantic.d.ts +22 -0
- package/dist/rules/phase8-semantic.js +109 -0
- package/dist/rules/shared.d.ts +7 -0
- package/dist/rules/shared.js +27 -0
- package/package.json +8 -3
- package/packages/vscode-drift/.vscodeignore +9 -0
- package/packages/vscode-drift/LICENSE +21 -0
- package/packages/vscode-drift/README.md +64 -0
- package/packages/vscode-drift/images/icon.png +0 -0
- package/packages/vscode-drift/images/icon.svg +30 -0
- package/packages/vscode-drift/package-lock.json +485 -0
- package/packages/vscode-drift/package.json +119 -0
- package/packages/vscode-drift/src/analyzer.ts +38 -0
- package/packages/vscode-drift/src/diagnostics.ts +55 -0
- package/packages/vscode-drift/src/extension.ts +111 -0
- package/packages/vscode-drift/src/statusbar.ts +47 -0
- package/packages/vscode-drift/src/treeview.ts +108 -0
- package/packages/vscode-drift/tsconfig.json +18 -0
- package/packages/vscode-drift/vscode-drift-0.1.0.vsix +0 -0
- package/packages/vscode-drift/vscode-drift-0.1.1.vsix +0 -0
- package/src/analyzer.ts +124 -1773
- package/src/cli.ts +53 -4
- package/src/config.ts +1 -1
- package/src/fix.ts +154 -0
- package/src/git/blame.ts +279 -0
- package/src/git/helpers.ts +198 -0
- package/src/git/trend.ts +116 -0
- package/src/git.ts +2 -2
- package/src/report.ts +631 -296
- package/src/rules/phase0-basic.ts +187 -0
- package/src/rules/phase1-complexity.ts +302 -0
- package/src/rules/phase2-crossfile.ts +149 -0
- package/src/rules/phase3-arch.ts +179 -0
- package/src/rules/phase5-ai.ts +292 -0
- package/src/rules/phase8-semantic.ts +132 -0
- package/src/rules/shared.ts +39 -0
- package/tests/helpers.ts +45 -0
- package/tests/rules.test.ts +1269 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Publish VS Code Extension
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
version:
|
|
9
|
+
description: 'Version to publish (e.g. 0.1.1)'
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
publish:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
defaults:
|
|
20
|
+
run:
|
|
21
|
+
working-directory: packages/vscode-drift
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: Checkout
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
|
+
with:
|
|
27
|
+
ref: ${{ github.event_name == 'release' && github.ref || github.event.repository.default_branch }}
|
|
28
|
+
|
|
29
|
+
- name: Setup Node.js
|
|
30
|
+
uses: actions/setup-node@v4
|
|
31
|
+
with:
|
|
32
|
+
node-version: '20'
|
|
33
|
+
cache: 'npm'
|
|
34
|
+
cache-dependency-path: packages/vscode-drift/package-lock.json
|
|
35
|
+
|
|
36
|
+
- name: Verify version matches tag
|
|
37
|
+
if: github.event_name == 'release'
|
|
38
|
+
run: |
|
|
39
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
40
|
+
TAG_VERSION="${{ inputs.version }}"
|
|
41
|
+
else
|
|
42
|
+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
43
|
+
fi
|
|
44
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
45
|
+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
|
46
|
+
echo "Error: Tag version ($TAG_VERSION) does not match package.json version ($PKG_VERSION)"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
echo "Version check passed: $PKG_VERSION"
|
|
50
|
+
|
|
51
|
+
- name: Check if version already published
|
|
52
|
+
run: |
|
|
53
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
54
|
+
PUBLISHED=$(npx @vscode/vsce show eduardbar.vscode-drift 2>&1 | grep "Version:" | awk '{print $2}' || echo "none")
|
|
55
|
+
if [ "$PUBLISHED" = "$PKG_VERSION" ]; then
|
|
56
|
+
echo "Version $PKG_VERSION already published on Marketplace. Skipping."
|
|
57
|
+
echo "skip_publish=true" >> $GITHUB_ENV
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
- name: Install dependencies
|
|
61
|
+
if: env.skip_publish != 'true'
|
|
62
|
+
run: npm ci
|
|
63
|
+
|
|
64
|
+
- name: Build extension
|
|
65
|
+
if: env.skip_publish != 'true'
|
|
66
|
+
run: npm run build
|
|
67
|
+
|
|
68
|
+
- name: Package extension
|
|
69
|
+
if: env.skip_publish != 'true'
|
|
70
|
+
run: npx @vscode/vsce package --no-dependencies
|
|
71
|
+
|
|
72
|
+
- name: Publish to VS Code Marketplace
|
|
73
|
+
if: env.skip_publish != 'true'
|
|
74
|
+
run: npx @vscode/vsce publish --no-dependencies
|
|
75
|
+
env:
|
|
76
|
+
VSCE_PAT: ${{ secrets.VSCE_PAT }}
|
package/AGENTS.md
CHANGED
|
@@ -88,18 +88,35 @@ npx @eduardbar/drift scan ./src -o report.md # exportar Markdown
|
|
|
88
88
|
|
|
89
89
|
## Reglas del analyzer
|
|
90
90
|
|
|
91
|
-
| Regla | Severidad | Peso |
|
|
92
|
-
|
|
93
|
-
| `large-file` | error | 20 |
|
|
94
|
-
| `large-function` | error | 15 |
|
|
95
|
-
| `duplicate-function-name` | error | 18 |
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
91
|
+
| Regla | Severidad | Peso |
|
|
92
|
+
|-------|-----------|------|
|
|
93
|
+
| `large-file` | error | 20 |
|
|
94
|
+
| `large-function` | error | 15 |
|
|
95
|
+
| `duplicate-function-name` | error | 18 |
|
|
96
|
+
| `high-complexity` | error | 15 |
|
|
97
|
+
| `circular-dependency` | error | 14 |
|
|
98
|
+
| `layer-violation` | error | 16 |
|
|
99
|
+
| `comment-contradiction` | warning | 12 |
|
|
100
|
+
| `deep-nesting` | warning | 12 |
|
|
101
|
+
| `semantic-duplication` | warning | 12 |
|
|
102
|
+
| `debug-leftover` | warning | 10 |
|
|
103
|
+
| `catch-swallow` | warning | 10 |
|
|
104
|
+
| `high-coupling` | warning | 10 |
|
|
105
|
+
| `dead-file` | warning | 10 |
|
|
106
|
+
| `hardcoded-config` | warning | 10 |
|
|
107
|
+
| `cross-boundary-import` | warning | 10 |
|
|
108
|
+
| `dead-code` | warning | 8 |
|
|
109
|
+
| `any-abuse` | warning | 8 |
|
|
110
|
+
| `too-many-params` | warning | 8 |
|
|
111
|
+
| `unused-export` | warning | 8 |
|
|
112
|
+
| `inconsistent-error-handling` | warning | 8 |
|
|
113
|
+
| `promise-style-mix` | warning | 7 |
|
|
114
|
+
| `unnecessary-abstraction` | warning | 7 |
|
|
115
|
+
| `naming-inconsistency` | warning | 6 |
|
|
116
|
+
| `unused-dependency` | warning | 6 |
|
|
117
|
+
| `no-return-type` | info | 5 |
|
|
118
|
+
| `over-commented` | info | 4 |
|
|
119
|
+
| `magic-number` | info | 3 |
|
|
103
120
|
|
|
104
121
|
**Score = suma de pesos capped a 100. Score del proyecto = promedio de archivos.**
|
|
105
122
|
|
|
@@ -199,6 +216,7 @@ Sin esto, Windows no ejecuta el shebang correctamente con ES modules.
|
|
|
199
216
|
|
|
200
217
|
| Versión | Cambios principales |
|
|
201
218
|
|---------|---------------------|
|
|
219
|
+
| **1.0.0** | 26 reglas, 131 tests, modular rules, JS/JSX, drift fix/report/diff/ci/badge/trend/blame, VS Code extension |
|
|
202
220
|
| **0.3.0** | `--ai` (LLM-optimized JSON output) + `--fix` (inline suggestions) |
|
|
203
221
|
| **0.2.3** | Fix: bin wrapper para compatibilidad Windows npx |
|
|
204
222
|
| **0.2.2** | Refactor: `formatMarkdown` dividido en helpers + fix CI doble publish |
|
package/README.md
CHANGED
|
@@ -418,7 +418,7 @@ See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) before participating.
|
|
|
418
418
|
| [`commander`](https://github.com/tj/commander.js) | CLI commands and flags |
|
|
419
419
|
| [`kleur`](https://github.com/lukeed/kleur) | Terminal colors (zero dependencies) |
|
|
420
420
|
|
|
421
|
-
**Runtime:** Node.js 18+ · TypeScript 5.x · ES Modules
|
|
421
|
+
**Runtime:** Node.js 18+ · TypeScript 5.x · ES Modules · Supports TypeScript (`.ts`, `.tsx`) and JavaScript (`.js`, `.jsx`) files
|
|
422
422
|
|
|
423
423
|
---
|
|
424
424
|
|
package/ROADMAP.md
CHANGED
|
@@ -42,165 +42,197 @@ drift's goal is to be the tool that sits between ESLint and SonarQube — lightw
|
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## Completed phases ✅
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
- Score 0–100 per file and project
|
|
49
|
-
- `--json`, `--ai` (LLM-optimized output), `--fix` (inline suggestions)
|
|
50
|
-
- `--min-score` for CI (exit 1 if score exceeds threshold)
|
|
51
|
-
- `drift-ignore` per line and per file
|
|
52
|
-
- Windows / Linux / macOS compatible via `npx`
|
|
47
|
+
### Phase 0 — Basic rules `v0.1.0` ✅
|
|
53
48
|
|
|
54
|
-
|
|
49
|
+
Foundation: AST analysis with ts-morph, score 0–100, `--json`, `--ai`, `--fix`, `--min-score`, `drift-ignore` per line and per file, Windows / Linux / macOS compatible via `npx`.
|
|
55
50
|
|
|
56
|
-
|
|
51
|
+
**Rules shipped:**
|
|
57
52
|
|
|
58
|
-
|
|
53
|
+
| Rule | Severity | Weight |
|
|
54
|
+
|------|----------|--------|
|
|
55
|
+
| `large-file` | error | 20 |
|
|
56
|
+
| `large-function` | error | 15 |
|
|
57
|
+
| `duplicate-function-name` | error | 18 |
|
|
58
|
+
| `debug-leftover` | warning | 10 |
|
|
59
|
+
| `dead-code` | warning | 8 |
|
|
60
|
+
| `any-abuse` | warning | 8 |
|
|
61
|
+
| `catch-swallow` | warning | 10 |
|
|
62
|
+
| `no-return-type` | info | 5 |
|
|
59
63
|
|
|
60
64
|
---
|
|
61
65
|
|
|
62
|
-
### 1
|
|
66
|
+
### Phase 1 — Complexity detection `v0.2.0` ✅
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
> — Hacker News
|
|
68
|
+
ESLint measures cyclomatic complexity per branch. drift measures cognitive load — how hard code is to *understand*. AI generates correct code, not simple code.
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
> — Hacker News, r/ExperiencedDevs
|
|
70
|
+
**Rules shipped:**
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
| Rule | Severity | Weight |
|
|
73
|
+
|------|----------|--------|
|
|
74
|
+
| `high-complexity` | error | 15 |
|
|
75
|
+
| `deep-nesting` | warning | 12 |
|
|
76
|
+
| `too-many-params` | warning | 8 |
|
|
77
|
+
| `high-coupling` | warning | 10 |
|
|
78
|
+
| `promise-style-mix` | warning | 7 |
|
|
79
|
+
| `magic-number` | info | 3 |
|
|
80
|
+
| `comment-contradiction` | warning | 12 |
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
- `high-complexity` — cyclomatic complexity > 10 per function
|
|
74
|
-
- `deep-nesting` — nesting depth > 3 levels (if inside if inside for inside try = unreadable)
|
|
75
|
-
- `too-many-params` — functions with more than 4 parameters (AI doesn't refactor into objects)
|
|
76
|
-
- `high-coupling` — files importing more than 10 distinct modules
|
|
77
|
-
- `promise-style-mix` — `async/await` and `.then()` mixed in the same file
|
|
82
|
+
---
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
### Phase 2 — Cross-file dead code `v0.3.0` ✅
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
ESLint detects unused variables inside a file. It cannot detect unused exports, dead files, or dead modules across a project — this is a fundamental architectural limitation (typescript-eslint issue #371, marked `wontfix`). drift builds a full import graph.
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
**Rules shipped:**
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
| Rule | Severity | What it detects |
|
|
91
|
+
|------|----------|-----------------|
|
|
92
|
+
| `unused-export` | warning | Exported symbol never imported anywhere in the project |
|
|
93
|
+
| `dead-file` | warning | File never imported by anything |
|
|
94
|
+
| `unused-dependency` | warning | Package in `package.json` with zero imports in the codebase |
|
|
87
95
|
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### Phase 3 — Architectural boundaries `v0.4.0` ✅
|
|
90
99
|
|
|
91
|
-
ESLint
|
|
100
|
+
Architecture violations are invisible until they're catastrophic. ESLint can validate import paths with `no-restricted-imports`. It cannot tell you if your UI layer is importing directly from your database layer, or if your domain logic has dependencies on your HTTP framework. AI generates code that works today and breaks your architecture silently.
|
|
92
101
|
|
|
93
|
-
**
|
|
94
|
-
- `unused-export` — exported symbol never imported anywhere in the project
|
|
95
|
-
- `dead-file` — file never imported by anything
|
|
96
|
-
- `unused-dependency` — package in `package.json` with zero imports in the codebase
|
|
102
|
+
**Rules shipped:**
|
|
97
103
|
|
|
98
|
-
|
|
104
|
+
| Rule | Severity | What it detects |
|
|
105
|
+
|------|----------|-----------------|
|
|
106
|
+
| `circular-dependency` | error | Module A depends on B which depends on A |
|
|
107
|
+
| `layer-violation` | error | Import from a prohibited architectural layer |
|
|
108
|
+
| `cross-boundary-import` | warning | Module outside its domain importing from another domain |
|
|
99
109
|
|
|
100
110
|
---
|
|
101
111
|
|
|
102
|
-
###
|
|
112
|
+
### Phase 5 — AI authorship heuristics `v0.6.0` ✅
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
> — Reddit, r/javascript
|
|
114
|
+
Patterns that are statistically more common in AI-generated code than human-written code. These don't fail tests. ESLint doesn't catch them. They accumulate until the codebase is unmaintainable.
|
|
106
115
|
|
|
107
|
-
|
|
116
|
+
**Rules shipped:**
|
|
108
117
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
| Rule | Severity | What it detects |
|
|
119
|
+
|------|----------|-----------------|
|
|
120
|
+
| `hardcoded-config` | warning | URLs, tokens, or env-specific paths hardcoded in logic |
|
|
121
|
+
| `inconsistent-error-handling` | warning | Different error handling patterns in equivalent functions |
|
|
122
|
+
| `unnecessary-abstraction` | warning | Class or interface used in exactly one place |
|
|
123
|
+
| `naming-inconsistency` | warning | Mixed naming conventions in the same module |
|
|
124
|
+
| `over-commented` | info | Comments that describe exactly what the code already says |
|
|
113
125
|
|
|
114
|
-
|
|
126
|
+
---
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
// drift.config.ts — optional
|
|
118
|
-
export default {
|
|
119
|
-
boundaries: {
|
|
120
|
-
layers: ['ui', 'domain', 'infrastructure'],
|
|
121
|
-
rules: [{ from: 'ui', allow: ['domain'] }]
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
128
|
+
### Phase 8 — Semantic duplication `v0.7.0` ✅
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
AI doesn't reuse — it regenerates. The same logic appears in 4 different forms across the same file. Text-comparison is what grep does. drift uses AST fingerprinting for Type-2 clone detection: structurally equivalent code regardless of variable names.
|
|
127
131
|
|
|
128
|
-
|
|
132
|
+
**Rules shipped:**
|
|
129
133
|
|
|
130
|
-
|
|
134
|
+
| Rule | Severity | What it detects |
|
|
135
|
+
|------|----------|-----------------|
|
|
136
|
+
| `semantic-duplication` | warning | Code blocks with equivalent logic via AST fingerprinting |
|
|
131
137
|
|
|
132
|
-
|
|
133
|
-
> — Reddit, r/devsecops
|
|
138
|
+
---
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
### Phase 4 — Historical analysis `v0.9.0` ✅
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
- `drift diff HEAD~N` — what got worse between two commits
|
|
139
|
-
- `drift trend --commits 30` — ASCII chart of score evolution over time
|
|
140
|
-
- `drift blame` — which commits introduced the most debt
|
|
142
|
+
A score of 45 means nothing without context. A score that went from 80 to 45 over 4 sprints means your team is actually improving. No database. No server. Git is the source of truth.
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
**Commands shipped:**
|
|
145
|
+
- `drift trend` — linear regression over project history with uniform sampling of 10 points
|
|
146
|
+
- `drift blame` — debt attribution by author via git blame
|
|
143
147
|
|
|
144
|
-
**
|
|
148
|
+
**v0.9.1 fix:** Full project snapshot per commit, uniform 10-point sampling for consistent trend lines.
|
|
145
149
|
|
|
146
150
|
---
|
|
147
151
|
|
|
148
|
-
|
|
152
|
+
## Current state — February 2026
|
|
149
153
|
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
- **26 rules active** across 9 detection categories
|
|
155
|
+
- **Self-scan score: 14/100 (LOW)**
|
|
156
|
+
- Published on npm as `@eduardbar/drift` — MIT, always free
|
|
157
|
+
- Cross-platform: Windows / Linux / macOS via `npx`
|
|
152
158
|
|
|
153
|
-
|
|
154
|
-
> — Reddit, r/vibecoding
|
|
159
|
+
---
|
|
155
160
|
|
|
156
|
-
|
|
161
|
+
## Path to v1.0.0 ✅
|
|
157
162
|
|
|
158
|
-
|
|
159
|
-
- `over-commented` — comments that describe exactly what the code already says (AI documents the obvious)
|
|
160
|
-
- `unnecessary-abstraction` — class or interface used in exactly one place (AI loves creating things it doesn't use)
|
|
161
|
-
- `hardcoded-config` — strings that look like URLs, tokens, or environment-specific paths hardcoded in logic
|
|
162
|
-
- `inconsistent-error-handling` — different error handling patterns in equivalent functions across the same file
|
|
163
|
+
### Unit test suite ✅
|
|
163
164
|
|
|
164
|
-
**
|
|
165
|
+
**Status:** complete
|
|
166
|
+
**Target:** vitest suite covering all 26 rules
|
|
167
|
+
|
|
168
|
+
Every rule needs at minimum: one test with a fixture that triggers the rule, one test with a fixture that doesn't. No rule ships without a test from v1.0.0 onward.
|
|
165
169
|
|
|
166
170
|
---
|
|
167
171
|
|
|
168
|
-
###
|
|
172
|
+
### Modular refactor ✅
|
|
173
|
+
|
|
174
|
+
**Status:** complete
|
|
175
|
+
**Target:** split `analyzer.ts` into `src/rules/*` and `src/git/*`
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
src/
|
|
179
|
+
├── rules/
|
|
180
|
+
│ ├── phase0*.ts
|
|
181
|
+
│ ├── phase1*.ts
|
|
182
|
+
│ ├── phase2*.ts
|
|
183
|
+
│ ├── phase3*.ts
|
|
184
|
+
│ ├── phase5*.ts
|
|
185
|
+
│ └── phase8*.ts
|
|
186
|
+
├── git/
|
|
187
|
+
│ ├── trend.ts
|
|
188
|
+
│ └── blame.ts
|
|
189
|
+
├── analyzer.ts ← orchestrator only, no rule logic
|
|
190
|
+
└── ...
|
|
191
|
+
```
|
|
169
192
|
|
|
170
|
-
|
|
171
|
-
> — Reddit, r/devsecops
|
|
193
|
+
---
|
|
172
194
|
|
|
173
|
-
|
|
195
|
+
### JavaScript / JSX support ✅
|
|
174
196
|
|
|
175
|
-
**
|
|
176
|
-
-
|
|
177
|
-
- `drift badge` — `badge.svg` with the current score for your README
|
|
178
|
-
- `drift ci` — GitHub Actions annotations on the exact lines with issues (inline in the PR diff)
|
|
197
|
+
**Status:** complete
|
|
198
|
+
**Target:** ts-morph can parse JS — extend scan to `.js` and `.jsx` files
|
|
179
199
|
|
|
180
200
|
---
|
|
181
201
|
|
|
182
|
-
###
|
|
202
|
+
### VS Code extension ✅
|
|
203
|
+
|
|
204
|
+
**Status:** complete
|
|
205
|
+
**Target:** extension that shows inline warnings directly in the editor
|
|
183
206
|
|
|
184
|
-
|
|
207
|
+
Published as `eduardbar.vscode-drift` v0.1.1.
|
|
185
208
|
|
|
186
|
-
|
|
187
|
-
- Compatible with ESLint 9 flat config
|
|
188
|
-
- The CLI remains canonical — the plugin is an integration path for teams already deep in ESLint
|
|
209
|
+
---
|
|
189
210
|
|
|
190
|
-
|
|
211
|
+
### `drift fix` — automated corrections ✅
|
|
212
|
+
|
|
213
|
+
**Status:** complete
|
|
214
|
+
**Target:** automatic application of simple fixes for low-effort rules
|
|
191
215
|
|
|
192
216
|
---
|
|
193
217
|
|
|
194
|
-
###
|
|
218
|
+
### Interactive HTML report ✅
|
|
195
219
|
|
|
196
|
-
|
|
197
|
-
|
|
220
|
+
**Status:** complete
|
|
221
|
+
**Target:** `drift report` command generates a self-contained `drift-report.html`
|
|
198
222
|
|
|
199
|
-
|
|
223
|
+
---
|
|
200
224
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
-
|
|
225
|
+
## v1.0.0 — Stable Release ✅
|
|
226
|
+
|
|
227
|
+
- [x] 26 detection rules across 6 phases
|
|
228
|
+
- [x] Full test coverage: 131 tests, all passing
|
|
229
|
+
- [x] Modular rule architecture: `src/rules/phase{0,1,2,3,5,8}*.ts`
|
|
230
|
+
- [x] JS/JSX support
|
|
231
|
+
- [x] `drift fix` auto-fix command
|
|
232
|
+
- [x] `drift report` HTML interactive report
|
|
233
|
+
- [x] `drift diff`, `drift ci`, `drift badge`, `drift trend`, `drift blame`
|
|
234
|
+
- [x] VS Code extension published (eduardbar.vscode-drift v0.1.1)
|
|
235
|
+
- [x] Self-scan score: 18/100 (LOW)
|
|
204
236
|
|
|
205
237
|
---
|
|
206
238
|
|
package/dist/analyzer.d.ts
CHANGED
|
@@ -1,44 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { DriftIssue, FileReport, DriftConfig } from './types.js';
|
|
2
|
+
export { TrendAnalyzer } from './git/trend.js';
|
|
3
|
+
export { BlameAnalyzer } from './git/blame.js';
|
|
3
4
|
export declare const RULE_WEIGHTS: Record<string, {
|
|
4
5
|
severity: DriftIssue['severity'];
|
|
5
6
|
weight: number;
|
|
6
7
|
}>;
|
|
7
|
-
export declare function analyzeFile(file: SourceFile): FileReport;
|
|
8
|
+
export declare function analyzeFile(file: import('ts-morph').SourceFile): FileReport;
|
|
8
9
|
export declare function analyzeProject(targetPath: string, config?: DriftConfig): FileReport[];
|
|
9
|
-
export declare class TrendAnalyzer {
|
|
10
|
-
private readonly projectPath;
|
|
11
|
-
private readonly config;
|
|
12
|
-
constructor(projectPath: string, config?: DriftConfig);
|
|
13
|
-
static calculateMovingAverage(data: TrendDataPoint[], windowSize: number): number[];
|
|
14
|
-
static linearRegression(data: TrendDataPoint[]): {
|
|
15
|
-
slope: number;
|
|
16
|
-
intercept: number;
|
|
17
|
-
r2: number;
|
|
18
|
-
};
|
|
19
|
-
/** Generate a simple horizontal ASCII bar chart (one bar per data point). */
|
|
20
|
-
static generateTrendChart(data: TrendDataPoint[]): string;
|
|
21
|
-
analyzeTrend(options: {
|
|
22
|
-
period?: 'week' | 'month' | 'quarter' | 'year';
|
|
23
|
-
since?: string;
|
|
24
|
-
until?: string;
|
|
25
|
-
}): Promise<DriftTrendReport>;
|
|
26
|
-
}
|
|
27
|
-
export declare class BlameAnalyzer {
|
|
28
|
-
private readonly projectPath;
|
|
29
|
-
private readonly config;
|
|
30
|
-
constructor(projectPath: string, config?: DriftConfig);
|
|
31
|
-
/** Blame a single file: returns per-author attribution. */
|
|
32
|
-
static analyzeFileBlame(filePath: string): Promise<BlameAttribution[]>;
|
|
33
|
-
/** Blame for a specific rule across all files in targetPath. */
|
|
34
|
-
static analyzeRuleBlame(rule: string, targetPath: string): Promise<BlameAttribution[]>;
|
|
35
|
-
/** Overall blame across all files and rules. */
|
|
36
|
-
static analyzeOverallBlame(targetPath: string): Promise<BlameAttribution[]>;
|
|
37
|
-
analyzeBlame(options: {
|
|
38
|
-
target?: 'file' | 'rule' | 'overall';
|
|
39
|
-
top?: number;
|
|
40
|
-
filePath?: string;
|
|
41
|
-
rule?: string;
|
|
42
|
-
}): Promise<DriftBlameReport>;
|
|
43
|
-
}
|
|
44
10
|
//# sourceMappingURL=analyzer.d.ts.map
|