@yasserkhanorg/e2e-agents 0.3.2

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 (221) hide show
  1. package/LICENSE +168 -0
  2. package/README.md +620 -0
  3. package/dist/agent/analysis.d.ts +62 -0
  4. package/dist/agent/analysis.d.ts.map +1 -0
  5. package/dist/agent/analysis.js +292 -0
  6. package/dist/agent/blast_radius.d.ts +4 -0
  7. package/dist/agent/blast_radius.d.ts.map +1 -0
  8. package/dist/agent/blast_radius.js +37 -0
  9. package/dist/agent/cache_utils.d.ts +38 -0
  10. package/dist/agent/cache_utils.d.ts.map +1 -0
  11. package/dist/agent/cache_utils.js +67 -0
  12. package/dist/agent/config.d.ts +148 -0
  13. package/dist/agent/config.d.ts.map +1 -0
  14. package/dist/agent/config.js +640 -0
  15. package/dist/agent/dependency_graph.d.ts +14 -0
  16. package/dist/agent/dependency_graph.d.ts.map +1 -0
  17. package/dist/agent/dependency_graph.js +227 -0
  18. package/dist/agent/feedback.d.ts +55 -0
  19. package/dist/agent/feedback.d.ts.map +1 -0
  20. package/dist/agent/feedback.js +257 -0
  21. package/dist/agent/flags.d.ts +23 -0
  22. package/dist/agent/flags.d.ts.map +1 -0
  23. package/dist/agent/flags.js +171 -0
  24. package/dist/agent/flow_catalog.d.ts +25 -0
  25. package/dist/agent/flow_catalog.d.ts.map +1 -0
  26. package/dist/agent/flow_catalog.js +106 -0
  27. package/dist/agent/flow_mapping.d.ts +10 -0
  28. package/dist/agent/flow_mapping.d.ts.map +1 -0
  29. package/dist/agent/flow_mapping.js +84 -0
  30. package/dist/agent/framework.d.ts +13 -0
  31. package/dist/agent/framework.d.ts.map +1 -0
  32. package/dist/agent/framework.js +149 -0
  33. package/dist/agent/gap_suggestions.d.ts +14 -0
  34. package/dist/agent/gap_suggestions.d.ts.map +1 -0
  35. package/dist/agent/gap_suggestions.js +101 -0
  36. package/dist/agent/generator.d.ts +10 -0
  37. package/dist/agent/generator.d.ts.map +1 -0
  38. package/dist/agent/generator.js +115 -0
  39. package/dist/agent/git.d.ts +11 -0
  40. package/dist/agent/git.d.ts.map +1 -0
  41. package/dist/agent/git.js +90 -0
  42. package/dist/agent/handoff.d.ts +22 -0
  43. package/dist/agent/handoff.d.ts.map +1 -0
  44. package/dist/agent/handoff.js +180 -0
  45. package/dist/agent/impact-analyzer.d.ts +114 -0
  46. package/dist/agent/impact-analyzer.d.ts.map +1 -0
  47. package/dist/agent/impact-analyzer.js +557 -0
  48. package/dist/agent/index.d.ts +21 -0
  49. package/dist/agent/index.d.ts.map +1 -0
  50. package/dist/agent/index.js +38 -0
  51. package/dist/agent/model-router.d.ts +57 -0
  52. package/dist/agent/model-router.d.ts.map +1 -0
  53. package/dist/agent/model-router.js +154 -0
  54. package/dist/agent/operational_insights.d.ts +41 -0
  55. package/dist/agent/operational_insights.d.ts.map +1 -0
  56. package/dist/agent/operational_insights.js +126 -0
  57. package/dist/agent/pipeline.d.ts +23 -0
  58. package/dist/agent/pipeline.d.ts.map +1 -0
  59. package/dist/agent/pipeline.js +609 -0
  60. package/dist/agent/plan.d.ts +91 -0
  61. package/dist/agent/plan.d.ts.map +1 -0
  62. package/dist/agent/plan.js +331 -0
  63. package/dist/agent/playwright_report.d.ts +8 -0
  64. package/dist/agent/playwright_report.d.ts.map +1 -0
  65. package/dist/agent/playwright_report.js +126 -0
  66. package/dist/agent/report-generator.d.ts +24 -0
  67. package/dist/agent/report-generator.d.ts.map +1 -0
  68. package/dist/agent/report-generator.js +250 -0
  69. package/dist/agent/report.d.ts +81 -0
  70. package/dist/agent/report.d.ts.map +1 -0
  71. package/dist/agent/report.js +147 -0
  72. package/dist/agent/runner.d.ts +7 -0
  73. package/dist/agent/runner.d.ts.map +1 -0
  74. package/dist/agent/runner.js +576 -0
  75. package/dist/agent/selectors.d.ts +10 -0
  76. package/dist/agent/selectors.d.ts.map +1 -0
  77. package/dist/agent/selectors.js +75 -0
  78. package/dist/agent/spec-bridge.d.ts +101 -0
  79. package/dist/agent/spec-bridge.d.ts.map +1 -0
  80. package/dist/agent/spec-bridge.js +273 -0
  81. package/dist/agent/spec-builder.d.ts +102 -0
  82. package/dist/agent/spec-builder.d.ts.map +1 -0
  83. package/dist/agent/spec-builder.js +273 -0
  84. package/dist/agent/subsystem_risk.d.ts +23 -0
  85. package/dist/agent/subsystem_risk.d.ts.map +1 -0
  86. package/dist/agent/subsystem_risk.js +207 -0
  87. package/dist/agent/telemetry.d.ts +84 -0
  88. package/dist/agent/telemetry.d.ts.map +1 -0
  89. package/dist/agent/telemetry.js +220 -0
  90. package/dist/agent/test_path.d.ts +2 -0
  91. package/dist/agent/test_path.d.ts.map +1 -0
  92. package/dist/agent/test_path.js +23 -0
  93. package/dist/agent/tests.d.ts +18 -0
  94. package/dist/agent/tests.d.ts.map +1 -0
  95. package/dist/agent/tests.js +106 -0
  96. package/dist/agent/traceability.d.ts +22 -0
  97. package/dist/agent/traceability.d.ts.map +1 -0
  98. package/dist/agent/traceability.js +183 -0
  99. package/dist/agent/traceability_capture.d.ts +18 -0
  100. package/dist/agent/traceability_capture.d.ts.map +1 -0
  101. package/dist/agent/traceability_capture.js +313 -0
  102. package/dist/agent/traceability_ingest.d.ts +21 -0
  103. package/dist/agent/traceability_ingest.d.ts.map +1 -0
  104. package/dist/agent/traceability_ingest.js +237 -0
  105. package/dist/agent/utils.d.ts +13 -0
  106. package/dist/agent/utils.d.ts.map +1 -0
  107. package/dist/agent/utils.js +152 -0
  108. package/dist/agent/validators/selector-validator.d.ts +74 -0
  109. package/dist/agent/validators/selector-validator.d.ts.map +1 -0
  110. package/dist/agent/validators/selector-validator.js +165 -0
  111. package/dist/anthropic_provider.d.ts +65 -0
  112. package/dist/anthropic_provider.d.ts.map +1 -0
  113. package/dist/anthropic_provider.js +332 -0
  114. package/dist/api.d.ts +48 -0
  115. package/dist/api.d.ts.map +1 -0
  116. package/dist/api.js +113 -0
  117. package/dist/base_provider.d.ts +53 -0
  118. package/dist/base_provider.d.ts.map +1 -0
  119. package/dist/base_provider.js +81 -0
  120. package/dist/cli.d.ts +3 -0
  121. package/dist/cli.d.ts.map +1 -0
  122. package/dist/cli.js +843 -0
  123. package/dist/custom_provider.d.ts +20 -0
  124. package/dist/custom_provider.d.ts.map +1 -0
  125. package/dist/custom_provider.js +276 -0
  126. package/dist/e2e-test-gen/index.d.ts +51 -0
  127. package/dist/e2e-test-gen/index.d.ts.map +1 -0
  128. package/dist/e2e-test-gen/index.js +57 -0
  129. package/dist/e2e-test-gen/spec_parser.d.ts +142 -0
  130. package/dist/e2e-test-gen/spec_parser.d.ts.map +1 -0
  131. package/dist/e2e-test-gen/spec_parser.js +786 -0
  132. package/dist/e2e-test-gen/types.d.ts +185 -0
  133. package/dist/e2e-test-gen/types.d.ts.map +1 -0
  134. package/dist/e2e-test-gen/types.js +4 -0
  135. package/dist/esm/agent/analysis.js +287 -0
  136. package/dist/esm/agent/blast_radius.js +34 -0
  137. package/dist/esm/agent/cache_utils.js +63 -0
  138. package/dist/esm/agent/config.js +637 -0
  139. package/dist/esm/agent/dependency_graph.js +224 -0
  140. package/dist/esm/agent/feedback.js +253 -0
  141. package/dist/esm/agent/flags.js +160 -0
  142. package/dist/esm/agent/flow_catalog.js +103 -0
  143. package/dist/esm/agent/flow_mapping.js +81 -0
  144. package/dist/esm/agent/framework.js +145 -0
  145. package/dist/esm/agent/gap_suggestions.js +98 -0
  146. package/dist/esm/agent/generator.js +112 -0
  147. package/dist/esm/agent/git.js +87 -0
  148. package/dist/esm/agent/handoff.js +177 -0
  149. package/dist/esm/agent/impact-analyzer.js +548 -0
  150. package/dist/esm/agent/index.js +22 -0
  151. package/dist/esm/agent/model-router.js +150 -0
  152. package/dist/esm/agent/operational_insights.js +123 -0
  153. package/dist/esm/agent/pipeline.js +605 -0
  154. package/dist/esm/agent/plan.js +324 -0
  155. package/dist/esm/agent/playwright_report.js +123 -0
  156. package/dist/esm/agent/report-generator.js +247 -0
  157. package/dist/esm/agent/report.js +144 -0
  158. package/dist/esm/agent/runner.js +572 -0
  159. package/dist/esm/agent/selectors.js +71 -0
  160. package/dist/esm/agent/spec-bridge.js +267 -0
  161. package/dist/esm/agent/spec-builder.js +267 -0
  162. package/dist/esm/agent/subsystem_risk.js +204 -0
  163. package/dist/esm/agent/telemetry.js +216 -0
  164. package/dist/esm/agent/test_path.js +20 -0
  165. package/dist/esm/agent/tests.js +101 -0
  166. package/dist/esm/agent/traceability.js +180 -0
  167. package/dist/esm/agent/traceability_capture.js +310 -0
  168. package/dist/esm/agent/traceability_ingest.js +234 -0
  169. package/dist/esm/agent/utils.js +138 -0
  170. package/dist/esm/agent/validators/selector-validator.js +160 -0
  171. package/dist/esm/anthropic_provider.js +324 -0
  172. package/dist/esm/api.js +105 -0
  173. package/dist/esm/base_provider.js +77 -0
  174. package/dist/esm/cli.js +841 -0
  175. package/dist/esm/custom_provider.js +272 -0
  176. package/dist/esm/e2e-test-gen/index.js +50 -0
  177. package/dist/esm/e2e-test-gen/spec_parser.js +782 -0
  178. package/dist/esm/e2e-test-gen/types.js +3 -0
  179. package/dist/esm/index.js +16 -0
  180. package/dist/esm/logger.js +89 -0
  181. package/dist/esm/mcp-server.js +465 -0
  182. package/dist/esm/ollama_provider.js +300 -0
  183. package/dist/esm/openai_provider.js +242 -0
  184. package/dist/esm/package.json +3 -0
  185. package/dist/esm/plan-and-test-constants.js +126 -0
  186. package/dist/esm/provider_factory.js +336 -0
  187. package/dist/esm/provider_interface.js +23 -0
  188. package/dist/esm/provider_utils.js +96 -0
  189. package/dist/index.d.ts +31 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +41 -0
  192. package/dist/logger.d.ts +23 -0
  193. package/dist/logger.d.ts.map +1 -0
  194. package/dist/logger.js +93 -0
  195. package/dist/mcp-server.d.ts +35 -0
  196. package/dist/mcp-server.d.ts.map +1 -0
  197. package/dist/mcp-server.js +469 -0
  198. package/dist/ollama_provider.d.ts +65 -0
  199. package/dist/ollama_provider.d.ts.map +1 -0
  200. package/dist/ollama_provider.js +308 -0
  201. package/dist/openai_provider.d.ts +23 -0
  202. package/dist/openai_provider.d.ts.map +1 -0
  203. package/dist/openai_provider.js +250 -0
  204. package/dist/plan-and-test-constants.d.ts +110 -0
  205. package/dist/plan-and-test-constants.d.ts.map +1 -0
  206. package/dist/plan-and-test-constants.js +132 -0
  207. package/dist/provider_factory.d.ts +99 -0
  208. package/dist/provider_factory.d.ts.map +1 -0
  209. package/dist/provider_factory.js +341 -0
  210. package/dist/provider_interface.d.ts +358 -0
  211. package/dist/provider_interface.d.ts.map +1 -0
  212. package/dist/provider_interface.js +28 -0
  213. package/dist/provider_utils.d.ts +39 -0
  214. package/dist/provider_utils.d.ts.map +1 -0
  215. package/dist/provider_utils.js +103 -0
  216. package/package.json +101 -0
  217. package/schemas/gap.schema.json +18 -0
  218. package/schemas/impact.schema.json +418 -0
  219. package/schemas/plan.schema.json +285 -0
  220. package/schemas/subsystem-risk-map.schema.json +62 -0
  221. package/schemas/traceability-input.schema.json +122 -0
@@ -0,0 +1,177 @@
1
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2
+ // See LICENSE.txt for license information.
3
+ import { execFileSync } from 'child_process';
4
+ import { existsSync, readFileSync } from 'fs';
5
+ import { relative, resolve } from 'path';
6
+ function runCommand(bin, args, cwd, opts = {}) {
7
+ try {
8
+ const stdout = execFileSync(bin, args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
9
+ return { ok: true, stdout: stdout.trim(), stderr: '' };
10
+ }
11
+ catch (error) {
12
+ if (opts.allowFailure) {
13
+ const cause = error;
14
+ const stdout = typeof cause.stdout === 'string' ? cause.stdout : cause.stdout?.toString('utf-8') || '';
15
+ const stderr = typeof cause.stderr === 'string' ? cause.stderr : cause.stderr?.toString('utf-8') || cause.message || '';
16
+ return { ok: false, stdout: stdout.trim(), stderr: stderr.trim() };
17
+ }
18
+ throw error;
19
+ }
20
+ }
21
+ function normalizeBranchName(branch) {
22
+ if (!branch || !branch.trim()) {
23
+ return undefined;
24
+ }
25
+ const trimmed = branch.trim();
26
+ if (trimmed.startsWith('codex/')) {
27
+ return trimmed;
28
+ }
29
+ return `codex/${trimmed.replace(/^\/+/, '')}`;
30
+ }
31
+ function resolveRepoRoot(appPath) {
32
+ const abs = resolve(appPath);
33
+ const result = runCommand('git', ['-C', abs, 'rev-parse', '--show-toplevel'], abs, { allowFailure: true });
34
+ if (!result.ok || !result.stdout) {
35
+ throw new Error(`Unable to find git repository root from ${abs}: ${result.stderr || 'git rev-parse failed'}`);
36
+ }
37
+ return result.stdout;
38
+ }
39
+ function readGapReport(path) {
40
+ if (!existsSync(path)) {
41
+ throw new Error(`Gap report not found: ${path}`);
42
+ }
43
+ try {
44
+ return JSON.parse(readFileSync(path, 'utf-8'));
45
+ }
46
+ catch (error) {
47
+ const message = error instanceof Error ? error.message : String(error);
48
+ throw new Error(`Unable to parse gap report at ${path}: ${message}`);
49
+ }
50
+ }
51
+ function uniq(values) {
52
+ return Array.from(new Set(values.filter(Boolean)));
53
+ }
54
+ function toRepoRelative(repoRoot, absoluteOrRelative) {
55
+ const absolute = resolve(absoluteOrRelative);
56
+ return relative(repoRoot, absolute) || '.';
57
+ }
58
+ function isRepoRelativePathSafe(path) {
59
+ if (!path || path === '.') {
60
+ return false;
61
+ }
62
+ if (path.startsWith('..') || path.includes('/../') || path.includes('\\..\\')) {
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+ function collectStageTargets(repoRoot, appPath, testsRoot, gap) {
68
+ const targets = [];
69
+ const applied = gap.applied || {};
70
+ for (const patched of applied.patchedFiles || []) {
71
+ targets.push(toRepoRelative(repoRoot, resolve(appPath, patched)));
72
+ }
73
+ for (const generated of applied.generatedTests || []) {
74
+ targets.push(toRepoRelative(repoRoot, generated));
75
+ }
76
+ for (const result of gap.pipeline?.results || []) {
77
+ if (result.generatedDir) {
78
+ targets.push(toRepoRelative(repoRoot, result.generatedDir));
79
+ }
80
+ }
81
+ const artifacts = ['gap.json', 'impact.json', 'plan.json', 'ci-summary.md', 'pr-comment.md'];
82
+ for (const file of artifacts) {
83
+ targets.push(toRepoRelative(repoRoot, resolve(testsRoot, '.e2e-ai-agents', file)));
84
+ }
85
+ return uniq(targets).filter((path) => isRepoRelativePathSafe(path) && existsSync(resolve(repoRoot, path)));
86
+ }
87
+ function ensureBranch(repoRoot, requestedBranch, dryRun = false) {
88
+ const current = runCommand('git', ['branch', '--show-current'], repoRoot, { allowFailure: true });
89
+ const currentBranch = current.stdout || 'HEAD';
90
+ const normalized = normalizeBranchName(requestedBranch);
91
+ if (!normalized) {
92
+ return currentBranch;
93
+ }
94
+ if (currentBranch === normalized) {
95
+ return currentBranch;
96
+ }
97
+ const exists = runCommand('git', ['rev-parse', '--verify', normalized], repoRoot, { allowFailure: true }).ok;
98
+ if (!dryRun) {
99
+ if (exists) {
100
+ runCommand('git', ['checkout', normalized], repoRoot);
101
+ }
102
+ else {
103
+ runCommand('git', ['checkout', '-b', normalized], repoRoot);
104
+ }
105
+ }
106
+ return normalized;
107
+ }
108
+ function hasStagedChanges(repoRoot) {
109
+ const result = runCommand('git', ['diff', '--cached', '--name-only'], repoRoot, { allowFailure: true });
110
+ if (!result.ok) {
111
+ return false;
112
+ }
113
+ return result.stdout.trim().length > 0;
114
+ }
115
+ export function finalizeGeneratedTests(options) {
116
+ const appPath = resolve(options.appPath);
117
+ const testsRoot = resolve(options.testsRoot || options.appPath);
118
+ const repoRoot = resolveRepoRoot(appPath);
119
+ const gapReportPath = options.gapReportPath || resolve(testsRoot, '.e2e-ai-agents', 'gap.json');
120
+ const gap = readGapReport(gapReportPath);
121
+ const stageTargets = collectStageTargets(repoRoot, appPath, testsRoot, gap);
122
+ const commitMessage = options.commitMessage || 'test(e2e): add generated coverage and healed specs';
123
+ const dryRun = Boolean(options.dryRun);
124
+ const branch = ensureBranch(repoRoot, options.branch, dryRun);
125
+ if (stageTargets.length === 0) {
126
+ return {
127
+ repoRoot,
128
+ branch,
129
+ stagedPaths: [],
130
+ committed: false,
131
+ };
132
+ }
133
+ for (const path of stageTargets) {
134
+ if (!dryRun) {
135
+ runCommand('git', ['add', '--', path], repoRoot, { allowFailure: true });
136
+ }
137
+ }
138
+ let committed = false;
139
+ let commitSha;
140
+ if (!dryRun && hasStagedChanges(repoRoot)) {
141
+ runCommand('git', ['commit', '-m', commitMessage], repoRoot);
142
+ committed = true;
143
+ const head = runCommand('git', ['rev-parse', 'HEAD'], repoRoot, { allowFailure: true });
144
+ if (head.ok) {
145
+ commitSha = head.stdout;
146
+ }
147
+ }
148
+ let prUrl;
149
+ if (!dryRun && options.createPr) {
150
+ const args = ['pr', 'create'];
151
+ if (options.prTitle) {
152
+ args.push('--title', options.prTitle);
153
+ }
154
+ if (options.prBody) {
155
+ args.push('--body', options.prBody);
156
+ }
157
+ if (options.baseBranch) {
158
+ args.push('--base', options.baseBranch);
159
+ }
160
+ if (!options.prTitle && !options.prBody) {
161
+ args.push('--fill');
162
+ }
163
+ const result = runCommand('gh', args, repoRoot, { allowFailure: true });
164
+ if (!result.ok) {
165
+ throw new Error(`Failed to create PR via gh: ${result.stderr || 'unknown error'}`);
166
+ }
167
+ prUrl = result.stdout.split('\n').find((line) => line.startsWith('http')) || result.stdout;
168
+ }
169
+ return {
170
+ repoRoot,
171
+ branch,
172
+ stagedPaths: stageTargets,
173
+ committed,
174
+ commitSha,
175
+ prUrl,
176
+ };
177
+ }