afterburn-cli 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.
Files changed (188) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +281 -0
  3. package/dist/ai/gemini-client.d.ts +21 -0
  4. package/dist/ai/gemini-client.js +105 -0
  5. package/dist/ai/gemini-client.js.map +1 -0
  6. package/dist/ai/index.d.ts +1 -0
  7. package/dist/ai/index.js +3 -0
  8. package/dist/ai/index.js.map +1 -0
  9. package/dist/analysis/diagnosis-schema.d.ts +106 -0
  10. package/dist/analysis/diagnosis-schema.js +54 -0
  11. package/dist/analysis/diagnosis-schema.js.map +1 -0
  12. package/dist/analysis/error-analyzer.d.ts +9 -0
  13. package/dist/analysis/error-analyzer.js +573 -0
  14. package/dist/analysis/error-analyzer.js.map +1 -0
  15. package/dist/analysis/index.d.ts +4 -0
  16. package/dist/analysis/index.js +6 -0
  17. package/dist/analysis/index.js.map +1 -0
  18. package/dist/analysis/source-mapper.d.ts +19 -0
  19. package/dist/analysis/source-mapper.js +329 -0
  20. package/dist/analysis/source-mapper.js.map +1 -0
  21. package/dist/analysis/ui-auditor.d.ts +9 -0
  22. package/dist/analysis/ui-auditor.js +104 -0
  23. package/dist/analysis/ui-auditor.js.map +1 -0
  24. package/dist/artifacts/artifact-storage.d.ts +44 -0
  25. package/dist/artifacts/artifact-storage.js +99 -0
  26. package/dist/artifacts/artifact-storage.js.map +1 -0
  27. package/dist/artifacts/index.d.ts +1 -0
  28. package/dist/artifacts/index.js +3 -0
  29. package/dist/artifacts/index.js.map +1 -0
  30. package/dist/browser/browser-manager.d.ts +45 -0
  31. package/dist/browser/browser-manager.js +88 -0
  32. package/dist/browser/browser-manager.js.map +1 -0
  33. package/dist/browser/challenge-detector.d.ts +10 -0
  34. package/dist/browser/challenge-detector.js +58 -0
  35. package/dist/browser/challenge-detector.js.map +1 -0
  36. package/dist/browser/cookie-dismisser.d.ts +18 -0
  37. package/dist/browser/cookie-dismisser.js +76 -0
  38. package/dist/browser/cookie-dismisser.js.map +1 -0
  39. package/dist/browser/index.d.ts +4 -0
  40. package/dist/browser/index.js +6 -0
  41. package/dist/browser/index.js.map +1 -0
  42. package/dist/browser/stealth-browser.d.ts +13 -0
  43. package/dist/browser/stealth-browser.js +59 -0
  44. package/dist/browser/stealth-browser.js.map +1 -0
  45. package/dist/cli/commander-cli.d.ts +2 -0
  46. package/dist/cli/commander-cli.js +150 -0
  47. package/dist/cli/commander-cli.js.map +1 -0
  48. package/dist/cli/doctor.d.ts +34 -0
  49. package/dist/cli/doctor.js +124 -0
  50. package/dist/cli/doctor.js.map +1 -0
  51. package/dist/cli/first-run.d.ts +6 -0
  52. package/dist/cli/first-run.js +58 -0
  53. package/dist/cli/first-run.js.map +1 -0
  54. package/dist/cli/index.d.ts +3 -0
  55. package/dist/cli/index.js +5 -0
  56. package/dist/cli/index.js.map +1 -0
  57. package/dist/cli/progress.d.ts +11 -0
  58. package/dist/cli/progress.js +30 -0
  59. package/dist/cli/progress.js.map +1 -0
  60. package/dist/core/engine.d.ts +33 -0
  61. package/dist/core/engine.js +269 -0
  62. package/dist/core/engine.js.map +1 -0
  63. package/dist/core/index.d.ts +3 -0
  64. package/dist/core/index.js +4 -0
  65. package/dist/core/index.js.map +1 -0
  66. package/dist/core/validation.d.ts +52 -0
  67. package/dist/core/validation.js +228 -0
  68. package/dist/core/validation.js.map +1 -0
  69. package/dist/discovery/crawler.d.ts +58 -0
  70. package/dist/discovery/crawler.js +240 -0
  71. package/dist/discovery/crawler.js.map +1 -0
  72. package/dist/discovery/discovery-pipeline.d.ts +22 -0
  73. package/dist/discovery/discovery-pipeline.js +256 -0
  74. package/dist/discovery/discovery-pipeline.js.map +1 -0
  75. package/dist/discovery/element-mapper.d.ts +21 -0
  76. package/dist/discovery/element-mapper.js +422 -0
  77. package/dist/discovery/element-mapper.js.map +1 -0
  78. package/dist/discovery/index.d.ts +8 -0
  79. package/dist/discovery/index.js +8 -0
  80. package/dist/discovery/index.js.map +1 -0
  81. package/dist/discovery/link-validator.d.ts +15 -0
  82. package/dist/discovery/link-validator.js +137 -0
  83. package/dist/discovery/link-validator.js.map +1 -0
  84. package/dist/discovery/sitemap-builder.d.ts +19 -0
  85. package/dist/discovery/sitemap-builder.js +166 -0
  86. package/dist/discovery/sitemap-builder.js.map +1 -0
  87. package/dist/discovery/spa-detector.d.ts +12 -0
  88. package/dist/discovery/spa-detector.js +271 -0
  89. package/dist/discovery/spa-detector.js.map +1 -0
  90. package/dist/execution/error-detector.d.ts +10 -0
  91. package/dist/execution/error-detector.js +87 -0
  92. package/dist/execution/error-detector.js.map +1 -0
  93. package/dist/execution/evidence-capture.d.ts +8 -0
  94. package/dist/execution/evidence-capture.js +37 -0
  95. package/dist/execution/evidence-capture.js.map +1 -0
  96. package/dist/execution/index.d.ts +5 -0
  97. package/dist/execution/index.js +7 -0
  98. package/dist/execution/index.js.map +1 -0
  99. package/dist/execution/step-handlers.d.ts +48 -0
  100. package/dist/execution/step-handlers.js +349 -0
  101. package/dist/execution/step-handlers.js.map +1 -0
  102. package/dist/execution/test-data.d.ts +50 -0
  103. package/dist/execution/test-data.js +160 -0
  104. package/dist/execution/test-data.js.map +1 -0
  105. package/dist/execution/workflow-executor.d.ts +56 -0
  106. package/dist/execution/workflow-executor.js +331 -0
  107. package/dist/execution/workflow-executor.js.map +1 -0
  108. package/dist/index.d.ts +2 -0
  109. package/dist/index.js +5 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/mcp/entry.d.ts +2 -0
  112. package/dist/mcp/entry.js +5 -0
  113. package/dist/mcp/entry.js.map +1 -0
  114. package/dist/mcp/index.d.ts +2 -0
  115. package/dist/mcp/index.js +4 -0
  116. package/dist/mcp/index.js.map +1 -0
  117. package/dist/mcp/server.d.ts +3 -0
  118. package/dist/mcp/server.js +19 -0
  119. package/dist/mcp/server.js.map +1 -0
  120. package/dist/mcp/tools.d.ts +2 -0
  121. package/dist/mcp/tools.js +162 -0
  122. package/dist/mcp/tools.js.map +1 -0
  123. package/dist/planning/heuristic-planner.d.ts +7 -0
  124. package/dist/planning/heuristic-planner.js +238 -0
  125. package/dist/planning/heuristic-planner.js.map +1 -0
  126. package/dist/planning/index.d.ts +3 -0
  127. package/dist/planning/index.js +5 -0
  128. package/dist/planning/index.js.map +1 -0
  129. package/dist/planning/plan-schema.d.ts +74 -0
  130. package/dist/planning/plan-schema.js +39 -0
  131. package/dist/planning/plan-schema.js.map +1 -0
  132. package/dist/planning/workflow-planner.d.ts +39 -0
  133. package/dist/planning/workflow-planner.js +211 -0
  134. package/dist/planning/workflow-planner.js.map +1 -0
  135. package/dist/reports/health-scorer.d.ts +14 -0
  136. package/dist/reports/health-scorer.js +88 -0
  137. package/dist/reports/health-scorer.js.map +1 -0
  138. package/dist/reports/html-generator.d.ts +10 -0
  139. package/dist/reports/html-generator.js +155 -0
  140. package/dist/reports/html-generator.js.map +1 -0
  141. package/dist/reports/index.d.ts +4 -0
  142. package/dist/reports/index.js +6 -0
  143. package/dist/reports/index.js.map +1 -0
  144. package/dist/reports/markdown-generator.d.ts +10 -0
  145. package/dist/reports/markdown-generator.js +334 -0
  146. package/dist/reports/markdown-generator.js.map +1 -0
  147. package/dist/reports/priority-ranker.d.ts +22 -0
  148. package/dist/reports/priority-ranker.js +608 -0
  149. package/dist/reports/priority-ranker.js.map +1 -0
  150. package/dist/screenshots/dual-format.d.ts +14 -0
  151. package/dist/screenshots/dual-format.js +59 -0
  152. package/dist/screenshots/dual-format.js.map +1 -0
  153. package/dist/screenshots/index.d.ts +2 -0
  154. package/dist/screenshots/index.js +4 -0
  155. package/dist/screenshots/index.js.map +1 -0
  156. package/dist/screenshots/screenshot-manager.d.ts +33 -0
  157. package/dist/screenshots/screenshot-manager.js +86 -0
  158. package/dist/screenshots/screenshot-manager.js.map +1 -0
  159. package/dist/testing/accessibility-auditor.d.ts +23 -0
  160. package/dist/testing/accessibility-auditor.js +44 -0
  161. package/dist/testing/accessibility-auditor.js.map +1 -0
  162. package/dist/testing/index.d.ts +4 -0
  163. package/dist/testing/index.js +5 -0
  164. package/dist/testing/index.js.map +1 -0
  165. package/dist/testing/meta-auditor.d.ts +16 -0
  166. package/dist/testing/meta-auditor.js +268 -0
  167. package/dist/testing/meta-auditor.js.map +1 -0
  168. package/dist/testing/performance-monitor.d.ts +15 -0
  169. package/dist/testing/performance-monitor.js +64 -0
  170. package/dist/testing/performance-monitor.js.map +1 -0
  171. package/dist/types/artifacts.d.ts +58 -0
  172. package/dist/types/artifacts.js +3 -0
  173. package/dist/types/artifacts.js.map +1 -0
  174. package/dist/types/discovery.d.ts +124 -0
  175. package/dist/types/discovery.js +3 -0
  176. package/dist/types/discovery.js.map +1 -0
  177. package/dist/types/execution.d.ts +154 -0
  178. package/dist/types/execution.js +3 -0
  179. package/dist/types/execution.js.map +1 -0
  180. package/dist/types/index.d.ts +2 -0
  181. package/dist/types/index.js +4 -0
  182. package/dist/types/index.js.map +1 -0
  183. package/dist/utils/sanitizer.d.ts +25 -0
  184. package/dist/utils/sanitizer.js +98 -0
  185. package/dist/utils/sanitizer.js.map +1 -0
  186. package/package.json +86 -0
  187. package/templates/report.hbs +202 -0
  188. package/templates/styles/report.css +607 -0
@@ -0,0 +1,334 @@
1
+ // Generates structured Markdown reports with YAML frontmatter for AI coding tool consumption
2
+ import fs from 'fs-extra';
3
+ import { dirname } from 'node:path';
4
+ import { calculateHealthScore } from './health-scorer.js';
5
+ import { prioritizeIssues, deduplicateIssues } from './priority-ranker.js';
6
+ import { redactSensitiveUrl, sanitizeForYaml, redactSensitiveData, sanitizeForMarkdownInline } from '../utils/sanitizer.js';
7
+ const REPORT_SCHEMA_VERSION = '1.1.0';
8
+ /**
9
+ * Redact sensitive data from text before inserting into reports.
10
+ * Strips query params with sensitive keys, truncates stack traces, replaces file paths with basename.
11
+ */
12
+ function redactSensitive(text) {
13
+ if (!text)
14
+ return text;
15
+ let result = text;
16
+ // Strip sensitive query params from URLs
17
+ result = result.replace(/\b(https?:\/\/[^\s]+\?[^\s]*)/g, (url) => {
18
+ try {
19
+ const parsed = new URL(url);
20
+ const sensitiveKeys = ['key', 'token', 'secret', 'password', 'auth', 'api', 'apikey', 'api_key', 'access_token', 'auth_token', 'session', 'jwt'];
21
+ for (const key of sensitiveKeys) {
22
+ if (parsed.searchParams.has(key)) {
23
+ parsed.searchParams.set(key, '[REDACTED]');
24
+ }
25
+ }
26
+ return parsed.toString();
27
+ }
28
+ catch {
29
+ return url;
30
+ }
31
+ });
32
+ // Truncate stack traces to first 3 lines
33
+ const lines = result.split('\n');
34
+ if (lines.length > 3 && lines.some(line => line.match(/^\s*at\s+/))) {
35
+ const stackStart = lines.findIndex(line => line.match(/^\s*at\s+/));
36
+ if (stackStart >= 0 && lines.length > stackStart + 3) {
37
+ result = lines.slice(0, stackStart + 3).join('\n') + '\n... (stack trace truncated)';
38
+ }
39
+ }
40
+ // Replace full file paths with basename only (remove directory info)
41
+ result = result.replace(/([A-Z]:[\/\\]|\/[^\/\s]+\/)[^\s:]+([\/\\][^\s:]+)/g, (match) => {
42
+ const lastSep = Math.max(match.lastIndexOf('/'), match.lastIndexOf('\\'));
43
+ return lastSep >= 0 ? match.substring(lastSep + 1) : match;
44
+ });
45
+ // Apply general sensitive data redaction
46
+ result = redactSensitiveData(result);
47
+ return result;
48
+ }
49
+ /**
50
+ * Sanitize text for safe inclusion in Markdown tables.
51
+ * Escapes pipes, replaces newlines, escapes backticks in inline contexts, truncates long fields.
52
+ */
53
+ function sanitizeForMarkdownTable(text) {
54
+ if (!text)
55
+ return '';
56
+ let result = text;
57
+ // Escape pipe characters
58
+ result = result.replace(/\|/g, '\\|');
59
+ // Replace newlines with spaces
60
+ result = result.replace(/\n/g, ' ');
61
+ // Escape backticks in inline contexts (prevent code block injection)
62
+ result = result.replace(/`/g, '\\`');
63
+ // Truncate overly long fields
64
+ if (result.length > 200) {
65
+ result = result.slice(0, 197) + '...';
66
+ }
67
+ return result;
68
+ }
69
+ /**
70
+ * Generate YAML frontmatter with machine-readable metadata
71
+ */
72
+ function generateFrontmatter(exec, analysis, healthScore, dedupedIssueCount) {
73
+ const workflowsPassed = exec.workflowResults.filter(w => w.overallStatus === 'passed').length;
74
+ const workflowsFailed = exec.workflowResults.filter(w => w.overallStatus === 'failed').length;
75
+ return `---
76
+ tool: afterburn
77
+ schema_version: ${REPORT_SCHEMA_VERSION}
78
+ session_id: ${sanitizeForYaml(exec.sessionId)}
79
+ generated_at_utc: ${new Date().toISOString()}
80
+ timestamp: ${exec.timestamp}
81
+ target_url: ${sanitizeForYaml(redactSensitiveUrl(exec.targetUrl))}
82
+ health_score: ${healthScore.overall}
83
+ health_label: ${healthScore.label}
84
+ total_issues: ${dedupedIssueCount}
85
+ workflows_tested: ${exec.workflowResults.length}
86
+ workflows_passed: ${workflowsPassed}
87
+ workflows_failed: ${workflowsFailed}
88
+ ai_powered: ${analysis.aiPowered}
89
+ source_analysis: ${analysis.sourceAnalysisAvailable}
90
+ ---`;
91
+ }
92
+ /**
93
+ * Generate prioritized issue table
94
+ */
95
+ function generateIssueTable(issues) {
96
+ if (issues.length === 0) {
97
+ return 'No issues found.';
98
+ }
99
+ const rows = issues.map((issue, i) => {
100
+ const priorityLabel = issue.priority.toUpperCase();
101
+ let summaryText = issue.summary;
102
+ if (issue.occurrenceCount && issue.occurrenceCount > 1) {
103
+ summaryText += ` (x${issue.occurrenceCount})`;
104
+ }
105
+ const summaryTruncated = summaryText.length > 80 ? summaryText.slice(0, 77) + '...' : summaryText;
106
+ const safeLocation = redactSensitiveUrl(issue.location);
107
+ return `| ${i + 1} | ${priorityLabel} | ${sanitizeForMarkdownTable(issue.category)} | ${sanitizeForMarkdownTable(summaryTruncated)} | ${sanitizeForMarkdownTable(safeLocation)} |`;
108
+ });
109
+ return `| # | Priority | Category | Summary | Location |
110
+ |---|----------|----------|---------|----------|
111
+ ${rows.join('\n')}`;
112
+ }
113
+ /**
114
+ * Generate technical details section with original error messages
115
+ */
116
+ function generateTechnicalDetails(diagnosedErrors) {
117
+ if (diagnosedErrors.length === 0) {
118
+ return 'No errors diagnosed.';
119
+ }
120
+ return diagnosedErrors.map((error, i) => {
121
+ let details = `### ${i + 1}. ${sanitizeForMarkdownTable(error.summary)}
122
+
123
+ - **Error Type:** ${sanitizeForMarkdownTable(error.errorType)}
124
+ - **Confidence:** ${error.confidence}
125
+ - **Root Cause:** ${sanitizeForMarkdownTable(error.rootCause)}
126
+ - **Suggested Fix:** ${sanitizeForMarkdownTable(error.suggestedFix)}
127
+ - **Original Error:** \`${redactSensitive(error.originalError)}\``;
128
+ if (error.technicalDetails) {
129
+ details += `\n- **Technical Details:** ${sanitizeForMarkdownTable(error.technicalDetails)}`;
130
+ }
131
+ if (error.sourceLocation) {
132
+ const redactedContext = redactSensitive(error.sourceLocation.context || '');
133
+ details += `\n- **Source:** \`${error.sourceLocation.file}:${error.sourceLocation.line}\`
134
+ - **Code Context:**
135
+ \`\`\`typescript
136
+ ${redactedContext}
137
+ \`\`\``;
138
+ }
139
+ return details;
140
+ }).join('\n\n');
141
+ }
142
+ /**
143
+ * Generate reproduction steps from failed workflow results
144
+ */
145
+ function generateReproductionSteps(workflowResults) {
146
+ const failedWorkflows = workflowResults.filter(w => w.overallStatus === 'failed');
147
+ if (failedWorkflows.length === 0) {
148
+ return 'All workflows passed successfully.';
149
+ }
150
+ return failedWorkflows.map(workflow => {
151
+ const steps = workflow.stepResults.map((step, i) => {
152
+ let stepLine = `${i + 1}. ${sanitizeForMarkdownTable(step.action)} on \`${sanitizeForMarkdownTable(step.selector || '')}\` - ${step.status}`;
153
+ if (step.error) {
154
+ stepLine += `\n Error: ${redactSensitive(step.error)}`;
155
+ }
156
+ return stepLine;
157
+ }).join('\n');
158
+ return `### ${sanitizeForMarkdownTable(workflow.workflowName)}
159
+
160
+ **Description:** ${sanitizeForMarkdownTable(workflow.description)}
161
+ **Status:** Failed (${workflow.failedSteps}/${workflow.totalSteps} steps failed)
162
+ **Duration:** ${workflow.duration}ms
163
+
164
+ **Steps:**
165
+ ${steps}`;
166
+ }).join('\n\n');
167
+ }
168
+ /**
169
+ * Generate UI audit section with layout, contrast, and formatting issues
170
+ */
171
+ function generateUIAuditSection(uiAudits) {
172
+ if (uiAudits.length === 0) {
173
+ return 'No UI audits performed.';
174
+ }
175
+ return uiAudits.map(audit => {
176
+ let section = `### ${redactSensitiveUrl(audit.pageUrl)}
177
+
178
+ **Overall Score:** ${audit.overallScore}`;
179
+ if (audit.layoutIssues.length > 0) {
180
+ section += '\n\n**Layout Issues:**\n' + audit.layoutIssues.map(issue => `- [${issue.severity}] ${sanitizeForMarkdownTable(issue.description)} at ${sanitizeForMarkdownTable(issue.location)}`).join('\n');
181
+ }
182
+ if (audit.contrastIssues.length > 0) {
183
+ section += '\n\n**Contrast Issues:**\n' + audit.contrastIssues.map(issue => `- ${sanitizeForMarkdownTable(issue.element)}: ${sanitizeForMarkdownTable(issue.issue)} - Fix: ${sanitizeForMarkdownTable(issue.suggestion)}`).join('\n');
184
+ }
185
+ if (audit.formattingIssues.length > 0) {
186
+ section += '\n\n**Formatting Issues:**\n' + audit.formattingIssues.map(issue => `- ${sanitizeForMarkdownTable(issue.problem)} - Fix: ${sanitizeForMarkdownTable(issue.suggestion)}`).join('\n');
187
+ }
188
+ if (audit.improvements.length > 0) {
189
+ section += '\n\n**Improvements:**\n' + audit.improvements.map(improvement => `- ${sanitizeForMarkdownTable(improvement)}`).join('\n');
190
+ }
191
+ return section;
192
+ }).join('\n\n');
193
+ }
194
+ /**
195
+ * Generate source code references section
196
+ */
197
+ function generateSourceReferences(diagnosedErrors) {
198
+ const errorsWithSource = diagnosedErrors.filter(e => e.sourceLocation);
199
+ if (errorsWithSource.length === 0) {
200
+ return 'No source code references available. Run with `--source ./path` for source-level diagnosis.';
201
+ }
202
+ return errorsWithSource.map(error => `- \`${error.sourceLocation.file}:${error.sourceLocation.line}\` - ${sanitizeForMarkdownTable(error.summary)}`).join('\n');
203
+ }
204
+ /**
205
+ * Generate accessibility summary with aggregated violations
206
+ */
207
+ function generateAccessibilitySummary(executionArtifact) {
208
+ const pageAudits = executionArtifact.pageAudits.filter(a => a.accessibility);
209
+ if (pageAudits.length === 0) {
210
+ return 'No accessibility audits performed.';
211
+ }
212
+ // Build summary table
213
+ const rows = pageAudits.map(audit => {
214
+ const report = audit.accessibility;
215
+ const critical = report.violations.filter(v => v.impact === 'critical').length;
216
+ const serious = report.violations.filter(v => v.impact === 'serious').length;
217
+ const moderate = report.violations.filter(v => v.impact === 'moderate').length;
218
+ const minor = report.violations.filter(v => v.impact === 'minor').length;
219
+ const total = report.violationCount;
220
+ return `| ${sanitizeForMarkdownTable(redactSensitiveUrl(audit.url))} | ${critical} | ${serious} | ${moderate} | ${minor} | ${total} |`;
221
+ });
222
+ let summary = `| Page | Critical | Serious | Moderate | Minor | Total |
223
+ |------|----------|---------|----------|-------|-------|
224
+ ${rows.join('\n')}`;
225
+ // Find top violations (most common across pages)
226
+ const violationCounts = new Map();
227
+ for (const audit of pageAudits) {
228
+ for (const violation of audit.accessibility.violations) {
229
+ const existing = violationCounts.get(violation.id);
230
+ if (existing) {
231
+ existing.count += violation.nodes;
232
+ }
233
+ else {
234
+ violationCounts.set(violation.id, {
235
+ count: violation.nodes,
236
+ description: violation.description,
237
+ helpUrl: violation.helpUrl,
238
+ });
239
+ }
240
+ }
241
+ }
242
+ if (violationCounts.size > 0) {
243
+ const topViolations = Array.from(violationCounts.entries())
244
+ .sort((a, b) => b[1].count - a[1].count)
245
+ .slice(0, 5);
246
+ summary += '\n\n**Top Violations:**\n' + topViolations.map(([id, data]) => `- **${sanitizeForMarkdownInline(data.description)}** (${data.count} elements) - [Learn more](${redactSensitiveUrl(data.helpUrl)})`).join('\n');
247
+ }
248
+ return summary;
249
+ }
250
+ /**
251
+ * Generate complete Markdown report with YAML frontmatter
252
+ */
253
+ export function generateMarkdownReport(executionArtifact, analysisArtifact) {
254
+ const healthScore = calculateHealthScore(executionArtifact);
255
+ const prioritizedIssues = deduplicateIssues(prioritizeIssues(analysisArtifact.diagnosedErrors, analysisArtifact.uiAudits, executionArtifact));
256
+ const frontmatter = generateFrontmatter(executionArtifact, analysisArtifact, healthScore, prioritizedIssues.length);
257
+ const issueTable = generateIssueTable(prioritizedIssues);
258
+ const technicalDetails = generateTechnicalDetails(analysisArtifact.diagnosedErrors);
259
+ const reproductionSteps = generateReproductionSteps(executionArtifact.workflowResults);
260
+ const uiAuditSection = generateUIAuditSection(analysisArtifact.uiAudits);
261
+ const accessibilitySummary = generateAccessibilitySummary(executionArtifact);
262
+ const sourceReferences = generateSourceReferences(analysisArtifact.diagnosedErrors);
263
+ // Format timestamp for display (ISO format for machine readability)
264
+ const readableTimestamp = new Date(executionArtifact.timestamp).toISOString();
265
+ const mode = analysisArtifact.aiPowered ? 'AI-powered' : 'Basic';
266
+ // Count specific issue types
267
+ const deadButtonCount = executionArtifact.deadButtons.filter(b => b.isDead).length;
268
+ const brokenFormCount = executionArtifact.brokenForms.filter(f => f.isBroken).length;
269
+ const brokenLinkCount = executionArtifact.brokenLinks.length;
270
+ const accessibilityViolations = executionArtifact.pageAudits.reduce((sum, audit) => sum + (audit.accessibility?.violationCount || 0), 0);
271
+ const workflowsPassed = executionArtifact.workflowResults.filter(w => w.overallStatus === 'passed').length;
272
+ const workflowsFailed = executionArtifact.workflowResults.filter(w => w.overallStatus === 'failed').length;
273
+ return `${frontmatter}
274
+
275
+ # Afterburn Test Report
276
+
277
+ **Target:** ${redactSensitiveUrl(executionArtifact.targetUrl)}
278
+ **Health Score:** ${healthScore.overall}/100 (${healthScore.label})
279
+ **Date:** ${readableTimestamp}
280
+ **Mode:** ${mode}
281
+
282
+ ## Summary
283
+
284
+ | Metric | Value |
285
+ |--------|-------|
286
+ | Workflows Tested | ${executionArtifact.workflowResults.length} |
287
+ | Workflows Passed | ${workflowsPassed} |
288
+ | Workflows Failed | ${workflowsFailed} |
289
+ | Total Issues | ${prioritizedIssues.length} |
290
+ | Dead Buttons | ${deadButtonCount} |
291
+ | Broken Forms | ${brokenFormCount} |
292
+ | Broken Links | ${brokenLinkCount} |
293
+ | Accessibility Violations | ${accessibilityViolations} |
294
+
295
+ ## Issues (Prioritized)
296
+
297
+ ${issueTable}
298
+
299
+ ## Issue Details
300
+
301
+ ${technicalDetails}
302
+
303
+ ## Reproduction Steps
304
+
305
+ ${reproductionSteps}
306
+
307
+ ## UI Audit Results
308
+
309
+ ${uiAuditSection}
310
+
311
+ ## Accessibility
312
+
313
+ ${accessibilitySummary}
314
+
315
+ ## Source Code References
316
+
317
+ ${sourceReferences}
318
+
319
+ ---
320
+ ${!analysisArtifact.aiPowered ? `
321
+ > **Tip:** Set \`GEMINI_API_KEY\` for smarter test planning and AI-powered root cause analysis. Get a free key at [aistudio.google.com/apikey](https://aistudio.google.com/apikey).
322
+
323
+ ` : ''}*Generated by Afterburn v1.0 on ${readableTimestamp}*
324
+ `;
325
+ }
326
+ /**
327
+ * Write Markdown report to file
328
+ */
329
+ export async function writeMarkdownReport(markdown, outputPath) {
330
+ await fs.ensureDir(dirname(outputPath));
331
+ await fs.writeFile(outputPath, markdown, 'utf-8');
332
+ console.log('Markdown report saved: ' + outputPath);
333
+ }
334
+ //# sourceMappingURL=markdown-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-generator.js","sourceRoot":"","sources":["../../src/reports/markdown-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { DiagnosedError, UIAuditResult } from '../analysis/diagnosis-schema.js';
2
+ import { ExecutionArtifact } from '../types/execution.js';
3
+ export type IssuePriority = 'high' | 'medium' | 'low';
4
+ export interface PrioritizedIssue {
5
+ priority: IssuePriority;
6
+ category: string;
7
+ summary: string;
8
+ impact: string;
9
+ fixSuggestion: string;
10
+ location: string;
11
+ screenshotRef?: string;
12
+ technicalDetails?: string;
13
+ occurrenceCount?: number;
14
+ }
15
+ export declare function prioritizeIssues(diagnosedErrors: DiagnosedError[], uiAudits: UIAuditResult[], executionArtifact: ExecutionArtifact): PrioritizedIssue[];
16
+ /**
17
+ * Deduplicate prioritized issues by grouping identical findings.
18
+ * Within each group, keeps the highest-priority instance and annotates with occurrence count.
19
+ * When issues from different pages are merged, aggregates unique page locations.
20
+ * Returns a new array sorted by priority (high > medium > low).
21
+ */
22
+ export declare function deduplicateIssues(issues: PrioritizedIssue[]): PrioritizedIssue[];