tech-debt-score 0.1.5 → 0.1.6
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/dist/adapters/input/FileSystemReader.d.ts.map +1 -1
- package/dist/adapters/input/FileSystemReader.js +4 -5
- package/dist/adapters/input/FileSystemReader.js.map +1 -1
- package/dist/adapters/output/TerminalReporter.d.ts.map +1 -1
- package/dist/adapters/output/TerminalReporter.js +8 -0
- package/dist/adapters/output/TerminalReporter.js.map +1 -1
- package/dist/application/config/AnalysisConfig.d.ts.map +1 -1
- package/dist/application/config/AnalysisConfig.js +10 -2
- package/dist/application/config/AnalysisConfig.js.map +1 -1
- package/dist/application/services/AnalysisService.d.ts.map +1 -1
- package/dist/application/services/AnalysisService.js +29 -11
- package/dist/application/services/AnalysisService.js.map +1 -1
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +8 -7
- package/dist/cli/commands/analyze.js.map +1 -1
- package/package.json +8 -2
- package/DEVELOPMENT.md +0 -147
- package/SETUP_COMPLETE.md +0 -188
- package/TECHNICAL_DESIGN.md +0 -563
- package/src/adapters/input/FileSystemReader.ts +0 -47
- package/src/adapters/input/TypeScriptParser.ts +0 -367
- package/src/adapters/output/JsonExporter.ts +0 -48
- package/src/adapters/output/TerminalReporter.ts +0 -94
- package/src/application/config/AnalysisConfig.ts +0 -58
- package/src/application/ports/IFileReader.ts +0 -36
- package/src/application/ports/IParser.ts +0 -40
- package/src/application/ports/IReporter.ts +0 -26
- package/src/application/services/AnalysisService.ts +0 -218
- package/src/application/services/DependencyAnalyzer.ts +0 -158
- package/src/application/services/DuplicationDetector.ts +0 -207
- package/src/cli/commands/analyze.ts +0 -77
- package/src/cli/index.ts +0 -81
- package/src/domain/entities/Finding.ts +0 -79
- package/src/domain/entities/Metric.ts +0 -70
- package/src/domain/entities/Rule.ts +0 -49
- package/src/domain/entities/Score.ts +0 -94
- package/src/domain/index.ts +0 -15
- package/src/domain/rules/CircularDependencyRule.ts +0 -65
- package/src/domain/rules/ComplexityRule.ts +0 -88
- package/src/domain/rules/DuplicationRule.ts +0 -70
- package/src/domain/rules/SizeRule.ts +0 -98
- package/src/domain/rules/TypeSafetyRule.ts +0 -63
- package/src/index.ts +0 -0
- package/src/shared/types.ts +0 -18
- package/tests/application/index.test.ts +0 -12
- package/tests/domain/index.test.ts +0 -14
- package/tests/e2e/index.test.ts +0 -13
- package/tsconfig.json +0 -31
package/TECHNICAL_DESIGN.md
DELETED
|
@@ -1,563 +0,0 @@
|
|
|
1
|
-
# Technical Design Document: tech-debt-score
|
|
2
|
-
|
|
3
|
-
> **Version:** 1.0
|
|
4
|
-
> **Last Updated:** 2026-01-20
|
|
5
|
-
> **Status:** Design Phase
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Table of Contents
|
|
10
|
-
|
|
11
|
-
1. [Overview](#overview)
|
|
12
|
-
2. [Goals and Non-Goals](#goals-and-non-goals)
|
|
13
|
-
3. [Supported Languages and Scope](#supported-languages-and-scope)
|
|
14
|
-
4. [Metrics Specification](#metrics-specification)
|
|
15
|
-
5. [Architecture](#architecture)
|
|
16
|
-
6. [Directory Structure](#directory-structure)
|
|
17
|
-
7. [Data Flow](#data-flow)
|
|
18
|
-
8. [Implementation Guidelines](#implementation-guidelines)
|
|
19
|
-
9. [Future Considerations](#future-considerations)
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Overview
|
|
24
|
-
|
|
25
|
-
`tech-debt-score` is an open-source CLI tool and analysis engine that quantifies technical debt in a codebase using a single, actionable score (0-100).
|
|
26
|
-
|
|
27
|
-
### Key Principles
|
|
28
|
-
|
|
29
|
-
- **Developer-focused**: Built by developers, for developers
|
|
30
|
-
- **Actionable over comprehensive**: Measures what teams can control
|
|
31
|
-
- **AST-based analysis**: No regex, language-aware parsing
|
|
32
|
-
- **Clean architecture**: Hexagonal/Ports & Adapters pattern
|
|
33
|
-
- **CI-friendly**: Easy integration into automated workflows
|
|
34
|
-
|
|
35
|
-
### Value Proposition
|
|
36
|
-
|
|
37
|
-
Unlike traditional tools that focus on lint errors and code smells, `tech-debt-score` answers critical questions:
|
|
38
|
-
- *How bad is our technical debt, really?*
|
|
39
|
-
- *Is it getting better or worse over time?*
|
|
40
|
-
- *Where should we focus first?*
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Goals and Non-Goals
|
|
45
|
-
|
|
46
|
-
### ✅ Goals (V1)
|
|
47
|
-
|
|
48
|
-
- Provide a **normalized 0-100 technical debt score**
|
|
49
|
-
- Measure **team-controllable factors** only
|
|
50
|
-
- Support **TypeScript and JavaScript** codebases
|
|
51
|
-
- Generate **human-readable and JSON reports**
|
|
52
|
-
- Enable **trend tracking** over time
|
|
53
|
-
- Maintain **fast execution** and minimal configuration
|
|
54
|
-
|
|
55
|
-
### ❌ Non-Goals (V1)
|
|
56
|
-
|
|
57
|
-
- Deprecated dependencies detection
|
|
58
|
-
- Security vulnerability scanning
|
|
59
|
-
- Runtime performance analysis
|
|
60
|
-
- External API/service health checks
|
|
61
|
-
- Supporting languages beyond JS/TS
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## Supported Languages and Scope
|
|
66
|
-
|
|
67
|
-
### Supported Languages
|
|
68
|
-
|
|
69
|
-
- **TypeScript** (`.ts` files)
|
|
70
|
-
- **JavaScript** (`.js` files)
|
|
71
|
-
|
|
72
|
-
### Default File Patterns
|
|
73
|
-
|
|
74
|
-
**Analyzed:**
|
|
75
|
-
- `src/**/*.ts`
|
|
76
|
-
- `src/**/*.js`
|
|
77
|
-
|
|
78
|
-
**Ignored:**
|
|
79
|
-
- `node_modules/`
|
|
80
|
-
- `dist/`
|
|
81
|
-
- `build/`
|
|
82
|
-
- `coverage/`
|
|
83
|
-
- `.git/`
|
|
84
|
-
- Generated files
|
|
85
|
-
|
|
86
|
-
### Future Configuration
|
|
87
|
-
|
|
88
|
-
CLI flags will allow customization of these patterns.
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## Metrics Specification
|
|
93
|
-
|
|
94
|
-
### 1. Structural Code Metrics (AST-based)
|
|
95
|
-
|
|
96
|
-
**Implementation Approach:** All metrics use AST parsing (not regex) for accuracy.
|
|
97
|
-
|
|
98
|
-
#### File-Level Metrics
|
|
99
|
-
|
|
100
|
-
| Metric | Description | Purpose |
|
|
101
|
-
|--------|-------------|---------|
|
|
102
|
-
| **File Length (LOC)** | Lines of code per file | Identify overly large files |
|
|
103
|
-
| **TODO Comments** | Count of `// TODO` comments | Track deferred work |
|
|
104
|
-
| **FIXME Comments** | Count of `// FIXME` comments | Track known issues |
|
|
105
|
-
|
|
106
|
-
#### Function-Level Metrics
|
|
107
|
-
|
|
108
|
-
| Metric | Description | Purpose |
|
|
109
|
-
|--------|-------------|---------|
|
|
110
|
-
| **Function Length** | Lines of code per function | Identify complex functions |
|
|
111
|
-
| **Nesting Depth** | Maximum nesting level | Measure code complexity |
|
|
112
|
-
| **Cyclomatic Complexity** | Number of decision paths | Measure testability |
|
|
113
|
-
| **Parameter Count** | Number of function parameters | Identify hard-to-use functions |
|
|
114
|
-
|
|
115
|
-
#### TypeScript-Specific Metrics
|
|
116
|
-
|
|
117
|
-
| Metric | Description | Purpose |
|
|
118
|
-
|--------|-------------|---------|
|
|
119
|
-
| **`any` Usage** | Usage of the `any` type | Track type safety violations |
|
|
120
|
-
|
|
121
|
-
### 2. Project-Level Signals (Aggregated)
|
|
122
|
-
|
|
123
|
-
These provide the "big picture" view:
|
|
124
|
-
|
|
125
|
-
| Signal | Calculation | Purpose |
|
|
126
|
-
|--------|-------------|---------|
|
|
127
|
-
| **Total Files** | Count of analyzed files | Scope indicator |
|
|
128
|
-
| **Average Complexity** | Mean complexity per file | Overall health indicator |
|
|
129
|
-
| **Large Files %** | Percentage of files exceeding threshold | Hotspot identification |
|
|
130
|
-
| **Complex Functions %** | Percentage of functions exceeding threshold | Risk assessment |
|
|
131
|
-
|
|
132
|
-
### 3. Scoring Algorithm (High-Level)
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
1. Collect raw metrics per file
|
|
136
|
-
2. Normalize metrics to 0-100 scale
|
|
137
|
-
3. Apply category weights:
|
|
138
|
-
- Complexity: 30%
|
|
139
|
-
- Size: 25%
|
|
140
|
-
- Type Safety: 20%
|
|
141
|
-
- Code Quality: 15%
|
|
142
|
-
- Structure: 10%
|
|
143
|
-
4. Calculate weighted average
|
|
144
|
-
5. Generate final score (inverse: 100 = no debt)
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## Architecture
|
|
150
|
-
|
|
151
|
-
### Architectural Style
|
|
152
|
-
|
|
153
|
-
**Hexagonal Architecture (Ports & Adapters)**
|
|
154
|
-
|
|
155
|
-
This pattern ensures:
|
|
156
|
-
- Clear separation of concerns
|
|
157
|
-
- High testability
|
|
158
|
-
- Easy adapter swapping
|
|
159
|
-
- Framework independence
|
|
160
|
-
|
|
161
|
-
### Layer Definitions
|
|
162
|
-
|
|
163
|
-
```
|
|
164
|
-
┌─────────────────────────────────────────┐
|
|
165
|
-
│ CLI Adapter (Entry) │
|
|
166
|
-
│ (No Business Logic) │
|
|
167
|
-
└─────────────────┬───────────────────────┘
|
|
168
|
-
│
|
|
169
|
-
┌─────────────────▼───────────────────────┐
|
|
170
|
-
│ Application Layer │
|
|
171
|
-
│ - Orchestrates analysis │
|
|
172
|
-
│ - Applies rules │
|
|
173
|
-
│ - Aggregates scores │
|
|
174
|
-
└─────┬───────────────────────┬───────────┘
|
|
175
|
-
│ │
|
|
176
|
-
┌─────▼─────────┐ ┌────────▼──────────┐
|
|
177
|
-
│ Input Adapters│ │ Output Adapters │
|
|
178
|
-
│ - File Reader │ │ - Terminal Report │
|
|
179
|
-
│ - AST Parser │ │ - JSON Exporter │
|
|
180
|
-
└─────┬─────────┘ └────────┬──────────┘
|
|
181
|
-
│ │
|
|
182
|
-
└───────────┬───────────┘
|
|
183
|
-
│
|
|
184
|
-
┌─────────▼──────────┐
|
|
185
|
-
│ Domain Layer │
|
|
186
|
-
│ (Pure Logic) │
|
|
187
|
-
│ - Score │
|
|
188
|
-
│ - Metric │
|
|
189
|
-
│ - Rule │
|
|
190
|
-
│ - Finding │
|
|
191
|
-
└────────────────────┘
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Layer Details
|
|
195
|
-
|
|
196
|
-
#### 1. Domain Layer (Pure Logic)
|
|
197
|
-
|
|
198
|
-
**Core Entities:**
|
|
199
|
-
- `Score` - Represents technical debt scores and calculations
|
|
200
|
-
- `Metric` - Individual measurement data
|
|
201
|
-
- `Rule` - Evaluation and scoring rules
|
|
202
|
-
- `Finding` - Identified code issues
|
|
203
|
-
|
|
204
|
-
**Constraints:**
|
|
205
|
-
- ❌ No filesystem access
|
|
206
|
-
- ❌ No CLI dependencies
|
|
207
|
-
- ❌ No Node.js APIs
|
|
208
|
-
- ❌ No external libraries (except utility functions)
|
|
209
|
-
- ✅ Pure TypeScript/JavaScript logic only
|
|
210
|
-
- ✅ 100% unit testable
|
|
211
|
-
|
|
212
|
-
**Example Domain Interfaces:**
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
interface Metric {
|
|
216
|
-
name: string;
|
|
217
|
-
value: number;
|
|
218
|
-
filePath: string;
|
|
219
|
-
location?: SourceLocation;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
interface Rule {
|
|
223
|
-
id: string;
|
|
224
|
-
name: string;
|
|
225
|
-
evaluate(metrics: Metric[]): Finding[];
|
|
226
|
-
calculateScore(findings: Finding[]): number;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
interface Score {
|
|
230
|
-
overall: number; // 0-100
|
|
231
|
-
categories: CategoryScore[];
|
|
232
|
-
timestamp: Date;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
interface Finding {
|
|
236
|
-
ruleId: string;
|
|
237
|
-
severity: 'low' | 'medium' | 'high';
|
|
238
|
-
message: string;
|
|
239
|
-
filePath: string;
|
|
240
|
-
location?: SourceLocation;
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
#### 2. Application Layer (Use Cases)
|
|
245
|
-
|
|
246
|
-
**Responsibilities:**
|
|
247
|
-
- Orchestrate the analysis workflow
|
|
248
|
-
- Coordinate between domain and adapters
|
|
249
|
-
- Apply business rules
|
|
250
|
-
- Aggregate results
|
|
251
|
-
|
|
252
|
-
**Example Services:**
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
class AnalysisService {
|
|
256
|
-
constructor(
|
|
257
|
-
private fileReader: IFileReader,
|
|
258
|
-
private parser: IParser,
|
|
259
|
-
private rules: Rule[]
|
|
260
|
-
) {}
|
|
261
|
-
|
|
262
|
-
async analyze(config: AnalysisConfig): Promise<AnalysisResult> {
|
|
263
|
-
// 1. Read files
|
|
264
|
-
// 2. Parse to AST
|
|
265
|
-
// 3. Extract metrics
|
|
266
|
-
// 4. Apply rules
|
|
267
|
-
// 5. Calculate scores
|
|
268
|
-
// 6. Return results
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
#### 3. Adapters Layer (External Interfaces)
|
|
274
|
-
|
|
275
|
-
##### Input Adapters (Inbound Ports)
|
|
276
|
-
|
|
277
|
-
**File System Reader:**
|
|
278
|
-
- Scans directories
|
|
279
|
-
- Filters files by patterns
|
|
280
|
-
- Respects ignore rules
|
|
281
|
-
- Returns file metadata
|
|
282
|
-
|
|
283
|
-
**AST Parser:**
|
|
284
|
-
- Parses TypeScript/JavaScript
|
|
285
|
-
- Extracts structural information
|
|
286
|
-
- Handles syntax errors gracefully
|
|
287
|
-
- Technology: `@typescript-eslint/parser`, `@babel/parser`, or `acorn`
|
|
288
|
-
|
|
289
|
-
##### Output Adapters (Outbound Ports)
|
|
290
|
-
|
|
291
|
-
**Terminal Reporter:**
|
|
292
|
-
- Formats results for console
|
|
293
|
-
- Uses colors and formatting
|
|
294
|
-
- Provides actionable output
|
|
295
|
-
- Technology: `chalk`, `cli-table3`
|
|
296
|
-
|
|
297
|
-
**JSON Exporter:**
|
|
298
|
-
- Exports structured data
|
|
299
|
-
- CI/CD friendly format
|
|
300
|
-
- Version-stamped output
|
|
301
|
-
|
|
302
|
-
#### 4. Entry Point
|
|
303
|
-
|
|
304
|
-
**CLI Adapter:**
|
|
305
|
-
- Parses command-line arguments
|
|
306
|
-
- Maps to application commands
|
|
307
|
-
- Handles errors and exit codes
|
|
308
|
-
- **No business logic**
|
|
309
|
-
- Technology: `commander` or `yargs`
|
|
310
|
-
|
|
311
|
-
### Dependency Rules
|
|
312
|
-
|
|
313
|
-
**The Dependency Rule:** Dependencies point **inward only**
|
|
314
|
-
|
|
315
|
-
```
|
|
316
|
-
CLI → Application → Domain
|
|
317
|
-
↓
|
|
318
|
-
Adapters (depend on Domain interfaces)
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
- Domain layer has **zero dependencies**
|
|
322
|
-
- Application layer depends on **Domain only**
|
|
323
|
-
- Adapters depend on **Domain interfaces**
|
|
324
|
-
- CLI depends on **Application and Adapters**
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Directory Structure
|
|
329
|
-
|
|
330
|
-
```
|
|
331
|
-
tech-debt-score/
|
|
332
|
-
├── src/
|
|
333
|
-
│ ├── domain/ # Pure business logic
|
|
334
|
-
│ │ ├── entities/
|
|
335
|
-
│ │ │ ├── Score.ts
|
|
336
|
-
│ │ │ ├── Metric.ts
|
|
337
|
-
│ │ │ ├── Rule.ts
|
|
338
|
-
│ │ │ └── Finding.ts
|
|
339
|
-
│ │ ├── rules/ # Scoring rules
|
|
340
|
-
│ │ │ ├── ComplexityRule.ts
|
|
341
|
-
│ │ │ ├── SizeRule.ts
|
|
342
|
-
│ │ │ └── TypeSafetyRule.ts
|
|
343
|
-
│ │ └── services/
|
|
344
|
-
│ │ └── ScoreCalculator.ts
|
|
345
|
-
│ │
|
|
346
|
-
│ ├── application/ # Use cases & orchestration
|
|
347
|
-
│ │ ├── services/
|
|
348
|
-
│ │ │ └── AnalysisService.ts
|
|
349
|
-
│ │ ├── ports/ # Interface definitions
|
|
350
|
-
│ │ │ ├── IFileReader.ts
|
|
351
|
-
│ │ │ ├── IParser.ts
|
|
352
|
-
│ │ │ └── IReporter.ts
|
|
353
|
-
│ │ └── config/
|
|
354
|
-
│ │ └── AnalysisConfig.ts
|
|
355
|
-
│ │
|
|
356
|
-
│ ├── adapters/ # External integrations
|
|
357
|
-
│ │ ├── input/
|
|
358
|
-
│ │ │ ├── FileSystemReader.ts
|
|
359
|
-
│ │ │ └── TypeScriptParser.ts
|
|
360
|
-
│ │ └── output/
|
|
361
|
-
│ │ ├── TerminalReporter.ts
|
|
362
|
-
│ │ └── JsonExporter.ts
|
|
363
|
-
│ │
|
|
364
|
-
│ ├── cli/ # Command-line interface
|
|
365
|
-
│ │ ├── index.ts # Entry point
|
|
366
|
-
│ │ └── commands/
|
|
367
|
-
│ │ └── analyze.ts
|
|
368
|
-
│ │
|
|
369
|
-
│ └── shared/ # Shared utilities
|
|
370
|
-
│ ├── types.ts
|
|
371
|
-
│ └── utils.ts
|
|
372
|
-
│
|
|
373
|
-
├── tests/
|
|
374
|
-
│ ├── domain/ # Unit tests (no I/O)
|
|
375
|
-
│ ├── application/ # Integration tests
|
|
376
|
-
│ └── e2e/ # End-to-end tests
|
|
377
|
-
│
|
|
378
|
-
├── docs/
|
|
379
|
-
├── package.json
|
|
380
|
-
├── tsconfig.json
|
|
381
|
-
└── README.md
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
---
|
|
385
|
-
|
|
386
|
-
## Data Flow
|
|
387
|
-
|
|
388
|
-
### Analysis Flow
|
|
389
|
-
|
|
390
|
-
```
|
|
391
|
-
1. User runs CLI command
|
|
392
|
-
↓
|
|
393
|
-
2. CLI adapter parses arguments
|
|
394
|
-
↓
|
|
395
|
-
3. Application layer receives config
|
|
396
|
-
↓
|
|
397
|
-
4. FileReader adapter scans files
|
|
398
|
-
↓
|
|
399
|
-
5. Parser adapter generates ASTs
|
|
400
|
-
↓
|
|
401
|
-
6. Application extracts Metrics
|
|
402
|
-
↓
|
|
403
|
-
7. Domain Rules evaluate Metrics → Findings
|
|
404
|
-
↓
|
|
405
|
-
8. Domain ScoreCalculator → Score
|
|
406
|
-
↓
|
|
407
|
-
9. Application returns AnalysisResult
|
|
408
|
-
↓
|
|
409
|
-
10. Reporter adapter formats output
|
|
410
|
-
↓
|
|
411
|
-
11. CLI displays results
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
### Data Structures
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
// Input
|
|
418
|
-
AnalysisConfig {
|
|
419
|
-
rootPath: string;
|
|
420
|
-
patterns: string[];
|
|
421
|
-
ignore: string[];
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Processing
|
|
425
|
-
File[] → AST[] → Metric[] → Finding[] → Score
|
|
426
|
-
|
|
427
|
-
// Output
|
|
428
|
-
AnalysisResult {
|
|
429
|
-
score: Score;
|
|
430
|
-
findings: Finding[];
|
|
431
|
-
metadata: {
|
|
432
|
-
filesAnalyzed: number;
|
|
433
|
-
duration: number;
|
|
434
|
-
timestamp: Date;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
## Implementation Guidelines
|
|
442
|
-
|
|
443
|
-
### Technology Stack
|
|
444
|
-
|
|
445
|
-
- **Language:** TypeScript
|
|
446
|
-
- **Runtime:** Node.js (v18+)
|
|
447
|
-
- **Package Manager:** npm
|
|
448
|
-
- **Build Tool:** tsc (TypeScript compiler)
|
|
449
|
-
|
|
450
|
-
### Recommended Libraries
|
|
451
|
-
|
|
452
|
-
| Purpose | Library | Why |
|
|
453
|
-
|---------|---------|-----|
|
|
454
|
-
| AST Parsing | `@typescript-eslint/parser` | TypeScript support |
|
|
455
|
-
| JS Parsing | `@babel/parser` or `acorn` | JavaScript support |
|
|
456
|
-
| File Scanning | `fast-glob` | Fast pattern matching |
|
|
457
|
-
| CLI Framework | `commander` | Intuitive API |
|
|
458
|
-
| Terminal Output | `chalk` + `cli-table3` | Beautiful formatting |
|
|
459
|
-
| Testing | `vitest` or `jest` | Fast, modern testing |
|
|
460
|
-
|
|
461
|
-
### Code Quality Standards
|
|
462
|
-
|
|
463
|
-
- **TypeScript strict mode:** Enabled
|
|
464
|
-
- **No `any` types** in core codebase (except adapters if needed)
|
|
465
|
-
- **100% test coverage** for domain layer
|
|
466
|
-
- **ESLint + Prettier** for consistency
|
|
467
|
-
- **Clear error messages** for users
|
|
468
|
-
|
|
469
|
-
### Testing Strategy
|
|
470
|
-
|
|
471
|
-
1. **Unit Tests** (Domain layer)
|
|
472
|
-
- Test pure functions
|
|
473
|
-
- No mocks needed (no I/O)
|
|
474
|
-
- Fast execution
|
|
475
|
-
|
|
476
|
-
2. **Integration Tests** (Application layer)
|
|
477
|
-
- Test with mock adapters
|
|
478
|
-
- Verify orchestration logic
|
|
479
|
-
|
|
480
|
-
3. **E2E Tests**
|
|
481
|
-
- Test real codebases
|
|
482
|
-
- Verify actual output
|
|
483
|
-
- Performance benchmarks
|
|
484
|
-
|
|
485
|
-
---
|
|
486
|
-
|
|
487
|
-
## Future Considerations
|
|
488
|
-
|
|
489
|
-
### V2 Features (Potential)
|
|
490
|
-
|
|
491
|
-
- **Additional Languages:** Python, Go, Java
|
|
492
|
-
- **Code Duplication Detection:** AST-based clone detection
|
|
493
|
-
- **Test Coverage Integration:** Parse coverage reports
|
|
494
|
-
- **Custom Rules:** User-defined scoring rules
|
|
495
|
-
- **Configuration File:** `.tech-debt-score.json`
|
|
496
|
-
- **Git Integration:** Track score over commits
|
|
497
|
-
- **Web Dashboard:** Visualize trends
|
|
498
|
-
- **IDE Extensions:** VS Code, IntelliJ
|
|
499
|
-
- **CI Platform Integrations:** GitHub Actions, GitLab CI
|
|
500
|
-
|
|
501
|
-
### Scalability Considerations
|
|
502
|
-
|
|
503
|
-
- **Caching:** Cache AST parsing results
|
|
504
|
-
- **Parallelization:** Process files in parallel
|
|
505
|
-
- **Incremental Analysis:** Only analyze changed files
|
|
506
|
-
- **Large Codebases:** Stream processing for memory efficiency
|
|
507
|
-
|
|
508
|
-
### Extensibility Points
|
|
509
|
-
|
|
510
|
-
The architecture supports:
|
|
511
|
-
- New input adapters (e.g., read from Git, API)
|
|
512
|
-
- New output adapters (e.g., HTML report, database)
|
|
513
|
-
- New parsing adapters (e.g., Python, Go)
|
|
514
|
-
- New rules (plugin system)
|
|
515
|
-
- Different scoring algorithms
|
|
516
|
-
|
|
517
|
-
---
|
|
518
|
-
|
|
519
|
-
## Questions & Decisions Log
|
|
520
|
-
|
|
521
|
-
### Open Questions
|
|
522
|
-
|
|
523
|
-
1. **Scoring thresholds:** What defines a "large file" or "complex function"?
|
|
524
|
-
- Proposal: Configurable, with sensible defaults (e.g., 300 LOC, cyclomatic > 10)
|
|
525
|
-
|
|
526
|
-
2. **Weighting system:** How to balance different metric categories?
|
|
527
|
-
- Proposal: Start with equal weights, tune based on user feedback
|
|
528
|
-
|
|
529
|
-
3. **Trend storage:** Where to store historical scores?
|
|
530
|
-
- Proposal: V1 outputs JSON, users can track; V2 adds built-in storage
|
|
531
|
-
|
|
532
|
-
### Decisions Made
|
|
533
|
-
|
|
534
|
-
- ✅ **Architecture:** Hexagonal/Ports & Adapters (2026-01-20)
|
|
535
|
-
- ✅ **Languages (V1):** TypeScript and JavaScript only (2026-01-20)
|
|
536
|
-
- ✅ **Analysis Method:** AST-based, no regex (2026-01-20)
|
|
537
|
-
- ✅ **Scope (V1):** Team-controllable metrics only (2026-01-20)
|
|
538
|
-
|
|
539
|
-
---
|
|
540
|
-
|
|
541
|
-
## Appendix
|
|
542
|
-
|
|
543
|
-
### References
|
|
544
|
-
|
|
545
|
-
- [Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/)
|
|
546
|
-
- [AST Explorer](https://astexplorer.net/) - For testing AST parsing
|
|
547
|
-
- [TypeScript Compiler API](https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API)
|
|
548
|
-
- [Cyclomatic Complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity)
|
|
549
|
-
|
|
550
|
-
### Contributors
|
|
551
|
-
|
|
552
|
-
- Initial Design: 2026-01-20
|
|
553
|
-
|
|
554
|
-
---
|
|
555
|
-
|
|
556
|
-
**Next Steps:**
|
|
557
|
-
1. Review and approve this design
|
|
558
|
-
2. Set up project structure
|
|
559
|
-
3. Implement domain layer (pure logic)
|
|
560
|
-
4. Implement AST parser adapter
|
|
561
|
-
5. Build CLI and reporting
|
|
562
|
-
6. Add comprehensive tests
|
|
563
|
-
7. Package and publish
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Input Adapter: File System Reader
|
|
3
|
-
* Implements IFileReader using Node.js filesystem
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { readFile } from 'node:fs/promises';
|
|
7
|
-
import { stat } from 'node:fs/promises';
|
|
8
|
-
import { resolve, join } from 'node:path';
|
|
9
|
-
import fg from 'fast-glob';
|
|
10
|
-
import type { IFileReader, FileReadResult } from '../../application/ports/IFileReader.js';
|
|
11
|
-
|
|
12
|
-
export class FileSystemReader implements IFileReader {
|
|
13
|
-
async scan(rootPath: string, patterns: string[], ignore: string[]): Promise<string[]> {
|
|
14
|
-
// Resolve the root path to absolute
|
|
15
|
-
const absoluteRoot = resolve(rootPath);
|
|
16
|
-
|
|
17
|
-
// Scan for files using cwd - this is more robust for glob matching
|
|
18
|
-
const files = await fg(patterns, {
|
|
19
|
-
cwd: absoluteRoot,
|
|
20
|
-
ignore,
|
|
21
|
-
absolute: true,
|
|
22
|
-
onlyFiles: true,
|
|
23
|
-
dot: false,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return files;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async read(filePath: string): Promise<FileReadResult> {
|
|
30
|
-
const content = await readFile(filePath, 'utf-8');
|
|
31
|
-
const stats = await stat(filePath);
|
|
32
|
-
const lines = content.split('\n');
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
content,
|
|
36
|
-
metadata: {
|
|
37
|
-
path: filePath,
|
|
38
|
-
size: stats.size,
|
|
39
|
-
linesOfCode: lines.length,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async readBatch(filePaths: string[]): Promise<FileReadResult[]> {
|
|
45
|
-
return Promise.all(filePaths.map(path => this.read(path)));
|
|
46
|
-
}
|
|
47
|
-
}
|