@yasserkhanorg/e2e-agents 1.8.5 → 1.9.5
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/README.md +95 -8
- package/dist/adapters/cypress.d.ts +10 -0
- package/dist/adapters/cypress.d.ts.map +1 -0
- package/dist/adapters/cypress.js +86 -0
- package/dist/adapters/framework_adapter.d.ts +41 -0
- package/dist/adapters/framework_adapter.d.ts.map +1 -0
- package/dist/adapters/framework_adapter.js +152 -0
- package/dist/adapters/playwright.d.ts +10 -0
- package/dist/adapters/playwright.d.ts.map +1 -0
- package/dist/adapters/playwright.js +86 -0
- package/dist/adapters/pytest.d.ts +10 -0
- package/dist/adapters/pytest.d.ts.map +1 -0
- package/dist/adapters/pytest.js +96 -0
- package/dist/adapters/supertest.d.ts +12 -0
- package/dist/adapters/supertest.d.ts.map +1 -0
- package/dist/adapters/supertest.js +85 -0
- package/dist/agent/config.d.ts +1 -1
- package/dist/agent/config.d.ts.map +1 -1
- package/dist/agent/git.d.ts +1 -0
- package/dist/agent/git.d.ts.map +1 -1
- package/dist/agent/git.js +3 -0
- package/dist/agentic/fix_loop.d.ts.map +1 -1
- package/dist/agentic/fix_loop.js +5 -4
- package/dist/agentic/runner.d.ts +2 -0
- package/dist/agentic/runner.d.ts.map +1 -1
- package/dist/agentic/runner.js +15 -12
- package/dist/agents/cross-impact.d.ts.map +1 -1
- package/dist/agents/cross-impact.js +6 -1
- package/dist/agents/executor.d.ts.map +1 -1
- package/dist/agents/executor.js +6 -1
- package/dist/agents/strategist.d.ts.map +1 -1
- package/dist/agents/strategist.js +6 -1
- package/dist/agents/test-designer.d.ts.map +1 -1
- package/dist/agents/test-designer.js +6 -1
- package/dist/anthropic_provider.d.ts.map +1 -1
- package/dist/anthropic_provider.js +1 -0
- package/dist/base_provider.d.ts +56 -0
- package/dist/base_provider.d.ts.map +1 -1
- package/dist/base_provider.js +123 -1
- package/dist/budget_ledger.d.ts +28 -0
- package/dist/budget_ledger.d.ts.map +1 -0
- package/dist/budget_ledger.js +62 -0
- package/dist/cache/cached_provider.d.ts +45 -0
- package/dist/cache/cached_provider.d.ts.map +1 -0
- package/dist/cache/cached_provider.js +88 -0
- package/dist/cache/response_cache.d.ts +79 -0
- package/dist/cache/response_cache.d.ts.map +1 -0
- package/dist/cache/response_cache.js +177 -0
- package/dist/cli/commands/bootstrap.d.ts +3 -0
- package/dist/cli/commands/bootstrap.d.ts.map +1 -0
- package/dist/cli/commands/bootstrap.js +109 -0
- package/dist/cli/commands/cost_report.d.ts +3 -0
- package/dist/cli/commands/cost_report.d.ts.map +1 -0
- package/dist/cli/commands/cost_report.js +115 -0
- package/dist/cli/commands/crew.d.ts.map +1 -1
- package/dist/cli/commands/crew.js +118 -1
- package/dist/cli/commands/gate.d.ts +3 -0
- package/dist/cli/commands/gate.d.ts.map +1 -0
- package/dist/cli/commands/gate.js +86 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +7 -62
- package/dist/cli/commands/train.d.ts.map +1 -1
- package/dist/cli/commands/train.js +16 -21
- package/dist/cli/defaults.d.ts +35 -0
- package/dist/cli/defaults.d.ts.map +1 -0
- package/dist/cli/defaults.js +125 -0
- package/dist/cli/errors.d.ts +27 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +57 -0
- package/dist/cli/parse_args.d.ts.map +1 -1
- package/dist/cli/parse_args.js +24 -2
- package/dist/cli/types.d.ts +7 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli.js +47 -2
- package/dist/crew/context.d.ts +15 -0
- package/dist/crew/context.d.ts.map +1 -1
- package/dist/crew/orchestrator.d.ts +14 -0
- package/dist/crew/orchestrator.d.ts.map +1 -1
- package/dist/crew/orchestrator.js +162 -4
- package/dist/crew/protocol.d.ts +13 -0
- package/dist/crew/protocol.d.ts.map +1 -1
- package/dist/crew/provider.d.ts +15 -1
- package/dist/crew/provider.d.ts.map +1 -1
- package/dist/crew/provider.js +24 -4
- package/dist/custom_provider.d.ts.map +1 -1
- package/dist/custom_provider.js +1 -0
- package/dist/engine/diff_loader.d.ts.map +1 -1
- package/dist/engine/diff_loader.js +3 -14
- package/dist/engine/impact_engine.d.ts.map +1 -1
- package/dist/engine/impact_engine.js +9 -23
- package/dist/esm/adapters/cypress.js +49 -0
- package/dist/esm/adapters/framework_adapter.js +114 -0
- package/dist/esm/adapters/playwright.js +49 -0
- package/dist/esm/adapters/pytest.js +59 -0
- package/dist/esm/adapters/supertest.js +48 -0
- package/dist/esm/agent/git.js +3 -1
- package/dist/esm/agentic/fix_loop.js +5 -4
- package/dist/esm/agentic/runner.js +15 -12
- package/dist/esm/agents/cross-impact.js +6 -1
- package/dist/esm/agents/executor.js +6 -1
- package/dist/esm/agents/strategist.js +6 -1
- package/dist/esm/agents/test-designer.js +6 -1
- package/dist/esm/anthropic_provider.js +1 -0
- package/dist/esm/base_provider.js +121 -0
- package/dist/esm/budget_ledger.js +58 -0
- package/dist/esm/cache/cached_provider.js +82 -0
- package/dist/esm/cache/response_cache.js +140 -0
- package/dist/esm/cli/commands/bootstrap.js +106 -0
- package/dist/esm/cli/commands/cost_report.js +112 -0
- package/dist/esm/cli/commands/crew.js +118 -1
- package/dist/esm/cli/commands/gate.js +83 -0
- package/dist/esm/cli/commands/init.js +3 -58
- package/dist/esm/cli/commands/train.js +16 -21
- package/dist/esm/cli/defaults.js +118 -0
- package/dist/esm/cli/errors.js +52 -0
- package/dist/esm/cli/parse_args.js +24 -2
- package/dist/esm/cli.js +47 -2
- package/dist/esm/crew/orchestrator.js +162 -4
- package/dist/esm/crew/provider.js +24 -4
- package/dist/esm/custom_provider.js +1 -0
- package/dist/esm/engine/diff_loader.js +1 -12
- package/dist/esm/engine/impact_engine.js +9 -23
- package/dist/esm/index.js +21 -0
- package/dist/esm/knowledge/cluster_utils.js +60 -0
- package/dist/esm/knowledge/kg_bridge.js +381 -0
- package/dist/esm/knowledge/kg_types.js +3 -0
- package/dist/esm/knowledge/route_families.js +89 -0
- package/dist/esm/mcp-server.js +2 -4
- package/dist/esm/metrics/prometheus.js +149 -0
- package/dist/esm/model_router.js +59 -0
- package/dist/esm/ollama_provider.js +1 -0
- package/dist/esm/openai_provider.js +1 -0
- package/dist/esm/pipeline/orchestrator.js +6 -12
- package/dist/esm/pipeline/stage0_preprocess.js +12 -19
- package/dist/esm/pipeline/stage2_coverage.js +1 -0
- package/dist/esm/pipeline/stage3_generation.js +1 -0
- package/dist/esm/progress.js +112 -0
- package/dist/esm/prompts/coverage.js +7 -24
- package/dist/esm/prompts/cross-impact.js +3 -21
- package/dist/esm/prompts/generation.js +158 -36
- package/dist/esm/prompts/generation_profile.js +147 -0
- package/dist/esm/prompts/heal.js +33 -15
- package/dist/esm/prompts/impact.js +3 -22
- package/dist/esm/prompts/json_extract.js +36 -0
- package/dist/esm/prompts/strategist.js +2 -20
- package/dist/esm/prompts/test-designer.js +6 -21
- package/dist/esm/provider_factory.js +6 -4
- package/dist/esm/reporters/junit.js +86 -0
- package/dist/esm/reporters/reporter.js +3 -0
- package/dist/esm/reporters/sarif.js +131 -0
- package/dist/esm/resilience/circuit_breaker.js +78 -0
- package/dist/esm/resilience/retry.js +56 -0
- package/dist/esm/sanitize.js +66 -0
- package/dist/esm/training/kg_scanner.js +115 -0
- package/dist/esm/training/scanner.js +27 -34
- package/dist/esm/version.js +33 -0
- package/dist/index.d.ts +21 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -1
- package/dist/knowledge/cluster_utils.d.ts +28 -0
- package/dist/knowledge/cluster_utils.d.ts.map +1 -0
- package/dist/knowledge/cluster_utils.js +67 -0
- package/dist/knowledge/kg_bridge.d.ts +31 -0
- package/dist/knowledge/kg_bridge.d.ts.map +1 -0
- package/dist/knowledge/kg_bridge.js +388 -0
- package/dist/knowledge/kg_types.d.ts +75 -0
- package/dist/knowledge/kg_types.d.ts.map +1 -0
- package/dist/knowledge/kg_types.js +4 -0
- package/dist/knowledge/route_families.d.ts +18 -0
- package/dist/knowledge/route_families.d.ts.map +1 -1
- package/dist/knowledge/route_families.js +91 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +2 -4
- package/dist/metrics/prometheus.d.ts +37 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +153 -0
- package/dist/model_router.d.ts +28 -0
- package/dist/model_router.d.ts.map +1 -0
- package/dist/model_router.js +63 -0
- package/dist/ollama_provider.d.ts.map +1 -1
- package/dist/ollama_provider.js +1 -0
- package/dist/openai_provider.d.ts.map +1 -1
- package/dist/openai_provider.js +1 -0
- package/dist/pipeline/orchestrator.d.ts +2 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +6 -12
- package/dist/pipeline/stage0_preprocess.d.ts.map +1 -1
- package/dist/pipeline/stage0_preprocess.js +11 -18
- package/dist/pipeline/stage2_coverage.d.ts +2 -0
- package/dist/pipeline/stage2_coverage.d.ts.map +1 -1
- package/dist/pipeline/stage2_coverage.js +1 -0
- package/dist/pipeline/stage3_generation.d.ts +2 -0
- package/dist/pipeline/stage3_generation.d.ts.map +1 -1
- package/dist/pipeline/stage3_generation.js +1 -0
- package/dist/pipeline/stage4_heal.d.ts +2 -0
- package/dist/pipeline/stage4_heal.d.ts.map +1 -1
- package/dist/progress.d.ts +22 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +116 -0
- package/dist/prompts/coverage.d.ts +2 -0
- package/dist/prompts/coverage.d.ts.map +1 -1
- package/dist/prompts/coverage.js +7 -24
- package/dist/prompts/cross-impact.d.ts +1 -0
- package/dist/prompts/cross-impact.d.ts.map +1 -1
- package/dist/prompts/cross-impact.js +3 -21
- package/dist/prompts/generation.d.ts +3 -1
- package/dist/prompts/generation.d.ts.map +1 -1
- package/dist/prompts/generation.js +158 -36
- package/dist/prompts/generation_profile.d.ts +29 -0
- package/dist/prompts/generation_profile.d.ts.map +1 -0
- package/dist/prompts/generation_profile.js +151 -0
- package/dist/prompts/heal.d.ts +3 -1
- package/dist/prompts/heal.d.ts.map +1 -1
- package/dist/prompts/heal.js +33 -15
- package/dist/prompts/impact.d.ts +1 -0
- package/dist/prompts/impact.d.ts.map +1 -1
- package/dist/prompts/impact.js +3 -22
- package/dist/prompts/json_extract.d.ts +14 -0
- package/dist/prompts/json_extract.d.ts.map +1 -0
- package/dist/prompts/json_extract.js +39 -0
- package/dist/prompts/strategist.d.ts.map +1 -1
- package/dist/prompts/strategist.js +2 -20
- package/dist/prompts/test-designer.d.ts +2 -0
- package/dist/prompts/test-designer.d.ts.map +1 -1
- package/dist/prompts/test-designer.js +6 -21
- package/dist/provider_factory.d.ts.map +1 -1
- package/dist/provider_factory.js +6 -4
- package/dist/reporters/junit.d.ts +6 -0
- package/dist/reporters/junit.d.ts.map +1 -0
- package/dist/reporters/junit.js +89 -0
- package/dist/reporters/reporter.d.ts +42 -0
- package/dist/reporters/reporter.d.ts.map +1 -0
- package/dist/reporters/reporter.js +4 -0
- package/dist/reporters/sarif.d.ts +7 -0
- package/dist/reporters/sarif.d.ts.map +1 -0
- package/dist/reporters/sarif.js +134 -0
- package/dist/resilience/circuit_breaker.d.ts +36 -0
- package/dist/resilience/circuit_breaker.d.ts.map +1 -0
- package/dist/resilience/circuit_breaker.js +82 -0
- package/dist/resilience/retry.d.ts +11 -0
- package/dist/resilience/retry.d.ts.map +1 -0
- package/dist/resilience/retry.js +59 -0
- package/dist/sanitize.d.ts +15 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +71 -0
- package/dist/training/kg_scanner.d.ts +13 -0
- package/dist/training/kg_scanner.d.ts.map +1 -0
- package/dist/training/kg_scanner.js +118 -0
- package/dist/training/scanner.d.ts +7 -2
- package/dist/training/scanner.d.ts.map +1 -1
- package/dist/training/scanner.js +27 -34
- package/dist/version.d.ts +6 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +36 -0
- package/package.json +7 -2
- package/schemas/route-families.schema.json +31 -1
|
@@ -44,10 +44,13 @@ const config_js_1 = require("../../agent/config.js");
|
|
|
44
44
|
const route_families_js_1 = require("../../knowledge/route_families.js");
|
|
45
45
|
const provider_factory_js_1 = require("../../provider_factory.js");
|
|
46
46
|
const logger_js_1 = require("../../logger.js");
|
|
47
|
+
const version_js_1 = require("../../version.js");
|
|
47
48
|
const scanner_js_1 = require("../../training/scanner.js");
|
|
49
|
+
const kg_scanner_js_1 = require("../../training/kg_scanner.js");
|
|
48
50
|
const merger_js_1 = require("../../training/merger.js");
|
|
49
51
|
const enricher_js_1 = require("../../training/enricher.js");
|
|
50
52
|
const validator_js_1 = require("../../training/validator.js");
|
|
53
|
+
const kg_bridge_js_1 = require("../../knowledge/kg_bridge.js");
|
|
51
54
|
class TrainError extends Error {
|
|
52
55
|
constructor(message) {
|
|
53
56
|
super(message);
|
|
@@ -157,24 +160,6 @@ function ask(rl, question, defaultValue) {
|
|
|
157
160
|
});
|
|
158
161
|
});
|
|
159
162
|
}
|
|
160
|
-
function serializeManifest(manifest) {
|
|
161
|
-
const output = {
|
|
162
|
-
families: manifest.families.map((f) => {
|
|
163
|
-
// Remove undefined/empty optional fields for clean JSON
|
|
164
|
-
const cleaned = { ...f };
|
|
165
|
-
const optionalArrays = ['pageObjects', 'components', 'webappPaths', 'serverPaths', 'specDirs', 'cypressSpecDirs', 'tags', 'userFlows', 'features'];
|
|
166
|
-
for (const key of optionalArrays) {
|
|
167
|
-
if (!cleaned[key] || (Array.isArray(cleaned[key]) && cleaned[key].length === 0)) {
|
|
168
|
-
delete cleaned[key];
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
if (!cleaned.priority)
|
|
172
|
-
delete cleaned.priority;
|
|
173
|
-
return cleaned;
|
|
174
|
-
}),
|
|
175
|
-
};
|
|
176
|
-
return JSON.stringify(output, null, 2) + '\n';
|
|
177
|
-
}
|
|
178
163
|
async function runTrainCommand(args, autoConfig) {
|
|
179
164
|
const opts = resolveTrainOptions(args, autoConfig);
|
|
180
165
|
const totalTimer = logger_js_1.logger.timer('train-total');
|
|
@@ -187,12 +172,22 @@ async function runTrainCommand(args, autoConfig) {
|
|
|
187
172
|
logger_js_1.logger.info('e2e-ai-agents train');
|
|
188
173
|
logger_js_1.logger.info('===================');
|
|
189
174
|
// ---------- Phase 1: Deterministic scan ----------
|
|
175
|
+
// Prefer knowledge graph when available
|
|
176
|
+
const kg = (0, kg_bridge_js_1.loadKnowledgeGraph)(opts.appPath);
|
|
190
177
|
logger_js_1.logger.info('Scanning project structure...');
|
|
191
178
|
if (opts.serverRoot) {
|
|
192
179
|
logger_js_1.logger.info(`Server root: ${opts.serverRoot}`);
|
|
193
180
|
}
|
|
194
181
|
const scanTimer = logger_js_1.logger.timer('scan');
|
|
195
|
-
|
|
182
|
+
let scanResult;
|
|
183
|
+
if (kg) {
|
|
184
|
+
logger_js_1.logger.info('Using knowledge graph for scanning (found .understand-anything/knowledge-graph.json)');
|
|
185
|
+
scanResult = (0, kg_scanner_js_1.scanFromKnowledgeGraph)(kg);
|
|
186
|
+
logger_js_1.logger.info(`KG: ${kg.nodes.length} nodes, ${kg.edges.length} edges`);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
scanResult = (0, scanner_js_1.scanProject)(opts.appPath, opts.testsRoot !== opts.appPath ? opts.testsRoot : undefined, opts.serverRoot, opts.gitRepoRoot);
|
|
190
|
+
}
|
|
196
191
|
timings.scan = scanTimer.end();
|
|
197
192
|
logger_js_1.logger.info(`Found ${scanResult.stats.totalSourceFiles} source files, ${scanResult.stats.totalTestFiles} test files`);
|
|
198
193
|
logger_js_1.logger.info(`Discovered ${scanResult.families.length} candidate families`);
|
|
@@ -269,7 +264,7 @@ async function runTrainCommand(args, autoConfig) {
|
|
|
269
264
|
timings.enrich = enrichTimer.end();
|
|
270
265
|
}
|
|
271
266
|
// ---------- Phase 5: Write manifest ----------
|
|
272
|
-
const json = serializeManifest(mergeResult.manifest);
|
|
267
|
+
const json = (0, route_families_js_1.serializeManifest)(mergeResult.manifest);
|
|
273
268
|
if (opts.dryRun) {
|
|
274
269
|
logger_js_1.logger.info('Dry run — proposed manifest:');
|
|
275
270
|
console.log(json);
|
|
@@ -368,7 +363,7 @@ async function runTrainCommand(args, autoConfig) {
|
|
|
368
363
|
const reportDir = (0, path_1.dirname)(opts.outputPath);
|
|
369
364
|
const trainReport = {
|
|
370
365
|
timestamp: new Date().toISOString(),
|
|
371
|
-
version:
|
|
366
|
+
version: (0, version_js_1.getVersion)(),
|
|
372
367
|
timings,
|
|
373
368
|
families: {
|
|
374
369
|
total: mergeResult.manifest.families.length,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { FrameworkType } from '../agent/config.js';
|
|
2
|
+
export interface ResolvedDefaults {
|
|
3
|
+
path: string;
|
|
4
|
+
testsRoot: string;
|
|
5
|
+
framework: FrameworkType;
|
|
6
|
+
since: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Detect the test framework from package.json dependencies.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectFramework(appPath: string): FrameworkType;
|
|
12
|
+
/**
|
|
13
|
+
* Detect the tests root directory by scanning common conventions.
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectTestsRoot(appPath: string): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Detect the git default branch for diffing.
|
|
18
|
+
* Returns origin/<branch> format.
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectGitDefaultBranch(appPath: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Detect the project root by walking up to find package.json or .git.
|
|
23
|
+
*/
|
|
24
|
+
export declare function detectProjectRoot(startDir: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve defaults for CLI commands that need path/testsRoot/framework/since.
|
|
27
|
+
* Explicit values from CLI flags take precedence over detected values.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveDefaults(explicit: {
|
|
30
|
+
path?: string;
|
|
31
|
+
testsRoot?: string;
|
|
32
|
+
framework?: FrameworkType;
|
|
33
|
+
gitSince?: string;
|
|
34
|
+
}): ResolvedDefaults;
|
|
35
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/cli/defaults.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAsB9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBnE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA4B9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,gBAAgB,CAOnB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
3
|
+
// See LICENSE.txt for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.detectFramework = detectFramework;
|
|
6
|
+
exports.detectTestsRoot = detectTestsRoot;
|
|
7
|
+
exports.detectGitDefaultBranch = detectGitDefaultBranch;
|
|
8
|
+
exports.detectProjectRoot = detectProjectRoot;
|
|
9
|
+
exports.resolveDefaults = resolveDefaults;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
/**
|
|
14
|
+
* Detect the test framework from package.json dependencies.
|
|
15
|
+
*/
|
|
16
|
+
function detectFramework(appPath) {
|
|
17
|
+
const resolvedPath = (0, path_1.resolve)(appPath);
|
|
18
|
+
const pkgPath = (0, path_1.join)(resolvedPath, 'package.json');
|
|
19
|
+
if (!(0, fs_1.existsSync)(pkgPath)) {
|
|
20
|
+
return 'auto';
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const pkg = JSON.parse((0, fs_1.readFileSync)(pkgPath, 'utf-8'));
|
|
24
|
+
const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
25
|
+
if (allDeps['@playwright/test'] || allDeps.playwright) {
|
|
26
|
+
return 'playwright';
|
|
27
|
+
}
|
|
28
|
+
if (allDeps.cypress) {
|
|
29
|
+
return 'cypress';
|
|
30
|
+
}
|
|
31
|
+
if (allDeps['selenium-webdriver'] || allDeps.webdriverio) {
|
|
32
|
+
return 'selenium';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// ignore malformed package.json
|
|
37
|
+
}
|
|
38
|
+
return 'auto';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect the tests root directory by scanning common conventions.
|
|
42
|
+
*/
|
|
43
|
+
function detectTestsRoot(appPath) {
|
|
44
|
+
const resolvedPath = (0, path_1.resolve)(appPath);
|
|
45
|
+
const candidates = [
|
|
46
|
+
'e2e-tests/playwright',
|
|
47
|
+
'e2e-tests',
|
|
48
|
+
'e2e',
|
|
49
|
+
'tests/e2e',
|
|
50
|
+
'test/e2e',
|
|
51
|
+
'tests',
|
|
52
|
+
'test',
|
|
53
|
+
'specs',
|
|
54
|
+
'playwright',
|
|
55
|
+
'cypress',
|
|
56
|
+
];
|
|
57
|
+
for (const candidate of candidates) {
|
|
58
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(resolvedPath, candidate))) {
|
|
59
|
+
return candidate;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Detect the git default branch for diffing.
|
|
66
|
+
* Returns origin/<branch> format.
|
|
67
|
+
*/
|
|
68
|
+
function detectGitDefaultBranch(appPath) {
|
|
69
|
+
try {
|
|
70
|
+
// Try to find the remote HEAD branch first
|
|
71
|
+
const remoteInfo = (0, child_process_1.execFileSync)('git', ['remote', 'show', 'origin'], {
|
|
72
|
+
cwd: (0, path_1.resolve)(appPath),
|
|
73
|
+
encoding: 'utf-8',
|
|
74
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
75
|
+
timeout: 5000,
|
|
76
|
+
});
|
|
77
|
+
const headMatch = remoteInfo.match(/HEAD branch:\s*(.+)/);
|
|
78
|
+
if (headMatch) {
|
|
79
|
+
return `origin/${headMatch[1].trim()}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// fallback to current branch
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const result = (0, child_process_1.execFileSync)('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
87
|
+
cwd: (0, path_1.resolve)(appPath),
|
|
88
|
+
encoding: 'utf-8',
|
|
89
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
90
|
+
timeout: 5000,
|
|
91
|
+
}).trim();
|
|
92
|
+
return `origin/${result}`;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return 'origin/main';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Detect the project root by walking up to find package.json or .git.
|
|
100
|
+
*/
|
|
101
|
+
function detectProjectRoot(startDir) {
|
|
102
|
+
let current = (0, path_1.resolve)(startDir);
|
|
103
|
+
while (true) {
|
|
104
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(current, 'package.json')) || (0, fs_1.existsSync)((0, path_1.join)(current, '.git'))) {
|
|
105
|
+
return current;
|
|
106
|
+
}
|
|
107
|
+
const parent = (0, path_1.resolve)(current, '..');
|
|
108
|
+
if (parent === current) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
current = parent;
|
|
112
|
+
}
|
|
113
|
+
return startDir;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Resolve defaults for CLI commands that need path/testsRoot/framework/since.
|
|
117
|
+
* Explicit values from CLI flags take precedence over detected values.
|
|
118
|
+
*/
|
|
119
|
+
function resolveDefaults(explicit) {
|
|
120
|
+
const path = explicit.path || detectProjectRoot(process.cwd());
|
|
121
|
+
const testsRoot = explicit.testsRoot || detectTestsRoot(path) || '.';
|
|
122
|
+
const framework = explicit.framework || detectFramework(path);
|
|
123
|
+
const since = explicit.gitSince || detectGitDefaultBranch(path);
|
|
124
|
+
return { path, testsRoot, framework, since };
|
|
125
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Error types with structured exit codes.
|
|
3
|
+
*
|
|
4
|
+
* Exit codes:
|
|
5
|
+
* 0 = success
|
|
6
|
+
* 1 = general/user error (bad args, missing config, invalid input)
|
|
7
|
+
* 2 = budget exceeded
|
|
8
|
+
* 3 = LLM provider unavailable (API down, auth failure)
|
|
9
|
+
* 4 = invalid manifest or config file
|
|
10
|
+
*/
|
|
11
|
+
export declare const EXIT_CODES: {
|
|
12
|
+
readonly SUCCESS: 0;
|
|
13
|
+
readonly GENERAL_ERROR: 1;
|
|
14
|
+
readonly BUDGET_EXCEEDED: 2;
|
|
15
|
+
readonly PROVIDER_UNAVAILABLE: 3;
|
|
16
|
+
readonly INVALID_CONFIG: 4;
|
|
17
|
+
};
|
|
18
|
+
export type ExitCode = typeof EXIT_CODES[keyof typeof EXIT_CODES];
|
|
19
|
+
export declare class CliError extends Error {
|
|
20
|
+
readonly exitCode: ExitCode;
|
|
21
|
+
constructor(message: string, exitCode?: ExitCode);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Classify an unknown error into the appropriate exit code.
|
|
25
|
+
*/
|
|
26
|
+
export declare function classifyError(error: unknown): ExitCode;
|
|
27
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH,eAAO,MAAM,UAAU;;;;;;CAMb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAElE,qBAAa,QAAS,SAAQ,KAAK;aAGX,QAAQ,EAAE,QAAQ;gBADlC,OAAO,EAAE,MAAM,EACC,QAAQ,GAAE,QAAmC;CAKpE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CA0BtD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
3
|
+
// See LICENSE.txt for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.CliError = exports.EXIT_CODES = void 0;
|
|
6
|
+
exports.classifyError = classifyError;
|
|
7
|
+
/**
|
|
8
|
+
* CLI Error types with structured exit codes.
|
|
9
|
+
*
|
|
10
|
+
* Exit codes:
|
|
11
|
+
* 0 = success
|
|
12
|
+
* 1 = general/user error (bad args, missing config, invalid input)
|
|
13
|
+
* 2 = budget exceeded
|
|
14
|
+
* 3 = LLM provider unavailable (API down, auth failure)
|
|
15
|
+
* 4 = invalid manifest or config file
|
|
16
|
+
*/
|
|
17
|
+
exports.EXIT_CODES = {
|
|
18
|
+
SUCCESS: 0,
|
|
19
|
+
GENERAL_ERROR: 1,
|
|
20
|
+
BUDGET_EXCEEDED: 2,
|
|
21
|
+
PROVIDER_UNAVAILABLE: 3,
|
|
22
|
+
INVALID_CONFIG: 4,
|
|
23
|
+
};
|
|
24
|
+
class CliError extends Error {
|
|
25
|
+
constructor(message, exitCode = exports.EXIT_CODES.GENERAL_ERROR) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.exitCode = exitCode;
|
|
28
|
+
this.name = 'CliError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.CliError = CliError;
|
|
32
|
+
/**
|
|
33
|
+
* Classify an unknown error into the appropriate exit code.
|
|
34
|
+
*/
|
|
35
|
+
function classifyError(error) {
|
|
36
|
+
if (error instanceof CliError)
|
|
37
|
+
return error.exitCode;
|
|
38
|
+
const msg = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
39
|
+
// Budget errors
|
|
40
|
+
if (msg.includes('budget exceeded') || msg.includes('budget limit')) {
|
|
41
|
+
return exports.EXIT_CODES.BUDGET_EXCEEDED;
|
|
42
|
+
}
|
|
43
|
+
// Provider/auth errors
|
|
44
|
+
if (msg.includes('api key') || msg.includes('authentication') ||
|
|
45
|
+
msg.includes('unauthorized') || msg.includes('403') ||
|
|
46
|
+
(msg.includes('provider') && msg.includes('unavailable')) ||
|
|
47
|
+
msg.includes('econnrefused') || msg.includes('econnreset')) {
|
|
48
|
+
return exports.EXIT_CODES.PROVIDER_UNAVAILABLE;
|
|
49
|
+
}
|
|
50
|
+
// Config/manifest errors
|
|
51
|
+
if ((msg.includes('manifest') && (msg.includes('invalid') || msg.includes('not found') || msg.includes('parse'))) ||
|
|
52
|
+
(msg.includes('config') && msg.includes('invalid')) ||
|
|
53
|
+
(msg.includes('route-families') && msg.includes('invalid'))) {
|
|
54
|
+
return exports.EXIT_CODES.INVALID_CONFIG;
|
|
55
|
+
}
|
|
56
|
+
return exports.EXIT_CODES.GENERAL_ERROR;
|
|
57
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse_args.d.ts","sourceRoot":"","sources":["../../src/cli/parse_args.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parse_args.d.ts","sourceRoot":"","sources":["../../src/cli/parse_args.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAU,UAAU,EAAC,MAAM,YAAY,CAAC;AAEpD,eAAO,MAAM,iBAAiB,UAA8D,CAAC;AAE7F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAmBlF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAmBtE;AA4JD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAuFpD"}
|
package/dist/cli/parse_args.js
CHANGED
|
@@ -8,6 +8,7 @@ exports.resolveAutoConfig = resolveAutoConfig;
|
|
|
8
8
|
exports.parseArgs = parseArgs;
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
10
|
const path_1 = require("path");
|
|
11
|
+
const logger_js_1 = require("../logger.js");
|
|
11
12
|
exports.CONFIG_CANDIDATES = ['e2e-ai-agents.config.json', '.e2e-ai-agents.config.json'];
|
|
12
13
|
function findConfigUpwards(startDir) {
|
|
13
14
|
if (!startDir) {
|
|
@@ -68,6 +69,7 @@ const FLAGS = {
|
|
|
68
69
|
'--generate': { key: 'analyzeGenerate', type: 'boolean' },
|
|
69
70
|
'--heal': { key: 'analyzeHeal', type: 'boolean' },
|
|
70
71
|
'--no-ai': { key: 'noAi', type: 'boolean' },
|
|
72
|
+
'--degraded-mode': { key: 'degradedMode', type: 'boolean' },
|
|
71
73
|
'--enrich': { key: 'trainEnrich', type: 'boolean' },
|
|
72
74
|
'--no-enrich': { key: 'trainEnrich', type: 'boolean-false' },
|
|
73
75
|
'--validate': { key: 'trainValidate', type: 'boolean' },
|
|
@@ -137,6 +139,13 @@ const FLAGS = {
|
|
|
137
139
|
type: 'csv',
|
|
138
140
|
transform: (v) => csvSplit(v).filter((s) => s === 'run-now' || s === 'must-add-tests' || s === 'safe-to-merge'),
|
|
139
141
|
},
|
|
142
|
+
// -- gate command --
|
|
143
|
+
'--threshold': { key: 'gateThreshold', type: 'number' },
|
|
144
|
+
// -- bootstrap command --
|
|
145
|
+
'--kg-path': { key: 'bootstrapKgPath', type: 'string' },
|
|
146
|
+
'--scaffold-framework': { key: 'bootstrapScaffoldFramework', type: 'boolean' },
|
|
147
|
+
'--test-mode': { key: 'bootstrapTestMode', type: 'enum', enumValues: ['ui', 'api', 'both'] },
|
|
148
|
+
'--max-families': { key: 'bootstrapMaxFamilies', type: 'number' },
|
|
140
149
|
};
|
|
141
150
|
// Build a lookup from alias -> canonical flag name
|
|
142
151
|
const ALIAS_MAP = {};
|
|
@@ -152,7 +161,8 @@ const COMMANDS = new Set([
|
|
|
152
161
|
'init', 'impact', 'plan', 'heal', 'suggest', 'generate',
|
|
153
162
|
'finalize-generated-tests', 'feedback',
|
|
154
163
|
'traceability-capture', 'traceability-ingest',
|
|
155
|
-
'analyze', 'llm-health', 'train', 'crew',
|
|
164
|
+
'analyze', 'llm-health', 'train', 'crew', 'cost-report', 'gate',
|
|
165
|
+
'bootstrap',
|
|
156
166
|
]);
|
|
157
167
|
// ---------------------------------------------------------------------------
|
|
158
168
|
// Parser
|
|
@@ -174,6 +184,9 @@ function parseArgs(argv) {
|
|
|
174
184
|
const arg = argv[i];
|
|
175
185
|
const canonical = ALIAS_MAP[arg];
|
|
176
186
|
if (!canonical) {
|
|
187
|
+
if (arg.startsWith('--')) {
|
|
188
|
+
logger_js_1.logger.warn(`Unknown flag "${arg}" (ignored)`);
|
|
189
|
+
}
|
|
177
190
|
continue;
|
|
178
191
|
}
|
|
179
192
|
const def = FLAGS[canonical];
|
|
@@ -202,7 +215,16 @@ function parseArgs(argv) {
|
|
|
202
215
|
break;
|
|
203
216
|
case 'number-raw':
|
|
204
217
|
if (next) {
|
|
205
|
-
|
|
218
|
+
const rawValue = def.transform ? def.transform(next) : Number(next);
|
|
219
|
+
// Allow non-number transforms through; reject NaN/Infinity for numbers
|
|
220
|
+
if (typeof rawValue === 'number') {
|
|
221
|
+
if (Number.isFinite(rawValue)) {
|
|
222
|
+
setField(parsed, def.key, rawValue);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
setField(parsed, def.key, rawValue);
|
|
227
|
+
}
|
|
206
228
|
i += 1;
|
|
207
229
|
}
|
|
208
230
|
break;
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnalysisProfile, FrameworkType } from '../agent/config.js';
|
|
2
|
-
export type Command = 'init' | 'impact' | 'plan' | 'heal' | 'suggest' | 'generate' | 'finalize-generated-tests' | 'feedback' | 'traceability-capture' | 'traceability-ingest' | 'analyze' | 'llm-health' | 'train' | 'crew';
|
|
2
|
+
export type Command = 'init' | 'impact' | 'plan' | 'heal' | 'suggest' | 'generate' | 'finalize-generated-tests' | 'feedback' | 'traceability-capture' | 'traceability-ingest' | 'analyze' | 'llm-health' | 'train' | 'crew' | 'cost-report' | 'gate' | 'bootstrap';
|
|
3
3
|
export interface ParsedArgs {
|
|
4
4
|
command?: Command;
|
|
5
5
|
configPath?: string;
|
|
@@ -74,6 +74,12 @@ export interface ParsedArgs {
|
|
|
74
74
|
trainYes?: boolean;
|
|
75
75
|
serverPath?: string;
|
|
76
76
|
crewWorkflow?: string;
|
|
77
|
+
gateThreshold?: number;
|
|
78
|
+
bootstrapKgPath?: string;
|
|
79
|
+
bootstrapScaffoldFramework?: boolean;
|
|
80
|
+
bootstrapTestMode?: 'ui' | 'api' | 'both';
|
|
81
|
+
bootstrapMaxFamilies?: number;
|
|
82
|
+
degradedMode?: boolean;
|
|
77
83
|
verbose?: boolean;
|
|
78
84
|
jsonOutput?: boolean;
|
|
79
85
|
}
|
package/dist/cli/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAE,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEvE,MAAM,MAAM,OAAO,GACf,MAAM,GACJ,QAAQ,GACR,MAAM,GACN,MAAM,GACN,SAAS,GACT,UAAU,GACV,0BAA0B,GAC1B,UAAU,GACV,sBAAsB,GACtB,qBAAqB,GACrB,SAAS,GACT,YAAY,GACZ,OAAO,GACP,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAE,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEvE,MAAM,MAAM,OAAO,GACf,MAAM,GACJ,QAAQ,GACR,MAAM,GACN,MAAM,GACN,SAAS,GACT,UAAU,GACV,0BAA0B,GAC1B,UAAU,GACV,sBAAsB,GACtB,qBAAqB,GACrB,SAAS,GACT,YAAY,GACZ,OAAO,GACP,MAAM,GACN,aAAa,GACb,MAAM,GACN,WAAW,CAAC;AAElB,MAAM,WAAW,UAAU;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC/D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,qBAAqB,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;IACtD,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,gBAAgB,GAAG,eAAe,CAAC,CAAC;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,iBAAiB,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB"}
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const config_js_1 = require("./agent/config.js");
|
|
7
7
|
const parse_args_js_1 = require("./cli/parse_args.js");
|
|
8
|
+
const defaults_js_1 = require("./cli/defaults.js");
|
|
8
9
|
const usage_js_1 = require("./cli/usage.js");
|
|
9
10
|
const llm_health_js_1 = require("./cli/commands/llm_health.js");
|
|
10
11
|
const analyze_js_1 = require("./cli/commands/analyze.js");
|
|
@@ -18,14 +19,42 @@ const generate_js_1 = require("./cli/commands/generate.js");
|
|
|
18
19
|
const init_js_1 = require("./cli/commands/init.js");
|
|
19
20
|
const train_js_1 = require("./cli/commands/train.js");
|
|
20
21
|
const crew_js_1 = require("./cli/commands/crew.js");
|
|
22
|
+
const cost_report_js_1 = require("./cli/commands/cost_report.js");
|
|
23
|
+
const gate_js_1 = require("./cli/commands/gate.js");
|
|
24
|
+
const bootstrap_js_1 = require("./cli/commands/bootstrap.js");
|
|
25
|
+
const errors_js_1 = require("./cli/errors.js");
|
|
26
|
+
// Commands that skip default resolution (they handle their own setup)
|
|
27
|
+
const SKIP_DEFAULTS_COMMANDS = new Set(['init', 'llm-health', 'cost-report', 'bootstrap']);
|
|
28
|
+
// Commands that need path/testsRoot/framework/since
|
|
29
|
+
const NEEDS_DEFAULTS_COMMANDS = new Set([
|
|
30
|
+
'impact', 'plan', 'suggest', 'crew', 'generate', 'heal', 'analyze', 'train',
|
|
31
|
+
'feedback', 'traceability-capture', 'traceability-ingest', 'finalize-generated-tests',
|
|
32
|
+
]);
|
|
21
33
|
async function main() {
|
|
22
34
|
const args = (0, parse_args_js_1.parseArgs)(process.argv.slice(2));
|
|
23
35
|
const autoConfig = (0, parse_args_js_1.resolveAutoConfig)(args);
|
|
36
|
+
// Auto-detect defaults for commands that need them (when no config file found)
|
|
37
|
+
if (args.command && NEEDS_DEFAULTS_COMMANDS.has(args.command) && !SKIP_DEFAULTS_COMMANDS.has(args.command)) {
|
|
38
|
+
const defaults = (0, defaults_js_1.resolveDefaults)({
|
|
39
|
+
path: args.path,
|
|
40
|
+
testsRoot: args.testsRoot,
|
|
41
|
+
framework: args.framework,
|
|
42
|
+
gitSince: args.gitSince,
|
|
43
|
+
});
|
|
44
|
+
args.path = args.path || defaults.path;
|
|
45
|
+
args.testsRoot = args.testsRoot || defaults.testsRoot;
|
|
46
|
+
args.framework = args.framework || defaults.framework;
|
|
47
|
+
args.gitSince = args.gitSince || defaults.since;
|
|
48
|
+
}
|
|
24
49
|
if (args.command === 'init') {
|
|
25
50
|
const hasYes = process.argv.includes('--yes') || process.argv.includes('-y');
|
|
26
51
|
await (0, init_js_1.runInitCommand)(hasYes);
|
|
27
52
|
return;
|
|
28
53
|
}
|
|
54
|
+
if (args.command === 'bootstrap') {
|
|
55
|
+
await (0, bootstrap_js_1.runBootstrapCommand)(args);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
29
58
|
if (args.command === 'train') {
|
|
30
59
|
await (0, train_js_1.runTrainCommand)(args, autoConfig);
|
|
31
60
|
return;
|
|
@@ -66,6 +95,14 @@ async function main() {
|
|
|
66
95
|
await (0, crew_js_1.runCrewCommand)(args, autoConfig);
|
|
67
96
|
return;
|
|
68
97
|
}
|
|
98
|
+
if (args.command === 'cost-report') {
|
|
99
|
+
(0, cost_report_js_1.runCostReportCommand)(args);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (args.command === 'gate') {
|
|
103
|
+
await (0, gate_js_1.runGateCommand)(args, autoConfig);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
69
106
|
if (!args.path && !autoConfig) {
|
|
70
107
|
console.error('Error: --path is required (or provide a config file with path set)');
|
|
71
108
|
(0, usage_js_1.printUsage)();
|
|
@@ -140,6 +177,14 @@ async function main() {
|
|
|
140
177
|
process.exit(1);
|
|
141
178
|
}
|
|
142
179
|
main().catch((error) => {
|
|
143
|
-
|
|
144
|
-
|
|
180
|
+
const exitCode = (0, errors_js_1.classifyError)(error);
|
|
181
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
182
|
+
console.error(message);
|
|
183
|
+
if (exitCode === errors_js_1.EXIT_CODES.BUDGET_EXCEEDED) {
|
|
184
|
+
console.error('Hint: Increase --budget or use --degraded-mode to skip AI features.');
|
|
185
|
+
}
|
|
186
|
+
else if (exitCode === errors_js_1.EXIT_CODES.PROVIDER_UNAVAILABLE) {
|
|
187
|
+
console.error('Hint: Check API key or use --degraded-mode for deterministic analysis only.');
|
|
188
|
+
}
|
|
189
|
+
process.exit(exitCode);
|
|
145
190
|
});
|
package/dist/crew/context.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { ProviderUsageStats } from '../provider_interface.js';
|
|
|
9
9
|
import type { GeneratedSpec } from '../pipeline/stage3_generation.js';
|
|
10
10
|
import type { LoadedContext } from '../knowledge/context_loader.js';
|
|
11
11
|
import type { FamilyGroup, PreprocessResult } from '../pipeline/stage0_preprocess.js';
|
|
12
|
+
import type { BudgetLedger } from '../budget_ledger.js';
|
|
12
13
|
import type { AgentMessage } from './protocol.js';
|
|
13
14
|
import type { TestDesign, CrossImpact, Finding, StrategyEntry, RegressionRisk } from './types.js';
|
|
14
15
|
export interface CrewContext {
|
|
@@ -24,6 +25,11 @@ export interface CrewContext {
|
|
|
24
25
|
testsRoot: string;
|
|
25
26
|
gitSince: string;
|
|
26
27
|
providerOverride?: string;
|
|
28
|
+
budgetUSD?: number;
|
|
29
|
+
modelRoutingProviderType?: string;
|
|
30
|
+
modelRoutingOverrides?: Record<string, string>;
|
|
31
|
+
/** @internal Shared budget enforcement — not part of the public API. */
|
|
32
|
+
budgetLedger?: BudgetLedger;
|
|
27
33
|
impactedFlows: FlowDecision[];
|
|
28
34
|
strategyEntries: StrategyEntry[];
|
|
29
35
|
testDesigns: TestDesign[];
|
|
@@ -32,9 +38,18 @@ export interface CrewContext {
|
|
|
32
38
|
findings: Finding[];
|
|
33
39
|
generatedSpecs: GeneratedSpec[];
|
|
34
40
|
usage: ProviderUsageStats;
|
|
41
|
+
agentUsage: AgentUsageEntry[];
|
|
35
42
|
messages: AgentMessage[];
|
|
36
43
|
warnings: string[];
|
|
37
44
|
}
|
|
45
|
+
export interface AgentUsageEntry {
|
|
46
|
+
agent: string;
|
|
47
|
+
family?: string;
|
|
48
|
+
inputTokens: number;
|
|
49
|
+
outputTokens: number;
|
|
50
|
+
cost: number;
|
|
51
|
+
durationMs: number;
|
|
52
|
+
}
|
|
38
53
|
export declare function createEmptyUsageStats(): ProviderUsageStats;
|
|
39
54
|
export declare function mergeUsageStats(target: ProviderUsageStats, source: ProviderUsageStats): void;
|
|
40
55
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/crew/context.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,OAAO,KAAK,EAAC,WAAW,EAAE,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACrF,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AACpF,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAC,MAAM,YAAY,CAAC;AAEhG,MAAM,WAAW,WAAW;IAExB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC;IACvB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAG1C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/crew/context.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,OAAO,KAAK,EAAC,WAAW,EAAE,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACrF,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AACpF,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAC,MAAM,YAAY,CAAC;AAEhG,MAAM,WAAW,WAAW;IAExB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC;IACvB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAG1C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,wEAAwE;IACxE,YAAY,CAAC,EAAE,YAAY,CAAC;IAG5B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,EAAE,aAAa,EAAE,CAAC;IAGhC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,CAa1D;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAe5F"}
|
|
@@ -15,15 +15,22 @@ export interface CrewConfig {
|
|
|
15
15
|
providerOverride?: string;
|
|
16
16
|
budgetUSD?: number;
|
|
17
17
|
dryRun?: boolean;
|
|
18
|
+
plugins?: string[];
|
|
18
19
|
}
|
|
19
20
|
export interface CrewResult {
|
|
20
21
|
context: CrewContext;
|
|
21
22
|
warnings: string[];
|
|
22
23
|
timings: Record<string, number>;
|
|
24
|
+
dryRun?: boolean;
|
|
23
25
|
}
|
|
24
26
|
export declare class CrewOrchestrator {
|
|
25
27
|
private agents;
|
|
26
28
|
registerAgent(agent: Agent): void;
|
|
29
|
+
/**
|
|
30
|
+
* Load and register plugins from file paths.
|
|
31
|
+
* Each module must default-export an object satisfying AgentPlugin.
|
|
32
|
+
*/
|
|
33
|
+
loadPlugins(pluginPaths: string[]): Promise<string[]>;
|
|
27
34
|
run(config: CrewConfig): Promise<CrewResult>;
|
|
28
35
|
dispatch(role: AgentRole, action: string, ctx: CrewContext): Promise<AgentResult>;
|
|
29
36
|
parallel(roles: AgentRole[], action: string, ctx: CrewContext): Promise<AgentResult[]>;
|
|
@@ -31,6 +38,13 @@ export declare class CrewOrchestrator {
|
|
|
31
38
|
private runBuiltInPhase;
|
|
32
39
|
private runParallel;
|
|
33
40
|
private runSequential;
|
|
41
|
+
/**
|
|
42
|
+
* Inject loaded plugins into workflow phases based on their `phase` and `runAfter` fields.
|
|
43
|
+
* Plugins with `runAfter` dependencies are appended to the sequential list of the matching phase;
|
|
44
|
+
* plugins without `runAfter` are appended to the parallel list.
|
|
45
|
+
* Returns a new array of phases (does not mutate the original workflow definition).
|
|
46
|
+
*/
|
|
47
|
+
private injectPluginsIntoPhases;
|
|
34
48
|
private checkPhaseResults;
|
|
35
49
|
}
|
|
36
50
|
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/crew/orchestrator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/crew/orchestrator.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAC,KAAK,EAAE,YAAY,EAAe,WAAW,EAAY,MAAM,eAAe,CAAC;AAC5F,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAA6B,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAG7E,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAA+B;IAE7C,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIjC;;;OAGG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqCrD,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAiG5C,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IA0CjF,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAKtF,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;YAerD,eAAe;YAwBf,WAAW;YAMX,aAAa;IAS3B;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IA2E/B,OAAO,CAAC,iBAAiB;CAM5B"}
|