@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
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { BaseAgent } from '../base-agent';
|
|
3
|
+
import type { Finding, Phase } from '../../core/types';
|
|
4
|
+
import type { ValidatedConfig } from '../../core/config';
|
|
5
|
+
|
|
6
|
+
const stubConfig = {
|
|
7
|
+
schemaVersion: 1,
|
|
8
|
+
name: 'test',
|
|
9
|
+
auth: { loginUrl: 'http://localhost' },
|
|
10
|
+
modules: [{ id: 'mod', route: '/mod', sidebarIcon: true }],
|
|
11
|
+
environments: {},
|
|
12
|
+
portals: [],
|
|
13
|
+
breakpoints: [],
|
|
14
|
+
integrations: [],
|
|
15
|
+
workers: [],
|
|
16
|
+
workflows: [],
|
|
17
|
+
accuracy: { enabled: false, decimalPrecision: 2, currencySymbol: '$', timezone: 'UTC' },
|
|
18
|
+
tenancy: { enabled: false, isolationField: 'firmId', testFirms: [] },
|
|
19
|
+
costBudget: { maxPerRun: 100, maxPerAgent: 10, alertThreshold: 0.8, onExceeded: 'abort' as const },
|
|
20
|
+
agentClassification: { blocking: [], advisory: [] },
|
|
21
|
+
thresholds: {
|
|
22
|
+
unitCoverage: { lines: 80, functions: 80, branches: 80, statements: 80 },
|
|
23
|
+
lighthouse: { accessibility: 90, performance: 90, bestPractices: 90, seo: 90 },
|
|
24
|
+
apiResponseTime: 2000,
|
|
25
|
+
bundleSizeLimit: 500000,
|
|
26
|
+
maxConsoleErrors: 0,
|
|
27
|
+
},
|
|
28
|
+
disabledAgents: [],
|
|
29
|
+
disabledAgentSet: new Set<number>(),
|
|
30
|
+
} satisfies ValidatedConfig;
|
|
31
|
+
|
|
32
|
+
class TestAgent extends BaseAgent {
|
|
33
|
+
readonly agentId = 99;
|
|
34
|
+
readonly agentName = 'test-agent';
|
|
35
|
+
preFlightFn: () => Promise<void> = async () => {};
|
|
36
|
+
executeFn: () => Promise<Finding[]> = async () => [];
|
|
37
|
+
|
|
38
|
+
protected async preFlight(): Promise<void> { await this.preFlightFn(); }
|
|
39
|
+
protected async execute(): Promise<Finding[]> { return this.executeFn(); }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function createAgent(phase: Phase = 'alpha'): TestAgent {
|
|
43
|
+
return new TestAgent(stubConfig, phase, '/tmp/test-run');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
describe('BaseAgent', () => {
|
|
47
|
+
it('calls preFlight() then execute() in order', async () => {
|
|
48
|
+
const agent = createAgent();
|
|
49
|
+
const callOrder: string[] = [];
|
|
50
|
+
agent.preFlightFn = async () => { callOrder.push('preFlight'); };
|
|
51
|
+
agent.executeFn = async () => { callOrder.push('execute'); return []; };
|
|
52
|
+
|
|
53
|
+
await agent.run();
|
|
54
|
+
|
|
55
|
+
expect(callOrder).toEqual(['preFlight', 'execute']);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('returns failed status with error when preFlight() throws', async () => {
|
|
59
|
+
const agent = createAgent();
|
|
60
|
+
agent.preFlightFn = async () => { throw new Error('pre-flight boom'); };
|
|
61
|
+
|
|
62
|
+
const result = await agent.run();
|
|
63
|
+
|
|
64
|
+
expect(result.status).toBe('failed');
|
|
65
|
+
expect(result.findings).toHaveLength(1);
|
|
66
|
+
expect(result.findings[0].severity).toBe('critical');
|
|
67
|
+
expect(result.findings[0].description).toBe('pre-flight boom');
|
|
68
|
+
expect(result.findings[0].type).toBe('infra-issue');
|
|
69
|
+
expect(result.summary).toContain('pre-flight boom');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('returns failed status when execute() returns critical findings', async () => {
|
|
73
|
+
const agent = createAgent();
|
|
74
|
+
agent.executeFn = async () => [{
|
|
75
|
+
id: '99-crit',
|
|
76
|
+
type: 'code-bug-logic',
|
|
77
|
+
severity: 'critical',
|
|
78
|
+
agentId: 99,
|
|
79
|
+
module: 'test',
|
|
80
|
+
description: 'critical issue',
|
|
81
|
+
}];
|
|
82
|
+
|
|
83
|
+
const result = await agent.run();
|
|
84
|
+
|
|
85
|
+
expect(result.status).toBe('failed');
|
|
86
|
+
expect(result.findings).toHaveLength(1);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('returns failed status when execute() returns high severity findings', async () => {
|
|
90
|
+
const agent = createAgent();
|
|
91
|
+
agent.executeFn = async () => [{
|
|
92
|
+
id: '99-high',
|
|
93
|
+
type: 'code-bug-logic',
|
|
94
|
+
severity: 'high',
|
|
95
|
+
agentId: 99,
|
|
96
|
+
module: 'test',
|
|
97
|
+
description: 'high issue',
|
|
98
|
+
}];
|
|
99
|
+
|
|
100
|
+
const result = await agent.run();
|
|
101
|
+
|
|
102
|
+
expect(result.status).toBe('failed');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('returns passed status when execute() returns only low findings', async () => {
|
|
106
|
+
const agent = createAgent();
|
|
107
|
+
agent.executeFn = async () => [{
|
|
108
|
+
id: '99-low',
|
|
109
|
+
type: 'code-bug-cosmetic',
|
|
110
|
+
severity: 'low',
|
|
111
|
+
agentId: 99,
|
|
112
|
+
module: 'test',
|
|
113
|
+
description: 'minor issue',
|
|
114
|
+
}];
|
|
115
|
+
|
|
116
|
+
const result = await agent.run();
|
|
117
|
+
|
|
118
|
+
expect(result.status).toBe('passed');
|
|
119
|
+
expect(result.summary).toContain('1 findings');
|
|
120
|
+
expect(result.summary).toContain('1 low');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('returns passed status when execute() returns only medium findings', async () => {
|
|
124
|
+
const agent = createAgent();
|
|
125
|
+
agent.executeFn = async () => [{
|
|
126
|
+
id: '99-med',
|
|
127
|
+
type: 'code-bug-cosmetic',
|
|
128
|
+
severity: 'medium',
|
|
129
|
+
agentId: 99,
|
|
130
|
+
module: 'test',
|
|
131
|
+
description: 'medium issue',
|
|
132
|
+
}];
|
|
133
|
+
|
|
134
|
+
const result = await agent.run();
|
|
135
|
+
|
|
136
|
+
expect(result.status).toBe('passed');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('includes evidence items added during execution in the result', async () => {
|
|
140
|
+
const agent = createAgent();
|
|
141
|
+
agent.executeFn = async () => {
|
|
142
|
+
agent['addEvidence']({ type: 'log', path: '/tmp/log.txt', description: 'test log' });
|
|
143
|
+
agent['addEvidence']({ type: 'screenshot', path: '/tmp/shot.png', description: 'test shot' });
|
|
144
|
+
return [];
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const result = await agent.run();
|
|
148
|
+
|
|
149
|
+
expect(result.evidence).toHaveLength(2);
|
|
150
|
+
expect(result.evidence[0].type).toBe('log');
|
|
151
|
+
expect(result.evidence[1].type).toBe('screenshot');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('produces a clean summary when no findings exist', async () => {
|
|
155
|
+
const agent = createAgent();
|
|
156
|
+
const result = await agent.run();
|
|
157
|
+
|
|
158
|
+
expect(result.summary).toBe('test-agent: All checks passed');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('captures non-Error throws in the error finding', async () => {
|
|
162
|
+
const agent = createAgent();
|
|
163
|
+
agent.preFlightFn = async () => { throw 'string-error'; };
|
|
164
|
+
|
|
165
|
+
const result = await agent.run();
|
|
166
|
+
|
|
167
|
+
expect(result.status).toBe('failed');
|
|
168
|
+
expect(result.findings[0].description).toBe('string-error');
|
|
169
|
+
expect(result.findings[0].stackTrace).toBeUndefined();
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('populates agentId, agentName, and phase correctly', async () => {
|
|
173
|
+
const agent = createAgent('beta');
|
|
174
|
+
const result = await agent.run();
|
|
175
|
+
|
|
176
|
+
expect(result.agentId).toBe(99);
|
|
177
|
+
expect(result.agentName).toBe('test-agent');
|
|
178
|
+
expect(result.phase).toBe('beta');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('computes durationMs as a non-negative number', async () => {
|
|
182
|
+
const agent = createAgent();
|
|
183
|
+
const result = await agent.run();
|
|
184
|
+
|
|
185
|
+
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
186
|
+
expect(typeof result.durationMs).toBe('number');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
AGENT_TIERS,
|
|
4
|
+
getAgentTier,
|
|
5
|
+
isAgentAvailable,
|
|
6
|
+
type LicenseTier,
|
|
7
|
+
} from '../registry';
|
|
8
|
+
|
|
9
|
+
describe('AGENT_TIERS', () => {
|
|
10
|
+
it('should contain exactly 23 agents', () => {
|
|
11
|
+
expect(Object.keys(AGENT_TIERS)).toHaveLength(23);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should have 8 free-tier agents', () => {
|
|
15
|
+
const freeAgents = Object.entries(AGENT_TIERS).filter(([, t]) => t === 'free');
|
|
16
|
+
expect(freeAgents).toHaveLength(8);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should have 9 pro-tier agents', () => {
|
|
20
|
+
const proAgents = Object.entries(AGENT_TIERS).filter(([, t]) => t === 'pro');
|
|
21
|
+
expect(proAgents).toHaveLength(9);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should have 6 enterprise-tier agents', () => {
|
|
25
|
+
const entAgents = Object.entries(AGENT_TIERS).filter(([, t]) => t === 'enterprise');
|
|
26
|
+
expect(entAgents).toHaveLength(6);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should classify known agents correctly', () => {
|
|
30
|
+
expect(AGENT_TIERS[1]).toBe('free'); // Analyst
|
|
31
|
+
expect(AGENT_TIERS[5]).toBe('free'); // Browser Crawler
|
|
32
|
+
expect(AGENT_TIERS[7]).toBe('pro'); // Security Scout
|
|
33
|
+
expect(AGENT_TIERS[13]).toBe('pro'); // Performance Profiler
|
|
34
|
+
expect(AGENT_TIERS[16]).toBe('enterprise'); // Chaos Agent
|
|
35
|
+
expect(AGENT_TIERS[19]).toBe('enterprise'); // Tenant Isolation Auditor
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('getAgentTier', () => {
|
|
40
|
+
it('should return the correct tier for each agent', () => {
|
|
41
|
+
expect(getAgentTier(1)).toBe('free');
|
|
42
|
+
expect(getAgentTier(6)).toBe('pro');
|
|
43
|
+
expect(getAgentTier(14)).toBe('enterprise');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should throw for an unknown agent number', () => {
|
|
47
|
+
expect(() => getAgentTier(99)).toThrow('Unknown agent number: 99');
|
|
48
|
+
expect(() => getAgentTier(0)).toThrow('Unknown agent number: 0');
|
|
49
|
+
expect(() => getAgentTier(-1)).toThrow('Unknown agent number: -1');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('isAgentAvailable', () => {
|
|
54
|
+
const freeAgents = [1, 2, 3, 4, 5, 9, 10, 11];
|
|
55
|
+
const proAgents = [6, 7, 8, 12, 13, 15, 21, 22, 23];
|
|
56
|
+
const enterpriseAgents = [14, 16, 17, 18, 19, 20];
|
|
57
|
+
|
|
58
|
+
describe('free license', () => {
|
|
59
|
+
it('should allow free-tier agents', () => {
|
|
60
|
+
for (const id of freeAgents) {
|
|
61
|
+
expect(isAgentAvailable(id, 'free')).toBe(true);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should deny pro-tier agents', () => {
|
|
66
|
+
for (const id of proAgents) {
|
|
67
|
+
expect(isAgentAvailable(id, 'free')).toBe(false);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should deny enterprise-tier agents', () => {
|
|
72
|
+
for (const id of enterpriseAgents) {
|
|
73
|
+
expect(isAgentAvailable(id, 'free')).toBe(false);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('pro license', () => {
|
|
79
|
+
it('should allow free-tier agents', () => {
|
|
80
|
+
for (const id of freeAgents) {
|
|
81
|
+
expect(isAgentAvailable(id, 'pro')).toBe(true);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should allow pro-tier agents', () => {
|
|
86
|
+
for (const id of proAgents) {
|
|
87
|
+
expect(isAgentAvailable(id, 'pro')).toBe(true);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should deny enterprise-tier agents', () => {
|
|
92
|
+
for (const id of enterpriseAgents) {
|
|
93
|
+
expect(isAgentAvailable(id, 'pro')).toBe(false);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe('enterprise license', () => {
|
|
99
|
+
it('should allow all agents', () => {
|
|
100
|
+
for (const id of [...freeAgents, ...proAgents, ...enterpriseAgents]) {
|
|
101
|
+
expect(isAgentAvailable(id, 'enterprise')).toBe(true);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should throw for unknown agent numbers', () => {
|
|
107
|
+
expect(() => isAgentAvailable(99, 'free')).toThrow('Unknown agent number: 99');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// registerAllAgents
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
describe('registerAllAgents', () => {
|
|
116
|
+
// We need to test that registerAllAgents creates 23 agents and registers them all.
|
|
117
|
+
// We mock the orchestrator's registerAgent method.
|
|
118
|
+
|
|
119
|
+
it('registers all 23 agents with the orchestrator', async () => {
|
|
120
|
+
// We need to dynamically import to avoid circular dependencies with mocked modules
|
|
121
|
+
// Instead, test the function signature by checking it registers the right count
|
|
122
|
+
const { registerAllAgents } = await import('../registry');
|
|
123
|
+
|
|
124
|
+
const mockOrchestrator = {
|
|
125
|
+
registerAgent: vi.fn(),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const stubConfig = {
|
|
129
|
+
schemaVersion: 1,
|
|
130
|
+
name: 'test',
|
|
131
|
+
auth: { loginUrl: '/login' },
|
|
132
|
+
modules: [],
|
|
133
|
+
environments: {},
|
|
134
|
+
portals: [],
|
|
135
|
+
breakpoints: [],
|
|
136
|
+
integrations: [],
|
|
137
|
+
workers: [],
|
|
138
|
+
workflows: [],
|
|
139
|
+
accuracy: { enabled: false, decimalPrecision: 2, currencySymbol: '$', timezone: 'UTC' },
|
|
140
|
+
tenancy: { enabled: false, isolationField: 'firmId', testFirms: [] },
|
|
141
|
+
costBudget: { maxPerRun: 100, maxPerAgent: 10, alertThreshold: 0.8, onExceeded: 'abort' as const },
|
|
142
|
+
agentClassification: { blocking: [], advisory: [] },
|
|
143
|
+
thresholds: {
|
|
144
|
+
unitCoverage: { lines: 80, functions: 80, branches: 80, statements: 80 },
|
|
145
|
+
lighthouse: { accessibility: 90, performance: 90, bestPractices: 90, seo: 90 },
|
|
146
|
+
apiResponseTime: 2000,
|
|
147
|
+
bundleSizeLimit: 500000,
|
|
148
|
+
maxConsoleErrors: 0,
|
|
149
|
+
},
|
|
150
|
+
disabledAgents: [],
|
|
151
|
+
disabledAgentSet: new Set<number>(),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
registerAllAgents(
|
|
155
|
+
mockOrchestrator as any,
|
|
156
|
+
stubConfig as any,
|
|
157
|
+
'alpha',
|
|
158
|
+
'/tmp/run',
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
expect(mockOrchestrator.registerAgent).toHaveBeenCalledTimes(23);
|
|
162
|
+
|
|
163
|
+
// Verify agent IDs 1-23 are all registered
|
|
164
|
+
const registeredIds = mockOrchestrator.registerAgent.mock.calls.map(
|
|
165
|
+
(call: unknown[]) => call[0],
|
|
166
|
+
);
|
|
167
|
+
for (let i = 1; i <= 23; i++) {
|
|
168
|
+
expect(registeredIds).toContain(i);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('passes correct config, phase, and runDir to each agent', async () => {
|
|
173
|
+
const { registerAllAgents } = await import('../registry');
|
|
174
|
+
|
|
175
|
+
const mockOrchestrator = {
|
|
176
|
+
registerAgent: vi.fn(),
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const stubConfig = {
|
|
180
|
+
schemaVersion: 1,
|
|
181
|
+
name: 'my-project',
|
|
182
|
+
auth: { loginUrl: '/login' },
|
|
183
|
+
modules: [],
|
|
184
|
+
environments: {},
|
|
185
|
+
portals: [],
|
|
186
|
+
breakpoints: [],
|
|
187
|
+
integrations: [],
|
|
188
|
+
workers: [],
|
|
189
|
+
workflows: [],
|
|
190
|
+
accuracy: { enabled: false, decimalPrecision: 2, currencySymbol: '$', timezone: 'UTC' },
|
|
191
|
+
tenancy: { enabled: false, isolationField: 'firmId', testFirms: [] },
|
|
192
|
+
costBudget: { maxPerRun: 100, maxPerAgent: 10, alertThreshold: 0.8, onExceeded: 'abort' as const },
|
|
193
|
+
agentClassification: { blocking: [], advisory: [] },
|
|
194
|
+
thresholds: {
|
|
195
|
+
unitCoverage: { lines: 80, functions: 80, branches: 80, statements: 80 },
|
|
196
|
+
lighthouse: { accessibility: 90, performance: 90, bestPractices: 90, seo: 90 },
|
|
197
|
+
apiResponseTime: 2000,
|
|
198
|
+
bundleSizeLimit: 500000,
|
|
199
|
+
maxConsoleErrors: 0,
|
|
200
|
+
},
|
|
201
|
+
disabledAgents: [],
|
|
202
|
+
disabledAgentSet: new Set<number>(),
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
registerAllAgents(
|
|
206
|
+
mockOrchestrator as any,
|
|
207
|
+
stubConfig as any,
|
|
208
|
+
'beta',
|
|
209
|
+
'/tmp/my-run',
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
// Check that each registered agent has the right agentId property matching the first arg
|
|
213
|
+
for (const call of mockOrchestrator.registerAgent.mock.calls) {
|
|
214
|
+
const [agentId, agent] = call as [number, { agentId: number }];
|
|
215
|
+
expect(agent.agentId).toBe(agentId);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { AgentResult, Finding, Phase, EvidenceItem } from '../core/types';
|
|
2
|
+
import type { ValidatedConfig } from '../core/config';
|
|
3
|
+
|
|
4
|
+
export abstract class BaseAgent {
|
|
5
|
+
constructor(
|
|
6
|
+
protected readonly config: ValidatedConfig,
|
|
7
|
+
protected readonly phase: Phase,
|
|
8
|
+
protected readonly runDir: string,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
abstract readonly agentId: number;
|
|
12
|
+
abstract readonly agentName: string;
|
|
13
|
+
|
|
14
|
+
async run(): Promise<AgentResult> {
|
|
15
|
+
const startedAt = new Date().toISOString();
|
|
16
|
+
try {
|
|
17
|
+
await this.preFlight();
|
|
18
|
+
const findings = await this.execute();
|
|
19
|
+
const completedAt = new Date().toISOString();
|
|
20
|
+
return {
|
|
21
|
+
agentId: this.agentId,
|
|
22
|
+
agentName: this.agentName,
|
|
23
|
+
phase: this.phase,
|
|
24
|
+
status: findings.some(f => f.severity === 'critical' || f.severity === 'high') ? 'failed' : 'passed',
|
|
25
|
+
startedAt,
|
|
26
|
+
completedAt,
|
|
27
|
+
durationMs: new Date(completedAt).getTime() - new Date(startedAt).getTime(),
|
|
28
|
+
findings,
|
|
29
|
+
evidence: this.evidence,
|
|
30
|
+
summary: this.buildSummary(findings),
|
|
31
|
+
};
|
|
32
|
+
} catch (error) {
|
|
33
|
+
const completedAt = new Date().toISOString();
|
|
34
|
+
return {
|
|
35
|
+
agentId: this.agentId,
|
|
36
|
+
agentName: this.agentName,
|
|
37
|
+
phase: this.phase,
|
|
38
|
+
status: 'failed',
|
|
39
|
+
startedAt,
|
|
40
|
+
completedAt,
|
|
41
|
+
durationMs: new Date(completedAt).getTime() - new Date(startedAt).getTime(),
|
|
42
|
+
findings: [{
|
|
43
|
+
id: `${this.agentId}-error`,
|
|
44
|
+
type: 'infra-issue',
|
|
45
|
+
severity: 'critical',
|
|
46
|
+
agentId: this.agentId,
|
|
47
|
+
module: 'agent-runtime',
|
|
48
|
+
description: error instanceof Error ? error.message : String(error),
|
|
49
|
+
stackTrace: error instanceof Error ? error.stack : undefined,
|
|
50
|
+
}],
|
|
51
|
+
evidence: this.evidence,
|
|
52
|
+
summary: `Agent ${this.agentName} failed with error: ${error instanceof Error ? error.message : String(error)}`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected evidence: EvidenceItem[] = [];
|
|
58
|
+
|
|
59
|
+
/** AVI-OS pre-flight: audit dependencies, validate plan, check pre-conditions */
|
|
60
|
+
protected abstract preFlight(): Promise<void>;
|
|
61
|
+
|
|
62
|
+
/** Main execution logic -- single pass, no incremental fix-and-see */
|
|
63
|
+
protected abstract execute(): Promise<Finding[]>;
|
|
64
|
+
|
|
65
|
+
protected addEvidence(item: EvidenceItem): void {
|
|
66
|
+
this.evidence.push(item);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private buildSummary(findings: Finding[]): string {
|
|
70
|
+
if (findings.length === 0) return `${this.agentName}: All checks passed`;
|
|
71
|
+
const critical = findings.filter(f => f.severity === 'critical').length;
|
|
72
|
+
const high = findings.filter(f => f.severity === 'high').length;
|
|
73
|
+
const medium = findings.filter(f => f.severity === 'medium').length;
|
|
74
|
+
const low = findings.filter(f => f.severity === 'low').length;
|
|
75
|
+
return `${this.agentName}: ${findings.length} findings (${critical} critical, ${high} high, ${medium} medium, ${low} low)`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { ValidatedConfig } from '../core/config';
|
|
2
|
+
import type { Phase } from '../core/types';
|
|
3
|
+
import type { Orchestrator } from '../core/orchestrator';
|
|
4
|
+
|
|
5
|
+
/** License tier type used for agent gating */
|
|
6
|
+
export type LicenseTier = 'free' | 'pro' | 'enterprise';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Maps each agent number to its license tier.
|
|
10
|
+
* - free (8 agents): core testing pipeline
|
|
11
|
+
* - pro (9 agents): advanced testing capabilities
|
|
12
|
+
* - enterprise (6 agents): full platform auditing
|
|
13
|
+
*/
|
|
14
|
+
export const AGENT_TIERS: Record<number, LicenseTier> = {
|
|
15
|
+
/* ── Free tier (8) ── */
|
|
16
|
+
1: 'free', // Analyst
|
|
17
|
+
2: 'free', // Seed Architect
|
|
18
|
+
3: 'free', // Test Generator
|
|
19
|
+
4: 'free', // Unit Runner
|
|
20
|
+
5: 'free', // Browser Crawler
|
|
21
|
+
9: 'free', // Healer
|
|
22
|
+
10: 'free', // Reporter
|
|
23
|
+
11: 'free', // Fixer
|
|
24
|
+
|
|
25
|
+
/* ── Pro tier (9) ── */
|
|
26
|
+
6: 'pro', // API Exerciser
|
|
27
|
+
7: 'pro', // Security Scout
|
|
28
|
+
8: 'pro', // A11y Guardian
|
|
29
|
+
12: 'pro', // UX Inspector
|
|
30
|
+
13: 'pro', // Performance Profiler
|
|
31
|
+
15: 'pro', // Regression Sentinel
|
|
32
|
+
21: 'pro', // State & Session Tester
|
|
33
|
+
22: 'pro', // Email Notification Verifier
|
|
34
|
+
23: 'pro', // Migration Tester
|
|
35
|
+
|
|
36
|
+
/* ── Enterprise tier (6) ── */
|
|
37
|
+
14: 'enterprise', // Data Integrity Auditor
|
|
38
|
+
16: 'enterprise', // Chaos Agent
|
|
39
|
+
17: 'enterprise', // Documentation Validator
|
|
40
|
+
18: 'enterprise', // Integration Watchdog
|
|
41
|
+
19: 'enterprise', // Tenant Isolation Auditor
|
|
42
|
+
20: 'enterprise', // Workflow Completion Tester
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Returns the tier classification for a given agent number. */
|
|
46
|
+
export function getAgentTier(agentNumber: number): LicenseTier {
|
|
47
|
+
const tier = AGENT_TIERS[agentNumber];
|
|
48
|
+
if (!tier) {
|
|
49
|
+
throw new Error(`Unknown agent number: ${agentNumber}`);
|
|
50
|
+
}
|
|
51
|
+
return tier;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const TIER_HIERARCHY: Record<LicenseTier, ReadonlySet<LicenseTier>> = {
|
|
55
|
+
free: new Set<LicenseTier>(['free']),
|
|
56
|
+
pro: new Set<LicenseTier>(['free', 'pro']),
|
|
57
|
+
enterprise: new Set<LicenseTier>(['free', 'pro', 'enterprise']),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Checks whether an agent is available under the given license tier.
|
|
62
|
+
* - free: only free agents
|
|
63
|
+
* - pro: free + pro agents
|
|
64
|
+
* - enterprise: all agents
|
|
65
|
+
*/
|
|
66
|
+
export function isAgentAvailable(agentNumber: number, licenseTier: LicenseTier): boolean {
|
|
67
|
+
const agentTier = getAgentTier(agentNumber);
|
|
68
|
+
return TIER_HIERARCHY[licenseTier].has(agentTier);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
import { AnalystAgent } from './01-analyst';
|
|
72
|
+
import { SeedArchitectAgent } from './02-seed-architect';
|
|
73
|
+
import { TestGeneratorAgent } from './03-test-generator';
|
|
74
|
+
import { UnitRunnerAgent } from './04-unit-runner';
|
|
75
|
+
import { BrowserCrawlerAgent } from './05-browser-crawler';
|
|
76
|
+
import { ApiExerciserAgent } from './06-api-exerciser';
|
|
77
|
+
import { SecurityScoutAgent } from './07-security-scout';
|
|
78
|
+
import { A11yGuardianAgent } from './08-a11y-guardian';
|
|
79
|
+
import { HealerAgent } from './09-healer';
|
|
80
|
+
import { ReporterAgent } from './10-reporter';
|
|
81
|
+
import { FixerAgent } from './11-fixer';
|
|
82
|
+
import { UxInspectorAgent } from './12-ux-inspector';
|
|
83
|
+
import { PerformanceProfilerAgent } from './13-performance-profiler';
|
|
84
|
+
import { DataIntegrityAuditorAgent } from './14-data-integrity-auditor';
|
|
85
|
+
import { RegressionSentinelAgent } from './15-regression-sentinel';
|
|
86
|
+
import { ChaosAgent } from './16-chaos-agent';
|
|
87
|
+
import { DocumentationValidatorAgent } from './17-documentation-validator';
|
|
88
|
+
import { IntegrationWatchdogAgent } from './18-integration-watchdog';
|
|
89
|
+
import { TenantIsolationAuditorAgent } from './19-tenant-isolation-auditor';
|
|
90
|
+
import { WorkflowCompletionTesterAgent } from './20-workflow-completion-tester';
|
|
91
|
+
import { StateSessionTesterAgent } from './21-state-session-tester';
|
|
92
|
+
import { EmailNotificationVerifierAgent } from './22-email-notification-verifier';
|
|
93
|
+
import { MigrationTesterAgent } from './23-migration-tester';
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Register all 23 agents with the orchestrator.
|
|
97
|
+
* Each agent is instantiated with the validated config, phase, and run directory.
|
|
98
|
+
* Since agents may run in different phases, we register them for all phases
|
|
99
|
+
* and the orchestrator handles dispatching only the ones needed per phase.
|
|
100
|
+
*/
|
|
101
|
+
export function registerAllAgents(
|
|
102
|
+
orchestrator: Orchestrator,
|
|
103
|
+
config: ValidatedConfig,
|
|
104
|
+
phase: Phase,
|
|
105
|
+
runDir: string,
|
|
106
|
+
): void {
|
|
107
|
+
const agents = [
|
|
108
|
+
new AnalystAgent(config, phase, runDir),
|
|
109
|
+
new SeedArchitectAgent(config, phase, runDir),
|
|
110
|
+
new TestGeneratorAgent(config, phase, runDir),
|
|
111
|
+
new UnitRunnerAgent(config, phase, runDir),
|
|
112
|
+
new BrowserCrawlerAgent(config, phase, runDir),
|
|
113
|
+
new ApiExerciserAgent(config, phase, runDir),
|
|
114
|
+
new SecurityScoutAgent(config, phase, runDir),
|
|
115
|
+
new A11yGuardianAgent(config, phase, runDir),
|
|
116
|
+
new HealerAgent(config, phase, runDir),
|
|
117
|
+
new ReporterAgent(config, phase, runDir),
|
|
118
|
+
new FixerAgent(config, phase, runDir),
|
|
119
|
+
new UxInspectorAgent(config, phase, runDir),
|
|
120
|
+
new PerformanceProfilerAgent(config, phase, runDir),
|
|
121
|
+
new DataIntegrityAuditorAgent(config, phase, runDir),
|
|
122
|
+
new RegressionSentinelAgent(config, phase, runDir),
|
|
123
|
+
new ChaosAgent(config, phase, runDir),
|
|
124
|
+
new DocumentationValidatorAgent(config, phase, runDir),
|
|
125
|
+
new IntegrationWatchdogAgent(config, phase, runDir),
|
|
126
|
+
new TenantIsolationAuditorAgent(config, phase, runDir),
|
|
127
|
+
new WorkflowCompletionTesterAgent(config, phase, runDir),
|
|
128
|
+
new StateSessionTesterAgent(config, phase, runDir),
|
|
129
|
+
new EmailNotificationVerifierAgent(config, phase, runDir),
|
|
130
|
+
new MigrationTesterAgent(config, phase, runDir),
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
for (const agent of agents) {
|
|
134
|
+
orchestrator.registerAgent(agent.agentId, agent);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/bin/testteam.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
const cli = join(__dirname, '..', 'core', 'cli.ts');
|
|
9
|
+
|
|
10
|
+
execFileSync('npx', ['tsx', cli, ...process.argv.slice(2)], { stdio: 'inherit' });
|