@yasserkhanorg/e2e-agents 1.4.0 → 1.6.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 (76) hide show
  1. package/dist/agent/feedback.d.ts +16 -0
  2. package/dist/agent/feedback.d.ts.map +1 -1
  3. package/dist/agent/feedback.js +62 -0
  4. package/dist/agent/process_runner.d.ts +1 -1
  5. package/dist/agent/process_runner.d.ts.map +1 -1
  6. package/dist/agent/process_runner.js +3 -3
  7. package/dist/api.d.ts.map +1 -1
  8. package/dist/api.js +5 -2
  9. package/dist/cli/commands/train.d.ts.map +1 -1
  10. package/dist/cli/commands/train.js +31 -4
  11. package/dist/cli/parse_args.d.ts.map +1 -1
  12. package/dist/cli/parse_args.js +1 -0
  13. package/dist/cli/types.d.ts +1 -0
  14. package/dist/cli/types.d.ts.map +1 -1
  15. package/dist/engine/plan_builder.d.ts +2 -1
  16. package/dist/engine/plan_builder.d.ts.map +1 -1
  17. package/dist/engine/plan_builder.js +22 -9
  18. package/dist/esm/agent/feedback.js +61 -0
  19. package/dist/esm/agent/process_runner.js +3 -3
  20. package/dist/esm/api.js +5 -2
  21. package/dist/esm/cli/commands/train.js +31 -4
  22. package/dist/esm/cli/parse_args.js +1 -0
  23. package/dist/esm/engine/plan_builder.js +22 -9
  24. package/dist/esm/index.js +1 -1
  25. package/dist/esm/pipeline/spec_verifier.js +75 -0
  26. package/dist/esm/pipeline/stage3_generation.js +122 -4
  27. package/dist/esm/pipeline/stage4_heal.js +146 -3
  28. package/dist/esm/prompts/heal.js +4 -0
  29. package/dist/esm/qa-agent/phase2/agent_loop.js +60 -24
  30. package/dist/esm/qa-agent/phase2/exploration_state.js +21 -0
  31. package/dist/esm/qa-agent/phase2/tools.js +99 -1
  32. package/dist/esm/qa-agent/phase3/reporter.js +31 -4
  33. package/dist/esm/training/enricher.js +71 -7
  34. package/dist/esm/training/merger.js +77 -10
  35. package/dist/esm/training/scanner.js +368 -2
  36. package/dist/esm/validation/guardrails.js +1 -0
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +3 -2
  40. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  41. package/dist/pipeline/spec_verifier.d.ts +20 -0
  42. package/dist/pipeline/spec_verifier.d.ts.map +1 -0
  43. package/dist/pipeline/spec_verifier.js +79 -0
  44. package/dist/pipeline/stage3_generation.d.ts +10 -0
  45. package/dist/pipeline/stage3_generation.d.ts.map +1 -1
  46. package/dist/pipeline/stage3_generation.js +120 -2
  47. package/dist/pipeline/stage4_heal.d.ts +4 -0
  48. package/dist/pipeline/stage4_heal.d.ts.map +1 -1
  49. package/dist/pipeline/stage4_heal.js +145 -2
  50. package/dist/prompts/heal.d.ts +2 -0
  51. package/dist/prompts/heal.d.ts.map +1 -1
  52. package/dist/prompts/heal.js +4 -0
  53. package/dist/qa-agent/phase2/agent_loop.d.ts.map +1 -1
  54. package/dist/qa-agent/phase2/agent_loop.js +60 -24
  55. package/dist/qa-agent/phase2/exploration_state.d.ts.map +1 -1
  56. package/dist/qa-agent/phase2/exploration_state.js +21 -0
  57. package/dist/qa-agent/phase2/tools.d.ts.map +1 -1
  58. package/dist/qa-agent/phase2/tools.js +99 -1
  59. package/dist/qa-agent/phase3/reporter.js +31 -4
  60. package/dist/qa-agent/types.d.ts +9 -1
  61. package/dist/qa-agent/types.d.ts.map +1 -1
  62. package/dist/training/enricher.d.ts +3 -1
  63. package/dist/training/enricher.d.ts.map +1 -1
  64. package/dist/training/enricher.js +71 -7
  65. package/dist/training/merger.d.ts +11 -1
  66. package/dist/training/merger.d.ts.map +1 -1
  67. package/dist/training/merger.js +77 -10
  68. package/dist/training/scanner.d.ts +15 -2
  69. package/dist/training/scanner.d.ts.map +1 -1
  70. package/dist/training/scanner.js +370 -2
  71. package/dist/training/types.d.ts +4 -0
  72. package/dist/training/types.d.ts.map +1 -1
  73. package/dist/validation/guardrails.d.ts +2 -0
  74. package/dist/validation/guardrails.d.ts.map +1 -1
  75. package/dist/validation/guardrails.js +4 -1
  76. package/package.json +1 -1
@@ -15,6 +15,50 @@ const SKIP_DIRS = new Set([
15
15
  ]);
16
16
  const TEST_EXTENSIONS = ['.spec.ts', '.test.ts', '.spec.js', '.test.js', '.spec.tsx', '.test.tsx'];
17
17
  const GO_TEST_SUFFIX = '_test.go';
18
+ /**
19
+ * Test category directories that organize tests but aren't feature families.
20
+ * Test-only families matching these names are excluded.
21
+ */
22
+ const TEST_CATEGORY_DIRS = new Set([
23
+ 'specs', 'spec', 'accessibility', 'visual', 'smoke', 'regression',
24
+ 'integration', 'functional', 'unit', 'e2e', 'performance', 'load',
25
+ ]);
26
+ /**
27
+ * Structural directories that are code-organization concerns, not feature families.
28
+ * Discovered source dirs matching these names are excluded from family creation.
29
+ */
30
+ const STRUCTURAL_DIRS = new Set([
31
+ 'actions', 'client', 'components', 'hooks', 'i18n', 'packages',
32
+ 'reducers', 'selectors', 'store', 'stores', 'tests', 'types',
33
+ 'utils', 'helpers', 'lib', 'common', 'shared', 'constants',
34
+ 'config', 'styles', 'sass', 'css', 'assets', 'images', 'fonts',
35
+ 'middleware', 'contexts', 'providers', 'layouts', 'templates',
36
+ ]);
37
+ /**
38
+ * Server Go files that are infrastructure / cross-cutting concerns,
39
+ * not feature-specific domains. Matched after stripping _local/_store suffixes.
40
+ */
41
+ const SERVER_INFRA_FILES = new Set([
42
+ 'api', 'apitestlib', 'context', 'helpers', 'params', 'swagger',
43
+ 'app', 'server', 'enterprise', 'product_service', 'security_update_check',
44
+ 'store', 'adapters', 'errors', 'integrity', 'migrate', 'doc',
45
+ 'main', 'init', 'cluster_discovery', 'web_conn', 'web_broadcast_hooks',
46
+ 'manualtesting', 'testlib', 'router', 'handler', 'opentracing',
47
+ 'platform', 'focalboard', 'playbooks', 'client4', 'model',
48
+ 'manifest', 'permission', 'log', 'utils',
49
+ ]);
50
+ /**
51
+ * Server tier directories to scan for Go domain files.
52
+ * Each tier represents a layer of the backend architecture.
53
+ */
54
+ const SERVER_TIERS = [
55
+ 'channels/api4',
56
+ 'channels/app',
57
+ 'channels/store/sqlstore',
58
+ 'channels/web',
59
+ 'channels/wsapi',
60
+ 'public/model',
61
+ ];
18
62
  /** Type-safe includes check for readonly arrays */
19
63
  const includes = (arr, v) => arr.includes(v);
20
64
  function isSkipped(name) {
@@ -314,10 +358,273 @@ function detectFeatures(familyId, group, projectRoot) {
314
358
  }
315
359
  return features;
316
360
  }
317
- export function scanProject(projectRoot) {
361
+ /**
362
+ * Discover families by walking the test directory tree at depth ≥ 2.
363
+ *
364
+ * This is the primary family discovery mechanism for projects where source
365
+ * code is organized by code type (components/, actions/) but tests are
366
+ * organized by feature (channels/drafts/, channels/search/).
367
+ *
368
+ * Each leaf test directory (containing spec files) at meaningful depth ≥ 2
369
+ * becomes a candidate family. Top-level feature dirs (depth 1) are already
370
+ * discovered by the standard `discoverTestDirs` + `groupByFamily` pipeline.
371
+ */
372
+ /**
373
+ * Normalize a Go filename into a family domain identifier.
374
+ * Strips _local, _store, trailing 's' (plurals), and normalizes casing.
375
+ */
376
+ function normalizeServerDomain(baseName) {
377
+ let name = baseName;
378
+ // Strip common suffixes
379
+ name = name.replace(/_local$/, '');
380
+ name = name.replace(/_store$/, '');
381
+ // Skip very short names (e.g., single-letter files)
382
+ if (name.length < 3)
383
+ return null;
384
+ return normalizeId(name);
385
+ }
386
+ /**
387
+ * Given a domain name like "channel_bookmark", find its parent domain
388
+ * if a shorter prefix exists in the set (e.g., "channel").
389
+ * This groups related server files under a single family.
390
+ */
391
+ function findParentDomain(name, allDomains) {
392
+ const parts = name.split('_');
393
+ // Try progressively shorter prefixes
394
+ for (let i = parts.length - 1; i >= 1; i--) {
395
+ const candidate = parts.slice(0, i).join('_');
396
+ if (allDomains.has(candidate) && candidate !== name) {
397
+ return candidate;
398
+ }
399
+ }
400
+ return name;
401
+ }
402
+ /**
403
+ * Discover families by scanning server Go source files.
404
+ *
405
+ * The backend follows a three-tier pattern:
406
+ * api4/draft.go + app/draft.go + store/sqlstore/draft_store.go
407
+ *
408
+ * Related files are grouped under parent domains:
409
+ * channel.go, channel_bookmark.go, channel_category.go → "channel" family
410
+ *
411
+ * Each domain becomes a candidate family with precise serverPaths.
412
+ */
413
+ export function discoverServerDerivedFamilies(serverRoot) {
414
+ const resolved = resolve(serverRoot);
415
+ // First pass: collect all raw domain names across tiers
416
+ const allRawDomains = new Set();
417
+ // domain → tier → Set<file basenames>
418
+ const domainTierFiles = new Map();
419
+ function collectGoFile(entry, tierRelPath) {
420
+ if (!entry.endsWith('.go') || entry.endsWith('_test.go') || entry.startsWith('.'))
421
+ return;
422
+ const baseName = entry.replace('.go', '');
423
+ const domain = normalizeServerDomain(baseName);
424
+ if (!domain || SERVER_INFRA_FILES.has(domain))
425
+ return;
426
+ allRawDomains.add(domain);
427
+ if (!domainTierFiles.has(domain))
428
+ domainTierFiles.set(domain, new Map());
429
+ const tierMap = domainTierFiles.get(domain);
430
+ if (!tierMap.has(tierRelPath))
431
+ tierMap.set(tierRelPath, new Set());
432
+ tierMap.get(tierRelPath).add(baseName);
433
+ }
434
+ for (const tier of SERVER_TIERS) {
435
+ const tierPath = join(resolved, tier);
436
+ if (!existsSync(tierPath))
437
+ continue;
438
+ let entries;
439
+ try {
440
+ entries = readdirSync(tierPath);
441
+ }
442
+ catch {
443
+ continue;
444
+ }
445
+ for (const entry of entries) {
446
+ collectGoFile(entry, tier);
447
+ // Also check subdirectories (e.g., app/slashcommands/, app/users/)
448
+ const subPath = join(tierPath, entry);
449
+ try {
450
+ const stat = lstatSync(subPath);
451
+ if (stat.isDirectory() && !isSkipped(entry)) {
452
+ const subEntries = readdirSync(subPath);
453
+ for (const subEntry of subEntries) {
454
+ collectGoFile(subEntry, `${tier}/${entry}`);
455
+ }
456
+ }
457
+ }
458
+ catch { /* skip */ }
459
+ }
460
+ }
461
+ // Scan job directories — each subdirectory is a job type
462
+ const jobsPath = join(resolved, 'channels/jobs');
463
+ if (existsSync(jobsPath)) {
464
+ try {
465
+ for (const entry of readdirSync(jobsPath)) {
466
+ const jobPath = join(jobsPath, entry);
467
+ try {
468
+ if (!lstatSync(jobPath).isDirectory() || isSkipped(entry))
469
+ continue;
470
+ const domain = normalizeId(entry);
471
+ if (SERVER_INFRA_FILES.has(domain))
472
+ continue;
473
+ allRawDomains.add(domain);
474
+ const jobFiles = readdirSync(jobPath);
475
+ for (const jf of jobFiles) {
476
+ if (jf.endsWith('.go') && !jf.endsWith('_test.go')) {
477
+ if (!domainTierFiles.has(domain))
478
+ domainTierFiles.set(domain, new Map());
479
+ const tierMap = domainTierFiles.get(domain);
480
+ const tierKey = `channels/jobs/${entry}`;
481
+ if (!tierMap.has(tierKey))
482
+ tierMap.set(tierKey, new Set());
483
+ tierMap.get(tierKey).add(jf.replace('.go', ''));
484
+ }
485
+ }
486
+ }
487
+ catch { /* skip */ }
488
+ }
489
+ }
490
+ catch { /* skip */ }
491
+ }
492
+ // Second pass: group child domains under parents
493
+ // e.g., channel_bookmark → channel, post_priority → post
494
+ // Track which top-level tiers each family touches for significance filtering.
495
+ const familyPaths = new Map();
496
+ const familyTiers = new Map();
497
+ for (const [domain, tierMap] of domainTierFiles) {
498
+ const parentDomain = findParentDomain(domain, allRawDomains);
499
+ if (!familyPaths.has(parentDomain))
500
+ familyPaths.set(parentDomain, new Set());
501
+ if (!familyTiers.has(parentDomain))
502
+ familyTiers.set(parentDomain, new Set());
503
+ const paths = familyPaths.get(parentDomain);
504
+ const tiers = familyTiers.get(parentDomain);
505
+ for (const [tierRelPath, fileNames] of tierMap) {
506
+ // Track the top-level tier (e.g., "channels/api4" from "channels/api4/slashcommands")
507
+ const topTier = tierRelPath.split('/').slice(0, 2).join('/');
508
+ tiers.add(topTier);
509
+ for (const baseName of fileNames) {
510
+ // Use directory-level glob to capture the file and related variants
511
+ paths.add(`server/${tierRelPath}/${baseName}*.go`);
512
+ }
513
+ }
514
+ }
515
+ // Build families from grouped domains.
516
+ // Only include server-only families that span ≥ 2 tiers (architecturally significant).
517
+ const families = [];
518
+ for (const [domain, paths] of familyPaths) {
519
+ if (paths.size === 0)
520
+ continue;
521
+ const tierCount = familyTiers.get(domain)?.size ?? 0;
522
+ if (tierCount < 2)
523
+ continue; // Skip single-tier domains (likely infrastructure)
524
+ families.push({
525
+ id: domain,
526
+ routes: [`/${domain.replace(/_/g, '-')}`],
527
+ webappPaths: [],
528
+ serverPaths: Array.from(paths),
529
+ specDirs: [],
530
+ cypressSpecDirs: [],
531
+ tags: [],
532
+ features: [],
533
+ routesGuessed: true,
534
+ });
535
+ }
536
+ return families;
537
+ }
538
+ export function discoverTestDerivedFamilies(testsRoot) {
539
+ const resolved = resolve(testsRoot);
540
+ const candidates = [];
541
+ function walk(dir, depth) {
542
+ if (depth > 8)
543
+ return;
544
+ let entries;
545
+ try {
546
+ entries = readdirSync(dir);
547
+ }
548
+ catch {
549
+ return;
550
+ }
551
+ const hasSpecs = entries.some((e) => TEST_EXTENSIONS.some((ext) => e.endsWith(ext)) || e.endsWith(GO_TEST_SUFFIX));
552
+ const subdirs = entries.filter((e) => {
553
+ if (isSkipped(e))
554
+ return false;
555
+ try {
556
+ const stat = lstatSync(join(dir, e));
557
+ return !stat.isSymbolicLink() && stat.isDirectory();
558
+ }
559
+ catch {
560
+ return false;
561
+ }
562
+ });
563
+ const relPath = relative(resolved, dir).replace(/\\/g, '/');
564
+ const parts = relPath.split('/').filter(Boolean);
565
+ const meaningful = parts.filter((p) => !TEST_CATEGORY_DIRS.has(normalizeId(p)) && !isSkipped(p));
566
+ // Depth-2+ meaningful dirs with spec files → candidate families
567
+ if (meaningful.length >= 2 && hasSpecs) {
568
+ const leafId = normalizeId(meaningful[meaningful.length - 1]);
569
+ const parentId = normalizeId(meaningful[meaningful.length - 2]);
570
+ if (!STRUCTURAL_DIRS.has(leafId) && !TEST_CATEGORY_DIRS.has(leafId)) {
571
+ candidates.push({ dir, relPath, leafId, parentId });
572
+ }
573
+ }
574
+ for (const sub of subdirs) {
575
+ walk(join(dir, sub), depth + 1);
576
+ }
577
+ }
578
+ // Walk from standard test roots
579
+ const testRoots = ['tests', 'test', 'e2e-tests', 'e2e', 'specs', 'spec'];
580
+ for (const root of testRoots) {
581
+ const rootPath = join(resolved, root);
582
+ if (existsSync(rootPath)) {
583
+ walk(rootPath, 0);
584
+ }
585
+ }
586
+ // Detect leaf-name collisions across parents
587
+ const idCount = new Map();
588
+ for (const c of candidates) {
589
+ idCount.set(c.leafId, (idCount.get(c.leafId) || 0) + 1);
590
+ }
591
+ // Build families — prefix with parent when names collide
592
+ const familyMap = new Map();
593
+ for (const c of candidates) {
594
+ let familyId = c.leafId;
595
+ if ((idCount.get(c.leafId) || 0) > 1 && c.parentId) {
596
+ familyId = `${c.parentId}_${c.leafId}`;
597
+ }
598
+ if (!familyMap.has(familyId)) {
599
+ const specFiles = getSpecFiles(c.dir);
600
+ familyMap.set(familyId, {
601
+ id: familyId,
602
+ routes: [`/${familyId.replace(/_/g, '-')}`],
603
+ webappPaths: [],
604
+ serverPaths: [],
605
+ specDirs: [c.relPath + '/'],
606
+ cypressSpecDirs: [],
607
+ tags: extractTags(specFiles),
608
+ features: [],
609
+ routesGuessed: true,
610
+ });
611
+ }
612
+ else {
613
+ const existing = familyMap.get(familyId);
614
+ const specDir = c.relPath + '/';
615
+ if (!existing.specDirs.includes(specDir)) {
616
+ existing.specDirs.push(specDir);
617
+ existing.tags = [...new Set([...existing.tags, ...extractTags(getSpecFiles(c.dir))])];
618
+ }
619
+ }
620
+ }
621
+ return Array.from(familyMap.values());
622
+ }
623
+ export function scanProject(projectRoot, testsRoot, serverRoot) {
318
624
  const resolved = resolve(projectRoot);
625
+ const resolvedTestsRoot = testsRoot ? resolve(testsRoot) : resolved;
319
626
  const sourceDirs = discoverSourceDirs(resolved);
320
- const testDirs = discoverTestDirs(resolved);
627
+ const testDirs = discoverTestDirs(resolvedTestsRoot);
321
628
  const allDirs = [...sourceDirs, ...testDirs];
322
629
  const groups = groupByFamily(allDirs);
323
630
  const families = [];
@@ -326,6 +633,13 @@ export function scanProject(projectRoot) {
326
633
  const hasTests = group.test.length > 0 || group.cypress.length > 0;
327
634
  if (!hasSrc && !hasTests)
328
635
  continue;
636
+ // Skip structural directories that are code-organization, not features.
637
+ // Only skip if they have source dirs but no corresponding test dirs.
638
+ if (STRUCTURAL_DIRS.has(familyId) && !hasTests)
639
+ continue;
640
+ // Skip test-only families that match broad test categories (not feature families).
641
+ if (!hasSrc && hasTests && TEST_CATEGORY_DIRS.has(familyId))
642
+ continue;
329
643
  const allSpecFiles = [];
330
644
  for (const td of [...group.test, ...group.cypress]) {
331
645
  allSpecFiles.push(...getSpecFiles(td.path));
@@ -343,6 +657,58 @@ export function scanProject(projectRoot) {
343
657
  routesGuessed: true,
344
658
  });
345
659
  }
660
+ // When a separate testsRoot is provided, discover families from test
661
+ // directory structure. Projects with feature-organized tests but
662
+ // code-type-organized source benefit from this.
663
+ if (testsRoot) {
664
+ const testFamilies = discoverTestDerivedFamilies(resolvedTestsRoot);
665
+ const existingIds = new Set(families.map((f) => f.id));
666
+ for (const tf of testFamilies) {
667
+ if (existingIds.has(tf.id)) {
668
+ // Merge specDirs into existing family
669
+ const existing = families.find((f) => f.id === tf.id);
670
+ for (const sd of tf.specDirs) {
671
+ if (!existing.specDirs.includes(sd)) {
672
+ existing.specDirs.push(sd);
673
+ }
674
+ }
675
+ existing.tags = [...new Set([...existing.tags, ...tf.tags])];
676
+ }
677
+ else {
678
+ families.push(tf);
679
+ existingIds.add(tf.id);
680
+ }
681
+ }
682
+ }
683
+ // When a separate serverRoot is provided, discover families from Go source
684
+ // filenames across the three-tier backend (api4, app, store).
685
+ if (serverRoot) {
686
+ const serverFamilies = discoverServerDerivedFamilies(resolve(serverRoot));
687
+ const existingIds = new Set(families.map((f) => f.id));
688
+ for (const sf of serverFamilies) {
689
+ // Try exact match, then singular/plural variants
690
+ let target = families.find((f) => f.id === sf.id);
691
+ if (!target && !sf.id.endsWith('s')) {
692
+ target = families.find((f) => f.id === sf.id + 's');
693
+ }
694
+ if (!target && sf.id.endsWith('s')) {
695
+ target = families.find((f) => f.id === sf.id.slice(0, -1));
696
+ }
697
+ if (target) {
698
+ // Merge serverPaths into existing family
699
+ for (const sp of sf.serverPaths) {
700
+ if (!target.serverPaths.includes(sp)) {
701
+ target.serverPaths.push(sp);
702
+ }
703
+ }
704
+ }
705
+ else {
706
+ // New server-only family
707
+ families.push(sf);
708
+ existingIds.add(sf.id);
709
+ }
710
+ }
711
+ }
346
712
  const familyIds = new Set(families.map((f) => f.id));
347
713
  const unmatchedSourceDirs = sourceDirs.filter((d) => !familyIds.has(normalizeId(d.familyHint)));
348
714
  const unmatchedTestDirs = testDirs.filter((d) => !familyIds.has(normalizeId(d.familyHint)));
@@ -93,3 +93,4 @@ export function computeOverallConfidence(decisions) {
93
93
  const avgConfidence = actionable.reduce((sum, d) => sum + d.confidence, 0) / actionable.length;
94
94
  return classifyConfidence(avgConfidence);
95
95
  }
96
+ export { compileCheckSpec, smokeRunSpec } from '../pipeline/spec_verifier.js';
package/dist/index.d.ts CHANGED
@@ -24,8 +24,8 @@ export { analyzeImpact as analyzeImpactV2, getGaps, getPartialGaps } from './eng
24
24
  export type { ImpactResult, ImpactedFeature, CoverageStatus, ImpactEngineOptions, SpecWithScenarios } from './engine/impact_engine.js';
25
25
  export { extractScenarios } from './engine/impact_engine.js';
26
26
  export { buildPlanFromImpact } from './engine/plan_builder.js';
27
- export { appendFeedbackAndRecompute, readCalibration, readFlakyTests } from './agent/feedback.js';
28
- export type { RecommendationFeedbackEntry, CalibrationSummary, FlakySummary } from './agent/feedback.js';
27
+ export { appendFeedbackAndRecompute, readCalibration, readFlakyTests, getAdaptiveThresholds } from './agent/feedback.js';
28
+ export type { RecommendationFeedbackEntry, CalibrationSummary, FlakySummary, AdaptiveThresholds } from './agent/feedback.js';
29
29
  export { finalizeGeneratedTests } from './agent/handoff.js';
30
30
  export type { FinalizeGeneratedTestsOptions, FinalizeGeneratedTestsResult } from './agent/handoff.js';
31
31
  export { ingestTraceabilityInput } from './agent/traceability_ingest.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
3
  // See LICENSE.txt for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.mergeFamilies = exports.scanProject = exports.runAgenticGeneration = exports.getSpecsForFamily = exports.buildSpecIndex = exports.loadOrBuildApiSurface = exports.buildApiSurface = exports.getUserFlowsForBinding = exports.getPriorityForBinding = exports.getCypressSpecDirsForBinding = exports.bindFilesToFamilies = exports.loadRouteFamilyManifest = exports.buildQualityFixPrompt = exports.buildHealPrompt = exports.renderHealMarkdown = exports.resolveHealTargets = exports.healFromReport = exports.runHealStage = exports.detectHallucinatedMethods = exports.parseGenerationResponse = exports.buildGenerationPrompt = exports.runGenerationStage = exports.runPipeline = exports.captureTraceabilityInput = exports.ingestTraceabilityInput = exports.finalizeGeneratedTests = exports.readFlakyTests = exports.readCalibration = exports.appendFeedbackAndRecompute = exports.buildPlanFromImpact = exports.extractScenarios = exports.getPartialGaps = exports.getGaps = exports.analyzeImpactV2 = exports.captureTraceability = exports.ingestTraceability = exports.handoffGeneratedTests = exports.recommendTestsDeterministic = exports.analyzeImpactDeterministic = exports.validateProviderSetup = exports.LLMProviderFactory = exports.CustomProvider = exports.checkOpenAISetup = exports.OpenAIProvider = exports.checkOllamaSetup = exports.OllamaProvider = exports.checkAnthropicSetup = exports.AnthropicProvider = exports.UnsupportedCapabilityError = exports.LLMProviderError = void 0;
6
- exports.formatValidationReport = exports.buildValidationReport = exports.validateCommit = exports.getCommitFiles = exports.enrichFamilies = exports.detectStaleFamilies = void 0;
5
+ exports.scanProject = exports.runAgenticGeneration = exports.getSpecsForFamily = exports.buildSpecIndex = exports.loadOrBuildApiSurface = exports.buildApiSurface = exports.getUserFlowsForBinding = exports.getPriorityForBinding = exports.getCypressSpecDirsForBinding = exports.bindFilesToFamilies = exports.loadRouteFamilyManifest = exports.buildQualityFixPrompt = exports.buildHealPrompt = exports.renderHealMarkdown = exports.resolveHealTargets = exports.healFromReport = exports.runHealStage = exports.detectHallucinatedMethods = exports.parseGenerationResponse = exports.buildGenerationPrompt = exports.runGenerationStage = exports.runPipeline = exports.captureTraceabilityInput = exports.ingestTraceabilityInput = exports.finalizeGeneratedTests = exports.getAdaptiveThresholds = exports.readFlakyTests = exports.readCalibration = exports.appendFeedbackAndRecompute = exports.buildPlanFromImpact = exports.extractScenarios = exports.getPartialGaps = exports.getGaps = exports.analyzeImpactV2 = exports.captureTraceability = exports.ingestTraceability = exports.handoffGeneratedTests = exports.recommendTestsDeterministic = exports.analyzeImpactDeterministic = exports.validateProviderSetup = exports.LLMProviderFactory = exports.CustomProvider = exports.checkOpenAISetup = exports.OpenAIProvider = exports.checkOllamaSetup = exports.OllamaProvider = exports.checkAnthropicSetup = exports.AnthropicProvider = exports.UnsupportedCapabilityError = exports.LLMProviderError = void 0;
6
+ exports.formatValidationReport = exports.buildValidationReport = exports.validateCommit = exports.getCommitFiles = exports.enrichFamilies = exports.detectStaleFamilies = exports.mergeFamilies = void 0;
7
7
  var provider_interface_js_1 = require("./provider_interface.js");
8
8
  Object.defineProperty(exports, "LLMProviderError", { enumerable: true, get: function () { return provider_interface_js_1.LLMProviderError; } });
9
9
  Object.defineProperty(exports, "UnsupportedCapabilityError", { enumerable: true, get: function () { return provider_interface_js_1.UnsupportedCapabilityError; } });
@@ -43,6 +43,7 @@ var feedback_js_1 = require("./agent/feedback.js");
43
43
  Object.defineProperty(exports, "appendFeedbackAndRecompute", { enumerable: true, get: function () { return feedback_js_1.appendFeedbackAndRecompute; } });
44
44
  Object.defineProperty(exports, "readCalibration", { enumerable: true, get: function () { return feedback_js_1.readCalibration; } });
45
45
  Object.defineProperty(exports, "readFlakyTests", { enumerable: true, get: function () { return feedback_js_1.readFlakyTests; } });
46
+ Object.defineProperty(exports, "getAdaptiveThresholds", { enumerable: true, get: function () { return feedback_js_1.getAdaptiveThresholds; } });
46
47
  var handoff_js_1 = require("./agent/handoff.js");
47
48
  Object.defineProperty(exports, "finalizeGeneratedTests", { enumerable: true, get: function () { return handoff_js_1.finalizeGeneratedTests; } });
48
49
  var traceability_ingest_js_1 = require("./agent/traceability_ingest.js");
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/pipeline/orchestrator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiB,KAAK,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAmB,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAC,MAAM,wBAAwB,CAAC;AACrG,OAAO,EAAuD,KAAK,UAAU,EAAE,KAAK,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAe,KAAK,kBAAkB,EAAoB,MAAM,gCAAgC,CAAC;AAExG,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,cAAc;IAC3B,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,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iEAAiE;IACjE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;CAChF;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;CAC3B;AAqBD,wBAAsB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAgIjF"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/pipeline/orchestrator.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,KAAK,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAmB,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAC,MAAM,wBAAwB,CAAC;AACrG,OAAO,EAAuD,KAAK,UAAU,EAAE,KAAK,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAe,KAAK,kBAAkB,EAAoB,MAAM,gCAAgC,CAAC;AAExG,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,cAAc;IAC3B,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,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iEAAiE;IACjE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;CAChF;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;CAC3B;AAqBD,wBAAsB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAgIjF"}
@@ -0,0 +1,20 @@
1
+ export interface CompileCheckResult {
2
+ success: boolean;
3
+ errors: string[];
4
+ }
5
+ /**
6
+ * Compile-check a generated spec file using tsc --noEmit.
7
+ * Returns success: true if compilation succeeds, or errors array on failure.
8
+ */
9
+ export declare function compileCheckSpec(specPath: string, testsRoot: string): CompileCheckResult;
10
+ export interface SmokeRunResult {
11
+ success: boolean;
12
+ error?: string;
13
+ }
14
+ /**
15
+ * Smoke-run a generated spec against a running app.
16
+ * Runs in a restricted environment with sensitive env vars stripped.
17
+ * Returns success: true if the test passes with retries.
18
+ */
19
+ export declare function smokeRunSpec(specPath: string, testsRoot: string, playwrightBinary: string): SmokeRunResult;
20
+ //# sourceMappingURL=spec_verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec_verifier.d.ts","sourceRoot":"","sources":["../../src/pipeline/spec_verifier.ts"],"names":[],"mappings":"AAyCA,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAuBxF;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACzB,cAAc,CAuBhB"}
@@ -0,0 +1,79 @@
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.compileCheckSpec = compileCheckSpec;
6
+ exports.smokeRunSpec = smokeRunSpec;
7
+ const path_1 = require("path");
8
+ const process_runner_js_1 = require("../agent/process_runner.js");
9
+ /** Env var prefixes/names stripped when running LLM-generated specs */
10
+ const SENSITIVE_ENV_PREFIXES = [
11
+ 'AWS_', 'AZURE_', 'GCP_', 'GOOGLE_', 'ANTHROPIC_', 'OPENAI_',
12
+ 'GITHUB_TOKEN', 'NPM_TOKEN', 'SSH_', 'SECRET_', 'PRIVATE_',
13
+ 'DATABASE_URL', 'DB_', 'REDIS_', 'POSTGRES_', 'MYSQL_', 'MONGO_',
14
+ 'API_KEY', 'API_SECRET', 'AUTH_', 'JWT_', 'STRIPE_', 'TWILIO_',
15
+ 'SENDGRID_', 'SLACK_TOKEN', 'SLACK_BOT', 'MATTERMOST_',
16
+ ];
17
+ /**
18
+ * Build a restricted environment for running LLM-generated spec files.
19
+ * Strips credentials and secrets to limit damage from malicious generated code.
20
+ */
21
+ function buildRestrictedEnv() {
22
+ const env = {};
23
+ for (const [key, value] of Object.entries(process.env)) {
24
+ const isSensitive = SENSITIVE_ENV_PREFIXES.some((prefix) => key.startsWith(prefix));
25
+ if (!isSensitive) {
26
+ env[key] = value;
27
+ }
28
+ }
29
+ return env;
30
+ }
31
+ /**
32
+ * Validate and normalize a spec path to prevent argument injection.
33
+ * Rejects raw input that starts with '-' (could be interpreted as flags by tsc/playwright).
34
+ */
35
+ function sanitizeSpecPath(specPath) {
36
+ if (specPath.startsWith('-')) {
37
+ throw new Error(`Invalid spec path: "${specPath}" — path must not start with a dash`);
38
+ }
39
+ return (0, path_1.resolve)(specPath);
40
+ }
41
+ /**
42
+ * Compile-check a generated spec file using tsc --noEmit.
43
+ * Returns success: true if compilation succeeds, or errors array on failure.
44
+ */
45
+ function compileCheckSpec(specPath, testsRoot) {
46
+ const safeSpecPath = sanitizeSpecPath(specPath);
47
+ const result = (0, process_runner_js_1.runCommand)('npx', ['tsc', '--noEmit', '--esModuleInterop', '--resolveJsonModule', '--moduleResolution', 'node', '--target', 'ES2020', safeSpecPath], testsRoot, 30000, buildRestrictedEnv());
48
+ if (result.status === 0) {
49
+ return { success: true, errors: [] };
50
+ }
51
+ const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
52
+ const errorLines = output.split('\n')
53
+ .filter((l) => l.includes('error TS') || l.includes('Error:'))
54
+ .slice(0, 10);
55
+ return {
56
+ success: false,
57
+ errors: errorLines.length > 0 ? errorLines : [output.slice(0, 500) || 'Compilation failed'],
58
+ };
59
+ }
60
+ /**
61
+ * Smoke-run a generated spec against a running app.
62
+ * Runs in a restricted environment with sensitive env vars stripped.
63
+ * Returns success: true if the test passes with retries.
64
+ */
65
+ function smokeRunSpec(specPath, testsRoot, playwrightBinary) {
66
+ const safeSpecPath = sanitizeSpecPath(specPath);
67
+ const result = (0, process_runner_js_1.runCommand)(playwrightBinary, ['test', safeSpecPath, '--retries', '2', '--reporter', 'list'], testsRoot, 120000, buildRestrictedEnv());
68
+ if (result.status === 0) {
69
+ return { success: true };
70
+ }
71
+ const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
72
+ const errorLines = output.split('\n')
73
+ .filter((l) => l.includes('Error') || l.includes('FAILED') || l.includes('Timeout'))
74
+ .slice(0, 5);
75
+ return {
76
+ success: false,
77
+ error: errorLines.join('\n') || result.error || 'Smoke run failed',
78
+ };
79
+ }
@@ -19,12 +19,22 @@ export interface GeneratedSpec {
19
19
  mode: 'create_spec' | 'add_scenarios';
20
20
  written: boolean;
21
21
  hallucinationWarnings: string[];
22
+ /** Whether the spec passed compile + smoke-run verification */
23
+ verified?: boolean;
24
+ /** If verification failed, the reason */
25
+ verificationError?: string;
22
26
  }
23
27
  export interface GenerationResult {
24
28
  generated: GeneratedSpec[];
25
29
  skipped: string[];
26
30
  warnings: string[];
27
31
  providerName: string;
32
+ /** Total number of specs generated */
33
+ generatedCount: number;
34
+ /** Number that passed compile + smoke-run */
35
+ verifiedCount: number;
36
+ /** Number that failed verification */
37
+ failedCount: number;
28
38
  }
29
39
  export declare function runGenerationStage(decisions: FlowDecision[], apiSurface: ApiSurfaceCatalog, testsRoot: string, config: GenerationConfig): Promise<GenerationResult>;
30
40
  export { loadSpecFileContent };
@@ -1 +1 @@
1
- {"version":3,"file":"stage3_generation.d.ts","sourceRoot":"","sources":["../../src/pipeline/stage3_generation.ts"],"names":[],"mappings":"AAQA,OAAO,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,aAAa,GAAG,eAAe,CAAC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACxB;AAyCD,wBAAsB,kBAAkB,CACpC,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,iBAAiB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAwH3B;AAGD,OAAO,EAAC,mBAAmB,EAAC,CAAC"}
1
+ {"version":3,"file":"stage3_generation.d.ts","sourceRoot":"","sources":["../../src/pipeline/stage3_generation.ts"],"names":[],"mappings":"AAQA,OAAO,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAInE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,aAAa,GAAG,eAAe,CAAC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;CACvB;AAyCD,wBAAsB,kBAAkB,CACpC,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,iBAAiB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CA0I3B;AAqHD,OAAO,EAAC,mBAAmB,EAAC,CAAC"}