@avi770/testteam 1.2.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/CHANGELOG.md +54 -0
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/agents/01-analyst.ts +100 -0
- package/agents/02-seed-architect.ts +59 -0
- package/agents/03-test-generator.ts +191 -0
- package/agents/04-unit-runner.ts +160 -0
- package/agents/05-browser-crawler.ts +790 -0
- package/agents/06-api-exerciser.ts +311 -0
- package/agents/07-security-scout.ts +188 -0
- package/agents/08-a11y-guardian.ts +212 -0
- package/agents/09-healer.ts +228 -0
- package/agents/10-reporter.ts +266 -0
- package/agents/11-fixer.ts +253 -0
- package/agents/12-ux-inspector.ts +444 -0
- package/agents/13-performance-profiler.ts +271 -0
- package/agents/14-data-integrity-auditor.ts +417 -0
- package/agents/15-regression-sentinel.ts +307 -0
- package/agents/16-chaos-agent.ts +228 -0
- package/agents/17-documentation-validator.ts +266 -0
- package/agents/18-integration-watchdog.ts +178 -0
- package/agents/19-tenant-isolation-auditor.ts +199 -0
- package/agents/20-workflow-completion-tester.ts +203 -0
- package/agents/21-state-session-tester.ts +262 -0
- package/agents/22-email-notification-verifier.ts +244 -0
- package/agents/23-migration-tester.ts +80 -0
- package/agents/__tests__/01-analyst.test.ts +188 -0
- package/agents/__tests__/02-seed-architect.test.ts +152 -0
- package/agents/__tests__/03-test-generator-full.test.ts +321 -0
- package/agents/__tests__/03-test-generator.test.ts +318 -0
- package/agents/__tests__/04-unit-runner.test.ts +320 -0
- package/agents/__tests__/05-browser-crawler-beta.test.ts +492 -0
- package/agents/__tests__/05-browser-crawler-release.test.ts +412 -0
- package/agents/__tests__/05-browser-crawler-uat.test.ts +578 -0
- package/agents/__tests__/05-browser-crawler.test.ts +518 -0
- package/agents/__tests__/06-api-exerciser.test.ts +619 -0
- package/agents/__tests__/07-security-scout.test.ts +382 -0
- package/agents/__tests__/08-a11y-guardian.test.ts +530 -0
- package/agents/__tests__/09-healer.test.ts +384 -0
- package/agents/__tests__/10-reporter.test.ts +366 -0
- package/agents/__tests__/11-fixer.test.ts +406 -0
- package/agents/__tests__/12-ux-inspector-extended.test.ts +465 -0
- package/agents/__tests__/12-ux-inspector.test.ts +443 -0
- package/agents/__tests__/13-performance-profiler.test.ts +411 -0
- package/agents/__tests__/14-data-integrity-auditor-extended.test.ts +573 -0
- package/agents/__tests__/14-data-integrity-auditor.test.ts +407 -0
- package/agents/__tests__/15-regression-sentinel.test.ts +657 -0
- package/agents/__tests__/16-chaos-agent.test.ts +427 -0
- package/agents/__tests__/17-documentation-validator.test.ts +402 -0
- package/agents/__tests__/18-integration-watchdog.test.ts +263 -0
- package/agents/__tests__/19-tenant-isolation-auditor.test.ts +400 -0
- package/agents/__tests__/20-workflow-completion-tester.test.ts +586 -0
- package/agents/__tests__/21-state-session-tester.test.ts +374 -0
- package/agents/__tests__/22-email-notification-verifier.test.ts +441 -0
- package/agents/__tests__/23-migration-tester.test.ts +145 -0
- package/agents/__tests__/base-agent.test.ts +188 -0
- package/agents/__tests__/registry.test.ts +218 -0
- package/agents/base-agent.ts +77 -0
- package/agents/registry.ts +136 -0
- package/baselines/api-schemas/.gitkeep +0 -0
- package/baselines/performance/.gitkeep +0 -0
- package/baselines/screenshots/.gitkeep +0 -0
- package/bin/testteam.js +10 -0
- package/core/__tests__/ci-output.test.ts +430 -0
- package/core/__tests__/cli.test.ts +387 -0
- package/core/__tests__/config.test.ts +78 -0
- package/core/__tests__/cost-tracker.test.ts +158 -0
- package/core/__tests__/evidence.test.ts +265 -0
- package/core/__tests__/fix-loop.test.ts +210 -0
- package/core/__tests__/health-check.test.ts +44 -0
- package/core/__tests__/init.test.ts +609 -0
- package/core/__tests__/integration.test.ts +204 -0
- package/core/__tests__/license-gen.test.ts +227 -0
- package/core/__tests__/license.test.ts +326 -0
- package/core/__tests__/multi-browser.test.ts +278 -0
- package/core/__tests__/orchestrator.test.ts +519 -0
- package/core/__tests__/phase-gate.test.ts +43 -0
- package/core/__tests__/report-html.test.ts +398 -0
- package/core/__tests__/report-upload.test.ts +325 -0
- package/core/__tests__/run-counter.test.ts +234 -0
- package/core/ci-output.ts +240 -0
- package/core/cli.ts +232 -0
- package/core/config.ts +178 -0
- package/core/cost-tracker.ts +59 -0
- package/core/evidence.ts +132 -0
- package/core/fix-loop.ts +85 -0
- package/core/health-check.ts +54 -0
- package/core/init.ts +546 -0
- package/core/license-gen.ts +212 -0
- package/core/license.ts +211 -0
- package/core/messages.ts +67 -0
- package/core/multi-browser.ts +136 -0
- package/core/orchestrator.ts +354 -0
- package/core/phase-gate.ts +55 -0
- package/core/report-html.ts +657 -0
- package/core/report-upload.ts +188 -0
- package/core/run-counter.ts +175 -0
- package/core/types.ts +57 -0
- package/dist/agents/01-analyst.d.ts +11 -0
- package/dist/agents/01-analyst.d.ts.map +1 -0
- package/dist/agents/01-analyst.js +75 -0
- package/dist/agents/01-analyst.js.map +1 -0
- package/dist/agents/02-seed-architect.d.ts +11 -0
- package/dist/agents/02-seed-architect.d.ts.map +1 -0
- package/dist/agents/02-seed-architect.js +51 -0
- package/dist/agents/02-seed-architect.js.map +1 -0
- package/dist/agents/03-test-generator.d.ts +9 -0
- package/dist/agents/03-test-generator.d.ts.map +1 -0
- package/dist/agents/03-test-generator.js +167 -0
- package/dist/agents/03-test-generator.js.map +1 -0
- package/dist/agents/04-unit-runner.d.ts +9 -0
- package/dist/agents/04-unit-runner.d.ts.map +1 -0
- package/dist/agents/04-unit-runner.js +113 -0
- package/dist/agents/04-unit-runner.js.map +1 -0
- package/dist/agents/05-browser-crawler.d.ts +30 -0
- package/dist/agents/05-browser-crawler.d.ts.map +1 -0
- package/dist/agents/05-browser-crawler.js +685 -0
- package/dist/agents/05-browser-crawler.js.map +1 -0
- package/dist/agents/06-api-exerciser.d.ts +23 -0
- package/dist/agents/06-api-exerciser.d.ts.map +1 -0
- package/dist/agents/06-api-exerciser.js +253 -0
- package/dist/agents/06-api-exerciser.js.map +1 -0
- package/dist/agents/07-security-scout.d.ts +11 -0
- package/dist/agents/07-security-scout.d.ts.map +1 -0
- package/dist/agents/07-security-scout.js +142 -0
- package/dist/agents/07-security-scout.js.map +1 -0
- package/dist/agents/08-a11y-guardian.d.ts +13 -0
- package/dist/agents/08-a11y-guardian.d.ts.map +1 -0
- package/dist/agents/08-a11y-guardian.js +176 -0
- package/dist/agents/08-a11y-guardian.js.map +1 -0
- package/dist/agents/09-healer.d.ts +33 -0
- package/dist/agents/09-healer.d.ts.map +1 -0
- package/dist/agents/09-healer.js +167 -0
- package/dist/agents/09-healer.js.map +1 -0
- package/dist/agents/10-reporter.d.ts +26 -0
- package/dist/agents/10-reporter.d.ts.map +1 -0
- package/dist/agents/10-reporter.js +215 -0
- package/dist/agents/10-reporter.js.map +1 -0
- package/dist/agents/11-fixer.d.ts +26 -0
- package/dist/agents/11-fixer.d.ts.map +1 -0
- package/dist/agents/11-fixer.js +195 -0
- package/dist/agents/11-fixer.js.map +1 -0
- package/dist/agents/12-ux-inspector.d.ts +15 -0
- package/dist/agents/12-ux-inspector.d.ts.map +1 -0
- package/dist/agents/12-ux-inspector.js +364 -0
- package/dist/agents/12-ux-inspector.js.map +1 -0
- package/dist/agents/13-performance-profiler.d.ts +13 -0
- package/dist/agents/13-performance-profiler.d.ts.map +1 -0
- package/dist/agents/13-performance-profiler.js +216 -0
- package/dist/agents/13-performance-profiler.js.map +1 -0
- package/dist/agents/14-data-integrity-auditor.d.ts +12 -0
- package/dist/agents/14-data-integrity-auditor.d.ts.map +1 -0
- package/dist/agents/14-data-integrity-auditor.js +356 -0
- package/dist/agents/14-data-integrity-auditor.js.map +1 -0
- package/dist/agents/15-regression-sentinel.d.ts +25 -0
- package/dist/agents/15-regression-sentinel.d.ts.map +1 -0
- package/dist/agents/15-regression-sentinel.js +251 -0
- package/dist/agents/15-regression-sentinel.js.map +1 -0
- package/dist/agents/16-chaos-agent.d.ts +9 -0
- package/dist/agents/16-chaos-agent.d.ts.map +1 -0
- package/dist/agents/16-chaos-agent.js +207 -0
- package/dist/agents/16-chaos-agent.js.map +1 -0
- package/dist/agents/17-documentation-validator.d.ts +31 -0
- package/dist/agents/17-documentation-validator.d.ts.map +1 -0
- package/dist/agents/17-documentation-validator.js +246 -0
- package/dist/agents/17-documentation-validator.js.map +1 -0
- package/dist/agents/18-integration-watchdog.d.ts +10 -0
- package/dist/agents/18-integration-watchdog.d.ts.map +1 -0
- package/dist/agents/18-integration-watchdog.js +138 -0
- package/dist/agents/18-integration-watchdog.js.map +1 -0
- package/dist/agents/19-tenant-isolation-auditor.d.ts +9 -0
- package/dist/agents/19-tenant-isolation-auditor.d.ts.map +1 -0
- package/dist/agents/19-tenant-isolation-auditor.js +166 -0
- package/dist/agents/19-tenant-isolation-auditor.js.map +1 -0
- package/dist/agents/20-workflow-completion-tester.d.ts +12 -0
- package/dist/agents/20-workflow-completion-tester.d.ts.map +1 -0
- package/dist/agents/20-workflow-completion-tester.js +159 -0
- package/dist/agents/20-workflow-completion-tester.js.map +1 -0
- package/dist/agents/21-state-session-tester.d.ts +10 -0
- package/dist/agents/21-state-session-tester.d.ts.map +1 -0
- package/dist/agents/21-state-session-tester.js +233 -0
- package/dist/agents/21-state-session-tester.js.map +1 -0
- package/dist/agents/22-email-notification-verifier.d.ts +11 -0
- package/dist/agents/22-email-notification-verifier.d.ts.map +1 -0
- package/dist/agents/22-email-notification-verifier.js +199 -0
- package/dist/agents/22-email-notification-verifier.js.map +1 -0
- package/dist/agents/23-migration-tester.d.ts +10 -0
- package/dist/agents/23-migration-tester.d.ts.map +1 -0
- package/dist/agents/23-migration-tester.js +74 -0
- package/dist/agents/23-migration-tester.js.map +1 -0
- package/dist/agents/base-agent.d.ts +19 -0
- package/dist/agents/base-agent.d.ts.map +1 -0
- package/dist/agents/base-agent.js +67 -0
- package/dist/agents/base-agent.js.map +1 -0
- package/dist/agents/registry.d.ts +29 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +117 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/core/ci-output.d.ts +35 -0
- package/dist/core/ci-output.d.ts.map +1 -0
- package/dist/core/ci-output.js +193 -0
- package/dist/core/ci-output.js.map +1 -0
- package/dist/core/cli.d.ts +11 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +197 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/config.d.ts +111 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +42 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/cost-tracker.d.ts +22 -0
- package/dist/core/cost-tracker.d.ts.map +1 -0
- package/dist/core/cost-tracker.js +41 -0
- package/dist/core/cost-tracker.js.map +1 -0
- package/dist/core/evidence.d.ts +28 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +95 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/fix-loop.d.ts +29 -0
- package/dist/core/fix-loop.d.ts.map +1 -0
- package/dist/core/fix-loop.js +70 -0
- package/dist/core/fix-loop.js.map +1 -0
- package/dist/core/health-check.d.ts +21 -0
- package/dist/core/health-check.d.ts.map +1 -0
- package/dist/core/health-check.js +26 -0
- package/dist/core/health-check.js.map +1 -0
- package/dist/core/init.d.ts +2 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +435 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/license-gen.d.ts +12 -0
- package/dist/core/license-gen.d.ts.map +1 -0
- package/dist/core/license-gen.js +169 -0
- package/dist/core/license-gen.js.map +1 -0
- package/dist/core/license.d.ts +33 -0
- package/dist/core/license.d.ts.map +1 -0
- package/dist/core/license.js +170 -0
- package/dist/core/license.js.map +1 -0
- package/dist/core/messages.d.ts +10 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +47 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/multi-browser.d.ts +36 -0
- package/dist/core/multi-browser.d.ts.map +1 -0
- package/dist/core/multi-browser.js +88 -0
- package/dist/core/multi-browser.js.map +1 -0
- package/dist/core/orchestrator.d.ts +48 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +291 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/phase-gate.d.ts +4 -0
- package/dist/core/phase-gate.d.ts.map +1 -0
- package/dist/core/phase-gate.js +39 -0
- package/dist/core/phase-gate.js.map +1 -0
- package/dist/core/report-html.d.ts +9 -0
- package/dist/core/report-html.d.ts.map +1 -0
- package/dist/core/report-html.js +617 -0
- package/dist/core/report-html.js.map +1 -0
- package/dist/core/report-upload.d.ts +16 -0
- package/dist/core/report-upload.d.ts.map +1 -0
- package/dist/core/report-upload.js +124 -0
- package/dist/core/report-upload.js.map +1 -0
- package/dist/core/run-counter.d.ts +40 -0
- package/dist/core/run-counter.d.ts.map +1 -0
- package/dist/core/run-counter.js +120 -0
- package/dist/core/run-counter.js.map +1 -0
- package/dist/core/types.d.ts +53 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/helpers/api-client.d.ts +30 -0
- package/dist/helpers/api-client.d.ts.map +1 -0
- package/dist/helpers/api-client.js +77 -0
- package/dist/helpers/api-client.js.map +1 -0
- package/dist/helpers/element-discovery.d.ts +18 -0
- package/dist/helpers/element-discovery.d.ts.map +1 -0
- package/dist/helpers/element-discovery.js +82 -0
- package/dist/helpers/element-discovery.js.map +1 -0
- package/dist/helpers/env-resolver.d.ts +29 -0
- package/dist/helpers/env-resolver.d.ts.map +1 -0
- package/dist/helpers/env-resolver.js +51 -0
- package/dist/helpers/env-resolver.js.map +1 -0
- package/dist/helpers/form-filler.d.ts +13 -0
- package/dist/helpers/form-filler.d.ts.map +1 -0
- package/dist/helpers/form-filler.js +98 -0
- package/dist/helpers/form-filler.js.map +1 -0
- package/dist/helpers/modal-handler.d.ts +16 -0
- package/dist/helpers/modal-handler.d.ts.map +1 -0
- package/dist/helpers/modal-handler.js +95 -0
- package/dist/helpers/modal-handler.js.map +1 -0
- package/dist/helpers/navigation.d.ts +37 -0
- package/dist/helpers/navigation.d.ts.map +1 -0
- package/dist/helpers/navigation.js +83 -0
- package/dist/helpers/navigation.js.map +1 -0
- package/dist/helpers/quality-gate.d.ts +17 -0
- package/dist/helpers/quality-gate.d.ts.map +1 -0
- package/dist/helpers/quality-gate.js +144 -0
- package/dist/helpers/quality-gate.js.map +1 -0
- package/dist/helpers/screenshot.d.ts +24 -0
- package/dist/helpers/screenshot.d.ts.map +1 -0
- package/dist/helpers/screenshot.js +76 -0
- package/dist/helpers/screenshot.js.map +1 -0
- package/dist/helpers/seed-validator.d.ts +15 -0
- package/dist/helpers/seed-validator.d.ts.map +1 -0
- package/dist/helpers/seed-validator.js +53 -0
- package/dist/helpers/seed-validator.js.map +1 -0
- package/helpers/__tests__/api-client.test.ts +199 -0
- package/helpers/__tests__/element-discovery.test.ts +202 -0
- package/helpers/__tests__/form-filler-extended.test.ts +212 -0
- package/helpers/__tests__/form-filler.test.ts +99 -0
- package/helpers/__tests__/modal-handler.test.ts +152 -0
- package/helpers/__tests__/navigation.test.ts +214 -0
- package/helpers/__tests__/quality-gate.test.ts +117 -0
- package/helpers/__tests__/screenshot.test.ts +139 -0
- package/helpers/__tests__/seed-validator.test.ts +114 -0
- package/helpers/api-client.ts +111 -0
- package/helpers/element-discovery.ts +105 -0
- package/helpers/env-resolver.ts +69 -0
- package/helpers/form-filler.ts +126 -0
- package/helpers/modal-handler.ts +108 -0
- package/helpers/navigation.ts +100 -0
- package/helpers/quality-gate.ts +180 -0
- package/helpers/screenshot.ts +111 -0
- package/helpers/seed-validator.ts +70 -0
- package/package.json +88 -0
package/dist/core/cli.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { validateConfig } from './config';
|
|
2
|
+
import { Orchestrator } from './orchestrator';
|
|
3
|
+
import { registerAllAgents } from '../agents/registry';
|
|
4
|
+
import { runInitWizard } from './init';
|
|
5
|
+
import { determineExitCode, writeCISummary, detectCIEnvironment } from './ci-output';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
const PHASES = ['alpha', 'beta', 'uat', 'release'];
|
|
8
|
+
function printUsage() {
|
|
9
|
+
console.log(`
|
|
10
|
+
Usage: testteam [options]
|
|
11
|
+
|
|
12
|
+
Options:
|
|
13
|
+
init Initialize TestTeam in current directory
|
|
14
|
+
--phase <alpha|beta|uat|release|all> Phase to run (required unless --dry-run)
|
|
15
|
+
--dry-run Show dispatch plan without executing
|
|
16
|
+
--agent <id> Run a single agent by ID
|
|
17
|
+
--config <path> Path to config file (default: testteam.config.ts)
|
|
18
|
+
--help Show this help message
|
|
19
|
+
`.trim());
|
|
20
|
+
}
|
|
21
|
+
export function parseArgs(argv) {
|
|
22
|
+
const args = argv.slice(2); // skip node + script path
|
|
23
|
+
let phase = null;
|
|
24
|
+
let dryRun = false;
|
|
25
|
+
let agent = null;
|
|
26
|
+
let configPath = 'testteam.config.ts';
|
|
27
|
+
for (let i = 0; i < args.length; i++) {
|
|
28
|
+
const arg = args[i];
|
|
29
|
+
switch (arg) {
|
|
30
|
+
case '--phase': {
|
|
31
|
+
const value = args[++i];
|
|
32
|
+
if (!value || (!PHASES.includes(value) && value !== 'all')) {
|
|
33
|
+
throw new Error(`Invalid phase: ${value}. Must be one of: ${PHASES.join(', ')}, all`);
|
|
34
|
+
}
|
|
35
|
+
phase = value;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case '--dry-run':
|
|
39
|
+
dryRun = true;
|
|
40
|
+
break;
|
|
41
|
+
case '--agent': {
|
|
42
|
+
const value = args[++i];
|
|
43
|
+
const parsed = Number(value);
|
|
44
|
+
if (!value || isNaN(parsed) || parsed < 1) {
|
|
45
|
+
throw new Error(`Invalid agent ID: ${value}. Must be a positive integer.`);
|
|
46
|
+
}
|
|
47
|
+
agent = parsed;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case '--config':
|
|
51
|
+
configPath = args[++i];
|
|
52
|
+
if (!configPath) {
|
|
53
|
+
throw new Error('--config requires a path argument');
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
case '--help':
|
|
57
|
+
printUsage();
|
|
58
|
+
process.exit(0);
|
|
59
|
+
break;
|
|
60
|
+
default:
|
|
61
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { phase, dryRun, agent, configPath };
|
|
65
|
+
}
|
|
66
|
+
async function loadConfig(configPath) {
|
|
67
|
+
const absolutePath = path.resolve(configPath);
|
|
68
|
+
// On Windows, dynamic import requires file:// URLs
|
|
69
|
+
const fileUrl = new URL(`file:///${absolutePath.replace(/\\/g, '/')}`).href;
|
|
70
|
+
const module = await import(fileUrl);
|
|
71
|
+
const raw = module.default ?? module.config;
|
|
72
|
+
if (!raw) {
|
|
73
|
+
throw new Error(`Config file does not export a default or named 'config': ${absolutePath}`);
|
|
74
|
+
}
|
|
75
|
+
return raw;
|
|
76
|
+
}
|
|
77
|
+
export async function main(argv = process.argv) {
|
|
78
|
+
// Handle init command before normal arg parsing
|
|
79
|
+
const rawArgs = argv.slice(2);
|
|
80
|
+
if (rawArgs.includes('init') || rawArgs.includes('--init')) {
|
|
81
|
+
return runInitWizard();
|
|
82
|
+
}
|
|
83
|
+
if (argv.length <= 2) {
|
|
84
|
+
printUsage();
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
87
|
+
let parsed;
|
|
88
|
+
try {
|
|
89
|
+
parsed = parseArgs(argv);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
93
|
+
printUsage();
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
const { phase, dryRun, configPath } = parsed;
|
|
97
|
+
if (!dryRun && !phase) {
|
|
98
|
+
console.error('--phase is required unless using --dry-run');
|
|
99
|
+
printUsage();
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
// Load and validate config
|
|
103
|
+
let rawConfig;
|
|
104
|
+
try {
|
|
105
|
+
rawConfig = await loadConfig(configPath);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error(`Failed to load config: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
const config = validateConfig(rawConfig);
|
|
112
|
+
// Shared run directory so all phases write results to the same location.
|
|
113
|
+
// This ensures the Reporter (Agent 10, release phase) can read results
|
|
114
|
+
// from prior phases (alpha, beta, uat).
|
|
115
|
+
const sharedRunDir = path.join(process.cwd(), '.run', `run-${Date.now()}`);
|
|
116
|
+
if (dryRun) {
|
|
117
|
+
const targetPhases = phase === 'all' || !phase
|
|
118
|
+
? [...PHASES]
|
|
119
|
+
: [phase];
|
|
120
|
+
for (const p of targetPhases) {
|
|
121
|
+
const phaseOrchestrator = new Orchestrator(config, sharedRunDir);
|
|
122
|
+
registerAllAgents(phaseOrchestrator, config, p, sharedRunDir);
|
|
123
|
+
const plan = phaseOrchestrator.dryRun(p);
|
|
124
|
+
console.log(`\nPhase: ${p}`);
|
|
125
|
+
for (const entry of plan) {
|
|
126
|
+
console.log(` Agent ${entry.agentId}: ${entry.status}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
// Run mode — create a fresh orchestrator per phase to avoid agent instance
|
|
132
|
+
// conflicts (GAP-023: registerAgent uses Map.set which overwrites).
|
|
133
|
+
const targetPhases = phase === 'all'
|
|
134
|
+
? [...PHASES]
|
|
135
|
+
: [phase];
|
|
136
|
+
const collectedGates = [];
|
|
137
|
+
const collectedResults = new Map();
|
|
138
|
+
let hadError = false;
|
|
139
|
+
for (const p of targetPhases) {
|
|
140
|
+
console.log(`\nRunning phase: ${p}`);
|
|
141
|
+
try {
|
|
142
|
+
const phaseOrchestrator = new Orchestrator(config, sharedRunDir);
|
|
143
|
+
registerAllAgents(phaseOrchestrator, config, p, sharedRunDir);
|
|
144
|
+
const result = await phaseOrchestrator.runPhase(p);
|
|
145
|
+
if (result.skippedAgents.length > 0) {
|
|
146
|
+
console.log(` Skipped agents: ${result.skippedAgents.join(', ')}`);
|
|
147
|
+
}
|
|
148
|
+
const resultCount = Object.keys(result.agentResults).length;
|
|
149
|
+
console.log(` Completed ${resultCount} agent(s)`);
|
|
150
|
+
if (result.gate.passed) {
|
|
151
|
+
console.log(` Gate: PASSED`);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.log(` Gate: FAILED (blocking agents: ${result.gate.failedBlockingAgents.join(', ')})`);
|
|
155
|
+
}
|
|
156
|
+
collectedGates.push(result.gate);
|
|
157
|
+
// Merge agent results for CI summary
|
|
158
|
+
for (const [agentId, agentResult] of Object.entries(result.agentResults)) {
|
|
159
|
+
collectedResults.set(Number(agentId), agentResult);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error(` Phase ${p} error: ${error instanceof Error ? error.message : String(error)}`);
|
|
164
|
+
hadError = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Determine structured exit code:
|
|
168
|
+
// - 0: All gates passed, no advisory failures
|
|
169
|
+
// - 1: Blocking agent failures (or runtime errors)
|
|
170
|
+
// - 2: Advisory warnings only
|
|
171
|
+
const exitCode = hadError
|
|
172
|
+
? 1
|
|
173
|
+
: determineExitCode(collectedGates);
|
|
174
|
+
// Write CI summary if running in a CI environment
|
|
175
|
+
const ciEnv = detectCIEnvironment();
|
|
176
|
+
if (ciEnv !== 'none') {
|
|
177
|
+
const runState = {
|
|
178
|
+
runId: path.basename(sharedRunDir),
|
|
179
|
+
startedAt: new Date().toISOString(),
|
|
180
|
+
currentPhase: targetPhases[targetPhases.length - 1],
|
|
181
|
+
phaseAttempt: 1,
|
|
182
|
+
agentResults: collectedResults,
|
|
183
|
+
gateResults: collectedGates,
|
|
184
|
+
totalCost: 0,
|
|
185
|
+
};
|
|
186
|
+
writeCISummary(runState);
|
|
187
|
+
}
|
|
188
|
+
return exitCode;
|
|
189
|
+
}
|
|
190
|
+
// Direct execution — works with both tsx and node
|
|
191
|
+
const isDirectExecution = typeof process !== 'undefined' &&
|
|
192
|
+
process.argv[1] &&
|
|
193
|
+
(process.argv[1].includes('cli.ts') || process.argv[1].includes('cli.js'));
|
|
194
|
+
if (isDirectExecution) {
|
|
195
|
+
main().then((code) => process.exit(code));
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../core/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export interface WorkflowStep {
|
|
2
|
+
action: 'navigate' | 'click' | 'fill-form' | 'wait' | 'verify';
|
|
3
|
+
target: string;
|
|
4
|
+
verify?: string;
|
|
5
|
+
data?: string;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
contains?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ModuleConfig {
|
|
10
|
+
id: string;
|
|
11
|
+
route: string;
|
|
12
|
+
sidebarIcon: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface CredentialEntry {
|
|
15
|
+
email: string;
|
|
16
|
+
password: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RoleEntry {
|
|
19
|
+
name: string;
|
|
20
|
+
email: string;
|
|
21
|
+
}
|
|
22
|
+
export interface AuthConfig {
|
|
23
|
+
loginUrl?: string;
|
|
24
|
+
credentials?: Record<string, CredentialEntry>;
|
|
25
|
+
roles?: RoleEntry[];
|
|
26
|
+
}
|
|
27
|
+
export interface EnvironmentConfig {
|
|
28
|
+
baseUrl: string;
|
|
29
|
+
seed?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface PortalConfig {
|
|
32
|
+
name: string;
|
|
33
|
+
queryParam: string | null;
|
|
34
|
+
}
|
|
35
|
+
export interface IntegrationConfig {
|
|
36
|
+
name: string;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
export interface WorkerConfig {
|
|
40
|
+
name: string;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface WorkflowConfig {
|
|
44
|
+
name: string;
|
|
45
|
+
steps: WorkflowStep[];
|
|
46
|
+
}
|
|
47
|
+
export interface AccuracyConfig {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
decimalPrecision: number;
|
|
50
|
+
currencySymbol: string;
|
|
51
|
+
timezone: string;
|
|
52
|
+
}
|
|
53
|
+
export interface TenancyConfig {
|
|
54
|
+
enabled: boolean;
|
|
55
|
+
isolationField: string;
|
|
56
|
+
testFirms: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface CostBudgetConfig {
|
|
59
|
+
maxPerRun: number;
|
|
60
|
+
maxPerAgent: number;
|
|
61
|
+
alertThreshold: number;
|
|
62
|
+
onExceeded: 'abort' | 'alert-continue' | 'skip-remaining';
|
|
63
|
+
}
|
|
64
|
+
export interface AgentClassificationConfig {
|
|
65
|
+
blocking: number[];
|
|
66
|
+
advisory: number[];
|
|
67
|
+
}
|
|
68
|
+
export interface CoverageThresholds {
|
|
69
|
+
lines: number;
|
|
70
|
+
functions: number;
|
|
71
|
+
branches: number;
|
|
72
|
+
statements: number;
|
|
73
|
+
}
|
|
74
|
+
export interface LighthouseThresholds {
|
|
75
|
+
accessibility: number;
|
|
76
|
+
performance: number;
|
|
77
|
+
bestPractices: number;
|
|
78
|
+
seo: number;
|
|
79
|
+
}
|
|
80
|
+
export interface ThresholdsConfig {
|
|
81
|
+
unitCoverage: CoverageThresholds;
|
|
82
|
+
lighthouse: LighthouseThresholds;
|
|
83
|
+
apiResponseTime: number;
|
|
84
|
+
bundleSizeLimit: number;
|
|
85
|
+
maxConsoleErrors: number;
|
|
86
|
+
}
|
|
87
|
+
export interface TestTeamConfig {
|
|
88
|
+
schemaVersion: number;
|
|
89
|
+
name: string;
|
|
90
|
+
/** Absolute path to the target project root (where package.json, prisma/, apps/ live) */
|
|
91
|
+
projectRoot?: string;
|
|
92
|
+
auth: AuthConfig;
|
|
93
|
+
modules: ModuleConfig[];
|
|
94
|
+
environments: Record<string, EnvironmentConfig>;
|
|
95
|
+
portals: PortalConfig[];
|
|
96
|
+
breakpoints: number[];
|
|
97
|
+
integrations: IntegrationConfig[];
|
|
98
|
+
workers: WorkerConfig[];
|
|
99
|
+
workflows: WorkflowConfig[];
|
|
100
|
+
accuracy: AccuracyConfig;
|
|
101
|
+
tenancy: TenancyConfig;
|
|
102
|
+
costBudget: CostBudgetConfig;
|
|
103
|
+
agentClassification: AgentClassificationConfig;
|
|
104
|
+
thresholds: ThresholdsConfig;
|
|
105
|
+
disabledAgents: number[];
|
|
106
|
+
}
|
|
107
|
+
export interface ValidatedConfig extends TestTeamConfig {
|
|
108
|
+
disabledAgentSet: Set<number>;
|
|
109
|
+
}
|
|
110
|
+
export declare function validateConfig(raw: TestTeamConfig): ValidatedConfig;
|
|
111
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function validateConfig(raw) {
|
|
2
|
+
if (raw.schemaVersion === undefined || raw.schemaVersion === null) {
|
|
3
|
+
throw new Error('schemaVersion is required');
|
|
4
|
+
}
|
|
5
|
+
if (!raw.name) {
|
|
6
|
+
throw new Error('name is required');
|
|
7
|
+
}
|
|
8
|
+
if (raw.modules !== undefined && !Array.isArray(raw.modules)) {
|
|
9
|
+
throw new Error('modules must be an array');
|
|
10
|
+
}
|
|
11
|
+
if (raw.modules !== undefined && Array.isArray(raw.modules) && raw.modules.length === 0) {
|
|
12
|
+
throw new Error('modules must contain at least one module');
|
|
13
|
+
}
|
|
14
|
+
if (!raw.auth) {
|
|
15
|
+
throw new Error('auth is required');
|
|
16
|
+
}
|
|
17
|
+
const disabledAgentSet = new Set(raw.disabledAgents ?? []);
|
|
18
|
+
// Warn on empty credential passwords and empty emails
|
|
19
|
+
if (raw.auth.credentials) {
|
|
20
|
+
const entries = Object.entries(raw.auth.credentials);
|
|
21
|
+
let allPasswordsEmpty = entries.length > 0;
|
|
22
|
+
for (const [role, entry] of entries) {
|
|
23
|
+
if (entry.password === '') {
|
|
24
|
+
console.warn(`[TestTeam] Warning: credential "${role}" has an empty password. Set a real password in your config.`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
allPasswordsEmpty = false;
|
|
28
|
+
}
|
|
29
|
+
if (entry.email === '') {
|
|
30
|
+
console.warn(`[TestTeam] Warning: credential "${role}" has an empty email. Set TF_${role.toUpperCase()}_EMAIL in your environment.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (allPasswordsEmpty && entries.length > 0) {
|
|
34
|
+
throw new Error('All credentials have empty passwords. At least one credential must have a non-empty password.');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
...raw,
|
|
39
|
+
disabledAgentSet,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../core/config.ts"],"names":[],"mappings":"AAgIA,MAAM,UAAU,cAAc,CAAC,GAAmB;IAChD,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS,IAAI,GAAG,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;IAEnE,sDAAsD;IACtD,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAE3C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,mCAAmC,IAAI,8DAA8D,CAAC,CAAC;YACtH,CAAC;iBAAM,CAAC;gBACN,iBAAiB,GAAG,KAAK,CAAC;YAC5B,CAAC;YAED,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,mCAAmC,IAAI,gCAAgC,IAAI,CAAC,WAAW,EAAE,6BAA6B,CAAC,CAAC;YACvI,CAAC;QACH,CAAC;QAED,IAAI,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG,GAAG;QACN,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface CostBudget {
|
|
2
|
+
maxPerRun: number;
|
|
3
|
+
maxPerAgent: number;
|
|
4
|
+
alertThreshold: number;
|
|
5
|
+
onExceeded: 'abort' | 'alert-continue' | 'skip-remaining';
|
|
6
|
+
}
|
|
7
|
+
export interface BudgetCheckResult {
|
|
8
|
+
status: 'ok' | 'alert' | 'exceeded';
|
|
9
|
+
totalCost: number;
|
|
10
|
+
budgetRemaining: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class CostTracker {
|
|
13
|
+
private readonly budget;
|
|
14
|
+
private readonly agentCosts;
|
|
15
|
+
constructor(budget: CostBudget);
|
|
16
|
+
trackCost(agentId: string, amount: number): void;
|
|
17
|
+
getTotalCost(): number;
|
|
18
|
+
getAgentCost(agentId: string): number;
|
|
19
|
+
checkBudget(): BudgetCheckResult;
|
|
20
|
+
isAgentOverBudget(agentId: string): boolean;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../../core/cost-tracker.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,OAAO,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;CAC3D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;gBAEjD,MAAM,EAAE,UAAU;IAI9B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhD,YAAY,IAAI,MAAM;IAQtB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIrC,WAAW,IAAI,iBAAiB;IAiBhC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;CAG5C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class CostTracker {
|
|
2
|
+
budget;
|
|
3
|
+
agentCosts = new Map();
|
|
4
|
+
constructor(budget) {
|
|
5
|
+
this.budget = budget;
|
|
6
|
+
}
|
|
7
|
+
trackCost(agentId, amount) {
|
|
8
|
+
const current = this.agentCosts.get(agentId) ?? 0;
|
|
9
|
+
this.agentCosts.set(agentId, current + amount);
|
|
10
|
+
}
|
|
11
|
+
getTotalCost() {
|
|
12
|
+
let total = 0;
|
|
13
|
+
for (const cost of this.agentCosts.values()) {
|
|
14
|
+
total += cost;
|
|
15
|
+
}
|
|
16
|
+
return total;
|
|
17
|
+
}
|
|
18
|
+
getAgentCost(agentId) {
|
|
19
|
+
return this.agentCosts.get(agentId) ?? 0;
|
|
20
|
+
}
|
|
21
|
+
checkBudget() {
|
|
22
|
+
const totalCost = this.getTotalCost();
|
|
23
|
+
const budgetRemaining = this.budget.maxPerRun - totalCost;
|
|
24
|
+
const alertLimit = this.budget.maxPerRun * this.budget.alertThreshold;
|
|
25
|
+
let status;
|
|
26
|
+
if (totalCost >= this.budget.maxPerRun) {
|
|
27
|
+
status = 'exceeded';
|
|
28
|
+
}
|
|
29
|
+
else if (totalCost >= alertLimit) {
|
|
30
|
+
status = 'alert';
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
status = 'ok';
|
|
34
|
+
}
|
|
35
|
+
return { status, totalCost, budgetRemaining };
|
|
36
|
+
}
|
|
37
|
+
isAgentOverBudget(agentId) {
|
|
38
|
+
return this.getAgentCost(agentId) >= this.budget.maxPerAgent;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=cost-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../core/cost-tracker.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,WAAW;IACL,MAAM,CAAa;IACnB,UAAU,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE7D,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,SAAS,CAAC,OAAe,EAAE,MAAc;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,YAAY;QACV,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,KAAK,IAAI,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,WAAW;QACT,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACtC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;QAEtE,IAAI,MAAmC,CAAC;QACxC,IAAI,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC;aAAM,IAAI,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,GAAG,OAAO,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;IAChD,CAAC;IAED,iBAAiB,CAAC,OAAe;QAC/B,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;IAC/D,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentResult, Finding, Phase } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the canonical `.run/{runId}/` directory structure.
|
|
4
|
+
* Safe to call multiple times — uses `{ recursive: true }`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function initRunDirectory(runDir: string): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Writes an AgentResult as JSON to `agent-results/{agentId}.json`.
|
|
9
|
+
* Creates the parent directory lazily if it does not yet exist.
|
|
10
|
+
*/
|
|
11
|
+
export declare function writeAgentResult(runDir: string, agentId: number, result: AgentResult): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Reads an AgentResult from `agent-results/{agentId}.json`.
|
|
14
|
+
* Returns `null` when the file does not exist.
|
|
15
|
+
*/
|
|
16
|
+
export declare function readAgentResult(runDir: string, agentId: number): Promise<AgentResult | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Writes a Finding as JSON to the appropriate subdirectory.
|
|
19
|
+
* Creates the target directory lazily if it does not yet exist.
|
|
20
|
+
*/
|
|
21
|
+
export declare function writeFinding(runDir: string, finding: Finding): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Moves all files currently in `agent-results/` to
|
|
24
|
+
* `archive/attempt-{attempt}/` and empties the source directory.
|
|
25
|
+
* Is a no-op when `agent-results/` is empty or does not exist.
|
|
26
|
+
*/
|
|
27
|
+
export declare function archivePhaseResults(runDir: string, phase: Phase, attempt: number): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../core/evidence.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAe,KAAK,EAAE,MAAM,SAAS,CAAC;AAWxE;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAW7B;AAgBD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlF;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAyBf"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
const SUBDIRS = [
|
|
4
|
+
'agent-results',
|
|
5
|
+
'findings/test-bugs',
|
|
6
|
+
'findings/code-bugs',
|
|
7
|
+
'evidence/screenshots',
|
|
8
|
+
'evidence/logs',
|
|
9
|
+
'evidence/reports',
|
|
10
|
+
];
|
|
11
|
+
/**
|
|
12
|
+
* Creates the canonical `.run/{runId}/` directory structure.
|
|
13
|
+
* Safe to call multiple times — uses `{ recursive: true }`.
|
|
14
|
+
*/
|
|
15
|
+
export async function initRunDirectory(runDir) {
|
|
16
|
+
for (const subdir of SUBDIRS) {
|
|
17
|
+
await fs.mkdir(path.join(runDir, subdir), { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Writes an AgentResult as JSON to `agent-results/{agentId}.json`.
|
|
22
|
+
* Creates the parent directory lazily if it does not yet exist.
|
|
23
|
+
*/
|
|
24
|
+
export async function writeAgentResult(runDir, agentId, result) {
|
|
25
|
+
const dir = path.join(runDir, 'agent-results');
|
|
26
|
+
await fs.mkdir(dir, { recursive: true });
|
|
27
|
+
await fs.writeFile(path.join(dir, `${agentId}.json`), JSON.stringify(result, null, 2), 'utf-8');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Reads an AgentResult from `agent-results/{agentId}.json`.
|
|
31
|
+
* Returns `null` when the file does not exist.
|
|
32
|
+
*/
|
|
33
|
+
export async function readAgentResult(runDir, agentId) {
|
|
34
|
+
const filePath = path.join(runDir, 'agent-results', `${agentId}.json`);
|
|
35
|
+
try {
|
|
36
|
+
const raw = await fs.readFile(filePath, 'utf-8');
|
|
37
|
+
return JSON.parse(raw);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (isNodeError(err) && err.code === 'ENOENT') {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Determines the findings subdirectory for a given FindingType.
|
|
48
|
+
*
|
|
49
|
+
* - `test-bug` → `findings/test-bugs/`
|
|
50
|
+
* - `code-bug-*` → `findings/code-bugs/`
|
|
51
|
+
* - `infra-issue` → `findings/code-bugs/`
|
|
52
|
+
*/
|
|
53
|
+
function findingSubdir(type) {
|
|
54
|
+
if (type === 'test-bug') {
|
|
55
|
+
return 'findings/test-bugs';
|
|
56
|
+
}
|
|
57
|
+
return 'findings/code-bugs';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Writes a Finding as JSON to the appropriate subdirectory.
|
|
61
|
+
* Creates the target directory lazily if it does not yet exist.
|
|
62
|
+
*/
|
|
63
|
+
export async function writeFinding(runDir, finding) {
|
|
64
|
+
const dir = path.join(runDir, findingSubdir(finding.type));
|
|
65
|
+
await fs.mkdir(dir, { recursive: true });
|
|
66
|
+
await fs.writeFile(path.join(dir, `${finding.id}.json`), JSON.stringify(finding, null, 2), 'utf-8');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Moves all files currently in `agent-results/` to
|
|
70
|
+
* `archive/attempt-{attempt}/` and empties the source directory.
|
|
71
|
+
* Is a no-op when `agent-results/` is empty or does not exist.
|
|
72
|
+
*/
|
|
73
|
+
export async function archivePhaseResults(runDir, phase, attempt) {
|
|
74
|
+
const sourceDir = path.join(runDir, 'agent-results');
|
|
75
|
+
let entries;
|
|
76
|
+
try {
|
|
77
|
+
entries = await fs.readdir(sourceDir);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (isNodeError(err) && err.code === 'ENOENT') {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
if (entries.length === 0) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const destDir = path.join(runDir, 'archive', `${phase}-attempt-${attempt}`);
|
|
89
|
+
await fs.mkdir(destDir, { recursive: true });
|
|
90
|
+
await Promise.all(entries.map((entry) => fs.rename(path.join(sourceDir, entry), path.join(destDir, entry))));
|
|
91
|
+
}
|
|
92
|
+
function isNodeError(err) {
|
|
93
|
+
return err instanceof Error && 'code' in err;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../core/evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Finding, FindingType, Phase } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Classifies a finding based on its file location and description keywords.
|
|
4
|
+
*
|
|
5
|
+
* Priority order:
|
|
6
|
+
* 1. Test file with unchanged source → test-bug
|
|
7
|
+
* 2. Security keyword in description → code-bug-security
|
|
8
|
+
* 3. Cosmetic keyword in description → code-bug-cosmetic
|
|
9
|
+
* 4. Fallback → code-bug-logic
|
|
10
|
+
*/
|
|
11
|
+
export declare function classifyFinding(finding: Finding, changedFiles: string[]): FindingType;
|
|
12
|
+
/**
|
|
13
|
+
* Determines whether a finding should be automatically committed without human intervention.
|
|
14
|
+
*
|
|
15
|
+
* UAT phase never auto-commits regardless of finding type.
|
|
16
|
+
* Test bugs always auto-commit (routed to the Healer agent).
|
|
17
|
+
* Cosmetic bugs auto-commit in alpha and beta only.
|
|
18
|
+
* Logic and security bugs never auto-commit (require human gates).
|
|
19
|
+
*/
|
|
20
|
+
export declare function shouldAutoCommit(findingType: FindingType, phase: Phase): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Determines whether a finding requires human review before any action is taken.
|
|
23
|
+
*
|
|
24
|
+
* Security and logic bugs always require human review.
|
|
25
|
+
* UAT phase requires human review for all finding types.
|
|
26
|
+
* Cosmetic bugs and test bugs in alpha/beta do not require human review.
|
|
27
|
+
*/
|
|
28
|
+
export declare function shouldRequireHumanReview(findingType: FindingType, phase: Phase): boolean;
|
|
29
|
+
//# sourceMappingURL=fix-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-loop.d.ts","sourceRoot":"","sources":["../../core/fix-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAc3D;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,WAAW,CAgBrF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAgBhF;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAUxF"}
|