@yasserkhanorg/e2e-agents 0.3.8 → 0.5.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 (77) 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/cli.js +103 -0
  5. package/dist/esm/agent/config.js +32 -0
  6. package/dist/esm/cli.js +103 -0
  7. package/dist/esm/index.js +10 -0
  8. package/dist/esm/knowledge/api_surface.js +177 -0
  9. package/dist/esm/knowledge/context_loader.js +85 -0
  10. package/dist/esm/knowledge/route_families.js +211 -0
  11. package/dist/esm/knowledge/spec_index.js +122 -0
  12. package/dist/esm/pipeline/orchestrator.js +219 -0
  13. package/dist/esm/pipeline/stage0_preprocess.js +109 -0
  14. package/dist/esm/pipeline/stage1_impact.js +124 -0
  15. package/dist/esm/pipeline/stage2_coverage.js +131 -0
  16. package/dist/esm/pipeline/stage3_generation.js +146 -0
  17. package/dist/esm/pipeline/stage4_heal.js +145 -0
  18. package/dist/esm/prompts/coverage.js +64 -0
  19. package/dist/esm/prompts/generation.js +141 -0
  20. package/dist/esm/prompts/heal.js +69 -0
  21. package/dist/esm/prompts/impact.js +82 -0
  22. package/dist/esm/validation/guardrails.js +95 -0
  23. package/dist/esm/validation/output_schema.js +80 -0
  24. package/dist/index.d.ts +17 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +28 -1
  27. package/dist/knowledge/api_surface.d.ts +25 -0
  28. package/dist/knowledge/api_surface.d.ts.map +1 -0
  29. package/dist/knowledge/api_surface.js +184 -0
  30. package/dist/knowledge/context_loader.d.ts +13 -0
  31. package/dist/knowledge/context_loader.d.ts.map +1 -0
  32. package/dist/knowledge/context_loader.js +90 -0
  33. package/dist/knowledge/route_families.d.ts +48 -0
  34. package/dist/knowledge/route_families.d.ts.map +1 -0
  35. package/dist/knowledge/route_families.js +220 -0
  36. package/dist/knowledge/spec_index.d.ts +18 -0
  37. package/dist/knowledge/spec_index.d.ts.map +1 -0
  38. package/dist/knowledge/spec_index.js +128 -0
  39. package/dist/pipeline/orchestrator.d.ts +31 -0
  40. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  41. package/dist/pipeline/orchestrator.js +222 -0
  42. package/dist/pipeline/stage0_preprocess.d.ts +31 -0
  43. package/dist/pipeline/stage0_preprocess.d.ts.map +1 -0
  44. package/dist/pipeline/stage0_preprocess.js +112 -0
  45. package/dist/pipeline/stage1_impact.d.ts +19 -0
  46. package/dist/pipeline/stage1_impact.d.ts.map +1 -0
  47. package/dist/pipeline/stage1_impact.js +127 -0
  48. package/dist/pipeline/stage2_coverage.d.ts +17 -0
  49. package/dist/pipeline/stage2_coverage.d.ts.map +1 -0
  50. package/dist/pipeline/stage2_coverage.js +134 -0
  51. package/dist/pipeline/stage3_generation.d.ts +31 -0
  52. package/dist/pipeline/stage3_generation.d.ts.map +1 -0
  53. package/dist/pipeline/stage3_generation.js +149 -0
  54. package/dist/pipeline/stage4_heal.d.ts +56 -0
  55. package/dist/pipeline/stage4_heal.d.ts.map +1 -0
  56. package/dist/pipeline/stage4_heal.js +151 -0
  57. package/dist/prompts/coverage.d.ts +37 -0
  58. package/dist/prompts/coverage.d.ts.map +1 -0
  59. package/dist/prompts/coverage.js +68 -0
  60. package/dist/prompts/generation.d.ts +23 -0
  61. package/dist/prompts/generation.d.ts.map +1 -0
  62. package/dist/prompts/generation.js +146 -0
  63. package/dist/prompts/heal.d.ts +19 -0
  64. package/dist/prompts/heal.d.ts.map +1 -0
  65. package/dist/prompts/heal.js +73 -0
  66. package/dist/prompts/impact.d.ts +30 -0
  67. package/dist/prompts/impact.d.ts.map +1 -0
  68. package/dist/prompts/impact.js +86 -0
  69. package/dist/validation/guardrails.d.ts +27 -0
  70. package/dist/validation/guardrails.d.ts.map +1 -0
  71. package/dist/validation/guardrails.js +104 -0
  72. package/dist/validation/output_schema.d.ts +64 -0
  73. package/dist/validation/output_schema.d.ts.map +1 -0
  74. package/dist/validation/output_schema.js +84 -0
  75. package/package.json +3 -1
  76. package/schemas/flow-decision.schema.json +83 -0
  77. 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":"AAMA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,CAAC;AAC5C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AACvF,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,YAAY;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC3B,YAAY,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACjC,cAAc,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACd,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK,GAAG,SAAS,CAAC;AAEjD,MAAM,MAAM,YAAY,GAClB,cAAc,GACd,YAAY,GACZ,eAAe,GACf,QAAQ,GACR,OAAO,GACP,aAAa,CAAC;AAEpB,MAAM,WAAW,UAAU;IACvB,YAAY,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC3B,YAAY,EAAE,YAAY,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IACzB,wBAAwB,EAAE,MAAM,CAAC;IACjC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4BAA4B,EAAE,MAAM,CAAC;IACrC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,cAAc,EAAE,KAAK,CAAC,SAAS,GAAG,gBAAgB,GAAG,eAAe,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,2BAA2B;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;IAC1B,aAAa,EAAE,mBAAmB,CAAC;IACnC,aAAa,EAAE,mBAAmB,CAAC;IACnC,cAAc,EAAE,oBAAoB,CAAC;IACrC,MAAM,EAAE;QACJ,aAAa,EAAE,OAAO,CAAC;QACvB,eAAe,EAAE,2BAA2B,CAAC;QAC7C,YAAY,EAAE,wBAAwB,CAAC;QACvC,aAAa,EAAE,yBAAyB,CAAC;QACzC,MAAM,EAAE,kBAAkB,CAAC;QAC3B,SAAS,EAAE,qBAAqB,CAAC;KACpC,CAAC;IACF,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,SAAS,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,gBAAgB,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB;AAiND,MAAM,WAAW,eAAe;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAuiBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,eAAe,GAAG,cAAc,CA2L3G"}
@@ -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;
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>] [--heal] [--heal-report <json>]',
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,24 @@ 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
+ }
496
+ if (arg === '--heal') {
497
+ parsed.analyzeHeal = true;
498
+ continue;
499
+ }
500
+ if (arg === '--heal-report' && next) {
501
+ parsed.analyzeHealReport = next;
502
+ i += 1;
503
+ continue;
504
+ }
484
505
  }
485
506
  return parsed;
486
507
  }
@@ -495,6 +516,88 @@ async function main() {
495
516
  await runLlmHealth();
496
517
  return;
497
518
  }
519
+ if (args.command === 'analyze') {
520
+ if (!args.path && !autoConfig) {
521
+ // eslint-disable-next-line no-console
522
+ console.error('Error: --path is required for analyze command');
523
+ process.exit(1);
524
+ }
525
+ const { config } = (0, config_js_1.resolveConfig)(process.cwd(), autoConfig, {
526
+ path: args.path,
527
+ profile: args.profile,
528
+ testsRoot: args.testsRoot,
529
+ mode: 'impact',
530
+ gitSince: args.gitSince,
531
+ llmProvider: args.llmProvider,
532
+ });
533
+ const testsRoot = config.testsRoot || config.path;
534
+ const analyzeStages = [
535
+ 'preprocess', 'impact', 'coverage',
536
+ ];
537
+ if (args.analyzeGenerate) {
538
+ analyzeStages.push('generation');
539
+ }
540
+ if (args.analyzeHeal || args.analyzeHealReport) {
541
+ analyzeStages.push('heal');
542
+ }
543
+ const result = await (0, orchestrator_js_1.runPipeline)({
544
+ appPath: config.path,
545
+ testsRoot,
546
+ gitSince: args.gitSince || config.git.since,
547
+ routeFamilies: config.routeFamilies,
548
+ apiSurface: config.apiSurface,
549
+ stages: analyzeStages,
550
+ generation: args.analyzeGenerate
551
+ ? {
552
+ defaultOutputDir: args.analyzeGenerateOutputDir || 'specs/functional/ai-assisted',
553
+ dryRun: args.dryRun,
554
+ }
555
+ : undefined,
556
+ heal: (args.analyzeHeal || args.analyzeHealReport)
557
+ ? {
558
+ mcp: args.pipelineMcp ?? true,
559
+ mcpAllowFallback: args.pipelineMcpAllowFallback ?? false,
560
+ mcpOnly: args.pipelineMcpOnly ?? false,
561
+ mcpCommandTimeoutMs: args.pipelineMcpTimeoutMs,
562
+ mcpRetries: args.pipelineMcpRetries ?? 1,
563
+ dryRun: args.dryRun,
564
+ }
565
+ : undefined,
566
+ playwrightReportPath: args.analyzeHealReport,
567
+ });
568
+ // eslint-disable-next-line no-console
569
+ console.log(`Analyze report: ${result.reportPath}`);
570
+ // eslint-disable-next-line no-console
571
+ console.log(`Analyze flows identified: ${result.report.summary.flowsIdentified}`);
572
+ // eslint-disable-next-line no-console
573
+ console.log(`Analyze flows covered: ${result.report.summary.flowsCovered}`);
574
+ // eslint-disable-next-line no-console
575
+ console.log(`Analyze flows uncovered: ${result.report.summary.flowsUncovered}`);
576
+ // eslint-disable-next-line no-console
577
+ console.log(`Analyze overall confidence: ${result.report.summary.overallConfidence}`);
578
+ // eslint-disable-next-line no-console
579
+ console.log(`Analyze route families: ${result.report.summary.routeFamiliesImpacted.join(', ') || 'none'}`);
580
+ if (result.generated && result.generated.length > 0) {
581
+ const written = result.generated.filter((g) => g.written).length;
582
+ // eslint-disable-next-line no-console
583
+ console.log(`Analyze generated specs: ${result.generated.length} (written=${written})`);
584
+ for (const g of result.generated) {
585
+ // eslint-disable-next-line no-console
586
+ console.log(` ${g.mode}: ${g.specPath}`);
587
+ }
588
+ }
589
+ if (result.healResult) {
590
+ const healed = result.healResult.summary.results.filter((r) => r.healStatus === 'success').length;
591
+ const healFailed = result.healResult.summary.results.filter((r) => r.healStatus === 'failed').length;
592
+ // eslint-disable-next-line no-console
593
+ console.log(`Analyze heal targets: ${result.healResult.targets.length} (healed=${healed}, failed=${healFailed})`);
594
+ }
595
+ if (result.warnings.length > 0) {
596
+ // eslint-disable-next-line no-console
597
+ console.log(`Analyze warnings: ${result.warnings.join(' | ')}`);
598
+ }
599
+ return;
600
+ }
498
601
  if (args.command === 'feedback') {
499
602
  if (!args.path && !autoConfig) {
500
603
  // 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;
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>] [--heal] [--heal-report <json>]',
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,24 @@ 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
+ }
494
+ if (arg === '--heal') {
495
+ parsed.analyzeHeal = true;
496
+ continue;
497
+ }
498
+ if (arg === '--heal-report' && next) {
499
+ parsed.analyzeHealReport = next;
500
+ i += 1;
501
+ continue;
502
+ }
482
503
  }
483
504
  return parsed;
484
505
  }
@@ -493,6 +514,88 @@ async function main() {
493
514
  await runLlmHealth();
494
515
  return;
495
516
  }
517
+ if (args.command === 'analyze') {
518
+ if (!args.path && !autoConfig) {
519
+ // eslint-disable-next-line no-console
520
+ console.error('Error: --path is required for analyze command');
521
+ process.exit(1);
522
+ }
523
+ const { config } = resolveConfig(process.cwd(), autoConfig, {
524
+ path: args.path,
525
+ profile: args.profile,
526
+ testsRoot: args.testsRoot,
527
+ mode: 'impact',
528
+ gitSince: args.gitSince,
529
+ llmProvider: args.llmProvider,
530
+ });
531
+ const testsRoot = config.testsRoot || config.path;
532
+ const analyzeStages = [
533
+ 'preprocess', 'impact', 'coverage',
534
+ ];
535
+ if (args.analyzeGenerate) {
536
+ analyzeStages.push('generation');
537
+ }
538
+ if (args.analyzeHeal || args.analyzeHealReport) {
539
+ analyzeStages.push('heal');
540
+ }
541
+ const result = await runPipeline({
542
+ appPath: config.path,
543
+ testsRoot,
544
+ gitSince: args.gitSince || config.git.since,
545
+ routeFamilies: config.routeFamilies,
546
+ apiSurface: config.apiSurface,
547
+ stages: analyzeStages,
548
+ generation: args.analyzeGenerate
549
+ ? {
550
+ defaultOutputDir: args.analyzeGenerateOutputDir || 'specs/functional/ai-assisted',
551
+ dryRun: args.dryRun,
552
+ }
553
+ : undefined,
554
+ heal: (args.analyzeHeal || args.analyzeHealReport)
555
+ ? {
556
+ mcp: args.pipelineMcp ?? true,
557
+ mcpAllowFallback: args.pipelineMcpAllowFallback ?? false,
558
+ mcpOnly: args.pipelineMcpOnly ?? false,
559
+ mcpCommandTimeoutMs: args.pipelineMcpTimeoutMs,
560
+ mcpRetries: args.pipelineMcpRetries ?? 1,
561
+ dryRun: args.dryRun,
562
+ }
563
+ : undefined,
564
+ playwrightReportPath: args.analyzeHealReport,
565
+ });
566
+ // eslint-disable-next-line no-console
567
+ console.log(`Analyze report: ${result.reportPath}`);
568
+ // eslint-disable-next-line no-console
569
+ console.log(`Analyze flows identified: ${result.report.summary.flowsIdentified}`);
570
+ // eslint-disable-next-line no-console
571
+ console.log(`Analyze flows covered: ${result.report.summary.flowsCovered}`);
572
+ // eslint-disable-next-line no-console
573
+ console.log(`Analyze flows uncovered: ${result.report.summary.flowsUncovered}`);
574
+ // eslint-disable-next-line no-console
575
+ console.log(`Analyze overall confidence: ${result.report.summary.overallConfidence}`);
576
+ // eslint-disable-next-line no-console
577
+ console.log(`Analyze route families: ${result.report.summary.routeFamiliesImpacted.join(', ') || 'none'}`);
578
+ if (result.generated && result.generated.length > 0) {
579
+ const written = result.generated.filter((g) => g.written).length;
580
+ // eslint-disable-next-line no-console
581
+ console.log(`Analyze generated specs: ${result.generated.length} (written=${written})`);
582
+ for (const g of result.generated) {
583
+ // eslint-disable-next-line no-console
584
+ console.log(` ${g.mode}: ${g.specPath}`);
585
+ }
586
+ }
587
+ if (result.healResult) {
588
+ const healed = result.healResult.summary.results.filter((r) => r.healStatus === 'success').length;
589
+ const healFailed = result.healResult.summary.results.filter((r) => r.healStatus === 'failed').length;
590
+ // eslint-disable-next-line no-console
591
+ console.log(`Analyze heal targets: ${result.healResult.targets.length} (healed=${healed}, failed=${healFailed})`);
592
+ }
593
+ if (result.warnings.length > 0) {
594
+ // eslint-disable-next-line no-console
595
+ console.log(`Analyze warnings: ${result.warnings.join(' | ')}`);
596
+ }
597
+ return;
598
+ }
496
599
  if (args.command === 'feedback') {
497
600
  if (!args.path && !autoConfig) {
498
601
  // eslint-disable-next-line no-console
package/dist/esm/index.js CHANGED
@@ -14,3 +14,13 @@ 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
+ export { runHealStage, healFromReport, resolveHealTargets, renderHealMarkdown } from './pipeline/stage4_heal.js';
22
+ export { buildHealPrompt, buildQualityFixPrompt } from './prompts/heal.js';
23
+ // Knowledge modules
24
+ export { loadRouteFamilyManifest, bindFilesToFamilies } from './knowledge/route_families.js';
25
+ export { buildApiSurface, loadOrBuildApiSurface } from './knowledge/api_surface.js';
26
+ 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
+ }