@redaksjon/brennpunkt 0.0.1
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/LICENSE +190 -0
- package/README.md +619 -0
- package/dist/analyzer.js +115 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/main.js +376 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/server.js +461 -0
- package/dist/mcp/server.js.map +1 -0
- package/guide/ai-integration.md +404 -0
- package/guide/api.md +324 -0
- package/guide/configuration.md +235 -0
- package/guide/index.md +177 -0
- package/guide/integration.md +283 -0
- package/guide/quickstart.md +119 -0
- package/guide/scoring.md +172 -0
- package/guide/usage.md +249 -0
- package/package.json +77 -0
package/guide/api.md
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Programmatic API
|
|
2
|
+
|
|
3
|
+
Use brennpunkt as a library in your Node.js applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @redaksjon/brennpunkt
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { parseLcov, analyzeCoverage, formatJson, formatTable } from '@redaksjon/brennpunkt';
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
|
|
17
|
+
// Read coverage file
|
|
18
|
+
const lcovContent = readFileSync('coverage/lcov.info', 'utf-8');
|
|
19
|
+
|
|
20
|
+
// Parse LCOV format
|
|
21
|
+
const files = parseLcov(lcovContent);
|
|
22
|
+
|
|
23
|
+
// Analyze with default weights
|
|
24
|
+
const result = analyzeCoverage(
|
|
25
|
+
files,
|
|
26
|
+
{ branches: 0.5, functions: 0.3, lines: 0.2 }, // weights
|
|
27
|
+
10, // minLines
|
|
28
|
+
null // top (null = all files)
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// Output as JSON
|
|
32
|
+
console.log(formatJson(result));
|
|
33
|
+
|
|
34
|
+
// Or as formatted table
|
|
35
|
+
console.log(formatTable(result, {
|
|
36
|
+
coveragePath: 'coverage/lcov.info',
|
|
37
|
+
weights: { branches: 0.5, functions: 0.3, lines: 0.2 },
|
|
38
|
+
minLines: 10,
|
|
39
|
+
json: false,
|
|
40
|
+
top: null
|
|
41
|
+
}));
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API Reference
|
|
45
|
+
|
|
46
|
+
### `parseLcov(content: string): FileCoverage[]`
|
|
47
|
+
|
|
48
|
+
Parse LCOV format content into structured coverage data.
|
|
49
|
+
|
|
50
|
+
**Parameters**:
|
|
51
|
+
- `content`: Raw LCOV file content as string
|
|
52
|
+
|
|
53
|
+
**Returns**: Array of `FileCoverage` objects
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
interface FileCoverage {
|
|
57
|
+
file: string;
|
|
58
|
+
linesFound: number;
|
|
59
|
+
linesHit: number;
|
|
60
|
+
functionsFound: number;
|
|
61
|
+
functionsHit: number;
|
|
62
|
+
branchesFound: number;
|
|
63
|
+
branchesHit: number;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Example**:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const lcov = `SF:src/index.ts
|
|
71
|
+
LF:100
|
|
72
|
+
LH:80
|
|
73
|
+
FNF:10
|
|
74
|
+
FNH:8
|
|
75
|
+
BRF:20
|
|
76
|
+
BRH:15
|
|
77
|
+
end_of_record`;
|
|
78
|
+
|
|
79
|
+
const files = parseLcov(lcov);
|
|
80
|
+
// [{ file: 'src/index.ts', linesFound: 100, linesHit: 80, ... }]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `analyzeCoverage(files, weights, minLines, top): AnalysisResult`
|
|
84
|
+
|
|
85
|
+
Analyze coverage data and calculate priority scores.
|
|
86
|
+
|
|
87
|
+
**Parameters**:
|
|
88
|
+
- `files`: Array of `FileCoverage` from `parseLcov()`
|
|
89
|
+
- `weights`: `PriorityWeights` object
|
|
90
|
+
- `minLines`: Minimum lines threshold (number)
|
|
91
|
+
- `top`: Limit to top N files (number or null)
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
interface PriorityWeights {
|
|
95
|
+
branches: number;
|
|
96
|
+
functions: number;
|
|
97
|
+
lines: number;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Returns**: `AnalysisResult` object
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
interface AnalysisResult {
|
|
105
|
+
overall: {
|
|
106
|
+
lines: { found: number; hit: number; coverage: number };
|
|
107
|
+
functions: { found: number; hit: number; coverage: number };
|
|
108
|
+
branches: { found: number; hit: number; coverage: number };
|
|
109
|
+
fileCount: number;
|
|
110
|
+
};
|
|
111
|
+
files: AnalyzedFile[];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface AnalyzedFile {
|
|
115
|
+
file: string;
|
|
116
|
+
lines: { found: number; hit: number; coverage: number };
|
|
117
|
+
functions: { found: number; hit: number; coverage: number };
|
|
118
|
+
branches: { found: number; hit: number; coverage: number };
|
|
119
|
+
priorityScore: number;
|
|
120
|
+
uncoveredLines: number;
|
|
121
|
+
uncoveredBranches: number;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Example**:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
const result = analyzeCoverage(
|
|
129
|
+
files,
|
|
130
|
+
{ branches: 0.5, functions: 0.3, lines: 0.2 },
|
|
131
|
+
10,
|
|
132
|
+
5 // Top 5 only
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
console.log(result.overall.lines.coverage); // 85.5
|
|
136
|
+
console.log(result.files[0].priorityScore); // 156.3
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `formatJson(result: AnalysisResult): string`
|
|
140
|
+
|
|
141
|
+
Format analysis result as JSON string.
|
|
142
|
+
|
|
143
|
+
**Parameters**:
|
|
144
|
+
- `result`: `AnalysisResult` from `analyzeCoverage()`
|
|
145
|
+
|
|
146
|
+
**Returns**: Formatted JSON string
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
const jsonOutput = formatJson(result);
|
|
150
|
+
console.log(jsonOutput);
|
|
151
|
+
// { "overall": { ... }, "files": [ ... ] }
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `formatTable(result, options): string`
|
|
155
|
+
|
|
156
|
+
Format analysis result as human-readable table.
|
|
157
|
+
|
|
158
|
+
**Parameters**:
|
|
159
|
+
- `result`: `AnalysisResult` from `analyzeCoverage()`
|
|
160
|
+
- `options`: `AnalyzerOptions` object
|
|
161
|
+
|
|
162
|
+
**Returns**: Formatted table string with ANSI colors
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface AnalyzerOptions {
|
|
166
|
+
coveragePath: string;
|
|
167
|
+
weights: PriorityWeights;
|
|
168
|
+
minLines: number;
|
|
169
|
+
json: boolean;
|
|
170
|
+
top: number | null;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### `discoverCoverageFile(): { found: string; searched: string[] } | null`
|
|
175
|
+
|
|
176
|
+
Search for coverage file in common locations.
|
|
177
|
+
|
|
178
|
+
**Returns**: Object with found path and searched paths, or null if not found
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
const discovery = discoverCoverageFile();
|
|
182
|
+
if (discovery) {
|
|
183
|
+
console.log(`Found: ${discovery.found}`);
|
|
184
|
+
console.log(`Searched: ${discovery.searched.join(', ')}`);
|
|
185
|
+
} else {
|
|
186
|
+
console.log('No coverage file found');
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Advanced Examples
|
|
191
|
+
|
|
192
|
+
### Custom Analysis Pipeline
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { parseLcov, analyzeCoverage } from '@redaksjon/brennpunkt';
|
|
196
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
197
|
+
|
|
198
|
+
async function runAnalysis() {
|
|
199
|
+
// Read coverage
|
|
200
|
+
const lcov = readFileSync('coverage/lcov.info', 'utf-8');
|
|
201
|
+
const files = parseLcov(lcov);
|
|
202
|
+
|
|
203
|
+
// Filter specific directories
|
|
204
|
+
const srcFiles = files.filter(f => f.file.startsWith('src/'));
|
|
205
|
+
|
|
206
|
+
// Analyze with custom weights
|
|
207
|
+
const result = analyzeCoverage(
|
|
208
|
+
srcFiles,
|
|
209
|
+
{ branches: 0.7, functions: 0.2, lines: 0.1 },
|
|
210
|
+
20,
|
|
211
|
+
10
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
// Process results
|
|
215
|
+
const criticalFiles = result.files.filter(f => f.priorityScore > 100);
|
|
216
|
+
|
|
217
|
+
if (criticalFiles.length > 0) {
|
|
218
|
+
console.error('Critical coverage gaps:');
|
|
219
|
+
criticalFiles.forEach(f => {
|
|
220
|
+
console.error(` - ${f.file}: ${f.priorityScore.toFixed(1)}`);
|
|
221
|
+
});
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Save report
|
|
226
|
+
writeFileSync('coverage-analysis.json', JSON.stringify(result, null, 2));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
runAnalysis();
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Integration with Test Framework
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// vitest.config.ts
|
|
236
|
+
import { defineConfig } from 'vitest/config';
|
|
237
|
+
|
|
238
|
+
export default defineConfig({
|
|
239
|
+
test: {
|
|
240
|
+
coverage: {
|
|
241
|
+
reporter: ['lcov', 'text'],
|
|
242
|
+
},
|
|
243
|
+
onFinished: async () => {
|
|
244
|
+
const { parseLcov, analyzeCoverage, formatTable } = await import('@redaksjon/brennpunkt');
|
|
245
|
+
const { readFileSync } = await import('node:fs');
|
|
246
|
+
|
|
247
|
+
const lcov = readFileSync('coverage/lcov.info', 'utf-8');
|
|
248
|
+
const files = parseLcov(lcov);
|
|
249
|
+
const result = analyzeCoverage(
|
|
250
|
+
files,
|
|
251
|
+
{ branches: 0.5, functions: 0.3, lines: 0.2 },
|
|
252
|
+
10,
|
|
253
|
+
5
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
console.log('\n' + formatTable(result, {
|
|
257
|
+
coveragePath: 'coverage/lcov.info',
|
|
258
|
+
weights: { branches: 0.5, functions: 0.3, lines: 0.2 },
|
|
259
|
+
minLines: 10,
|
|
260
|
+
json: false,
|
|
261
|
+
top: 5
|
|
262
|
+
}));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### AI/LLM Integration
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { parseLcov, analyzeCoverage } from '@redaksjon/brennpunkt';
|
|
272
|
+
import { readFileSync } from 'node:fs';
|
|
273
|
+
|
|
274
|
+
// Get actionable data for AI assistants
|
|
275
|
+
function getCoverageTargets(topN = 3) {
|
|
276
|
+
const lcov = readFileSync('coverage/lcov.info', 'utf-8');
|
|
277
|
+
const files = parseLcov(lcov);
|
|
278
|
+
const result = analyzeCoverage(
|
|
279
|
+
files,
|
|
280
|
+
{ branches: 0.5, functions: 0.3, lines: 0.2 },
|
|
281
|
+
10,
|
|
282
|
+
topN
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
return result.files.map(f => ({
|
|
286
|
+
file: f.file,
|
|
287
|
+
priority: f.priorityScore,
|
|
288
|
+
missingBranches: f.uncoveredBranches,
|
|
289
|
+
missingLines: f.uncoveredLines,
|
|
290
|
+
branchCoverage: f.branches.coverage,
|
|
291
|
+
suggestion: f.branches.coverage < 50
|
|
292
|
+
? 'Focus on branch coverage - test conditional logic'
|
|
293
|
+
: f.functions.coverage < 50
|
|
294
|
+
? 'Focus on function coverage - test more entry points'
|
|
295
|
+
: 'General coverage improvement'
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Example output for AI:
|
|
300
|
+
// [
|
|
301
|
+
// {
|
|
302
|
+
// file: 'src/auth/login.ts',
|
|
303
|
+
// priority: 156.3,
|
|
304
|
+
// missingBranches: 13,
|
|
305
|
+
// missingLines: 45,
|
|
306
|
+
// branchCoverage: 35,
|
|
307
|
+
// suggestion: 'Focus on branch coverage - test conditional logic'
|
|
308
|
+
// }
|
|
309
|
+
// ]
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## TypeScript Types
|
|
313
|
+
|
|
314
|
+
All types are exported from the package:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import type {
|
|
318
|
+
FileCoverage,
|
|
319
|
+
AnalyzedFile,
|
|
320
|
+
AnalysisResult,
|
|
321
|
+
PriorityWeights,
|
|
322
|
+
AnalyzerOptions
|
|
323
|
+
} from '@redaksjon/brennpunkt';
|
|
324
|
+
```
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Brennpunkt can be configured via a YAML file in your project directory.
|
|
4
|
+
|
|
5
|
+
## Configuration File
|
|
6
|
+
|
|
7
|
+
Create a `brennpunkt.yaml` file in your project root:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
# Brennpunkt Configuration
|
|
11
|
+
# https://github.com/redaksjon/brennpunkt
|
|
12
|
+
|
|
13
|
+
# Path to lcov.info coverage file
|
|
14
|
+
coveragePath: coverage/lcov.info
|
|
15
|
+
|
|
16
|
+
# Priority weights for branches, functions, lines (should sum to 1.0)
|
|
17
|
+
# Higher branch weight = untested branches are prioritized more heavily
|
|
18
|
+
weights: "0.5,0.3,0.2"
|
|
19
|
+
|
|
20
|
+
# Minimum number of lines for a file to be included
|
|
21
|
+
# Helps filter out tiny utility files
|
|
22
|
+
minLines: 10
|
|
23
|
+
|
|
24
|
+
# Output format (true for JSON, false for table)
|
|
25
|
+
json: false
|
|
26
|
+
|
|
27
|
+
# Limit results to top N files (remove for all files)
|
|
28
|
+
top: 20
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Generate Default Config
|
|
32
|
+
|
|
33
|
+
Create a starter configuration file:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
brennpunkt --init-config
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This creates `brennpunkt.yaml` with all options commented out.
|
|
40
|
+
|
|
41
|
+
## Custom Config Location
|
|
42
|
+
|
|
43
|
+
Specify a different config file:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Use config in .config directory
|
|
47
|
+
brennpunkt --config .config/brennpunkt.yaml
|
|
48
|
+
|
|
49
|
+
# Generate config at specific path
|
|
50
|
+
brennpunkt --init-config --config .config/brennpunkt.yaml
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration Options
|
|
54
|
+
|
|
55
|
+
### `coveragePath`
|
|
56
|
+
|
|
57
|
+
**Type**: `string`
|
|
58
|
+
**Default**: Auto-discovered
|
|
59
|
+
|
|
60
|
+
Path to the lcov.info coverage file. If not specified, brennpunkt searches common locations.
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
coveragePath: coverage/lcov.info
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### `weights`
|
|
67
|
+
|
|
68
|
+
**Type**: `string` (comma-separated numbers)
|
|
69
|
+
**Default**: `"0.5,0.3,0.2"`
|
|
70
|
+
|
|
71
|
+
Priority weights for branches, functions, and lines. Should sum to 1.0.
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
# Branch-heavy (for complex conditional logic)
|
|
75
|
+
weights: "0.7,0.2,0.1"
|
|
76
|
+
|
|
77
|
+
# Equal weights
|
|
78
|
+
weights: "0.33,0.33,0.34"
|
|
79
|
+
|
|
80
|
+
# Function-heavy (for finding dead code)
|
|
81
|
+
weights: "0.2,0.6,0.2"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `minLines`
|
|
85
|
+
|
|
86
|
+
**Type**: `number`
|
|
87
|
+
**Default**: `10`
|
|
88
|
+
|
|
89
|
+
Exclude files with fewer than this many lines. Helps filter noise from tiny files.
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
# Default
|
|
93
|
+
minLines: 10
|
|
94
|
+
|
|
95
|
+
# More aggressive filtering
|
|
96
|
+
minLines: 50
|
|
97
|
+
|
|
98
|
+
# Include everything
|
|
99
|
+
minLines: 0
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `json`
|
|
103
|
+
|
|
104
|
+
**Type**: `boolean`
|
|
105
|
+
**Default**: `false`
|
|
106
|
+
|
|
107
|
+
Output as JSON instead of formatted table.
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
json: true
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `top`
|
|
114
|
+
|
|
115
|
+
**Type**: `number`
|
|
116
|
+
**Default**: (all files)
|
|
117
|
+
|
|
118
|
+
Limit output to top N priority files.
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
top: 20
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Configuration Precedence
|
|
125
|
+
|
|
126
|
+
Configuration is resolved in this order (highest priority first):
|
|
127
|
+
|
|
128
|
+
1. **CLI arguments** - Always override everything
|
|
129
|
+
2. **Config file** - `brennpunkt.yaml` in current directory
|
|
130
|
+
3. **Built-in defaults** - Fallback values
|
|
131
|
+
|
|
132
|
+
**Example**:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
# brennpunkt.yaml
|
|
136
|
+
weights: "0.6,0.2,0.2"
|
|
137
|
+
top: 20
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# CLI overrides config file
|
|
142
|
+
brennpunkt --top 5
|
|
143
|
+
# Uses: weights from config (0.6,0.2,0.2), top=5 from CLI
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Check Configuration
|
|
147
|
+
|
|
148
|
+
View resolved configuration with source tracking:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
brennpunkt --check-config
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Output:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
================================================================================
|
|
158
|
+
BRENNPUNKT CONFIGURATION
|
|
159
|
+
================================================================================
|
|
160
|
+
|
|
161
|
+
Config file: brennpunkt.yaml
|
|
162
|
+
Status: Found
|
|
163
|
+
|
|
164
|
+
RESOLVED CONFIGURATION:
|
|
165
|
+
--------------------------------------------------------------------------------
|
|
166
|
+
[config file] coveragePath : "coverage/lcov.info"
|
|
167
|
+
[config file] weights : "0.6,0.2,0.2"
|
|
168
|
+
[config file] minLines : 20
|
|
169
|
+
[default] json : false
|
|
170
|
+
[config file] top : 10
|
|
171
|
+
|
|
172
|
+
================================================================================
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Environment-Specific Configs
|
|
176
|
+
|
|
177
|
+
For different environments, use the `--config` flag:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Development (verbose)
|
|
181
|
+
brennpunkt --config .config/brennpunkt.dev.yaml
|
|
182
|
+
|
|
183
|
+
# CI (JSON output)
|
|
184
|
+
brennpunkt --config .config/brennpunkt.ci.yaml
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Example CI config:
|
|
188
|
+
|
|
189
|
+
```yaml
|
|
190
|
+
# .config/brennpunkt.ci.yaml
|
|
191
|
+
json: true
|
|
192
|
+
top: 10
|
|
193
|
+
minLines: 20
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## MCP Server Configuration
|
|
197
|
+
|
|
198
|
+
The MCP server automatically loads each project's `brennpunkt.yaml`:
|
|
199
|
+
|
|
200
|
+
- Pass `projectPath` as a parameter to each MCP tool call
|
|
201
|
+
- The server reads `{projectPath}/brennpunkt.yaml` if it exists
|
|
202
|
+
- Responses include `configUsed: "brennpunkt.yaml"` or `configUsed: "defaults"`
|
|
203
|
+
- No per-project MCP server configuration needed
|
|
204
|
+
|
|
205
|
+
This means different projects can have different analysis settings (weights, minLines, etc.) without any server reconfiguration.
|
|
206
|
+
|
|
207
|
+
## Monorepo Usage
|
|
208
|
+
|
|
209
|
+
For monorepos, place config files in each package:
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
packages/
|
|
213
|
+
├── auth/
|
|
214
|
+
│ ├── brennpunkt.yaml
|
|
215
|
+
│ └── coverage/lcov.info
|
|
216
|
+
├── api/
|
|
217
|
+
│ ├── brennpunkt.yaml
|
|
218
|
+
│ └── coverage/lcov.info
|
|
219
|
+
└── shared/
|
|
220
|
+
├── brennpunkt.yaml
|
|
221
|
+
└── coverage/lcov.info
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Run from each package directory:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
cd packages/auth && brennpunkt
|
|
228
|
+
cd packages/api && brennpunkt
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Or specify paths:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
brennpunkt --config packages/auth/brennpunkt.yaml packages/auth/coverage/lcov.info
|
|
235
|
+
```
|