@yasserkhanorg/e2e-agents 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +22 -18
  2. package/dist/agent/config.d.ts +1 -0
  3. package/dist/agent/config.d.ts.map +1 -1
  4. package/dist/agent/config.js +10 -0
  5. package/dist/agent/pipeline.d.ts +6 -1
  6. package/dist/agent/pipeline.d.ts.map +1 -1
  7. package/dist/agent/pipeline.js +627 -27
  8. package/dist/agent/report.d.ts +5 -0
  9. package/dist/agent/report.d.ts.map +1 -1
  10. package/dist/agent/report.js +3 -0
  11. package/dist/agent/runner.d.ts.map +1 -1
  12. package/dist/agent/runner.js +25 -6
  13. package/dist/agent/tests.d.ts.map +1 -1
  14. package/dist/agent/tests.js +12 -2
  15. package/dist/cli.js +73 -5
  16. package/dist/esm/agent/config.js +10 -0
  17. package/dist/esm/agent/pipeline.js +627 -27
  18. package/dist/esm/agent/report.js +3 -0
  19. package/dist/esm/agent/runner.js +25 -6
  20. package/dist/esm/agent/tests.js +12 -2
  21. package/dist/esm/cli.js +73 -5
  22. package/package.json +1 -1
  23. package/dist/agent/cache_utils.d.ts +0 -38
  24. package/dist/agent/cache_utils.d.ts.map +0 -1
  25. package/dist/agent/cache_utils.js +0 -67
  26. package/dist/agent/impact-analyzer.d.ts +0 -114
  27. package/dist/agent/impact-analyzer.d.ts.map +0 -1
  28. package/dist/agent/impact-analyzer.js +0 -557
  29. package/dist/agent/index.d.ts +0 -21
  30. package/dist/agent/index.d.ts.map +0 -1
  31. package/dist/agent/index.js +0 -38
  32. package/dist/agent/model-router.d.ts +0 -57
  33. package/dist/agent/model-router.d.ts.map +0 -1
  34. package/dist/agent/model-router.js +0 -154
  35. package/dist/agent/report-generator.d.ts +0 -24
  36. package/dist/agent/report-generator.d.ts.map +0 -1
  37. package/dist/agent/report-generator.js +0 -250
  38. package/dist/agent/spec-bridge.d.ts +0 -101
  39. package/dist/agent/spec-bridge.d.ts.map +0 -1
  40. package/dist/agent/spec-bridge.js +0 -273
  41. package/dist/agent/spec-builder.d.ts +0 -102
  42. package/dist/agent/spec-builder.d.ts.map +0 -1
  43. package/dist/agent/spec-builder.js +0 -273
  44. package/dist/agent/telemetry.d.ts +0 -84
  45. package/dist/agent/telemetry.d.ts.map +0 -1
  46. package/dist/agent/telemetry.js +0 -220
  47. package/dist/agent/validators/selector-validator.d.ts +0 -74
  48. package/dist/agent/validators/selector-validator.d.ts.map +0 -1
  49. package/dist/agent/validators/selector-validator.js +0 -165
  50. package/dist/e2e-test-gen/index.d.ts +0 -51
  51. package/dist/e2e-test-gen/index.d.ts.map +0 -1
  52. package/dist/e2e-test-gen/index.js +0 -57
  53. package/dist/e2e-test-gen/spec_parser.d.ts +0 -142
  54. package/dist/e2e-test-gen/spec_parser.d.ts.map +0 -1
  55. package/dist/e2e-test-gen/spec_parser.js +0 -786
  56. package/dist/e2e-test-gen/types.d.ts +0 -185
  57. package/dist/e2e-test-gen/types.d.ts.map +0 -1
  58. package/dist/e2e-test-gen/types.js +0 -4
  59. package/dist/esm/agent/cache_utils.js +0 -63
  60. package/dist/esm/agent/impact-analyzer.js +0 -548
  61. package/dist/esm/agent/index.js +0 -22
  62. package/dist/esm/agent/model-router.js +0 -150
  63. package/dist/esm/agent/report-generator.js +0 -247
  64. package/dist/esm/agent/spec-bridge.js +0 -267
  65. package/dist/esm/agent/spec-builder.js +0 -267
  66. package/dist/esm/agent/telemetry.js +0 -216
  67. package/dist/esm/agent/validators/selector-validator.js +0 -160
  68. package/dist/esm/e2e-test-gen/index.js +0 -50
  69. package/dist/esm/e2e-test-gen/spec_parser.js +0 -782
  70. package/dist/esm/e2e-test-gen/types.js +0 -3
  71. package/dist/esm/plan-and-test-constants.js +0 -126
  72. package/dist/plan-and-test-constants.d.ts +0 -110
  73. package/dist/plan-and-test-constants.d.ts.map +0 -1
  74. package/dist/plan-and-test-constants.js +0 -132
@@ -67,6 +67,11 @@ export interface ReportData {
67
67
  error?: string;
68
68
  }>;
69
69
  warnings: string[];
70
+ mcp?: {
71
+ requested: boolean;
72
+ active: boolean;
73
+ backend: string;
74
+ };
70
75
  };
71
76
  applied?: {
72
77
  patchedFiles: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}
@@ -94,6 +94,9 @@ function writeReport(appRoot, config, data) {
94
94
  markdownLines.push('');
95
95
  markdownLines.push('Pipeline Results:');
96
96
  markdownLines.push(`- Runner: ${data.pipeline.runner}`);
97
+ if (data.pipeline.mcp) {
98
+ markdownLines.push(`- MCP: requested=${data.pipeline.mcp.requested} active=${data.pipeline.mcp.active} backend=${data.pipeline.mcp.backend}`);
99
+ }
97
100
  for (const result of data.pipeline.results) {
98
101
  const status = result.healStatus ? `${result.generateStatus}/${result.healStatus}` : result.generateStatus;
99
102
  markdownLines.push(`- ${result.flowId} (${result.flowName}): ${status} -> ${result.generatedDir}`);
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AA6M7C,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4LzF;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4LtF"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAiN7C,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA6LzF;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0MtF"}
@@ -21,6 +21,7 @@ const pipeline_js_1 = require("./pipeline.js");
21
21
  const gap_suggestions_js_1 = require("./gap_suggestions.js");
22
22
  const dependency_graph_js_1 = require("./dependency_graph.js");
23
23
  const traceability_js_1 = require("./traceability.js");
24
+ const utils_js_1 = require("./utils.js");
24
25
  const PRIORITY_RANK = {
25
26
  P0: 0,
26
27
  P1: 1,
@@ -84,11 +85,14 @@ function buildRecommendedTestsWithFlags(flows, testsByFlow) {
84
85
  const tests = testsByFlow.get(flow.id) || [];
85
86
  const flagSummary = (0, flags_js_1.formatFlags)(flow.flags || []);
86
87
  for (const test of tests) {
87
- if (!testNotes.has(test)) {
88
- testNotes.set(test, new Set());
88
+ const normalizedTest = (0, utils_js_1.normalizePath)(test)
89
+ .replace(/^\.\//, '')
90
+ .replace(/^e2e-tests\/playwright\//, '');
91
+ if (!testNotes.has(normalizedTest)) {
92
+ testNotes.set(normalizedTest, new Set());
89
93
  }
90
94
  if (flagSummary !== 'none') {
91
- testNotes.get(test)?.add(flagSummary);
95
+ testNotes.get(normalizedTest)?.add(flagSummary);
92
96
  }
93
97
  }
94
98
  }
@@ -213,7 +217,8 @@ async function runImpact(_config, _options) {
213
217
  if (changedFiles.length === 0 && !_config.impact.allowFallback) {
214
218
  throw new Error('No changed files detected. Provide --since or use gap mode (or --allow-fallback).');
215
219
  }
216
- let analysisTargets = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
220
+ const changedAppFiles = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
221
+ let analysisTargets = [...changedAppFiles];
217
222
  if (analysisTargets.length === 0 && _config.impact.allowFallback) {
218
223
  warnings.push('No changed files detected. Falling back to repository scan for screens.');
219
224
  analysisTargets = (0, analysis_js_1.scanRepositoryFlows)(_config.path, 250, _config.flowDiscovery.patterns, _config.flowDiscovery.exclude);
@@ -379,7 +384,8 @@ async function runGap(_config, _options) {
379
384
  if (gitResult.error) {
380
385
  warnings.push(`Git diff failed: ${gitResult.error}`);
381
386
  }
382
- let analysisTargets = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
387
+ const changedAppFiles = changedFiles.filter((file) => !(0, analysis_js_1.isTestFilePath)(file));
388
+ let analysisTargets = [...changedAppFiles];
383
389
  if (analysisTargets.length === 0) {
384
390
  analysisTargets = (0, analysis_js_1.scanRepositoryFlows)(_config.path, 250, _config.flowDiscovery.patterns, _config.flowDiscovery.exclude);
385
391
  }
@@ -414,7 +420,20 @@ async function runGap(_config, _options) {
414
420
  let traceabilityStats;
415
421
  if (catalog) {
416
422
  flowCatalogSource = catalog.source;
417
- const mapping = (0, flow_mapping_js_1.mapChangesToCatalogFlows)(catalog, analysisTargets, 'gap', _config);
423
+ const catalogMode = changedAppFiles.length > 0 ? 'impact' : 'gap';
424
+ let mapping = (0, flow_mapping_js_1.mapChangesToCatalogFlows)(catalog, analysisTargets, catalogMode, _config);
425
+ if (catalogMode === 'impact' && mapping.flows.length === 0 && _config.impact.allowFallback) {
426
+ const fallbackMapping = (0, flow_mapping_js_1.mapChangesToCatalogFlows)(catalog, analysisTargets, 'gap', _config);
427
+ mapping = {
428
+ flows: fallbackMapping.flows,
429
+ testsByFlow: fallbackMapping.testsByFlow,
430
+ warnings: [
431
+ ...mapping.warnings,
432
+ ...fallbackMapping.warnings,
433
+ 'No catalog flow matched changed files; applied full-catalog fallback because allowFallback=true.',
434
+ ],
435
+ };
436
+ }
418
437
  flows = mapping.flows;
419
438
  testsByFlow = mapping.testsByFlow;
420
439
  warnings.push(...mapping.warnings);
@@ -1 +1 @@
1
- {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../src/agent/tests.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;CACrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAkB7E;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAgCtF;AAaD,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,UAAU,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACnC,YAAY,EAAE,CA8BhB"}
1
+ {"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../src/agent/tests.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;CACrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAkB7E;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAgCtF;AAuBD,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,UAAU,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACnC,YAAY,EAAE,CA8BhB"}
@@ -70,9 +70,19 @@ function resolveExpectedTests(testsRoot, expectedTests) {
70
70
  if (!entry) {
71
71
  continue;
72
72
  }
73
- resolved.push((0, utils_js_1.normalizePath)(entry));
73
+ const normalized = (0, utils_js_1.normalizePath)(entry).replace(/^\.\//, '');
74
+ if (normalized.startsWith('e2e-tests/playwright/')) {
75
+ resolved.push(normalized.slice('e2e-tests/playwright/'.length));
76
+ continue;
77
+ }
78
+ const specsIndex = normalized.indexOf('specs/');
79
+ if (specsIndex >= 0) {
80
+ resolved.push(normalized.slice(specsIndex));
81
+ continue;
82
+ }
83
+ resolved.push(normalized);
74
84
  }
75
- return resolved;
85
+ return Array.from(new Set(resolved));
76
86
  }
77
87
  function mapCatalogTestsToFlows(flows, testsRoot, testsByFlow) {
78
88
  return flows.map((flow) => {
package/dist/cli.js CHANGED
@@ -61,6 +61,9 @@ function printUsage() {
61
61
  'Usage:',
62
62
  ' e2e-ai-agents impact --path <app-root> [options]',
63
63
  ' e2e-ai-agents gap --path <app-root> [options]',
64
+ ' e2e-ai-agents plan --path <app-root> [options]',
65
+ ' e2e-ai-agents generate --path <app-root> [options]',
66
+ ' e2e-ai-agents heal --path <app-root> --traceability-report <json> [options]',
64
67
  ' e2e-ai-agents suggest --path <app-root> [options]',
65
68
  ' e2e-ai-agents approve-and-generate --path <app-root> [options]',
66
69
  ' e2e-ai-agents auto-heal-pr --path <app-root> [options]',
@@ -90,6 +93,7 @@ function printUsage() {
90
93
  ' --pipeline-parallel Enable parallel mode in generator',
91
94
  ' --pipeline-dry-run Do not execute pipeline (report only)',
92
95
  ' --pipeline-mcp Use Playwright MCP server for exploration/healing',
96
+ ' --pipeline-mcp-allow-fallback Allow non-MCP fallback if official MCP setup fails',
93
97
  ' --spec <path> Optional spec PDF for context',
94
98
  ' --since <git-ref> Git ref for impact analysis (default HEAD~1)',
95
99
  ' --time <minutes> Time limit in minutes',
@@ -132,6 +136,9 @@ function parseArgs(argv) {
132
136
  const command = argv[0];
133
137
  if (command === 'impact'
134
138
  || command === 'gap'
139
+ || command === 'plan'
140
+ || command === 'generate'
141
+ || command === 'heal'
135
142
  || command === 'suggest'
136
143
  || command === 'approve-and-generate'
137
144
  || command === 'auto-heal-pr'
@@ -205,6 +212,10 @@ function parseArgs(argv) {
205
212
  parsed.pipelineMcp = true;
206
213
  continue;
207
214
  }
215
+ if (arg === '--pipeline-mcp-allow-fallback') {
216
+ parsed.pipelineMcpAllowFallback = true;
217
+ continue;
218
+ }
208
219
  if (arg === '--pipeline-scenarios' && next) {
209
220
  const value = Number(next);
210
221
  if (Number.isFinite(value)) {
@@ -614,6 +625,7 @@ async function main() {
614
625
  parallel: args.pipelineParallel,
615
626
  dryRun: args.pipelineDryRun,
616
627
  mcp: args.pipelineMcp,
628
+ mcpAllowFallback: args.pipelineMcpAllowFallback,
617
629
  },
618
630
  });
619
631
  if (args.allowFallback) {
@@ -688,17 +700,72 @@ async function main() {
688
700
  }
689
701
  return;
690
702
  }
703
+ if (args.command === 'heal') {
704
+ if (!args.path && !autoConfig) {
705
+ // eslint-disable-next-line no-console
706
+ console.error('Error: --path is required for heal command');
707
+ process.exit(1);
708
+ }
709
+ if (!args.traceabilityReportPath) {
710
+ // eslint-disable-next-line no-console
711
+ console.error('Error: --traceability-report <path> is required for heal command');
712
+ process.exit(1);
713
+ }
714
+ const { config } = (0, config_js_1.resolveConfig)(process.cwd(), autoConfig, {
715
+ path: args.path,
716
+ testsRoot: args.testsRoot,
717
+ mode: 'gap',
718
+ framework: args.framework,
719
+ pipeline: {
720
+ enabled: true,
721
+ scenarios: args.pipelineScenarios,
722
+ outputDir: args.pipelineOutput,
723
+ baseUrl: args.pipelineBaseUrl,
724
+ browser: args.pipelineBrowser,
725
+ headless: args.pipelineHeadless,
726
+ project: args.pipelineProject,
727
+ parallel: args.pipelineParallel,
728
+ dryRun: args.pipelineDryRun,
729
+ mcp: args.pipelineMcp,
730
+ mcpAllowFallback: args.pipelineMcpAllowFallback,
731
+ },
732
+ });
733
+ const reportRoot = config.testsRoot || config.path;
734
+ const unstableSpecs = (0, playwright_report_js_1.extractPlaywrightUnstableSpecs)(args.traceabilityReportPath, [reportRoot, config.path]);
735
+ if (unstableSpecs.length === 0) {
736
+ // eslint-disable-next-line no-console
737
+ console.log('Heal targeted unstable specs: 0');
738
+ return;
739
+ }
740
+ const targetedSummary = (0, pipeline_js_1.runTargetedSpecHeal)(reportRoot, unstableSpecs.map((spec) => ({
741
+ specPath: spec.specPath,
742
+ status: spec.status,
743
+ reason: `Playwright report: failingTests=${spec.failingTests}, flakyTests=${spec.flakyTests}`,
744
+ })), {
745
+ ...config.pipeline,
746
+ enabled: true,
747
+ heal: true,
748
+ });
749
+ const healedCount = targetedSummary.results.filter((result) => result.healStatus === 'success').length;
750
+ // eslint-disable-next-line no-console
751
+ console.log(`Heal targeted unstable specs: ${unstableSpecs.length} (healed=${healedCount})`);
752
+ if (targetedSummary.warnings.length > 0) {
753
+ // eslint-disable-next-line no-console
754
+ console.log(`Heal warnings: ${targetedSummary.warnings.join(' | ')}`);
755
+ }
756
+ return;
757
+ }
691
758
  if (!args.path && !autoConfig) {
692
759
  // eslint-disable-next-line no-console
693
760
  console.error('Error: --path is required (or provide a config file with path set)');
694
761
  printUsage();
695
762
  process.exit(1);
696
763
  }
697
- const forcePipelineFromApproval = args.command === 'approve-and-generate';
764
+ const forcePipelineFromApproval = args.command === 'approve-and-generate' || args.command === 'generate';
698
765
  const { config } = (0, config_js_1.resolveConfig)(process.cwd(), autoConfig, {
699
766
  path: args.path,
700
767
  testsRoot: args.testsRoot,
701
- mode: (args.command === 'gap' || args.command === 'approve-and-generate') ? 'gap' : 'impact',
768
+ mode: (args.command === 'gap' || args.command === 'approve-and-generate' || args.command === 'generate') ? 'gap' : 'impact',
702
769
  framework: args.framework,
703
770
  timeLimitMinutes: args.timeLimitMinutes,
704
771
  budget: {
@@ -723,6 +790,7 @@ async function main() {
723
790
  parallel: args.pipelineParallel,
724
791
  dryRun: args.pipelineDryRun,
725
792
  mcp: args.pipelineMcp !== undefined ? args.pipelineMcp : forcePipelineFromApproval,
793
+ mcpAllowFallback: args.pipelineMcpAllowFallback,
726
794
  }
727
795
  : undefined,
728
796
  policy: args.policyMinConfidence !== undefined ||
@@ -744,7 +812,7 @@ async function main() {
744
812
  await (0, runner_js_1.runImpact)(config, { apply: args.apply });
745
813
  return;
746
814
  }
747
- if (args.command === 'suggest') {
815
+ if (args.command === 'suggest' || args.command === 'plan') {
748
816
  await (0, runner_js_1.runImpact)(config, { apply: args.apply });
749
817
  const reportRoot = config.testsRoot || config.path;
750
818
  const impactPath = (0, path_1.join)(reportRoot, '.e2e-ai-agents', 'impact.json');
@@ -793,8 +861,8 @@ async function main() {
793
861
  }
794
862
  return;
795
863
  }
796
- if (args.command === 'approve-and-generate') {
797
- await (0, runner_js_1.runGap)(config, { apply: true });
864
+ if (args.command === 'approve-and-generate' || args.command === 'generate') {
865
+ await (0, runner_js_1.runGap)(config, { apply: args.apply });
798
866
  return;
799
867
  }
800
868
  await (0, runner_js_1.runGap)(config, { apply: args.apply });
@@ -73,6 +73,7 @@ const DEFAULT_CONFIG = {
73
73
  outputDir: 'specs/functional/ai-assisted',
74
74
  heal: true,
75
75
  mcp: false,
76
+ mcpAllowFallback: false,
76
77
  },
77
78
  llm: {
78
79
  provider: 'anthropic',
@@ -434,6 +435,9 @@ function extractConfigPatch(raw) {
434
435
  parallel: pipeline.parallel !== undefined ? Boolean(pipeline.parallel) : undefined,
435
436
  dryRun: pipeline.dryRun !== undefined ? Boolean(pipeline.dryRun) : undefined,
436
437
  mcp: pipeline.mcp !== undefined ? Boolean(pipeline.mcp) : DEFAULT_CONFIG.pipeline.mcp,
438
+ mcpAllowFallback: pipeline.mcpAllowFallback !== undefined
439
+ ? Boolean(pipeline.mcpAllowFallback)
440
+ : DEFAULT_CONFIG.pipeline.mcpAllowFallback,
437
441
  };
438
442
  }
439
443
  if (raw.llm && typeof raw.llm === 'object') {
@@ -578,6 +582,12 @@ export function resolveConfig(cwd, configPath, overrides) {
578
582
  if (overrides.pipeline.dryRun !== undefined) {
579
583
  pipelinePatch.dryRun = overrides.pipeline.dryRun;
580
584
  }
585
+ if (overrides.pipeline.mcp !== undefined) {
586
+ pipelinePatch.mcp = overrides.pipeline.mcp;
587
+ }
588
+ if (overrides.pipeline.mcpAllowFallback !== undefined) {
589
+ pipelinePatch.mcpAllowFallback = overrides.pipeline.mcpAllowFallback;
590
+ }
581
591
  config.pipeline = { ...config.pipeline, ...pipelinePatch };
582
592
  }
583
593
  if (overrides?.policy) {