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,124 @@
1
+ // Pre-flight environment checks for Afterburn
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ import dns from 'node:dns';
6
+ /**
7
+ * Check Node.js version >= 18
8
+ */
9
+ export function checkNodeVersion() {
10
+ const version = process.versions.node;
11
+ const major = parseInt(version.split('.')[0], 10);
12
+ if (major >= 18) {
13
+ return { name: 'Node.js', status: 'pass', message: `v${version} (>= 18 required)`, required: true };
14
+ }
15
+ return { name: 'Node.js', status: 'fail', message: `v${version} (>= 18 required, yours is too old)`, required: true };
16
+ }
17
+ /**
18
+ * Check if Playwright Chromium browser is installed
19
+ */
20
+ export function checkBrowserInstalled() {
21
+ // Determine Playwright cache directory based on platform
22
+ // macOS: ~/Library/Caches/ms-playwright
23
+ // Windows: %LOCALAPPDATA%/ms-playwright
24
+ // Linux: ~/.cache/ms-playwright
25
+ let playwrightCache;
26
+ if (process.platform === 'darwin') {
27
+ playwrightCache = path.join(os.homedir(), 'Library', 'Caches', 'ms-playwright');
28
+ }
29
+ else if (process.platform === 'win32') {
30
+ playwrightCache = path.join(process.env.LOCALAPPDATA || os.homedir(), 'ms-playwright');
31
+ }
32
+ else {
33
+ playwrightCache = path.join(os.homedir(), '.cache', 'ms-playwright');
34
+ }
35
+ // Also check PLAYWRIGHT_BROWSERS_PATH env var if set
36
+ if (process.env.PLAYWRIGHT_BROWSERS_PATH) {
37
+ playwrightCache = process.env.PLAYWRIGHT_BROWSERS_PATH;
38
+ }
39
+ if (fs.existsSync(playwrightCache)) {
40
+ try {
41
+ const entries = fs.readdirSync(playwrightCache);
42
+ const found = entries.some((entry) => entry.startsWith('chromium-') || entry.startsWith('chromium_headless_shell-'));
43
+ if (found) {
44
+ return { name: 'Chromium browser', status: 'pass', message: 'Installed', required: true };
45
+ }
46
+ }
47
+ catch {
48
+ // Directory exists but can't be read
49
+ }
50
+ }
51
+ return {
52
+ name: 'Chromium browser',
53
+ status: 'fail',
54
+ message: 'Not found. Run: npx playwright install chromium',
55
+ required: true,
56
+ };
57
+ }
58
+ /**
59
+ * Check if GEMINI_API_KEY is set (optional, warn only)
60
+ */
61
+ export function checkApiKey() {
62
+ const key = process.env.GEMINI_API_KEY;
63
+ if (key && key.trim().length > 0) {
64
+ return { name: 'GEMINI_API_KEY', status: 'pass', message: 'Set', required: false };
65
+ }
66
+ return {
67
+ name: 'GEMINI_API_KEY',
68
+ status: 'warn',
69
+ message: 'Not set (AI features disabled, heuristic mode will be used)',
70
+ required: false,
71
+ };
72
+ }
73
+ /**
74
+ * Check network connectivity by resolving a known host
75
+ */
76
+ export async function checkNetwork() {
77
+ return new Promise((resolve) => {
78
+ const timeout = setTimeout(() => {
79
+ resolve({ name: 'Network', status: 'warn', message: 'DNS resolution timed out', required: false });
80
+ }, 5000);
81
+ dns.lookup('registry.npmjs.org', (err) => {
82
+ clearTimeout(timeout);
83
+ if (err) {
84
+ resolve({ name: 'Network', status: 'warn', message: 'Cannot resolve DNS (offline?)', required: false });
85
+ }
86
+ else {
87
+ resolve({ name: 'Network', status: 'pass', message: 'Connectivity OK', required: false });
88
+ }
89
+ });
90
+ });
91
+ }
92
+ /**
93
+ * Run all doctor checks and return results + exit code
94
+ */
95
+ export async function runDoctor() {
96
+ const results = [];
97
+ results.push(checkNodeVersion());
98
+ results.push(checkBrowserInstalled());
99
+ results.push(checkApiKey());
100
+ results.push(await checkNetwork());
101
+ const failedRequired = results.some(r => r.required && r.status === 'fail');
102
+ return { results, exitCode: failedRequired ? 1 : 0 };
103
+ }
104
+ /**
105
+ * Format and print doctor results to console
106
+ */
107
+ export function printDoctorResults(results, exitCode) {
108
+ console.log('Afterburn Doctor\n');
109
+ for (const result of results) {
110
+ const icon = result.status === 'pass' ? '[PASS]'
111
+ : result.status === 'warn' ? '[WARN]'
112
+ : '[FAIL]';
113
+ console.log(` ${icon} ${result.name}: ${result.message}`);
114
+ }
115
+ console.log('');
116
+ if (exitCode === 0) {
117
+ console.log('All checks passed! Ready to scan.');
118
+ }
119
+ else {
120
+ const failCount = results.filter(r => r.required && r.status === 'fail').length;
121
+ console.log(`${failCount} check(s) failed.`);
122
+ }
123
+ }
124
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,GAAG,MAAM,UAAU,CAAC;AAW3B;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAElD,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,OAAO,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACtG,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,OAAO,qCAAqC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACxH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,yDAAyD;IACzD,wCAAwC;IACxC,wCAAwC;IACxC,gCAAgC;IAChC,IAAI,eAAuB,CAAC;IAC5B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IAClF,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACxC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;IACzF,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACvE,CAAC;IAED,qDAAqD;IACrD,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QACzC,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACzD,CAAC;IAED,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CACxB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,0BAA0B,CAAC,CACzF,CAAC;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC5F,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,iDAAiD;QAC1D,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACvC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACrF,CAAC;IACD,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,6DAA6D;QACtE,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACrG,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,GAAG,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,EAAE;YACvC,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,+BAA+B,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1G,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC;IAEnC,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAC5E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAsB,EAAE,QAAgB;IACzE,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAElC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ;YAC9C,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ;gBACrC,CAAC,CAAC,QAAQ,CAAC;QAEb,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,mBAAmB,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Ensures Playwright Chromium browser is installed.
3
+ * On first run, downloads the browser (~150-280MB) with progress feedback.
4
+ * Throws if installation fails.
5
+ */
6
+ export declare function ensureBrowserInstalled(): Promise<void>;
@@ -0,0 +1,58 @@
1
+ // First-run browser installation check with progress feedback
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ import { execSync } from 'node:child_process';
6
+ import ora from 'ora';
7
+ /**
8
+ * Ensures Playwright Chromium browser is installed.
9
+ * On first run, downloads the browser (~150-280MB) with progress feedback.
10
+ * Throws if installation fails.
11
+ */
12
+ export async function ensureBrowserInstalled() {
13
+ const spinner = ora('Checking browser installation...').start();
14
+ try {
15
+ // Determine Playwright cache directory based on platform
16
+ // macOS: ~/Library/Caches/ms-playwright
17
+ // Windows: %LOCALAPPDATA%/ms-playwright
18
+ // Linux: ~/.cache/ms-playwright
19
+ let playwrightCache;
20
+ if (process.platform === 'darwin') {
21
+ playwrightCache = path.join(os.homedir(), 'Library', 'Caches', 'ms-playwright');
22
+ }
23
+ else if (process.platform === 'win32') {
24
+ playwrightCache = path.join(process.env.LOCALAPPDATA || os.homedir(), 'ms-playwright');
25
+ }
26
+ else {
27
+ playwrightCache = path.join(os.homedir(), '.cache', 'ms-playwright');
28
+ }
29
+ // Also check PLAYWRIGHT_BROWSERS_PATH env var if set
30
+ if (process.env.PLAYWRIGHT_BROWSERS_PATH) {
31
+ playwrightCache = process.env.PLAYWRIGHT_BROWSERS_PATH;
32
+ }
33
+ // Check if playwright cache exists and has chromium installations
34
+ // Modern Playwright uses chromium_headless_shell, older versions use chromium-
35
+ let browserFound = false;
36
+ if (fs.existsSync(playwrightCache)) {
37
+ const entries = fs.readdirSync(playwrightCache);
38
+ browserFound = entries.some((entry) => entry.startsWith('chromium-') || entry.startsWith('chromium_headless_shell-'));
39
+ }
40
+ if (browserFound) {
41
+ spinner.succeed('Browser ready');
42
+ return;
43
+ }
44
+ // Browser not found - need to download
45
+ spinner.text = 'First run: Downloading Chromium (150-280MB)... this may take a minute';
46
+ // Install chromium (suppress Playwright's own output by piping to null)
47
+ execSync('npx playwright install chromium', {
48
+ stdio: 'pipe',
49
+ encoding: 'utf-8',
50
+ });
51
+ spinner.succeed('Browser installed successfully');
52
+ }
53
+ catch (error) {
54
+ spinner.fail('Browser installation failed');
55
+ throw new Error('Failed to install Chromium. Run manually: npx playwright install chromium');
56
+ }
57
+ }
58
+ //# sourceMappingURL=first-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-run.js","sourceRoot":"","sources":["../../src/cli/first-run.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,kCAAkC,CAAC,CAAC,KAAK,EAAE,CAAC;IAEhE,IAAI,CAAC;QACH,yDAAyD;QACzD,wCAAwC;QACxC,wCAAwC;QACxC,gCAAgC;QAChC,IAAI,eAAuB,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QAClF,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACxC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QACvE,CAAC;QAED,qDAAqD;QACrD,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;YACzC,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;QACzD,CAAC;QAED,kEAAkE;QAClE,+EAA+E;QAC/E,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;YAChD,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACpC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAC9E,CAAC;QACJ,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,uCAAuC;QACvC,OAAO,CAAC,IAAI,GAAG,uEAAuE,CAAC;QAEvF,wEAAwE;QACxE,QAAQ,CAAC,iCAAiC,EAAE;YAC1C,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QAEH,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ensureBrowserInstalled } from './first-run.js';
2
+ export { createSpinner, withSpinner } from './progress.js';
3
+ export { program } from './commander-cli.js';
@@ -0,0 +1,5 @@
1
+ // Barrel export for CLI utilities
2
+ export { ensureBrowserInstalled } from './first-run.js';
3
+ export { createSpinner, withSpinner } from './progress.js';
4
+ export { program } from './commander-cli.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Ora } from 'ora';
2
+ /**
3
+ * Creates an ora spinner with consistent styling.
4
+ */
5
+ export declare function createSpinner(text: string): Ora;
6
+ /**
7
+ * Wraps an async function with a spinner that auto-succeeds or fails.
8
+ * Returns the result of the async function on success.
9
+ * Re-throws the error on failure after displaying spinner.fail().
10
+ */
11
+ export declare function withSpinner<T>(text: string, fn: () => Promise<T>): Promise<T>;
@@ -0,0 +1,30 @@
1
+ // Reusable CLI progress utilities
2
+ import ora from 'ora';
3
+ /**
4
+ * Creates an ora spinner with consistent styling.
5
+ */
6
+ export function createSpinner(text) {
7
+ return ora({
8
+ text,
9
+ color: 'cyan',
10
+ spinner: 'dots',
11
+ });
12
+ }
13
+ /**
14
+ * Wraps an async function with a spinner that auto-succeeds or fails.
15
+ * Returns the result of the async function on success.
16
+ * Re-throws the error on failure after displaying spinner.fail().
17
+ */
18
+ export async function withSpinner(text, fn) {
19
+ const spinner = createSpinner(text).start();
20
+ try {
21
+ const result = await fn();
22
+ spinner.succeed(`${text} done`);
23
+ return result;
24
+ }
25
+ catch (error) {
26
+ spinner.fail(`${text} failed`);
27
+ throw error;
28
+ }
29
+ }
30
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/cli/progress.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,GAAY,MAAM,KAAK,CAAC;AAE/B;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,GAAG,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,EAAoB;IAEpB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC;QAC/B,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { HealthScore, PrioritizedIssue } from '../reports/index.js';
2
+ import type { ExecutionArtifact } from '../types/execution.js';
3
+ import type { BrokenLink } from '../types/discovery.js';
4
+ export interface AfterBurnOptions {
5
+ targetUrl: string;
6
+ sessionId?: string;
7
+ sourcePath?: string;
8
+ email?: string;
9
+ password?: string;
10
+ outputDir?: string;
11
+ flowHints?: string[];
12
+ maxPages?: number;
13
+ headless?: boolean;
14
+ onProgress?: (stage: string, message: string) => void;
15
+ }
16
+ export interface AfterBurnResult {
17
+ healthScore: HealthScore;
18
+ prioritizedIssues: PrioritizedIssue[];
19
+ totalIssues: number;
20
+ highPriorityCount: number;
21
+ mediumPriorityCount: number;
22
+ lowPriorityCount: number;
23
+ workflowsPassed: number;
24
+ workflowsTotal: number;
25
+ htmlReportPath: string | null;
26
+ markdownReportPath: string | null;
27
+ exitCode: number;
28
+ sessionId: string;
29
+ warnings?: string[];
30
+ }
31
+ export declare function mergeDiscoveryBrokenLinks(executionArtifact: ExecutionArtifact, discoveryBrokenLinks: BrokenLink[]): void;
32
+ export declare function recalculateExecutionSummary(executionArtifact: ExecutionArtifact): void;
33
+ export declare function runAfterburn(options: AfterBurnOptions): Promise<AfterBurnResult>;
@@ -0,0 +1,269 @@
1
+ // Core pipeline engine - reusable function for CLI, MCP, and GitHub Action interfaces
2
+ import crypto from 'node:crypto';
3
+ import fs from 'fs-extra';
4
+ import path from 'node:path';
5
+ import { runDiscovery } from '../discovery/index.js';
6
+ import { WorkflowExecutor } from '../execution/index.js';
7
+ import { analyzeErrors, auditUI, mapErrorToSource } from '../analysis/index.js';
8
+ import { ArtifactStorage } from '../artifacts/index.js';
9
+ import { generateHtmlReport, writeHtmlReport, generateMarkdownReport, writeMarkdownReport, calculateHealthScore, prioritizeIssues, deduplicateIssues } from '../reports/index.js';
10
+ import { validatePublicUrl, validatePath, validateMaxPages } from './validation.js';
11
+ // Hard timeout to prevent the pipeline from hanging forever on unresponsive sites
12
+ const PIPELINE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
13
+ function toBrokenLinkIssue(link) {
14
+ return {
15
+ url: link.url,
16
+ sourceUrl: link.sourceUrl,
17
+ statusCode: link.statusCode,
18
+ statusText: link.statusText,
19
+ };
20
+ }
21
+ export function mergeDiscoveryBrokenLinks(executionArtifact, discoveryBrokenLinks) {
22
+ const existingKeys = new Set(executionArtifact.brokenLinks.map(link => `${link.url}|${link.sourceUrl}|${link.statusCode}`));
23
+ for (const link of discoveryBrokenLinks) {
24
+ const key = `${link.url}|${link.sourceUrl}|${link.statusCode}`;
25
+ if (!existingKeys.has(key)) {
26
+ executionArtifact.brokenLinks.push(toBrokenLinkIssue(link));
27
+ existingKeys.add(key);
28
+ }
29
+ }
30
+ }
31
+ export function recalculateExecutionSummary(executionArtifact) {
32
+ let totalIssues = 0;
33
+ totalIssues += executionArtifact.workflowResults.reduce((sum, result) => sum + result.failedSteps, 0);
34
+ totalIssues += executionArtifact.workflowResults.reduce((sum, result) => sum + result.errors.consoleErrors.length, 0);
35
+ totalIssues += executionArtifact.workflowResults.reduce((sum, result) => sum + result.errors.networkFailures.length, 0);
36
+ totalIssues += executionArtifact.workflowResults.reduce((sum, result) => sum + result.errors.brokenImages.length, 0);
37
+ totalIssues += executionArtifact.deadButtons.filter(button => button.isDead).length;
38
+ totalIssues += executionArtifact.brokenForms.filter(form => form.isBroken).length;
39
+ totalIssues += executionArtifact.brokenLinks.length;
40
+ totalIssues += executionArtifact.pageAudits.reduce((sum, audit) => {
41
+ if (!audit.accessibility)
42
+ return sum;
43
+ return sum + audit.accessibility.violations.filter(violation => violation.impact === 'critical' || violation.impact === 'serious').length;
44
+ }, 0);
45
+ executionArtifact.totalIssues = totalIssues;
46
+ executionArtifact.exitCode = (executionArtifact.workflowResults.some(result => result.overallStatus === 'failed') || totalIssues > 0) ? 1 : 0;
47
+ }
48
+ export async function runAfterburn(options) {
49
+ // Defense in depth: validate inputs even if caller already validated
50
+ const validatedTargetUrl = await validatePublicUrl(options.targetUrl);
51
+ const validatedSourcePath = options.sourcePath ? validatePath(options.sourcePath, 'sourcePath') : undefined;
52
+ const validatedMaxPages = validateMaxPages(options.maxPages);
53
+ // Generate sessionId if not provided, and sanitize it for filesystem safety
54
+ let sessionId = options.sessionId || crypto.randomUUID();
55
+ // Issue 17: Sanitize session ID to prevent path traversal in filenames
56
+ sessionId = sessionId.replace(/[^a-zA-Z0-9_-]/g, '-');
57
+ // Create outputDir if it doesn't exist
58
+ const outputDir = options.outputDir
59
+ ? validatePath(options.outputDir, 'outputDir')
60
+ : `./afterburn-reports/${Date.now()}`;
61
+ await fs.ensureDir(outputDir);
62
+ // Cancellation flag for timeout handling (Issue 1)
63
+ const cancellation = { cancelled: false };
64
+ // Wrap the entire pipeline in a timeout to prevent infinite hangs
65
+ let timeoutId;
66
+ const timeoutPromise = new Promise((_, reject) => {
67
+ timeoutId = setTimeout(() => {
68
+ // Issue 1: Set cancellation flag to stop work between pipeline stages
69
+ cancellation.cancelled = true;
70
+ reject(new Error('Scan timed out after 5 minutes. Try with --max-pages 5 for a faster scan.'));
71
+ }, PIPELINE_TIMEOUT_MS);
72
+ });
73
+ try {
74
+ const result = await Promise.race([runPipeline(options, validatedTargetUrl, validatedSourcePath, validatedMaxPages, sessionId, outputDir, cancellation), timeoutPromise]);
75
+ clearTimeout(timeoutId);
76
+ return result;
77
+ }
78
+ catch (error) {
79
+ clearTimeout(timeoutId);
80
+ throw error;
81
+ }
82
+ }
83
+ async function runPipeline(options, validatedTargetUrl, validatedSourcePath, validatedMaxPages, sessionId, outputDir, cancellation) {
84
+ // Stage: browser check
85
+ options.onProgress?.('browser', 'Checking browser installation...');
86
+ try {
87
+ // Issue 1: Check cancellation before each major stage
88
+ if (cancellation.cancelled) {
89
+ throw new Error('Scan cancelled by timeout');
90
+ }
91
+ // Stage: discovery
92
+ options.onProgress?.('discovery', 'Crawling site and discovering workflows...');
93
+ const discoveryOptions = {
94
+ targetUrl: validatedTargetUrl,
95
+ sessionId,
96
+ userHints: options.flowHints || [],
97
+ maxPages: validatedMaxPages,
98
+ headless: options.headless ?? true,
99
+ onProgress: (msg) => {
100
+ // Pass discovery progress messages through
101
+ options.onProgress?.('discovery', msg);
102
+ },
103
+ };
104
+ const discoveryResult = await runDiscovery(discoveryOptions);
105
+ // Issue 1: Check cancellation after discovery
106
+ if (cancellation.cancelled) {
107
+ throw new Error('Scan cancelled by timeout');
108
+ }
109
+ // Issue 10: Don't return early — always generate reports even when no workflows found
110
+ // Build minimal execution result for no-workflow case
111
+ let executionResult;
112
+ let diagnosedErrors = [];
113
+ let uiAudits = [];
114
+ if (discoveryResult.workflowPlans.length === 0) {
115
+ options.onProgress?.('complete', 'No testable elements found on site — generating report...');
116
+ // Create minimal execution result with all required fields
117
+ executionResult = {
118
+ version: '1.0.0',
119
+ stage: 'execution',
120
+ timestamp: new Date().toISOString(),
121
+ sessionId,
122
+ targetUrl: validatedTargetUrl,
123
+ workflowResults: [],
124
+ pageAudits: [],
125
+ deadButtons: [],
126
+ brokenForms: [],
127
+ brokenLinks: discoveryResult.crawlResult?.brokenLinks?.map(toBrokenLinkIssue) || [],
128
+ totalIssues: 0,
129
+ exitCode: 1,
130
+ };
131
+ }
132
+ else {
133
+ // Issue 1: Check cancellation before execution
134
+ if (cancellation.cancelled) {
135
+ throw new Error('Scan cancelled by timeout');
136
+ }
137
+ // Stage: execution
138
+ options.onProgress?.('execution', 'Testing workflows...');
139
+ const executionOptions = {
140
+ targetUrl: validatedTargetUrl,
141
+ sessionId,
142
+ workflowPlans: discoveryResult.workflowPlans,
143
+ email: options.email,
144
+ password: options.password,
145
+ headless: options.headless ?? true,
146
+ onProgress: (msg) => {
147
+ // Pass execution progress messages through
148
+ options.onProgress?.('execution', msg);
149
+ },
150
+ };
151
+ const executor = new WorkflowExecutor(executionOptions);
152
+ executionResult = await executor.execute();
153
+ mergeDiscoveryBrokenLinks(executionResult, discoveryResult.crawlResult?.brokenLinks || []);
154
+ recalculateExecutionSummary(executionResult);
155
+ // Issue 1: Check cancellation before analysis
156
+ if (cancellation.cancelled) {
157
+ throw new Error('Scan cancelled by timeout');
158
+ }
159
+ // Stage: analysis
160
+ options.onProgress?.('analysis', 'Analyzing results...');
161
+ // Run error diagnosis and UI auditing in parallel (they share no mutable state)
162
+ const [rawDiagnosedErrors, uiAuditsResult] = await Promise.all([
163
+ analyzeErrors(executionResult),
164
+ auditUI(executionResult),
165
+ ]);
166
+ diagnosedErrors = rawDiagnosedErrors;
167
+ uiAudits = uiAuditsResult;
168
+ // Source code mapping runs after both complete (only depends on diagnosedErrors)
169
+ if (validatedSourcePath) {
170
+ for (const diagnosed of diagnosedErrors) {
171
+ const sourceLocation = await mapErrorToSource(diagnosed.originalError, validatedSourcePath);
172
+ if (sourceLocation) {
173
+ diagnosed.sourceLocation = sourceLocation;
174
+ }
175
+ }
176
+ }
177
+ }
178
+ // Persist final execution artifact after post-processing merges/recalculations.
179
+ const artifactStorage = new ArtifactStorage();
180
+ await artifactStorage.save(executionResult);
181
+ // Save analysis artifact
182
+ const analysisArtifact = {
183
+ version: '1.0.0',
184
+ stage: 'analysis',
185
+ timestamp: new Date().toISOString(),
186
+ sessionId,
187
+ diagnosedErrors,
188
+ uiAudits,
189
+ sourceAnalysisAvailable: !!validatedSourcePath,
190
+ aiPowered: !!process.env.GEMINI_API_KEY,
191
+ };
192
+ await artifactStorage.save(analysisArtifact);
193
+ // Stage: reporting
194
+ options.onProgress?.('reporting', 'Generating reports...');
195
+ // Calculate health score and prioritize issues
196
+ const healthScore = calculateHealthScore(executionResult);
197
+ let prioritizedIssues = deduplicateIssues(prioritizeIssues(diagnosedErrors, uiAudits, executionResult));
198
+ // Issue 10: If no workflows were found, add a single high-priority issue
199
+ if (discoveryResult.workflowPlans.length === 0) {
200
+ prioritizedIssues = [{
201
+ priority: 'high',
202
+ category: 'No Testable Content',
203
+ summary: 'No forms, buttons, or interactive elements found on the site',
204
+ impact: 'Afterburn could not test anything — the site may be empty, under maintenance, or blocking automated access',
205
+ fixSuggestion: 'Verify the site loads correctly in a browser. If the site uses anti-bot protection, results may be incomplete.',
206
+ location: validatedTargetUrl,
207
+ }];
208
+ }
209
+ let htmlReportPath = null;
210
+ let markdownReportPath = null;
211
+ const warnings = [];
212
+ // Generate HTML and Markdown reports in parallel (independent outputs)
213
+ await Promise.all([
214
+ (async () => {
215
+ try {
216
+ const htmlReport = await generateHtmlReport(executionResult, analysisArtifact);
217
+ htmlReportPath = path.join(outputDir, `report-${sessionId}.html`);
218
+ await writeHtmlReport(htmlReport, htmlReportPath);
219
+ }
220
+ catch (reportError) {
221
+ // Issue 11: Track report generation failures as warnings
222
+ warnings.push(`HTML report generation failed: ${reportError instanceof Error ? reportError.message : String(reportError)}`);
223
+ }
224
+ })(),
225
+ (async () => {
226
+ try {
227
+ const markdownReport = generateMarkdownReport(executionResult, analysisArtifact);
228
+ markdownReportPath = path.join(outputDir, `report-${sessionId}.md`);
229
+ await writeMarkdownReport(markdownReport, markdownReportPath);
230
+ }
231
+ catch (reportError) {
232
+ // Issue 11: Track report generation failures as warnings
233
+ warnings.push(`Markdown report generation failed: ${reportError instanceof Error ? reportError.message : String(reportError)}`);
234
+ }
235
+ })(),
236
+ ]);
237
+ // Stage: complete
238
+ const statusMessage = warnings.length > 0
239
+ ? `Scan complete with warnings: ${warnings.join(', ')}`
240
+ : 'Scan complete';
241
+ options.onProgress?.('complete', statusMessage);
242
+ // Calculate issue counts
243
+ const highPriorityCount = prioritizedIssues.filter(i => i.priority === 'high').length;
244
+ const mediumPriorityCount = prioritizedIssues.filter(i => i.priority === 'medium').length;
245
+ const lowPriorityCount = prioritizedIssues.filter(i => i.priority === 'low').length;
246
+ const workflowsPassed = executionResult.workflowResults.filter(w => w.overallStatus === 'passed').length;
247
+ const workflowsTotal = executionResult.workflowResults.length;
248
+ return {
249
+ healthScore,
250
+ prioritizedIssues,
251
+ totalIssues: prioritizedIssues.length,
252
+ highPriorityCount,
253
+ mediumPriorityCount,
254
+ lowPriorityCount,
255
+ workflowsPassed,
256
+ workflowsTotal,
257
+ htmlReportPath,
258
+ markdownReportPath,
259
+ exitCode: executionResult.exitCode,
260
+ sessionId,
261
+ warnings: warnings.length > 0 ? warnings : undefined,
262
+ };
263
+ }
264
+ catch (error) {
265
+ // Re-throw errors for caller to handle
266
+ throw error;
267
+ }
268
+ }
269
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { runAfterburn } from './engine.js';
2
+ export type { AfterBurnOptions, AfterBurnResult } from './engine.js';
3
+ export { validateUrl, validatePublicUrl, ensurePublicHostname, validatePath, validateMaxPages, validateSelector, sanitizeValue } from './validation.js';
@@ -0,0 +1,4 @@
1
+ // Barrel export for core engine
2
+ export { runAfterburn } from './engine.js';
3
+ export { validateUrl, validatePublicUrl, ensurePublicHostname, validatePath, validateMaxPages, validateSelector, sanitizeValue } from './validation.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACd,MAAM,iBAAiB,CAAC"}