@yasserkhanorg/e2e-agents 0.3.7 → 0.4.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.
Files changed (72) hide show
  1. package/dist/agent/config.d.ts +12 -0
  2. package/dist/agent/config.d.ts.map +1 -1
  3. package/dist/agent/config.js +32 -0
  4. package/dist/anthropic_provider.d.ts.map +1 -1
  5. package/dist/anthropic_provider.js +1 -0
  6. package/dist/cli.js +74 -0
  7. package/dist/esm/agent/config.js +32 -0
  8. package/dist/esm/anthropic_provider.js +1 -0
  9. package/dist/esm/cli.js +74 -0
  10. package/dist/esm/index.js +8 -0
  11. package/dist/esm/knowledge/api_surface.js +177 -0
  12. package/dist/esm/knowledge/context_loader.js +85 -0
  13. package/dist/esm/knowledge/route_families.js +211 -0
  14. package/dist/esm/knowledge/spec_index.js +122 -0
  15. package/dist/esm/pipeline/orchestrator.js +199 -0
  16. package/dist/esm/pipeline/stage0_preprocess.js +109 -0
  17. package/dist/esm/pipeline/stage1_impact.js +124 -0
  18. package/dist/esm/pipeline/stage2_coverage.js +131 -0
  19. package/dist/esm/pipeline/stage3_generation.js +146 -0
  20. package/dist/esm/prompts/coverage.js +64 -0
  21. package/dist/esm/prompts/generation.js +141 -0
  22. package/dist/esm/prompts/impact.js +82 -0
  23. package/dist/esm/validation/guardrails.js +95 -0
  24. package/dist/esm/validation/output_schema.js +80 -0
  25. package/dist/index.d.ts +13 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +20 -1
  28. package/dist/knowledge/api_surface.d.ts +25 -0
  29. package/dist/knowledge/api_surface.d.ts.map +1 -0
  30. package/dist/knowledge/api_surface.js +184 -0
  31. package/dist/knowledge/context_loader.d.ts +13 -0
  32. package/dist/knowledge/context_loader.d.ts.map +1 -0
  33. package/dist/knowledge/context_loader.js +90 -0
  34. package/dist/knowledge/route_families.d.ts +48 -0
  35. package/dist/knowledge/route_families.d.ts.map +1 -0
  36. package/dist/knowledge/route_families.js +220 -0
  37. package/dist/knowledge/spec_index.d.ts +18 -0
  38. package/dist/knowledge/spec_index.d.ts.map +1 -0
  39. package/dist/knowledge/spec_index.js +128 -0
  40. package/dist/pipeline/orchestrator.d.ts +26 -0
  41. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  42. package/dist/pipeline/orchestrator.js +202 -0
  43. package/dist/pipeline/stage0_preprocess.d.ts +31 -0
  44. package/dist/pipeline/stage0_preprocess.d.ts.map +1 -0
  45. package/dist/pipeline/stage0_preprocess.js +112 -0
  46. package/dist/pipeline/stage1_impact.d.ts +19 -0
  47. package/dist/pipeline/stage1_impact.d.ts.map +1 -0
  48. package/dist/pipeline/stage1_impact.js +127 -0
  49. package/dist/pipeline/stage2_coverage.d.ts +17 -0
  50. package/dist/pipeline/stage2_coverage.d.ts.map +1 -0
  51. package/dist/pipeline/stage2_coverage.js +134 -0
  52. package/dist/pipeline/stage3_generation.d.ts +31 -0
  53. package/dist/pipeline/stage3_generation.d.ts.map +1 -0
  54. package/dist/pipeline/stage3_generation.js +149 -0
  55. package/dist/prompts/coverage.d.ts +37 -0
  56. package/dist/prompts/coverage.d.ts.map +1 -0
  57. package/dist/prompts/coverage.js +68 -0
  58. package/dist/prompts/generation.d.ts +23 -0
  59. package/dist/prompts/generation.d.ts.map +1 -0
  60. package/dist/prompts/generation.js +146 -0
  61. package/dist/prompts/impact.d.ts +30 -0
  62. package/dist/prompts/impact.d.ts.map +1 -0
  63. package/dist/prompts/impact.js +86 -0
  64. package/dist/validation/guardrails.d.ts +27 -0
  65. package/dist/validation/guardrails.d.ts.map +1 -0
  66. package/dist/validation/guardrails.js +104 -0
  67. package/dist/validation/output_schema.d.ts +64 -0
  68. package/dist/validation/output_schema.d.ts.map +1 -0
  69. package/dist/validation/output_schema.js +84 -0
  70. package/package.json +3 -1
  71. package/schemas/flow-decision.schema.json +83 -0
  72. package/schemas/route-families.schema.json +107 -0
@@ -121,6 +121,16 @@ export interface GitConfig {
121
121
  since: string;
122
122
  includeUncommitted?: boolean;
123
123
  }
124
+ export interface RouteFamiliesConfig {
125
+ manifestPath?: string;
126
+ strict?: boolean;
127
+ }
128
+ export interface ApiSurfaceConfig {
129
+ enabled: boolean;
130
+ pageObjectsDir?: string;
131
+ componentsDir?: string;
132
+ cachePath?: string;
133
+ }
124
134
  export interface AgentConfig {
125
135
  path: string;
126
136
  profile: AnalysisProfile;
@@ -152,6 +162,8 @@ export interface AgentConfig {
152
162
  audience: AudienceConfig;
153
163
  blastRadius: BlastRadiusConfig;
154
164
  git: GitConfig;
165
+ routeFamilies: RouteFamiliesConfig;
166
+ apiSurface: ApiSurfaceConfig;
155
167
  }
156
168
  export interface ResolvedConfig {
157
169
  config: AgentConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/agent/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/agent/config.ts"],"names":[],"mappings":"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"}
@@ -172,6 +172,12 @@ const DEFAULT_CONFIG = {
172
172
  since: 'HEAD~1',
173
173
  includeUncommitted: true,
174
174
  },
175
+ routeFamilies: {
176
+ strict: false,
177
+ },
178
+ apiSurface: {
179
+ enabled: false,
180
+ },
175
181
  };
176
182
  function normalizeMattermostProvider(rawProvider, fallback, strict = false) {
177
183
  if (typeof rawProvider !== 'string') {
@@ -295,6 +301,14 @@ function mergeConfig(base, patch) {
295
301
  ...base.git,
296
302
  ...(patch.git || {}),
297
303
  },
304
+ routeFamilies: {
305
+ ...base.routeFamilies,
306
+ ...(patch.routeFamilies || {}),
307
+ },
308
+ apiSurface: {
309
+ ...base.apiSurface,
310
+ ...(patch.apiSurface || {}),
311
+ },
298
312
  };
299
313
  }
300
314
  function coerceNumber(value) {
@@ -652,6 +666,22 @@ function extractConfigPatch(raw) {
652
666
  includeUncommitted: git.includeUncommitted !== undefined ? Boolean(git.includeUncommitted) : DEFAULT_CONFIG.git.includeUncommitted,
653
667
  };
654
668
  }
669
+ if (raw.routeFamilies && typeof raw.routeFamilies === 'object') {
670
+ const rf = raw.routeFamilies;
671
+ patch.routeFamilies = {
672
+ manifestPath: typeof rf.manifestPath === 'string' ? rf.manifestPath : undefined,
673
+ strict: rf.strict !== undefined ? Boolean(rf.strict) : DEFAULT_CONFIG.routeFamilies.strict,
674
+ };
675
+ }
676
+ if (raw.apiSurface && typeof raw.apiSurface === 'object') {
677
+ const api = raw.apiSurface;
678
+ patch.apiSurface = {
679
+ enabled: api.enabled !== undefined ? Boolean(api.enabled) : DEFAULT_CONFIG.apiSurface.enabled,
680
+ pageObjectsDir: typeof api.pageObjectsDir === 'string' ? api.pageObjectsDir : undefined,
681
+ componentsDir: typeof api.componentsDir === 'string' ? api.componentsDir : undefined,
682
+ cachePath: typeof api.cachePath === 'string' ? api.cachePath : undefined,
683
+ };
684
+ }
655
685
  return patch;
656
686
  }
657
687
  function resolveConfig(cwd, configPath, overrides) {
@@ -815,6 +845,8 @@ function resolveConfig(cwd, configPath, overrides) {
815
845
  config.policy.forceFullOnWarningsAtOrAbove = 1;
816
846
  config.policy.forceFullOnP0WithGaps = true;
817
847
  config.policy.forceFullOnRiskyFiles = true;
848
+ config.routeFamilies.strict = true;
849
+ config.apiSurface.enabled = true;
818
850
  }
819
851
  const resolvedRoot = (0, path_1.resolve)(configDir, config.path);
820
852
  config.path = resolvedRoot;
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic_provider.d.ts","sourceRoot":"","sources":["../src/anthropic_provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACR,eAAe,EACf,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAehD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAC/C,IAAI,SAAe;IACnB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IAEtB,YAAY,EAAE,oBAAoB,CAShC;gBAEU,MAAM,EAAE,eAAe;IA2B7B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IA4D7E,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAgHlG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IA4CnG,OAAO,CAAC,uBAAuB;IAU/B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAchC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CAyBpE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/D,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;CAChC,CAAC,CAyBD"}
1
+ {"version":3,"file":"anthropic_provider.d.ts","sourceRoot":"","sources":["../src/anthropic_provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACR,eAAe,EACf,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAehD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAC/C,IAAI,SAAe;IACnB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IAEtB,YAAY,EAAE,oBAAoB,CAShC;gBAEU,MAAM,EAAE,eAAe;IA4B7B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IA4D7E,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAgHlG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IA4CnG,OAAO,CAAC,uBAAuB;IAU/B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAchC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CAyBpE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/D,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;CAChC,CAAC,CAyBD"}
@@ -70,6 +70,7 @@ class AnthropicProvider extends base_provider_js_1.BaseProvider {
70
70
  this.client = new sdk_1.default({
71
71
  apiKey: config.apiKey,
72
72
  baseURL: config.baseUrl,
73
+ maxRetries: 0,
73
74
  });
74
75
  this.model = config.model || 'claude-sonnet-4-5-20250929';
75
76
  }
package/dist/cli.js CHANGED
@@ -17,6 +17,7 @@ const traceability_ingest_js_1 = require("./agent/traceability_ingest.js");
17
17
  const traceability_capture_js_1 = require("./agent/traceability_capture.js");
18
18
  const pipeline_js_1 = require("./agent/pipeline.js");
19
19
  const playwright_report_js_1 = require("./agent/playwright_report.js");
20
+ const orchestrator_js_1 = require("./pipeline/orchestrator.js");
20
21
  const CONFIG_CANDIDATES = ['e2e-ai-agents.config.json', '.e2e-ai-agents.config.json'];
21
22
  function findConfigUpwards(startDir) {
22
23
  if (!startDir) {
@@ -71,6 +72,7 @@ function printUsage() {
71
72
  ' e2e-ai-agents feedback --path <app-root> --feedback-input <json>',
72
73
  ' e2e-ai-agents traceability-capture --path <app-root> --traceability-report <json>',
73
74
  ' e2e-ai-agents traceability-ingest --path <app-root> --traceability-input <json>',
75
+ ' e2e-ai-agents analyze --path <app-root> [--tests-root <path>] [--since <ref>] [--generate] [--generate-output <dir>]',
74
76
  ' e2e-ai-agents llm-health',
75
77
  '',
76
78
  'Options:',
@@ -155,6 +157,7 @@ function parseArgs(argv) {
155
157
  || command === 'feedback'
156
158
  || command === 'traceability-capture'
157
159
  || command === 'traceability-ingest'
160
+ || command === 'analyze'
158
161
  || command === 'llm-health') {
159
162
  parsed.command = command;
160
163
  }
@@ -481,6 +484,15 @@ function parseArgs(argv) {
481
484
  parsed.dryRun = true;
482
485
  continue;
483
486
  }
487
+ if (arg === '--generate') {
488
+ parsed.analyzeGenerate = true;
489
+ continue;
490
+ }
491
+ if (arg === '--generate-output' && next) {
492
+ parsed.analyzeGenerateOutputDir = next;
493
+ i += 1;
494
+ continue;
495
+ }
484
496
  }
485
497
  return parsed;
486
498
  }
@@ -495,6 +507,68 @@ async function main() {
495
507
  await runLlmHealth();
496
508
  return;
497
509
  }
510
+ if (args.command === 'analyze') {
511
+ if (!args.path && !autoConfig) {
512
+ // eslint-disable-next-line no-console
513
+ console.error('Error: --path is required for analyze command');
514
+ process.exit(1);
515
+ }
516
+ const { config } = (0, config_js_1.resolveConfig)(process.cwd(), autoConfig, {
517
+ path: args.path,
518
+ profile: args.profile,
519
+ testsRoot: args.testsRoot,
520
+ mode: 'impact',
521
+ gitSince: args.gitSince,
522
+ llmProvider: args.llmProvider,
523
+ });
524
+ const testsRoot = config.testsRoot || config.path;
525
+ const analyzeStages = [
526
+ 'preprocess', 'impact', 'coverage',
527
+ ];
528
+ if (args.analyzeGenerate) {
529
+ analyzeStages.push('generation');
530
+ }
531
+ const result = await (0, orchestrator_js_1.runPipeline)({
532
+ appPath: config.path,
533
+ testsRoot,
534
+ gitSince: args.gitSince || config.git.since,
535
+ routeFamilies: config.routeFamilies,
536
+ apiSurface: config.apiSurface,
537
+ stages: analyzeStages,
538
+ generation: args.analyzeGenerate
539
+ ? {
540
+ defaultOutputDir: args.analyzeGenerateOutputDir || 'specs/functional/ai-assisted',
541
+ dryRun: args.dryRun,
542
+ }
543
+ : undefined,
544
+ });
545
+ // eslint-disable-next-line no-console
546
+ console.log(`Analyze report: ${result.reportPath}`);
547
+ // eslint-disable-next-line no-console
548
+ console.log(`Analyze flows identified: ${result.report.summary.flowsIdentified}`);
549
+ // eslint-disable-next-line no-console
550
+ console.log(`Analyze flows covered: ${result.report.summary.flowsCovered}`);
551
+ // eslint-disable-next-line no-console
552
+ console.log(`Analyze flows uncovered: ${result.report.summary.flowsUncovered}`);
553
+ // eslint-disable-next-line no-console
554
+ console.log(`Analyze overall confidence: ${result.report.summary.overallConfidence}`);
555
+ // eslint-disable-next-line no-console
556
+ console.log(`Analyze route families: ${result.report.summary.routeFamiliesImpacted.join(', ') || 'none'}`);
557
+ if (result.generated && result.generated.length > 0) {
558
+ const written = result.generated.filter((g) => g.written).length;
559
+ // eslint-disable-next-line no-console
560
+ console.log(`Analyze generated specs: ${result.generated.length} (written=${written})`);
561
+ for (const g of result.generated) {
562
+ // eslint-disable-next-line no-console
563
+ console.log(` ${g.mode}: ${g.specPath}`);
564
+ }
565
+ }
566
+ if (result.warnings.length > 0) {
567
+ // eslint-disable-next-line no-console
568
+ console.log(`Analyze warnings: ${result.warnings.join(' | ')}`);
569
+ }
570
+ return;
571
+ }
498
572
  if (args.command === 'feedback') {
499
573
  if (!args.path && !autoConfig) {
500
574
  // eslint-disable-next-line no-console
@@ -169,6 +169,12 @@ const DEFAULT_CONFIG = {
169
169
  since: 'HEAD~1',
170
170
  includeUncommitted: true,
171
171
  },
172
+ routeFamilies: {
173
+ strict: false,
174
+ },
175
+ apiSurface: {
176
+ enabled: false,
177
+ },
172
178
  };
173
179
  function normalizeMattermostProvider(rawProvider, fallback, strict = false) {
174
180
  if (typeof rawProvider !== 'string') {
@@ -292,6 +298,14 @@ function mergeConfig(base, patch) {
292
298
  ...base.git,
293
299
  ...(patch.git || {}),
294
300
  },
301
+ routeFamilies: {
302
+ ...base.routeFamilies,
303
+ ...(patch.routeFamilies || {}),
304
+ },
305
+ apiSurface: {
306
+ ...base.apiSurface,
307
+ ...(patch.apiSurface || {}),
308
+ },
295
309
  };
296
310
  }
297
311
  function coerceNumber(value) {
@@ -649,6 +663,22 @@ function extractConfigPatch(raw) {
649
663
  includeUncommitted: git.includeUncommitted !== undefined ? Boolean(git.includeUncommitted) : DEFAULT_CONFIG.git.includeUncommitted,
650
664
  };
651
665
  }
666
+ if (raw.routeFamilies && typeof raw.routeFamilies === 'object') {
667
+ const rf = raw.routeFamilies;
668
+ patch.routeFamilies = {
669
+ manifestPath: typeof rf.manifestPath === 'string' ? rf.manifestPath : undefined,
670
+ strict: rf.strict !== undefined ? Boolean(rf.strict) : DEFAULT_CONFIG.routeFamilies.strict,
671
+ };
672
+ }
673
+ if (raw.apiSurface && typeof raw.apiSurface === 'object') {
674
+ const api = raw.apiSurface;
675
+ patch.apiSurface = {
676
+ enabled: api.enabled !== undefined ? Boolean(api.enabled) : DEFAULT_CONFIG.apiSurface.enabled,
677
+ pageObjectsDir: typeof api.pageObjectsDir === 'string' ? api.pageObjectsDir : undefined,
678
+ componentsDir: typeof api.componentsDir === 'string' ? api.componentsDir : undefined,
679
+ cachePath: typeof api.cachePath === 'string' ? api.cachePath : undefined,
680
+ };
681
+ }
652
682
  return patch;
653
683
  }
654
684
  export function resolveConfig(cwd, configPath, overrides) {
@@ -812,6 +842,8 @@ export function resolveConfig(cwd, configPath, overrides) {
812
842
  config.policy.forceFullOnWarningsAtOrAbove = 1;
813
843
  config.policy.forceFullOnP0WithGaps = true;
814
844
  config.policy.forceFullOnRiskyFiles = true;
845
+ config.routeFamilies.strict = true;
846
+ config.apiSurface.enabled = true;
815
847
  }
816
848
  const resolvedRoot = resolve(configDir, config.path);
817
849
  config.path = resolvedRoot;
@@ -63,6 +63,7 @@ export class AnthropicProvider extends BaseProvider {
63
63
  this.client = new Anthropic({
64
64
  apiKey: config.apiKey,
65
65
  baseURL: config.baseUrl,
66
+ maxRetries: 0,
66
67
  });
67
68
  this.model = config.model || 'claude-sonnet-4-5-20250929';
68
69
  }
package/dist/esm/cli.js CHANGED
@@ -15,6 +15,7 @@ import { ingestTraceabilityInput } from './agent/traceability_ingest.js';
15
15
  import { captureTraceabilityInput } from './agent/traceability_capture.js';
16
16
  import { runTargetedSpecHeal } from './agent/pipeline.js';
17
17
  import { extractPlaywrightUnstableSpecs } from './agent/playwright_report.js';
18
+ import { runPipeline } from './pipeline/orchestrator.js';
18
19
  const CONFIG_CANDIDATES = ['e2e-ai-agents.config.json', '.e2e-ai-agents.config.json'];
19
20
  function findConfigUpwards(startDir) {
20
21
  if (!startDir) {
@@ -69,6 +70,7 @@ function printUsage() {
69
70
  ' e2e-ai-agents feedback --path <app-root> --feedback-input <json>',
70
71
  ' e2e-ai-agents traceability-capture --path <app-root> --traceability-report <json>',
71
72
  ' e2e-ai-agents traceability-ingest --path <app-root> --traceability-input <json>',
73
+ ' e2e-ai-agents analyze --path <app-root> [--tests-root <path>] [--since <ref>] [--generate] [--generate-output <dir>]',
72
74
  ' e2e-ai-agents llm-health',
73
75
  '',
74
76
  'Options:',
@@ -153,6 +155,7 @@ function parseArgs(argv) {
153
155
  || command === 'feedback'
154
156
  || command === 'traceability-capture'
155
157
  || command === 'traceability-ingest'
158
+ || command === 'analyze'
156
159
  || command === 'llm-health') {
157
160
  parsed.command = command;
158
161
  }
@@ -479,6 +482,15 @@ function parseArgs(argv) {
479
482
  parsed.dryRun = true;
480
483
  continue;
481
484
  }
485
+ if (arg === '--generate') {
486
+ parsed.analyzeGenerate = true;
487
+ continue;
488
+ }
489
+ if (arg === '--generate-output' && next) {
490
+ parsed.analyzeGenerateOutputDir = next;
491
+ i += 1;
492
+ continue;
493
+ }
482
494
  }
483
495
  return parsed;
484
496
  }
@@ -493,6 +505,68 @@ async function main() {
493
505
  await runLlmHealth();
494
506
  return;
495
507
  }
508
+ if (args.command === 'analyze') {
509
+ if (!args.path && !autoConfig) {
510
+ // eslint-disable-next-line no-console
511
+ console.error('Error: --path is required for analyze command');
512
+ process.exit(1);
513
+ }
514
+ const { config } = resolveConfig(process.cwd(), autoConfig, {
515
+ path: args.path,
516
+ profile: args.profile,
517
+ testsRoot: args.testsRoot,
518
+ mode: 'impact',
519
+ gitSince: args.gitSince,
520
+ llmProvider: args.llmProvider,
521
+ });
522
+ const testsRoot = config.testsRoot || config.path;
523
+ const analyzeStages = [
524
+ 'preprocess', 'impact', 'coverage',
525
+ ];
526
+ if (args.analyzeGenerate) {
527
+ analyzeStages.push('generation');
528
+ }
529
+ const result = await runPipeline({
530
+ appPath: config.path,
531
+ testsRoot,
532
+ gitSince: args.gitSince || config.git.since,
533
+ routeFamilies: config.routeFamilies,
534
+ apiSurface: config.apiSurface,
535
+ stages: analyzeStages,
536
+ generation: args.analyzeGenerate
537
+ ? {
538
+ defaultOutputDir: args.analyzeGenerateOutputDir || 'specs/functional/ai-assisted',
539
+ dryRun: args.dryRun,
540
+ }
541
+ : undefined,
542
+ });
543
+ // eslint-disable-next-line no-console
544
+ console.log(`Analyze report: ${result.reportPath}`);
545
+ // eslint-disable-next-line no-console
546
+ console.log(`Analyze flows identified: ${result.report.summary.flowsIdentified}`);
547
+ // eslint-disable-next-line no-console
548
+ console.log(`Analyze flows covered: ${result.report.summary.flowsCovered}`);
549
+ // eslint-disable-next-line no-console
550
+ console.log(`Analyze flows uncovered: ${result.report.summary.flowsUncovered}`);
551
+ // eslint-disable-next-line no-console
552
+ console.log(`Analyze overall confidence: ${result.report.summary.overallConfidence}`);
553
+ // eslint-disable-next-line no-console
554
+ console.log(`Analyze route families: ${result.report.summary.routeFamiliesImpacted.join(', ') || 'none'}`);
555
+ if (result.generated && result.generated.length > 0) {
556
+ const written = result.generated.filter((g) => g.written).length;
557
+ // eslint-disable-next-line no-console
558
+ console.log(`Analyze generated specs: ${result.generated.length} (written=${written})`);
559
+ for (const g of result.generated) {
560
+ // eslint-disable-next-line no-console
561
+ console.log(` ${g.mode}: ${g.specPath}`);
562
+ }
563
+ }
564
+ if (result.warnings.length > 0) {
565
+ // eslint-disable-next-line no-console
566
+ console.log(`Analyze warnings: ${result.warnings.join(' | ')}`);
567
+ }
568
+ return;
569
+ }
496
570
  if (args.command === 'feedback') {
497
571
  if (!args.path && !autoConfig) {
498
572
  // eslint-disable-next-line no-console
package/dist/esm/index.js CHANGED
@@ -14,3 +14,11 @@ export { appendFeedbackAndRecompute, readCalibration } from './agent/feedback.js
14
14
  export { finalizeGeneratedTests } from './agent/handoff.js';
15
15
  export { ingestTraceabilityInput } from './agent/traceability_ingest.js';
16
16
  export { captureTraceabilityInput } from './agent/traceability_capture.js';
17
+ // Pipeline API (route-family-bound impact analysis)
18
+ export { runPipeline } from './pipeline/orchestrator.js';
19
+ export { runGenerationStage } from './pipeline/stage3_generation.js';
20
+ export { buildGenerationPrompt, parseGenerationResponse, detectHallucinatedMethods } from './prompts/generation.js';
21
+ // Knowledge modules
22
+ export { loadRouteFamilyManifest, bindFilesToFamilies } from './knowledge/route_families.js';
23
+ export { buildApiSurface, loadOrBuildApiSurface } from './knowledge/api_surface.js';
24
+ export { buildSpecIndex, getSpecsForFamily } from './knowledge/spec_index.js';
@@ -0,0 +1,177 @@
1
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2
+ // See LICENSE.txt for license information.
3
+ import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs';
4
+ import { join, extname } from 'path';
5
+ const RESERVED_WORDS = new Set([
6
+ 'private', 'protected', 'static', 'abstract', 'override',
7
+ 'if', 'for', 'while', 'switch', 'return',
8
+ 'const', 'let', 'var', 'import', 'export',
9
+ 'class', 'type', 'interface', 'constructor',
10
+ ]);
11
+ function extractMethodsFromSource(content) {
12
+ const methods = [];
13
+ const seen = new Set();
14
+ // Match async method declarations: async methodName(
15
+ const asyncMethodRe = /(?:async\s+)([a-zA-Z_]\w*)\s*\(/g;
16
+ let match;
17
+ while ((match = asyncMethodRe.exec(content)) !== null) {
18
+ const name = match[1];
19
+ if (RESERVED_WORDS.has(name)) {
20
+ continue;
21
+ }
22
+ if (!seen.has(name)) {
23
+ seen.add(name);
24
+ methods.push({ name, kind: 'method' });
25
+ }
26
+ }
27
+ // Match non-async public method patterns
28
+ const methodRe = /^\s+(?:readonly\s+)?([a-zA-Z_]\w*)\s*(?:\(|=\s*(?:async\s*)?\()/gm;
29
+ while ((match = methodRe.exec(content)) !== null) {
30
+ const name = match[1];
31
+ if (RESERVED_WORDS.has(name) || seen.has(name)) {
32
+ continue;
33
+ }
34
+ seen.add(name);
35
+ methods.push({ name, kind: 'method' });
36
+ }
37
+ // Match getter patterns: get propertyName()
38
+ const getterRe = /\bget\s+([a-zA-Z_]\w*)\s*\(\)/g;
39
+ while ((match = getterRe.exec(content)) !== null) {
40
+ const name = match[1];
41
+ if (!seen.has(name)) {
42
+ seen.add(name);
43
+ methods.push({ name, kind: 'getter' });
44
+ }
45
+ }
46
+ // Match readonly property declarations
47
+ const propRe = /^\s+(?:readonly\s+)?([a-zA-Z_]\w*)\s*[:=]/gm;
48
+ while ((match = propRe.exec(content)) !== null) {
49
+ const name = match[1];
50
+ if (RESERVED_WORDS.has(name) || seen.has(name)) {
51
+ continue;
52
+ }
53
+ seen.add(name);
54
+ methods.push({ name, kind: 'property' });
55
+ }
56
+ return methods;
57
+ }
58
+ function extractClassName(content) {
59
+ const match = content.match(/(?:export\s+)?class\s+(\w+)/);
60
+ return match ? match[1] : null;
61
+ }
62
+ function scanDirectory(dir) {
63
+ const surfaces = [];
64
+ if (!existsSync(dir)) {
65
+ return surfaces;
66
+ }
67
+ const entries = readdirSync(dir, { withFileTypes: true });
68
+ for (const entry of entries) {
69
+ const fullPath = join(dir, entry.name);
70
+ if (entry.isDirectory()) {
71
+ surfaces.push(...scanDirectory(fullPath));
72
+ continue;
73
+ }
74
+ const ext = extname(entry.name);
75
+ if (ext !== '.ts' && ext !== '.tsx') {
76
+ continue;
77
+ }
78
+ if (entry.name === 'index.ts' || entry.name === 'index.tsx') {
79
+ continue;
80
+ }
81
+ try {
82
+ const content = readFileSync(fullPath, 'utf-8');
83
+ const className = extractClassName(content);
84
+ if (!className) {
85
+ continue;
86
+ }
87
+ const extractedMethods = extractMethodsFromSource(content);
88
+ if (extractedMethods.length > 0) {
89
+ surfaces.push({
90
+ className,
91
+ file: fullPath,
92
+ methods: extractedMethods,
93
+ });
94
+ }
95
+ }
96
+ catch {
97
+ continue;
98
+ }
99
+ }
100
+ return surfaces;
101
+ }
102
+ export function buildApiSurface(testsRoot, config) {
103
+ const pageObjectsDir = config?.pageObjectsDir
104
+ ? join(testsRoot, config.pageObjectsDir)
105
+ : join(testsRoot, 'lib', 'src', 'ui', 'pages');
106
+ const componentsDir = config?.componentsDir
107
+ ? join(testsRoot, config.componentsDir)
108
+ : join(testsRoot, 'lib', 'src', 'ui', 'components');
109
+ const pageObjects = [
110
+ ...scanDirectory(pageObjectsDir),
111
+ ...scanDirectory(componentsDir),
112
+ ];
113
+ return {
114
+ pageObjects,
115
+ generatedAt: new Date().toISOString(),
116
+ };
117
+ }
118
+ export function loadOrBuildApiSurface(testsRoot, config) {
119
+ if (!config?.enabled) {
120
+ return { pageObjects: [], generatedAt: new Date().toISOString() };
121
+ }
122
+ const cachePath = config.cachePath
123
+ ? join(testsRoot, config.cachePath)
124
+ : join(testsRoot, '.e2e-ai-agents', 'api-surface.json');
125
+ if (existsSync(cachePath)) {
126
+ try {
127
+ const cached = JSON.parse(readFileSync(cachePath, 'utf-8'));
128
+ if (cached.pageObjects && Array.isArray(cached.pageObjects)) {
129
+ return cached;
130
+ }
131
+ }
132
+ catch {
133
+ // Rebuild if cache is corrupt
134
+ }
135
+ }
136
+ const catalog = buildApiSurface(testsRoot, config);
137
+ try {
138
+ const dir = join(cachePath, '..');
139
+ if (existsSync(dir)) {
140
+ writeFileSync(cachePath, JSON.stringify(catalog, null, 2), 'utf-8');
141
+ }
142
+ }
143
+ catch {
144
+ // Cache write failure is non-fatal
145
+ }
146
+ return catalog;
147
+ }
148
+ export function getMethodsForPageObject(catalog, className) {
149
+ const surface = catalog.pageObjects.find((po) => po.className === className);
150
+ return surface?.methods || [];
151
+ }
152
+ export function validateMethodCall(catalog, className, methodName) {
153
+ const methods = getMethodsForPageObject(catalog, className);
154
+ return methods.some((m) => m.name === methodName);
155
+ }
156
+ export function formatApiSurfaceForPrompt(catalog, classNames) {
157
+ const sections = [];
158
+ for (const name of classNames) {
159
+ const surface = catalog.pageObjects.find((po) => po.className === name);
160
+ if (!surface) {
161
+ continue;
162
+ }
163
+ const methodList = surface.methods
164
+ .map((m) => {
165
+ if (m.kind === 'property') {
166
+ return ` ${m.name} (property)`;
167
+ }
168
+ if (m.kind === 'getter') {
169
+ return ` get ${m.name}()`;
170
+ }
171
+ return ` ${m.name}()`;
172
+ })
173
+ .join('\n');
174
+ sections.push(`${name}:\n${methodList}`);
175
+ }
176
+ return sections.join('\n\n');
177
+ }