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.
- package/LICENSE +21 -0
- package/README.md +281 -0
- package/dist/ai/gemini-client.d.ts +21 -0
- package/dist/ai/gemini-client.js +105 -0
- package/dist/ai/gemini-client.js.map +1 -0
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.js +3 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/analysis/diagnosis-schema.d.ts +106 -0
- package/dist/analysis/diagnosis-schema.js +54 -0
- package/dist/analysis/diagnosis-schema.js.map +1 -0
- package/dist/analysis/error-analyzer.d.ts +9 -0
- package/dist/analysis/error-analyzer.js +573 -0
- package/dist/analysis/error-analyzer.js.map +1 -0
- package/dist/analysis/index.d.ts +4 -0
- package/dist/analysis/index.js +6 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/source-mapper.d.ts +19 -0
- package/dist/analysis/source-mapper.js +329 -0
- package/dist/analysis/source-mapper.js.map +1 -0
- package/dist/analysis/ui-auditor.d.ts +9 -0
- package/dist/analysis/ui-auditor.js +104 -0
- package/dist/analysis/ui-auditor.js.map +1 -0
- package/dist/artifacts/artifact-storage.d.ts +44 -0
- package/dist/artifacts/artifact-storage.js +99 -0
- package/dist/artifacts/artifact-storage.js.map +1 -0
- package/dist/artifacts/index.d.ts +1 -0
- package/dist/artifacts/index.js +3 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/browser/browser-manager.d.ts +45 -0
- package/dist/browser/browser-manager.js +88 -0
- package/dist/browser/browser-manager.js.map +1 -0
- package/dist/browser/challenge-detector.d.ts +10 -0
- package/dist/browser/challenge-detector.js +58 -0
- package/dist/browser/challenge-detector.js.map +1 -0
- package/dist/browser/cookie-dismisser.d.ts +18 -0
- package/dist/browser/cookie-dismisser.js +76 -0
- package/dist/browser/cookie-dismisser.js.map +1 -0
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +6 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/stealth-browser.d.ts +13 -0
- package/dist/browser/stealth-browser.js +59 -0
- package/dist/browser/stealth-browser.js.map +1 -0
- package/dist/cli/commander-cli.d.ts +2 -0
- package/dist/cli/commander-cli.js +150 -0
- package/dist/cli/commander-cli.js.map +1 -0
- package/dist/cli/doctor.d.ts +34 -0
- package/dist/cli/doctor.js +124 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/first-run.d.ts +6 -0
- package/dist/cli/first-run.js +58 -0
- package/dist/cli/first-run.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/progress.d.ts +11 -0
- package/dist/cli/progress.js +30 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/core/engine.d.ts +33 -0
- package/dist/core/engine.js +269 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/validation.d.ts +52 -0
- package/dist/core/validation.js +228 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/discovery/crawler.d.ts +58 -0
- package/dist/discovery/crawler.js +240 -0
- package/dist/discovery/crawler.js.map +1 -0
- package/dist/discovery/discovery-pipeline.d.ts +22 -0
- package/dist/discovery/discovery-pipeline.js +256 -0
- package/dist/discovery/discovery-pipeline.js.map +1 -0
- package/dist/discovery/element-mapper.d.ts +21 -0
- package/dist/discovery/element-mapper.js +422 -0
- package/dist/discovery/element-mapper.js.map +1 -0
- package/dist/discovery/index.d.ts +8 -0
- package/dist/discovery/index.js +8 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/link-validator.d.ts +15 -0
- package/dist/discovery/link-validator.js +137 -0
- package/dist/discovery/link-validator.js.map +1 -0
- package/dist/discovery/sitemap-builder.d.ts +19 -0
- package/dist/discovery/sitemap-builder.js +166 -0
- package/dist/discovery/sitemap-builder.js.map +1 -0
- package/dist/discovery/spa-detector.d.ts +12 -0
- package/dist/discovery/spa-detector.js +271 -0
- package/dist/discovery/spa-detector.js.map +1 -0
- package/dist/execution/error-detector.d.ts +10 -0
- package/dist/execution/error-detector.js +87 -0
- package/dist/execution/error-detector.js.map +1 -0
- package/dist/execution/evidence-capture.d.ts +8 -0
- package/dist/execution/evidence-capture.js +37 -0
- package/dist/execution/evidence-capture.js.map +1 -0
- package/dist/execution/index.d.ts +5 -0
- package/dist/execution/index.js +7 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/execution/step-handlers.d.ts +48 -0
- package/dist/execution/step-handlers.js +349 -0
- package/dist/execution/step-handlers.js.map +1 -0
- package/dist/execution/test-data.d.ts +50 -0
- package/dist/execution/test-data.js +160 -0
- package/dist/execution/test-data.js.map +1 -0
- package/dist/execution/workflow-executor.d.ts +56 -0
- package/dist/execution/workflow-executor.js +331 -0
- package/dist/execution/workflow-executor.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/entry.d.ts +2 -0
- package/dist/mcp/entry.js +5 -0
- package/dist/mcp/entry.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +19 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +2 -0
- package/dist/mcp/tools.js +162 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/planning/heuristic-planner.d.ts +7 -0
- package/dist/planning/heuristic-planner.js +238 -0
- package/dist/planning/heuristic-planner.js.map +1 -0
- package/dist/planning/index.d.ts +3 -0
- package/dist/planning/index.js +5 -0
- package/dist/planning/index.js.map +1 -0
- package/dist/planning/plan-schema.d.ts +74 -0
- package/dist/planning/plan-schema.js +39 -0
- package/dist/planning/plan-schema.js.map +1 -0
- package/dist/planning/workflow-planner.d.ts +39 -0
- package/dist/planning/workflow-planner.js +211 -0
- package/dist/planning/workflow-planner.js.map +1 -0
- package/dist/reports/health-scorer.d.ts +14 -0
- package/dist/reports/health-scorer.js +88 -0
- package/dist/reports/health-scorer.js.map +1 -0
- package/dist/reports/html-generator.d.ts +10 -0
- package/dist/reports/html-generator.js +155 -0
- package/dist/reports/html-generator.js.map +1 -0
- package/dist/reports/index.d.ts +4 -0
- package/dist/reports/index.js +6 -0
- package/dist/reports/index.js.map +1 -0
- package/dist/reports/markdown-generator.d.ts +10 -0
- package/dist/reports/markdown-generator.js +334 -0
- package/dist/reports/markdown-generator.js.map +1 -0
- package/dist/reports/priority-ranker.d.ts +22 -0
- package/dist/reports/priority-ranker.js +608 -0
- package/dist/reports/priority-ranker.js.map +1 -0
- package/dist/screenshots/dual-format.d.ts +14 -0
- package/dist/screenshots/dual-format.js +59 -0
- package/dist/screenshots/dual-format.js.map +1 -0
- package/dist/screenshots/index.d.ts +2 -0
- package/dist/screenshots/index.js +4 -0
- package/dist/screenshots/index.js.map +1 -0
- package/dist/screenshots/screenshot-manager.d.ts +33 -0
- package/dist/screenshots/screenshot-manager.js +86 -0
- package/dist/screenshots/screenshot-manager.js.map +1 -0
- package/dist/testing/accessibility-auditor.d.ts +23 -0
- package/dist/testing/accessibility-auditor.js +44 -0
- package/dist/testing/accessibility-auditor.js.map +1 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/meta-auditor.d.ts +16 -0
- package/dist/testing/meta-auditor.js +268 -0
- package/dist/testing/meta-auditor.js.map +1 -0
- package/dist/testing/performance-monitor.d.ts +15 -0
- package/dist/testing/performance-monitor.js +64 -0
- package/dist/testing/performance-monitor.js.map +1 -0
- package/dist/types/artifacts.d.ts +58 -0
- package/dist/types/artifacts.js +3 -0
- package/dist/types/artifacts.js.map +1 -0
- package/dist/types/discovery.d.ts +124 -0
- package/dist/types/discovery.js +3 -0
- package/dist/types/discovery.js.map +1 -0
- package/dist/types/execution.d.ts +154 -0
- package/dist/types/execution.js +3 -0
- package/dist/types/execution.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/sanitizer.d.ts +25 -0
- package/dist/utils/sanitizer.js +98 -0
- package/dist/utils/sanitizer.js.map +1 -0
- package/package.json +86 -0
- package/templates/report.hbs +202 -0
- 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":"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"}
|
|
@@ -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 @@
|
|
|
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":"AAAA,sFAAsF;AAEtF,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAElL,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAiCpF,kFAAkF;AAClF,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAEvD,SAAS,iBAAiB,CAAC,IAAgB;IACzC,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,iBAAoC,EACpC,oBAAkC;IAElC,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,CAC9F,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,iBAAiB,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,iBAAoC;IAC9E,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,WAAW,IAAI,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtG,WAAW,IAAI,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtH,WAAW,IAAI,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxH,WAAW,IAAI,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrH,WAAW,IAAI,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IACpF,WAAW,IAAI,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAClF,WAAW,IAAI,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC;IACpD,WAAW,IAAI,iBAAiB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAChE,IAAI,CAAC,KAAK,CAAC,aAAa;YAAE,OAAO,GAAG,CAAC;QACrC,OAAO,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAChD,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,UAAU,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAC/E,CAAC,MAAM,CAAC;IACX,CAAC,EAAE,CAAC,CAAC,CAAC;IAEN,iBAAiB,CAAC,WAAW,GAAG,WAAW,CAAC;IAC5C,iBAAiB,CAAC,QAAQ,GAAG,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,KAAK,QAAQ,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB;IAC1D,qEAAqE;IACrE,MAAM,kBAAkB,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtE,MAAM,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE7D,4EAA4E;IAC5E,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;IACzD,uEAAuE;IACvE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IAEtD,uCAAuC;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS;QACjC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC;QAC9C,CAAC,CAAC,uBAAuB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACxC,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAE9B,mDAAmD;IACnD,MAAM,YAAY,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAE1C,kEAAkE;IAClE,IAAI,SAAwC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QACtD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,sEAAsE;YACtE,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC;YAC9B,MAAM,CAAC,IAAI,KAAK,CACd,2EAA2E,CAC5E,CAAC,CAAC;QACL,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAC1K,YAAY,CAAC,SAAU,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,SAAU,CAAC,CAAC;QACzB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,OAAyB,EACzB,kBAA0B,EAC1B,mBAAuC,EACvC,iBAAyB,EACzB,SAAiB,EACjB,SAAiB,EACjB,YAAoC;IAEpC,uBAAuB;IACvB,OAAO,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,kCAAkC,CAAC,CAAC;IAEpE,IAAI,CAAC;QACH,sDAAsD;QACtD,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,mBAAmB;QACnB,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,4CAA4C,CAAC,CAAC;QAEhF,MAAM,gBAAgB,GAAqB;YACzC,SAAS,EAAE,kBAAkB;YAC7B,SAAS;YACT,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;YAClC,QAAQ,EAAE,iBAAiB;YAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;YAClC,UAAU,EAAE,CAAC,GAAW,EAAE,EAAE;gBAC1B,2CAA2C;gBAC3C,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YACzC,CAAC;SACF,CAAC;QAEF,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAE7D,8CAA8C;QAC9C,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,sFAAsF;QACtF,sDAAsD;QACtD,IAAI,eAAe,CAAC;QACpB,IAAI,eAAe,GAAU,EAAE,CAAC;QAChC,IAAI,QAAQ,GAAU,EAAE,CAAC;QAEzB,IAAI,eAAe,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,2DAA2D,CAAC,CAAC;YAE9F,2DAA2D;YAC3D,eAAe,GAAG;gBAChB,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE,WAAW;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,SAAS;gBACT,SAAS,EAAE,kBAAkB;gBAC7B,eAAe,EAAE,EAAE;gBACnB,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,EAAE;gBACf,WAAW,EAAE,EAAE;gBACf,WAAW,EAAE,eAAe,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE;gBACnF,WAAW,EAAE,CAAC;gBACd,QAAQ,EAAE,CAAC;aACZ,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,+CAA+C;YAC/C,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,CAAC;YAED,mBAAmB;YACnB,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;YAE1D,MAAM,gBAAgB,GAAqB;gBACzC,SAAS,EAAE,kBAAkB;gBAC7B,SAAS;gBACT,aAAa,EAAE,eAAe,CAAC,aAAa;gBAC5C,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;gBAClC,UAAU,EAAE,CAAC,GAAW,EAAE,EAAE;oBAC1B,2CAA2C;oBAC3C,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACzC,CAAC;aACF,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;YACxD,eAAe,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC3C,yBAAyB,CAAC,eAAe,EAAE,eAAe,CAAC,WAAW,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;YAC3F,2BAA2B,CAAC,eAAe,CAAC,CAAC;YAE7C,8CAA8C;YAC9C,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,CAAC;YAED,kBAAkB;YAClB,OAAO,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;YAEzD,gFAAgF;YAChF,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC7D,aAAa,CAAC,eAAe,CAAC;gBAC9B,OAAO,CAAC,eAAe,CAAC;aACzB,CAAC,CAAC;YACH,eAAe,GAAG,kBAAkB,CAAC;YACrC,QAAQ,GAAG,cAAc,CAAC;YAE1B,iFAAiF;YACjF,IAAI,mBAAmB,EAAE,CAAC;gBACxB,KAAK,MAAM,SAAS,IAAI,eAAe,EAAE,CAAC;oBACxC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;oBAC5F,IAAI,cAAc,EAAE,CAAC;wBACnB,SAAS,CAAC,cAAc,GAAG,cAAc,CAAC;oBAC5C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,gFAAgF;QAChF,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,MAAM,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAE5C,yBAAyB;QACzB,MAAM,gBAAgB,GAAqB;YACzC,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS;YACT,eAAe;YACf,QAAQ;YACR,uBAAuB,EAAE,CAAC,CAAC,mBAAmB;YAC9C,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc;SACxC,CAAC;QAEF,MAAM,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAE7C,mBAAmB;QACnB,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;QAE3D,+CAA+C;QAC/C,MAAM,WAAW,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAC1D,IAAI,iBAAiB,GAAG,iBAAiB,CACvC,gBAAgB,CAAC,eAAe,EAAE,QAAQ,EAAE,eAAe,CAAC,CAC7D,CAAC;QAEF,yEAAyE;QACzE,IAAI,eAAe,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,iBAAiB,GAAG,CAAC;oBACnB,QAAQ,EAAE,MAAe;oBACzB,QAAQ,EAAE,qBAAqB;oBAC/B,OAAO,EAAE,8DAA8D;oBACvE,MAAM,EAAE,4GAA4G;oBACpH,aAAa,EAAE,gHAAgH;oBAC/H,QAAQ,EAAE,kBAAkB;iBAC7B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,cAAc,GAAkB,IAAI,CAAC;QACzC,IAAI,kBAAkB,GAAkB,IAAI,CAAC;QAC7C,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,uEAAuE;QACvE,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,CAAC,KAAK,IAAI,EAAE;gBACV,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;oBAC/E,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,SAAS,OAAO,CAAC,CAAC;oBAClE,MAAM,eAAe,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;gBACpD,CAAC;gBAAC,OAAO,WAAW,EAAE,CAAC;oBACrB,yDAAyD;oBACzD,QAAQ,CAAC,IAAI,CAAC,kCAAkC,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAC9H,CAAC;YACH,CAAC,CAAC,EAAE;YACJ,CAAC,KAAK,IAAI,EAAE;gBACV,IAAI,CAAC;oBACH,MAAM,cAAc,GAAG,sBAAsB,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;oBACjF,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,SAAS,KAAK,CAAC,CAAC;oBACpE,MAAM,mBAAmB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;gBAChE,CAAC;gBAAC,OAAO,WAAW,EAAE,CAAC;oBACrB,yDAAyD;oBACzD,QAAQ,CAAC,IAAI,CAAC,sCAAsC,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAClI,CAAC;YACH,CAAC,CAAC,EAAE;SACL,CAAC,CAAC;QAEH,kBAAkB;QAClB,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;YACvC,CAAC,CAAC,gCAAgC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACvD,CAAC,CAAC,eAAe,CAAC;QACpB,OAAO,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAEhD,yBAAyB;QACzB,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QACtF,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;QAC1F,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC;QAEpF,MAAM,eAAe,GAAG,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;QACzG,MAAM,cAAc,GAAG,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC;QAE9D,OAAO;YACL,WAAW;YACX,iBAAiB;YACjB,WAAW,EAAE,iBAAiB,CAAC,MAAM;YACrC,iBAAiB;YACjB,mBAAmB;YACnB,gBAAgB;YAChB,eAAe;YACf,cAAc;YACd,cAAc;YACd,kBAAkB;YAClB,QAAQ,EAAE,eAAe,CAAC,QAAQ;YAClC,SAAS;YACT,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;SACrD,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uCAAuC;QACvC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -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"}
|