@promptci/core 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 +201 -0
- package/README.md +30 -0
- package/dist/agent-practices.d.ts +22 -0
- package/dist/agent-practices.d.ts.map +1 -0
- package/dist/agent-practices.js +582 -0
- package/dist/agent-practices.js.map +1 -0
- package/dist/baseline.d.ts +40 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +172 -0
- package/dist/baseline.js.map +1 -0
- package/dist/canonical-owner.d.ts +3 -0
- package/dist/canonical-owner.d.ts.map +1 -0
- package/dist/canonical-owner.js +131 -0
- package/dist/canonical-owner.js.map +1 -0
- package/dist/cheap-model-routing.d.ts +4 -0
- package/dist/cheap-model-routing.d.ts.map +1 -0
- package/dist/cheap-model-routing.js +43 -0
- package/dist/cheap-model-routing.js.map +1 -0
- package/dist/ci-alignment.d.ts +10 -0
- package/dist/ci-alignment.d.ts.map +1 -0
- package/dist/ci-alignment.js +343 -0
- package/dist/ci-alignment.js.map +1 -0
- package/dist/cli-output-filter.d.ts +16 -0
- package/dist/cli-output-filter.d.ts.map +1 -0
- package/dist/cli-output-filter.js +88 -0
- package/dist/cli-output-filter.js.map +1 -0
- package/dist/command-validity.d.ts +12 -0
- package/dist/command-validity.d.ts.map +1 -0
- package/dist/command-validity.js +543 -0
- package/dist/command-validity.js.map +1 -0
- package/dist/conflicts.d.ts +49 -0
- package/dist/conflicts.d.ts.map +1 -0
- package/dist/conflicts.js +1065 -0
- package/dist/conflicts.js.map +1 -0
- package/dist/context-analysis.d.ts +15 -0
- package/dist/context-analysis.d.ts.map +1 -0
- package/dist/context-analysis.js +24 -0
- package/dist/context-analysis.js.map +1 -0
- package/dist/context-bloat.d.ts +17 -0
- package/dist/context-bloat.d.ts.map +1 -0
- package/dist/context-bloat.js +148 -0
- package/dist/context-bloat.js.map +1 -0
- package/dist/context-cost.d.ts +4 -0
- package/dist/context-cost.d.ts.map +1 -0
- package/dist/context-cost.js +70 -0
- package/dist/context-cost.js.map +1 -0
- package/dist/context-optimizer.d.ts +14 -0
- package/dist/context-optimizer.d.ts.map +1 -0
- package/dist/context-optimizer.js +219 -0
- package/dist/context-optimizer.js.map +1 -0
- package/dist/context-recommender.d.ts +3 -0
- package/dist/context-recommender.d.ts.map +1 -0
- package/dist/context-recommender.js +329 -0
- package/dist/context-recommender.js.map +1 -0
- package/dist/dead-references.d.ts +33 -0
- package/dist/dead-references.d.ts.map +1 -0
- package/dist/dead-references.js +607 -0
- package/dist/dead-references.js.map +1 -0
- package/dist/detectors.d.ts +11 -0
- package/dist/detectors.d.ts.map +1 -0
- package/dist/detectors.js +160 -0
- package/dist/detectors.js.map +1 -0
- package/dist/duplicates.d.ts +36 -0
- package/dist/duplicates.d.ts.map +1 -0
- package/dist/duplicates.js +436 -0
- package/dist/duplicates.js.map +1 -0
- package/dist/fix-engine.d.ts +16 -0
- package/dist/fix-engine.d.ts.map +1 -0
- package/dist/fix-engine.js +179 -0
- package/dist/fix-engine.js.map +1 -0
- package/dist/framework-packs.d.ts +8 -0
- package/dist/framework-packs.d.ts.map +1 -0
- package/dist/framework-packs.js +22 -0
- package/dist/framework-packs.js.map +1 -0
- package/dist/frameworks/dotnet.d.ts +4 -0
- package/dist/frameworks/dotnet.d.ts.map +1 -0
- package/dist/frameworks/dotnet.js +77 -0
- package/dist/frameworks/dotnet.js.map +1 -0
- package/dist/frameworks/go.d.ts +4 -0
- package/dist/frameworks/go.d.ts.map +1 -0
- package/dist/frameworks/go.js +39 -0
- package/dist/frameworks/go.js.map +1 -0
- package/dist/frameworks/nextjs.d.ts +4 -0
- package/dist/frameworks/nextjs.d.ts.map +1 -0
- package/dist/frameworks/nextjs.js +66 -0
- package/dist/frameworks/nextjs.js.map +1 -0
- package/dist/frameworks/python.d.ts +4 -0
- package/dist/frameworks/python.d.ts.map +1 -0
- package/dist/frameworks/python.js +66 -0
- package/dist/frameworks/python.js.map +1 -0
- package/dist/frameworks/rust.d.ts +4 -0
- package/dist/frameworks/rust.d.ts.map +1 -0
- package/dist/frameworks/rust.js +72 -0
- package/dist/frameworks/rust.js.map +1 -0
- package/dist/frameworks/unity.d.ts +4 -0
- package/dist/frameworks/unity.d.ts.map +1 -0
- package/dist/frameworks/unity.js +74 -0
- package/dist/frameworks/unity.js.map +1 -0
- package/dist/health-score.d.ts +37 -0
- package/dist/health-score.d.ts.map +1 -0
- package/dist/health-score.js +164 -0
- package/dist/health-score.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/llm.d.ts +6 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +67 -0
- package/dist/llm.js.map +1 -0
- package/dist/manifest-consistency.d.ts +37 -0
- package/dist/manifest-consistency.d.ts.map +1 -0
- package/dist/manifest-consistency.js +659 -0
- package/dist/manifest-consistency.js.map +1 -0
- package/dist/mcp-detector.d.ts +4 -0
- package/dist/mcp-detector.d.ts.map +1 -0
- package/dist/mcp-detector.js +131 -0
- package/dist/mcp-detector.js.map +1 -0
- package/dist/missing-context.d.ts +15 -0
- package/dist/missing-context.d.ts.map +1 -0
- package/dist/missing-context.js +517 -0
- package/dist/missing-context.js.map +1 -0
- package/dist/native-tool-preference.d.ts +20 -0
- package/dist/native-tool-preference.d.ts.map +1 -0
- package/dist/native-tool-preference.js +94 -0
- package/dist/native-tool-preference.js.map +1 -0
- package/dist/output-verbosity.d.ts +3 -0
- package/dist/output-verbosity.d.ts.map +1 -0
- package/dist/output-verbosity.js +83 -0
- package/dist/output-verbosity.js.map +1 -0
- package/dist/product-boundary.d.ts +11 -0
- package/dist/product-boundary.d.ts.map +1 -0
- package/dist/product-boundary.js +301 -0
- package/dist/product-boundary.js.map +1 -0
- package/dist/project-type.d.ts +15 -0
- package/dist/project-type.d.ts.map +1 -0
- package/dist/project-type.js +116 -0
- package/dist/project-type.js.map +1 -0
- package/dist/prompt-cache.d.ts +3 -0
- package/dist/prompt-cache.d.ts.map +1 -0
- package/dist/prompt-cache.js +151 -0
- package/dist/prompt-cache.js.map +1 -0
- package/dist/repo-context.d.ts +37 -0
- package/dist/repo-context.d.ts.map +1 -0
- package/dist/repo-context.js +221 -0
- package/dist/repo-context.js.map +1 -0
- package/dist/report.d.ts +87 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +558 -0
- package/dist/report.js.map +1 -0
- package/dist/scan.d.ts +7 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +43 -0
- package/dist/scan.js.map +1 -0
- package/dist/scanner.d.ts +3 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +216 -0
- package/dist/scanner.js.map +1 -0
- package/dist/security-pack.d.ts +4 -0
- package/dist/security-pack.d.ts.map +1 -0
- package/dist/security-pack.js +403 -0
- package/dist/security-pack.js.map +1 -0
- package/dist/stale-instructions.d.ts +20 -0
- package/dist/stale-instructions.d.ts.map +1 -0
- package/dist/stale-instructions.js +269 -0
- package/dist/stale-instructions.js.map +1 -0
- package/dist/suppression.d.ts +64 -0
- package/dist/suppression.d.ts.map +1 -0
- package/dist/suppression.js +338 -0
- package/dist/suppression.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/vague-guidance.d.ts +12 -0
- package/dist/vague-guidance.d.ts.map +1 -0
- package/dist/vague-guidance.js +235 -0
- package/dist/vague-guidance.js.map +1 -0
- package/package.json +54 -0
package/dist/report.js
ADDED
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown and JSON report generation for PromptCI scan results.
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as nodePath from 'node:path';
|
|
6
|
+
import * as crypto from 'node:crypto';
|
|
7
|
+
import { generateContextRecommendations } from './context-recommender.js';
|
|
8
|
+
const SEVERITY_LABEL = {
|
|
9
|
+
critical: 'CRITICAL',
|
|
10
|
+
high: 'HIGH',
|
|
11
|
+
warning: 'WARNING',
|
|
12
|
+
info: 'INFO',
|
|
13
|
+
};
|
|
14
|
+
const SEVERITY_EMOJI = {
|
|
15
|
+
critical: '🔴',
|
|
16
|
+
high: '🟠',
|
|
17
|
+
warning: '🟡',
|
|
18
|
+
info: '🔵',
|
|
19
|
+
};
|
|
20
|
+
const SEVERITY_ORDER = {
|
|
21
|
+
critical: 0,
|
|
22
|
+
high: 1,
|
|
23
|
+
warning: 2,
|
|
24
|
+
info: 3,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Return a path relative to repoPath for display in reports.
|
|
28
|
+
* Falls back to the absolute path if the relative form escapes the repo root.
|
|
29
|
+
*/
|
|
30
|
+
function relPath(absPath, repoPath) {
|
|
31
|
+
const rel = nodePath.relative(repoPath, absPath);
|
|
32
|
+
if (!rel || rel.startsWith('..'))
|
|
33
|
+
return absPath;
|
|
34
|
+
return rel;
|
|
35
|
+
}
|
|
36
|
+
function trendIssueKey(issue, repoPath) {
|
|
37
|
+
if (!issue.filePaths || issue.filePaths.length === 0)
|
|
38
|
+
return issue.id ?? '';
|
|
39
|
+
const idFamily = issue.id?.replace(/-[^-]+$/, '') ?? '';
|
|
40
|
+
const normalizedPaths = issue.filePaths
|
|
41
|
+
.map((filePath) => {
|
|
42
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
43
|
+
return repoPath && nodePath.isAbsolute(filePath) ? relPath(filePath, repoPath).replace(/\\/g, '/') : normalized;
|
|
44
|
+
})
|
|
45
|
+
.sort();
|
|
46
|
+
const hash = crypto
|
|
47
|
+
.createHash('sha1')
|
|
48
|
+
.update(JSON.stringify({
|
|
49
|
+
category: issue.category ?? '',
|
|
50
|
+
severity: issue.severity ?? '',
|
|
51
|
+
idFamily,
|
|
52
|
+
title: issue.title ?? '',
|
|
53
|
+
filePaths: normalizedPaths,
|
|
54
|
+
}))
|
|
55
|
+
.digest('hex')
|
|
56
|
+
.slice(0, 12);
|
|
57
|
+
return `trend-${hash}`;
|
|
58
|
+
}
|
|
59
|
+
function trendIssueKeys(issues, repoPath) {
|
|
60
|
+
const seenRawIds = new Set();
|
|
61
|
+
const keys = [];
|
|
62
|
+
for (const issue of issues) {
|
|
63
|
+
if (issue.id) {
|
|
64
|
+
if (seenRawIds.has(issue.id))
|
|
65
|
+
continue;
|
|
66
|
+
seenRawIds.add(issue.id);
|
|
67
|
+
}
|
|
68
|
+
keys.push(trendIssueKey(issue, repoPath));
|
|
69
|
+
}
|
|
70
|
+
return keys;
|
|
71
|
+
}
|
|
72
|
+
function scoreBar(score) {
|
|
73
|
+
const filled = Math.round(score / 10);
|
|
74
|
+
const empty = 10 - filled;
|
|
75
|
+
return '█'.repeat(filled) + '░'.repeat(empty);
|
|
76
|
+
}
|
|
77
|
+
function scoreLabel(score) {
|
|
78
|
+
if (score >= 90)
|
|
79
|
+
return 'Healthy';
|
|
80
|
+
if (score >= 70)
|
|
81
|
+
return 'Fair';
|
|
82
|
+
if (score >= 50)
|
|
83
|
+
return 'Needs attention';
|
|
84
|
+
return 'Critical issues found';
|
|
85
|
+
}
|
|
86
|
+
function groupIssuesBySeverity(issues) {
|
|
87
|
+
const map = new Map();
|
|
88
|
+
for (const sev of ['critical', 'high', 'warning', 'info']) {
|
|
89
|
+
map.set(sev, []);
|
|
90
|
+
}
|
|
91
|
+
for (const issue of issues) {
|
|
92
|
+
map.get(issue.severity).push(issue);
|
|
93
|
+
}
|
|
94
|
+
return map;
|
|
95
|
+
}
|
|
96
|
+
function sortedIssues(issues) {
|
|
97
|
+
return [...issues].sort((a, b) => {
|
|
98
|
+
const sevDiff = SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity];
|
|
99
|
+
if (sevDiff !== 0)
|
|
100
|
+
return sevDiff;
|
|
101
|
+
const confDiff = b.confidence - a.confidence;
|
|
102
|
+
if (confDiff !== 0)
|
|
103
|
+
return confDiff;
|
|
104
|
+
return a.id.localeCompare(b.id);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Truncate evidence strings so the report stays readable.
|
|
109
|
+
* Evidence items are often normalised section blobs — 100 chars is enough.
|
|
110
|
+
*/
|
|
111
|
+
function truncateEvidence(ev, maxLen = 100) {
|
|
112
|
+
const single = ev.replace(/\s+/g, ' ').trim();
|
|
113
|
+
return single.length <= maxLen ? single : `${single.slice(0, maxLen)}…`;
|
|
114
|
+
}
|
|
115
|
+
function renderIssue(issue, idx, rel) {
|
|
116
|
+
const emoji = SEVERITY_EMOJI[issue.severity];
|
|
117
|
+
const label = SEVERITY_LABEL[issue.severity];
|
|
118
|
+
const lines = [];
|
|
119
|
+
lines.push(`### ${idx}. ${emoji} [${label}] ${issue.title}`);
|
|
120
|
+
lines.push('');
|
|
121
|
+
lines.push(`${issue.summary}`);
|
|
122
|
+
lines.push('');
|
|
123
|
+
// Always show affected files (canonical list)
|
|
124
|
+
if (issue.filePaths.length > 0) {
|
|
125
|
+
for (const fp of issue.filePaths) {
|
|
126
|
+
lines.push(`**File:** \`${rel(fp)}\``);
|
|
127
|
+
}
|
|
128
|
+
lines.push('');
|
|
129
|
+
}
|
|
130
|
+
// Show line-number locations when available
|
|
131
|
+
const withLines = issue.locations.filter((l) => l.startLine !== undefined);
|
|
132
|
+
if (withLines.length > 0) {
|
|
133
|
+
for (const loc of withLines) {
|
|
134
|
+
const range = loc.endLine !== undefined ? `L${loc.startLine}–L${loc.endLine}` : `L${loc.startLine}`;
|
|
135
|
+
lines.push(`**Location:** \`${rel(loc.filePath)}\` ${range}`);
|
|
136
|
+
}
|
|
137
|
+
lines.push('');
|
|
138
|
+
}
|
|
139
|
+
if (issue.evidence.length > 0) {
|
|
140
|
+
lines.push('**Evidence:**');
|
|
141
|
+
for (const ev of issue.evidence) {
|
|
142
|
+
lines.push(`- ${truncateEvidence(ev)}`);
|
|
143
|
+
}
|
|
144
|
+
lines.push('');
|
|
145
|
+
}
|
|
146
|
+
lines.push(`> **Recommendation:** ${issue.recommendation}`);
|
|
147
|
+
if (issue.fixRecipe) {
|
|
148
|
+
lines.push('');
|
|
149
|
+
lines.push('**Suggested text to add:**');
|
|
150
|
+
lines.push('```markdown');
|
|
151
|
+
lines.push(issue.fixRecipe);
|
|
152
|
+
lines.push('```');
|
|
153
|
+
}
|
|
154
|
+
return lines.join('\n');
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Generate a Markdown-formatted scan report.
|
|
158
|
+
*/
|
|
159
|
+
export function generateMarkdownReport(report) {
|
|
160
|
+
const lines = [];
|
|
161
|
+
const { healthScore, topFixes, issues, projectType, repoPath, generatedAt, filesScanned } = report;
|
|
162
|
+
const rel = (absPath) => relPath(absPath, repoPath);
|
|
163
|
+
// Header
|
|
164
|
+
lines.push('# PromptCI Health Report');
|
|
165
|
+
lines.push('');
|
|
166
|
+
lines.push(`**Generated:** ${generatedAt}`);
|
|
167
|
+
lines.push(`**Repo:** \`${repoPath}\``);
|
|
168
|
+
lines.push(`**Project type:** ${projectType}`);
|
|
169
|
+
lines.push(`**Files scanned:** ${filesScanned.length}`);
|
|
170
|
+
if (report.metrics) {
|
|
171
|
+
lines.push(`**Estimated instruction tokens:** ${report.metrics.estimatedInstructionTokens}`);
|
|
172
|
+
}
|
|
173
|
+
lines.push('');
|
|
174
|
+
// Health score
|
|
175
|
+
lines.push('## Health Score');
|
|
176
|
+
lines.push('');
|
|
177
|
+
lines.push('```');
|
|
178
|
+
lines.push(`${scoreBar(healthScore)} ${healthScore}/100 ${scoreLabel(healthScore)}`);
|
|
179
|
+
lines.push('```');
|
|
180
|
+
lines.push('');
|
|
181
|
+
// Issue summary counts
|
|
182
|
+
const grouped = groupIssuesBySeverity(issues);
|
|
183
|
+
if (issues.length > 0) {
|
|
184
|
+
const countParts = [];
|
|
185
|
+
for (const sev of ['critical', 'high', 'warning', 'info']) {
|
|
186
|
+
const n = grouped.get(sev).length;
|
|
187
|
+
if (n > 0)
|
|
188
|
+
countParts.push(`${SEVERITY_EMOJI[sev]} ${n} ${sev}`);
|
|
189
|
+
}
|
|
190
|
+
lines.push(countParts.join(' · '));
|
|
191
|
+
lines.push('');
|
|
192
|
+
}
|
|
193
|
+
// Trend
|
|
194
|
+
lines.push('## Trend');
|
|
195
|
+
lines.push('');
|
|
196
|
+
if (report.trend) {
|
|
197
|
+
const t = report.trend;
|
|
198
|
+
if (t.previousScanDate) {
|
|
199
|
+
lines.push(`- **Previous scan:** ${t.previousScanDate}`);
|
|
200
|
+
}
|
|
201
|
+
const scoreSign = t.scoreDelta > 0 ? `+${t.scoreDelta}` : `${t.scoreDelta}`;
|
|
202
|
+
lines.push(`- **Score change:** ${scoreSign}`);
|
|
203
|
+
lines.push(`- **New issues:** ${t.newIssuesCount}`);
|
|
204
|
+
lines.push(`- **Resolved issues:** ${t.resolvedIssuesCount}`);
|
|
205
|
+
const cats = Object.keys(t.categoryDeltas);
|
|
206
|
+
if (cats.length > 0) {
|
|
207
|
+
lines.push('- **Category changes:**');
|
|
208
|
+
for (const cat of cats) {
|
|
209
|
+
const deltaVal = t.categoryDeltas[cat];
|
|
210
|
+
const deltaSign = deltaVal > 0 ? `+${deltaVal}` : `${deltaVal}`;
|
|
211
|
+
lines.push(` - ${cat}: ${deltaSign}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (t.streak > 0) {
|
|
215
|
+
lines.push(`- **Streak:** ${t.streak} scan(s) without high/critical issues`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
lines.push('First scan — no trend data available yet.');
|
|
220
|
+
}
|
|
221
|
+
lines.push('');
|
|
222
|
+
// Top fixes
|
|
223
|
+
if (topFixes.length > 0) {
|
|
224
|
+
lines.push('## Top Fixes');
|
|
225
|
+
lines.push('');
|
|
226
|
+
topFixes.forEach((fix, i) => {
|
|
227
|
+
lines.push(`**${i + 1}. ${fix.title}**`);
|
|
228
|
+
lines.push('');
|
|
229
|
+
lines.push(`${fix.reason}`);
|
|
230
|
+
lines.push('');
|
|
231
|
+
lines.push(`*Action:* ${fix.suggestedAction}`);
|
|
232
|
+
lines.push('');
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
// Issues
|
|
236
|
+
if (issues.length === 0) {
|
|
237
|
+
lines.push('## Issues');
|
|
238
|
+
lines.push('');
|
|
239
|
+
lines.push('No issues found. Instruction files look good!');
|
|
240
|
+
lines.push('');
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
lines.push('## Issues');
|
|
244
|
+
lines.push('');
|
|
245
|
+
const ordered = sortedIssues(issues);
|
|
246
|
+
ordered.forEach((issue, i) => {
|
|
247
|
+
lines.push(renderIssue(issue, i + 1, rel));
|
|
248
|
+
lines.push('');
|
|
249
|
+
lines.push('---');
|
|
250
|
+
lines.push('');
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
// Suppressed issues
|
|
254
|
+
const suppressed = report.suppressedIssues;
|
|
255
|
+
if (suppressed && suppressed.length > 0) {
|
|
256
|
+
lines.push(`## Suppressed (${suppressed.length})`);
|
|
257
|
+
lines.push('');
|
|
258
|
+
lines.push(`The following ${suppressed.length === 1 ? 'issue was' : 'issues were'} silenced by ` +
|
|
259
|
+
`inline \`promptci-ignore\` annotations and do not affect the health score.`);
|
|
260
|
+
lines.push('');
|
|
261
|
+
for (const s of suppressed) {
|
|
262
|
+
const primaryFile = s.filePaths[0] ? rel(s.filePaths[0]) : '(unknown)';
|
|
263
|
+
const loc = s.locations.find((l) => l.startLine !== undefined);
|
|
264
|
+
const lineRef = loc
|
|
265
|
+
? ` L${loc.startLine}${loc.endLine ? `–${loc.endLine}` : ''}`
|
|
266
|
+
: '';
|
|
267
|
+
lines.push(`- **${s.category}** in \`${primaryFile}\`${lineRef}`);
|
|
268
|
+
}
|
|
269
|
+
lines.push('');
|
|
270
|
+
}
|
|
271
|
+
// Files scanned
|
|
272
|
+
if (filesScanned.length > 0) {
|
|
273
|
+
lines.push('## Files Scanned');
|
|
274
|
+
lines.push('');
|
|
275
|
+
for (const f of filesScanned) {
|
|
276
|
+
lines.push(`- \`${rel(f.path)}\` (${f.fileType}, ${f.lineCount} lines, ~${f.estimatedTokens} tokens)`);
|
|
277
|
+
}
|
|
278
|
+
lines.push('');
|
|
279
|
+
}
|
|
280
|
+
// Context Recommendations (Cost 2, 5, 10, 11)
|
|
281
|
+
const recommendations = generateContextRecommendations(report);
|
|
282
|
+
if (recommendations) {
|
|
283
|
+
lines.push(recommendations);
|
|
284
|
+
lines.push('');
|
|
285
|
+
}
|
|
286
|
+
// Footer
|
|
287
|
+
lines.push('---');
|
|
288
|
+
lines.push('> Findings are heuristic. Review each item before acting. ' +
|
|
289
|
+
'This report identifies patterns — it does not auto-fix.');
|
|
290
|
+
lines.push('');
|
|
291
|
+
lines.push('*Generated by [PromptCI](https://github.com/SeriousGeese/PromptCI)*');
|
|
292
|
+
return lines.join('\n');
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Serialize a ScanReport to JSON (schema v0.1).
|
|
296
|
+
*
|
|
297
|
+
* All file paths are repo-relative so reports are portable — the absolute
|
|
298
|
+
* repo root is preserved as `repoPath` so callers can reconstruct full paths.
|
|
299
|
+
* Verbose section content is excluded from filesScanned to keep output compact.
|
|
300
|
+
*/
|
|
301
|
+
export function generateJsonReport(report, pretty = true) {
|
|
302
|
+
const rel = (absPath) => relPath(absPath, report.repoPath);
|
|
303
|
+
// R1: typed as ScanReportJson (the COMPACT shape actually written to disk),
|
|
304
|
+
// not ScanReport — filesScanned below intentionally omits `content` and
|
|
305
|
+
// `sections` to keep report.json from duplicating every scanned file's
|
|
306
|
+
// full text. Typing the payload accurately here means a consumer that
|
|
307
|
+
// imports ScanReportJson (instead of misusing ScanReport) gets a type that
|
|
308
|
+
// matches reality.
|
|
309
|
+
const payload = {
|
|
310
|
+
schemaVersion: report.schemaVersion,
|
|
311
|
+
generatedAt: report.generatedAt,
|
|
312
|
+
repoPath: report.repoPath,
|
|
313
|
+
projectType: report.projectType,
|
|
314
|
+
healthScore: report.healthScore,
|
|
315
|
+
topFixes: report.topFixes,
|
|
316
|
+
...(report.metrics ? { metrics: report.metrics } : {}),
|
|
317
|
+
...(report.trend ? { trend: report.trend } : {}),
|
|
318
|
+
issues: report.issues.map((issue) => ({
|
|
319
|
+
...issue,
|
|
320
|
+
filePaths: issue.filePaths.map(rel),
|
|
321
|
+
locations: issue.locations.map((loc) => ({
|
|
322
|
+
...loc,
|
|
323
|
+
filePath: rel(loc.filePath),
|
|
324
|
+
})),
|
|
325
|
+
})),
|
|
326
|
+
filesScanned: report.filesScanned.map((f) => ({
|
|
327
|
+
path: rel(f.path),
|
|
328
|
+
fileType: f.fileType,
|
|
329
|
+
lineCount: f.lineCount,
|
|
330
|
+
charCount: f.charCount,
|
|
331
|
+
estimatedTokens: f.estimatedTokens,
|
|
332
|
+
})),
|
|
333
|
+
...(report.suppressedIssues && report.suppressedIssues.length > 0
|
|
334
|
+
? {
|
|
335
|
+
suppressedIssues: report.suppressedIssues.map((issue) => ({
|
|
336
|
+
...issue,
|
|
337
|
+
filePaths: issue.filePaths.map(rel),
|
|
338
|
+
locations: issue.locations.map((loc) => ({ ...loc, filePath: rel(loc.filePath) })),
|
|
339
|
+
})),
|
|
340
|
+
}
|
|
341
|
+
: {}),
|
|
342
|
+
};
|
|
343
|
+
return pretty ? JSON.stringify(payload, null, 2) : JSON.stringify(payload);
|
|
344
|
+
}
|
|
345
|
+
// ── History helpers ───────────────────────────────────────────────────────────
|
|
346
|
+
/** Path to the history index file for a given repo. */
|
|
347
|
+
export function historyIndexPath(repoPath) {
|
|
348
|
+
return nodePath.join(repoPath, '.promptci', 'history', 'index.json');
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Read the history index for a repo, returning an empty array if it doesn't
|
|
352
|
+
* exist yet or cannot be parsed.
|
|
353
|
+
*/
|
|
354
|
+
export async function readHistoryIndex(repoPath) {
|
|
355
|
+
const indexPath = historyIndexPath(repoPath);
|
|
356
|
+
try {
|
|
357
|
+
const raw = await fs.readFile(indexPath, 'utf8');
|
|
358
|
+
const parsed = JSON.parse(raw);
|
|
359
|
+
if (Array.isArray(parsed))
|
|
360
|
+
return parsed;
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
// File missing or corrupt — start fresh
|
|
364
|
+
}
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Archive the current latest.md and report.json (if they exist) into
|
|
369
|
+
* .promptci/history/<slug>/ and append a compact entry to the history index.
|
|
370
|
+
*
|
|
371
|
+
* The slug is derived from the report's generatedAt timestamp so archives are
|
|
372
|
+
* human-readable on disk. Returns the new HistoryEntry, or null if there was
|
|
373
|
+
* nothing to archive.
|
|
374
|
+
*/
|
|
375
|
+
export async function archiveExistingReport(repoPath, latestMdPath, latestJsonPath) {
|
|
376
|
+
// Check whether there is an existing JSON report to archive
|
|
377
|
+
let existingJson;
|
|
378
|
+
try {
|
|
379
|
+
existingJson = await fs.readFile(latestJsonPath, 'utf8');
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
return null; // Nothing to archive yet
|
|
383
|
+
}
|
|
384
|
+
let parsed;
|
|
385
|
+
try {
|
|
386
|
+
parsed = JSON.parse(existingJson);
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return null; // Corrupt report — skip archiving
|
|
390
|
+
}
|
|
391
|
+
const generatedAt = typeof parsed.generatedAt === 'string' ? parsed.generatedAt : new Date().toISOString();
|
|
392
|
+
// Build a filesystem-safe slug from the timestamp (replace colons and dots)
|
|
393
|
+
const slug = generatedAt.replace(/[:.]/g, '-').replace(/Z$/, 'Z');
|
|
394
|
+
const archiveDir = nodePath.join(repoPath, '.promptci', 'history', slug);
|
|
395
|
+
await fs.mkdir(archiveDir, { recursive: true });
|
|
396
|
+
const archiveMdRel = nodePath.join('.promptci', 'history', slug, 'report.md');
|
|
397
|
+
const archiveJsonRel = nodePath.join('.promptci', 'history', slug, 'report.json');
|
|
398
|
+
const archiveMdAbs = nodePath.join(repoPath, archiveMdRel);
|
|
399
|
+
const archiveJsonAbs = nodePath.join(repoPath, archiveJsonRel);
|
|
400
|
+
// Copy existing md (best-effort — may not exist on first run)
|
|
401
|
+
try {
|
|
402
|
+
await fs.copyFile(latestMdPath, archiveMdAbs);
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// latest.md didn't exist; write a placeholder
|
|
406
|
+
await fs.writeFile(archiveMdAbs, existingJson, 'utf8');
|
|
407
|
+
}
|
|
408
|
+
await fs.copyFile(latestJsonPath, archiveJsonAbs);
|
|
409
|
+
// Build the compact history entry from the parsed JSON
|
|
410
|
+
const issues = Array.isArray(parsed.issues) ? parsed.issues : [];
|
|
411
|
+
const issueCount = { critical: 0, high: 0, warning: 0, info: 0 };
|
|
412
|
+
for (const issue of issues) {
|
|
413
|
+
const sev = issue.severity;
|
|
414
|
+
if (sev in issueCount)
|
|
415
|
+
issueCount[sev]++;
|
|
416
|
+
}
|
|
417
|
+
const entry = {
|
|
418
|
+
generatedAt,
|
|
419
|
+
healthScore: typeof parsed.healthScore === 'number' ? parsed.healthScore : 0,
|
|
420
|
+
issueCount,
|
|
421
|
+
archiveMdPath: archiveMdRel,
|
|
422
|
+
archiveJsonPath: archiveJsonRel,
|
|
423
|
+
};
|
|
424
|
+
// Append to the index
|
|
425
|
+
const existing = await readHistoryIndex(repoPath);
|
|
426
|
+
existing.push(entry);
|
|
427
|
+
const indexPath = historyIndexPath(repoPath);
|
|
428
|
+
await fs.mkdir(nodePath.dirname(indexPath), { recursive: true });
|
|
429
|
+
await fs.writeFile(indexPath, JSON.stringify(existing, null, 2), 'utf8');
|
|
430
|
+
return entry;
|
|
431
|
+
}
|
|
432
|
+
// ── writeReport ───────────────────────────────────────────────────────────────
|
|
433
|
+
/**
|
|
434
|
+
* Write markdown and JSON reports to disk.
|
|
435
|
+
*
|
|
436
|
+
* Default output paths (relative to the repo root):
|
|
437
|
+
* .promptci/latest.md
|
|
438
|
+
* .promptci/report.json
|
|
439
|
+
*
|
|
440
|
+
* Before overwriting, the previous reports are archived to:
|
|
441
|
+
* .promptci/history/<timestamp>/report.md
|
|
442
|
+
* .promptci/history/<timestamp>/report.json
|
|
443
|
+
*
|
|
444
|
+
* A compact history index is maintained at:
|
|
445
|
+
* .promptci/history/index.json
|
|
446
|
+
*
|
|
447
|
+
* The .promptci/ directory is created if it does not exist.
|
|
448
|
+
*/
|
|
449
|
+
export async function writeReport(report, options = {}) {
|
|
450
|
+
const outputDir = nodePath.join(report.repoPath, '.promptci');
|
|
451
|
+
const resolvedMd = options.mdPath ?? nodePath.join(outputDir, 'latest.md');
|
|
452
|
+
const resolvedJson = options.jsonPath ?? nodePath.join(outputDir, 'report.json');
|
|
453
|
+
await fs.mkdir(nodePath.dirname(resolvedMd), { recursive: true });
|
|
454
|
+
await fs.mkdir(nodePath.dirname(resolvedJson), { recursive: true });
|
|
455
|
+
// Load previous report and history index to compute trend
|
|
456
|
+
const previousReport = await loadPreviousReport(resolvedJson);
|
|
457
|
+
const history = await readHistoryIndex(report.repoPath);
|
|
458
|
+
const trend = await computeTrend(report, previousReport, history);
|
|
459
|
+
if (trend) {
|
|
460
|
+
report.trend = trend;
|
|
461
|
+
}
|
|
462
|
+
// Archive the previous report before overwriting (only for default paths)
|
|
463
|
+
const shouldArchive = options.archive !== false && !options.mdPath && !options.jsonPath;
|
|
464
|
+
const archivedEntry = shouldArchive
|
|
465
|
+
? await archiveExistingReport(report.repoPath, resolvedMd, resolvedJson)
|
|
466
|
+
: null;
|
|
467
|
+
const md = generateMarkdownReport(report);
|
|
468
|
+
const json = generateJsonReport(report);
|
|
469
|
+
await Promise.all([fs.writeFile(resolvedMd, md, 'utf8'), fs.writeFile(resolvedJson, json, 'utf8')]);
|
|
470
|
+
return { mdPath: resolvedMd, jsonPath: resolvedJson, archivedEntry };
|
|
471
|
+
}
|
|
472
|
+
async function loadPreviousReport(path) {
|
|
473
|
+
try {
|
|
474
|
+
const raw = await fs.readFile(path, 'utf8');
|
|
475
|
+
return JSON.parse(raw);
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
export async function computeTrend(report, previousReport, history) {
|
|
482
|
+
if (!previousReport)
|
|
483
|
+
return null;
|
|
484
|
+
try {
|
|
485
|
+
const currentIssues = report.issues || [];
|
|
486
|
+
const previousIssues = Array.isArray(previousReport.issues)
|
|
487
|
+
? previousReport.issues
|
|
488
|
+
: [];
|
|
489
|
+
const currentIds = new Set(trendIssueKeys(currentIssues, report.repoPath));
|
|
490
|
+
const previousIds = new Set(trendIssueKeys(previousIssues));
|
|
491
|
+
// R2: derive new/resolved ids from the DEDUPLICATED id sets, not by
|
|
492
|
+
// filtering the raw (possibly duplicated) issues arrays. The old code
|
|
493
|
+
// assumed every issue in `currentIssues`/`previousIssues` had a unique
|
|
494
|
+
// id — if a detector bug ever emits the same id for two different
|
|
495
|
+
// findings (the exact BUG-B class of bug, now fixed at the source, but
|
|
496
|
+
// this function shouldn't silently corrupt counts if it recurs), both
|
|
497
|
+
// duplicates got counted/listed, inflating newIssuesCount/
|
|
498
|
+
// resolvedIssuesCount and putting the same id twice in
|
|
499
|
+
// newIssueIds/resolvedIssueIds.
|
|
500
|
+
const newIssueIds = [...currentIds].filter((id) => !previousIds.has(id));
|
|
501
|
+
const resolvedIssueIds = [...previousIds].filter((id) => !currentIds.has(id));
|
|
502
|
+
const categories = new Set([
|
|
503
|
+
...currentIssues.map((i) => i.category),
|
|
504
|
+
...previousIssues.map((i) => i.category),
|
|
505
|
+
].filter((category) => typeof category === 'string'));
|
|
506
|
+
const categoryDeltas = {};
|
|
507
|
+
for (const cat of categories) {
|
|
508
|
+
if (!cat)
|
|
509
|
+
continue;
|
|
510
|
+
const currentCount = currentIssues.filter((i) => i.category === cat).length;
|
|
511
|
+
const previousCount = previousIssues.filter((i) => i.category === cat).length;
|
|
512
|
+
categoryDeltas[cat] = currentCount - previousCount;
|
|
513
|
+
}
|
|
514
|
+
const severities = ['critical', 'high', 'warning', 'info'];
|
|
515
|
+
const severityDeltas = {};
|
|
516
|
+
for (const sev of severities) {
|
|
517
|
+
const currentCount = currentIssues.filter((i) => i.severity === sev).length;
|
|
518
|
+
const previousCount = previousIssues.filter((i) => i.severity === sev).length;
|
|
519
|
+
severityDeltas[sev] = currentCount - previousCount;
|
|
520
|
+
}
|
|
521
|
+
const currentHighOrCriticalCount = currentIssues.filter((i) => i.severity === 'high' || i.severity === 'critical').length;
|
|
522
|
+
let streak = 0;
|
|
523
|
+
if (currentHighOrCriticalCount === 0) {
|
|
524
|
+
streak = 1;
|
|
525
|
+
const prevHighOrCriticalCount = previousIssues.filter((i) => i.severity === 'high' || i.severity === 'critical').length;
|
|
526
|
+
if (prevHighOrCriticalCount === 0) {
|
|
527
|
+
streak++;
|
|
528
|
+
// Go backwards through history
|
|
529
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
530
|
+
const h = history[i];
|
|
531
|
+
if (h && (h.issueCount.high ?? 0) === 0 && (h.issueCount.critical ?? 0) === 0) {
|
|
532
|
+
streak++;
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
const prevDate = typeof previousReport.generatedAt === 'string' ? previousReport.generatedAt : undefined;
|
|
541
|
+
const prevScore = typeof previousReport.healthScore === 'number' ? previousReport.healthScore : 0;
|
|
542
|
+
return {
|
|
543
|
+
previousScanDate: prevDate,
|
|
544
|
+
scoreDelta: report.healthScore - prevScore,
|
|
545
|
+
newIssuesCount: newIssueIds.length,
|
|
546
|
+
resolvedIssuesCount: resolvedIssueIds.length,
|
|
547
|
+
severityDeltas,
|
|
548
|
+
categoryDeltas,
|
|
549
|
+
newIssueIds,
|
|
550
|
+
resolvedIssueIds,
|
|
551
|
+
streak,
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
catch {
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
package/dist/scan.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main scan pipeline: discovers files, detects project type, runs detectors,
|
|
3
|
+
* computes health score, and assembles a ScanReport.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScanInput, ScanReport } from './types.js';
|
|
6
|
+
export declare function scan(input: ScanInput): Promise<ScanReport>;
|
|
7
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExD,wBAAsB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAqChE"}
|
package/dist/scan.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main scan pipeline: discovers files, detects project type, runs detectors,
|
|
3
|
+
* computes health score, and assembles a ScanReport.
|
|
4
|
+
*/
|
|
5
|
+
import { buildRepoContext } from './repo-context.js';
|
|
6
|
+
import { runDetectors } from './detectors.js';
|
|
7
|
+
import { parseSuppressions, buildValidationIssues, applySuppressions } from './suppression.js';
|
|
8
|
+
import { computeHealthScore, selectTopFixes } from './health-score.js';
|
|
9
|
+
import { filterNewIssues } from './baseline.js';
|
|
10
|
+
export async function scan(input) {
|
|
11
|
+
const context = await buildRepoContext(input);
|
|
12
|
+
const issues = runDetectors(context, 'scan');
|
|
13
|
+
// Apply inline suppression annotations.
|
|
14
|
+
// Invalid annotations are surfaced as warning issues (count against score).
|
|
15
|
+
// Suppressed issues are excluded from health score and topFixes.
|
|
16
|
+
const annotations = parseSuppressions(context.files);
|
|
17
|
+
const allIssues = [...issues, ...buildValidationIssues(annotations)];
|
|
18
|
+
const { active, suppressed } = applySuppressions(allIssues, annotations);
|
|
19
|
+
const healthScore = computeHealthScore(active);
|
|
20
|
+
const topFixes = selectTopFixes(active);
|
|
21
|
+
let newIssues;
|
|
22
|
+
let baselinedIssues;
|
|
23
|
+
if (input.baseline) {
|
|
24
|
+
const filtered = filterNewIssues(active, input.baseline, context.repoRoot);
|
|
25
|
+
newIssues = filtered.newIssues;
|
|
26
|
+
baselinedIssues = filtered.baselinedIssues;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
schemaVersion: '0.1',
|
|
30
|
+
generatedAt: new Date().toISOString(),
|
|
31
|
+
repoPath: context.repoRoot,
|
|
32
|
+
projectType: context.projectType,
|
|
33
|
+
healthScore,
|
|
34
|
+
metrics: context.metrics,
|
|
35
|
+
filesScanned: context.files,
|
|
36
|
+
issues: active,
|
|
37
|
+
topFixes,
|
|
38
|
+
newIssues,
|
|
39
|
+
baselinedIssues,
|
|
40
|
+
suppressedIssues: suppressed.length > 0 ? suppressed : undefined,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=scan.js.map
|
package/dist/scan.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAAgB;IACzC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE7C,wCAAwC;IACxC,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC;IACrE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAEzE,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAExC,IAAI,SAAS,CAAC;IACd,IAAI,eAAe,CAAC;IAEpB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3E,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC/B,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;IAC7C,CAAC;IAED,OAAO;QACL,aAAa,EAAE,KAAK;QACpB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW;QACX,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,YAAY,EAAE,OAAO,CAAC,KAAK;QAC3B,MAAM,EAAE,MAAM;QACd,QAAQ;QACR,SAAS;QACT,eAAe;QACf,gBAAgB,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;KACjE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,eAAe,EAAsB,SAAS,EAAE,MAAM,YAAY,CAAC;AAoK3F,wBAAsB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA6D5E"}
|