@empiricalrun/test-gen 0.71.1 → 0.72.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 (141) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/actions/index.d.ts.map +1 -1
  3. package/dist/actions/index.js +0 -6
  4. package/dist/agent/browsing/index.d.ts.map +1 -1
  5. package/dist/agent/browsing/index.js +6 -14
  6. package/dist/agent/chat/agent-loop.d.ts +11 -9
  7. package/dist/agent/chat/agent-loop.d.ts.map +1 -1
  8. package/dist/agent/chat/agent-loop.js +20 -10
  9. package/dist/agent/chat/exports.d.ts +2 -2
  10. package/dist/agent/chat/exports.d.ts.map +1 -1
  11. package/dist/agent/chat/exports.js +6 -1
  12. package/dist/agent/chat/index.d.ts.map +1 -1
  13. package/dist/agent/chat/index.js +48 -13
  14. package/dist/agent/chat/prompt/index.d.ts +2 -2
  15. package/dist/agent/chat/prompt/index.d.ts.map +1 -1
  16. package/dist/agent/chat/prompt/index.js +2 -2
  17. package/dist/agent/chat/prompt/repo.d.ts +2 -2
  18. package/dist/agent/chat/prompt/repo.d.ts.map +1 -1
  19. package/dist/agent/chat/prompt/repo.js +20 -11
  20. package/dist/agent/chat/state.d.ts +2 -2
  21. package/dist/agent/chat/state.d.ts.map +1 -1
  22. package/dist/agent/chat/types.d.ts +0 -6
  23. package/dist/agent/chat/types.d.ts.map +1 -1
  24. package/dist/agent/chat/utils/tool-calls.d.ts +21 -0
  25. package/dist/agent/chat/utils/tool-calls.d.ts.map +1 -0
  26. package/dist/agent/chat/utils/tool-calls.js +64 -0
  27. package/dist/agent/chat/utils.d.ts +2 -4
  28. package/dist/agent/chat/utils.d.ts.map +1 -1
  29. package/dist/agent/chat/utils.js +5 -11
  30. package/dist/agent/codegen/repo-edit.d.ts.map +1 -1
  31. package/dist/agent/codegen/repo-edit.js +0 -4
  32. package/dist/agent/codegen/run.d.ts.map +1 -1
  33. package/dist/agent/codegen/run.js +0 -4
  34. package/dist/agent/codegen/utils.d.ts +1 -3
  35. package/dist/agent/codegen/utils.d.ts.map +1 -1
  36. package/dist/agent/codegen/utils.js +1 -2
  37. package/dist/agent/cua/index.d.ts +2 -1
  38. package/dist/agent/cua/index.d.ts.map +1 -1
  39. package/dist/agent/cua/index.js +4 -4
  40. package/dist/agent/master/browser-tests/index.spec.js +1 -1
  41. package/dist/agent/master/execute-browser-action.d.ts.map +1 -1
  42. package/dist/agent/master/execute-browser-action.js +1 -4
  43. package/dist/agent/master/run.d.ts.map +1 -1
  44. package/dist/agent/master/run.js +0 -19
  45. package/dist/agent/master/scroller.d.ts.map +1 -1
  46. package/dist/agent/master/scroller.js +0 -4
  47. package/dist/auth/api-client.d.ts.map +1 -1
  48. package/dist/auth/api-client.js +6 -2
  49. package/dist/bin/environments.d.ts +1 -1
  50. package/dist/bin/environments.d.ts.map +1 -1
  51. package/dist/bin/environments.js +70 -36
  52. package/dist/bin/index.js +2 -36
  53. package/dist/bin/logger/index.d.ts +0 -1
  54. package/dist/bin/logger/index.d.ts.map +1 -1
  55. package/dist/bin/logger/index.js +0 -16
  56. package/dist/bin/setup.d.ts.map +1 -1
  57. package/dist/bin/setup.js +10 -10
  58. package/dist/dashboard/index.d.ts +21 -0
  59. package/dist/dashboard/index.d.ts.map +1 -0
  60. package/dist/dashboard/index.js +83 -0
  61. package/dist/dashboard/totp.d.ts +2 -0
  62. package/dist/dashboard/totp.d.ts.map +1 -0
  63. package/dist/dashboard/totp.js +18 -0
  64. package/dist/file-info/file-system.d.ts +3 -0
  65. package/dist/file-info/file-system.d.ts.map +1 -0
  66. package/dist/{utils/file-tree.js → file-info/file-system.js} +2 -8
  67. package/dist/file-info/github.d.ts +3 -0
  68. package/dist/file-info/github.d.ts.map +1 -0
  69. package/dist/file-info/github.js +108 -0
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +0 -6
  72. package/dist/tools/commit-and-create-pr.js +2 -2
  73. package/dist/tools/definitions/index.d.ts +22 -0
  74. package/dist/tools/definitions/index.d.ts.map +1 -0
  75. package/dist/tools/definitions/index.js +61 -0
  76. package/dist/tools/definitions/run-test.d.ts +23 -0
  77. package/dist/tools/definitions/run-test.d.ts.map +1 -0
  78. package/dist/tools/definitions/run-test.js +28 -0
  79. package/dist/tools/definitions/str_replace_editor.d.ts +3 -0
  80. package/dist/tools/definitions/str_replace_editor.d.ts.map +1 -0
  81. package/dist/tools/definitions/str_replace_editor.js +74 -0
  82. package/dist/tools/definitions/test-gen-browser.d.ts +26 -0
  83. package/dist/tools/definitions/test-gen-browser.d.ts.map +1 -0
  84. package/dist/tools/definitions/test-gen-browser.js +88 -0
  85. package/dist/{tool-call-service/utils.d.ts → tools/definitions/utils/queue.d.ts} +6 -4
  86. package/dist/tools/definitions/utils/queue.d.ts.map +1 -0
  87. package/dist/{tool-call-service/utils.js → tools/definitions/utils/queue.js} +20 -19
  88. package/dist/tools/diagnosis-fetcher.js +1 -1
  89. package/dist/{tool-call-service → tools/executor}/index.d.ts +2 -7
  90. package/dist/tools/executor/index.d.ts.map +1 -0
  91. package/dist/{tool-call-service → tools/executor}/index.js +16 -30
  92. package/dist/tools/executor/utils/checkpoint.d.ts.map +1 -0
  93. package/dist/tools/executor/utils/git.d.ts.map +1 -0
  94. package/dist/{utils → tools/executor/utils}/git.js +5 -5
  95. package/dist/tools/executor/utils/index.d.ts.map +1 -0
  96. package/dist/tools/list-environments.js +1 -1
  97. package/dist/tools/{test-run.d.ts → run-test.d.ts} +1 -1
  98. package/dist/tools/run-test.d.ts.map +1 -0
  99. package/dist/tools/{test-run.js → run-test.js} +5 -24
  100. package/dist/tools/str_replace_editor.d.ts.map +1 -1
  101. package/dist/tools/str_replace_editor.js +6 -58
  102. package/dist/tools/test-gen-browser.d.ts.map +1 -1
  103. package/dist/tools/test-gen-browser.js +2 -83
  104. package/dist/tools/test-run-fetcher/index.js +1 -1
  105. package/dist/tools/upgrade-packages/index.js +2 -2
  106. package/dist/tools/upgrade-packages/utils.js +1 -1
  107. package/dist/types/index.d.ts +0 -8
  108. package/dist/types/index.d.ts.map +1 -1
  109. package/dist/utils/SQSClient.d.ts +14 -0
  110. package/dist/utils/SQSClient.d.ts.map +1 -0
  111. package/dist/utils/SQSClient.js +116 -0
  112. package/dist/utils/repo-tree.d.ts +1 -1
  113. package/dist/utils/repo-tree.d.ts.map +1 -1
  114. package/dist/utils/repo-tree.js +7 -7
  115. package/package.json +18 -10
  116. package/tsconfig.tsbuildinfo +1 -1
  117. package/dist/reporter/index.d.ts +0 -26
  118. package/dist/reporter/index.d.ts.map +0 -1
  119. package/dist/reporter/index.js +0 -149
  120. package/dist/reporter/lib.d.ts +0 -31
  121. package/dist/reporter/lib.d.ts.map +0 -1
  122. package/dist/reporter/lib.js +0 -71
  123. package/dist/tool-call-service/index.d.ts.map +0 -1
  124. package/dist/tool-call-service/utils.d.ts.map +0 -1
  125. package/dist/tools/test-run.d.ts.map +0 -1
  126. package/dist/tools/utils/index.d.ts.map +0 -1
  127. package/dist/uploader/index.d.ts +0 -26
  128. package/dist/uploader/index.d.ts.map +0 -1
  129. package/dist/uploader/index.js +0 -103
  130. package/dist/uploader/utils.d.ts +0 -8
  131. package/dist/uploader/utils.d.ts.map +0 -1
  132. package/dist/uploader/utils.js +0 -35
  133. package/dist/utils/checkpoint.d.ts.map +0 -1
  134. package/dist/utils/file-tree.d.ts +0 -3
  135. package/dist/utils/file-tree.d.ts.map +0 -1
  136. package/dist/utils/git.d.ts.map +0 -1
  137. /package/dist/{utils → tools/executor/utils}/checkpoint.d.ts +0 -0
  138. /package/dist/{utils → tools/executor/utils}/checkpoint.js +0 -0
  139. /package/dist/{utils → tools/executor/utils}/git.d.ts +0 -0
  140. /package/dist/tools/{utils → executor/utils}/index.d.ts +0 -0
  141. /package/dist/tools/{utils → executor/utils}/index.js +0 -0
@@ -1,12 +1,66 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listEnvironments = listEnvironments;
4
+ const test_run_1 = require("@empiricalrun/test-run");
4
5
  const api_client_1 = require("../auth/api-client");
5
6
  const validation_1 = require("../recorder/validation");
6
- // TODO: Match against playwright project names - show that to the user
7
- async function listEnvironments() {
7
+ async function getMatchingPlaywrightProjects(patterns, repoDir) {
8
+ if (patterns.length === 0) {
9
+ return [];
10
+ }
11
+ try {
12
+ // Use test-run's existing logic that handles comma-separated values and all patterns
13
+ return await (0, test_run_1.generateProjectFilters)({
14
+ platform: test_run_1.Platform.WEB,
15
+ filteringSets: patterns,
16
+ repoDir,
17
+ });
18
+ }
19
+ catch (error) {
20
+ console.warn("Warning: Could not match Playwright projects:", error);
21
+ return [];
22
+ }
23
+ }
24
+ function printLatestBuild(latestBuild) {
25
+ if (!latestBuild) {
26
+ console.log(` └─ No builds available`);
27
+ return;
28
+ }
29
+ console.log("");
30
+ const commit = latestBuild.commit
31
+ ? latestBuild.commit.substring(0, 7)
32
+ : "N/A";
33
+ const branch = latestBuild.branch || "N/A";
34
+ // Calculate relative time
35
+ const createdAt = new Date(latestBuild.created_at);
36
+ const now = new Date();
37
+ const diffMs = now.getTime() - createdAt.getTime();
38
+ const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
39
+ const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
40
+ const diffMinutes = Math.floor(diffMs / (1000 * 60));
41
+ let timeAgo;
42
+ if (diffDays > 0) {
43
+ timeAgo = `${diffDays} day${diffDays > 1 ? "s" : ""} ago`;
44
+ }
45
+ else if (diffHours > 0) {
46
+ timeAgo = `${diffHours} hour${diffHours > 1 ? "s" : ""} ago`;
47
+ }
48
+ else if (diffMinutes > 0) {
49
+ timeAgo = `${diffMinutes} minute${diffMinutes > 1 ? "s" : ""} ago`;
50
+ }
51
+ else {
52
+ timeAgo = "Just now";
53
+ }
54
+ console.log(` ┌─ Latest build`);
55
+ console.log(` │ Commit: ${commit}`);
56
+ console.log(` │ Branch: ${branch}`);
57
+ console.log(` │ Created: ${timeAgo}`);
58
+ console.log(` │ URL: ${latestBuild.build_url}`);
59
+ console.log(` └─`);
60
+ }
61
+ async function listEnvironments(repoDir) {
8
62
  try {
9
- let repoName = await (0, validation_1.validatePackageJson)(process.cwd());
63
+ let repoName = await (0, validation_1.validatePackageJson)(repoDir);
10
64
  const response = await api_client_1.apiClient.request(`/api/environments/list?project_repo_name=${encodeURIComponent(repoName)}`);
11
65
  if (!response.ok) {
12
66
  console.error(`❌ Failed to fetch environments for repo ${repoName}:`, response.statusText);
@@ -14,47 +68,27 @@ async function listEnvironments() {
14
68
  }
15
69
  const result = await response.json();
16
70
  if (result.data?.environments && result.data.environments.length > 0) {
17
- result.data.environments.forEach((env, index) => {
18
- if (index > 0) {
19
- console.log(""); // Add spacing between environments
71
+ for (const env of result.data.environments) {
72
+ const envIndex = result.data.environments.indexOf(env);
73
+ if (envIndex > 0) {
74
+ console.log("");
20
75
  }
21
76
  console.log(`Environment: ${env.name}`);
22
- if (env.latest_build) {
23
- const commit = env.latest_build.commit
24
- ? env.latest_build.commit.substring(0, 7)
25
- : "N/A";
26
- const branch = env.latest_build.branch || "N/A";
27
- // Calculate relative time
28
- const createdAt = new Date(env.latest_build.created_at);
29
- const now = new Date();
30
- const diffMs = now.getTime() - createdAt.getTime();
31
- const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
32
- const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
33
- const diffMinutes = Math.floor(diffMs / (1000 * 60));
34
- let timeAgo;
35
- if (diffDays > 0) {
36
- timeAgo = `${diffDays} day${diffDays > 1 ? "s" : ""} ago`;
37
- }
38
- else if (diffHours > 0) {
39
- timeAgo = `${diffHours} hour${diffHours > 1 ? "s" : ""} ago`;
40
- }
41
- else if (diffMinutes > 0) {
42
- timeAgo = `${diffMinutes} minute${diffMinutes > 1 ? "s" : ""} ago`;
77
+ console.log(` Slug: ${env.slug}`);
78
+ if (env.playwright_projects && env.playwright_projects.length > 0) {
79
+ const matchingProjects = await getMatchingPlaywrightProjects(env.playwright_projects, repoDir);
80
+ if (matchingProjects.length > 0) {
81
+ console.log(` Playwright Projects: ${matchingProjects.join(", ")}`);
43
82
  }
44
83
  else {
45
- timeAgo = "Just now";
84
+ console.log(` Playwright Projects: No matches found for patterns: ${env.playwright_projects.join(", ")}`);
46
85
  }
47
- console.log(` ┌─ Latest build`);
48
- console.log(` │ Commit: ${commit}`);
49
- console.log(` │ Branch: ${branch}`);
50
- console.log(` │ Created: ${timeAgo}`);
51
- console.log(` │ URL: ${env.latest_build.build_url}`);
52
- console.log(` └─`);
53
86
  }
54
87
  else {
55
- console.log(` └─ No builds available`);
88
+ console.log(` Playwright Projects: None`);
56
89
  }
57
- });
90
+ printLatestBuild(env.latest_build);
91
+ }
58
92
  }
59
93
  else {
60
94
  console.log(`No environments found for repository: ${repoName}`);
package/dist/bin/index.js CHANGED
@@ -21,7 +21,6 @@ const auth_1 = require("../auth");
21
21
  const api_client_1 = require("../auth/api-client");
22
22
  const recorder_1 = require("../recorder");
23
23
  const validation_1 = require("../recorder/validation");
24
- const reporter_1 = require("../reporter");
25
24
  const session_1 = require("../session");
26
25
  const test_build_1 = require("../test-build");
27
26
  const environments_1 = require("./environments");
@@ -57,14 +56,6 @@ async function runChatAgent({ modelInput, useDiskForChatState, initialPromptPath
57
56
  async function runAgentsWorkflow(testGenConfig, testGenToken) {
58
57
  const logger = new logger_1.CustomLogger();
59
58
  const { specPath, testCase } = testGenConfig;
60
- if (process.env.LOG_URL) {
61
- try {
62
- void new reporter_1.TestGenUpdatesReporter().sendLogUrl(process.env.LOG_URL);
63
- }
64
- catch (e) {
65
- console.warn("Failed to send log url to test gen update", e);
66
- }
67
- }
68
59
  const session = (0, session_1.getSessionDetails)();
69
60
  const trace = llm_1.langfuseInstance?.trace({
70
61
  name: "generate-test",
@@ -87,14 +78,6 @@ async function runAgentsWorkflow(testGenConfig, testGenToken) {
87
78
  testUrl: session.testUrl,
88
79
  },
89
80
  });
90
- if (trace) {
91
- try {
92
- void new reporter_1.TestGenUpdatesReporter().sendAgentTraceUrl(trace.getTraceUrl());
93
- }
94
- catch (e) {
95
- console.warn("Failed to send trace url as test gen update", e);
96
- }
97
- }
98
81
  // assuming if there is no test case specific test name, we need to update the test case name
99
82
  if (!testCase.name) {
100
83
  logger.success(`Generating code for the provided task. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`);
@@ -147,7 +130,6 @@ async function runAgentsWorkflow(testGenConfig, testGenToken) {
147
130
  });
148
131
  new logger_1.CustomLogger({ useReporter: false }).log("Generated Plan:");
149
132
  console.log(plan);
150
- await new reporter_1.TestGenUpdatesReporter().sendMessage(plan);
151
133
  }
152
134
  else if (agent === "code") {
153
135
  await (0, run_2.generateTestWithCodegen)({
@@ -287,7 +269,7 @@ async function main() {
287
269
  .command("environments")
288
270
  .description("List environments and their latest builds")
289
271
  .action(async () => {
290
- await (0, environments_1.listEnvironments)();
272
+ await (0, environments_1.listEnvironments)(process.cwd());
291
273
  process.exit(0);
292
274
  });
293
275
  program
@@ -396,11 +378,6 @@ async function main() {
396
378
  const testGenToken = options.token
397
379
  ? options.token
398
380
  : (0, scenarios_1.buildTokenFromOptions)(options);
399
- (0, reporter_1.setReporterConfig)({
400
- projectRepoName: testGenConfig.options?.metadata.projectRepoName,
401
- testSessionId: testGenConfig.options?.metadata.testSessionId,
402
- generationId: testGenConfig.options?.metadata.generationId,
403
- });
404
381
  (0, session_1.setSessionDetails)({
405
382
  testCaseId: testGenConfig.testCase.id,
406
383
  sessionId: testGenConfig.options?.metadata.testSessionId,
@@ -414,25 +391,14 @@ async function main() {
414
391
  repoPath: process.cwd(),
415
392
  });
416
393
  }
417
- let agentUsed;
418
394
  let testGenFailed = false;
419
395
  try {
420
- agentUsed = await runAgentsWorkflow(testGenConfig, testGenToken);
396
+ await runAgentsWorkflow(testGenConfig, testGenToken);
421
397
  }
422
398
  catch (e) {
423
399
  testGenFailed = true;
424
400
  new logger_1.CustomLogger().error(`Failed to generate test for the scenario. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`, e?.message, e?.stack);
425
401
  }
426
- if (agentUsed &&
427
- agentUsed !== "code" &&
428
- agentUsed !== "plan" &&
429
- testGenConfig.testCase.name &&
430
- testGenConfig.options) {
431
- await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
432
- projectRepoName: testGenConfig.options.metadata.projectRepoName,
433
- testName: testGenConfig.testCase.name,
434
- });
435
- }
436
402
  await (0, llm_1.flushAllTraces)();
437
403
  await (0, logger_1.waitForLogsToFlush)();
438
404
  await (0, session_1.endSession)();
@@ -3,7 +3,6 @@ export declare class CustomLogger {
3
3
  constructor({ useReporter }?: {
4
4
  useReporter?: boolean | undefined;
5
5
  });
6
- private logToReporter;
7
6
  log(message?: string, ...optionalParams: any[]): void;
8
7
  warn(message?: string, ...optionalParams: any[]): void;
9
8
  success(message?: string, ...optionalParams: any[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/logger/index.ts"],"names":[],"mappings":"AAOA,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAkB;gBACzB,EAAE,WAAkB,EAAE;;KAAK;IAIvC,OAAO,CAAC,aAAa;IAYrB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAK9C,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAK/C,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAKlD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAKhD,YAAY;CAGb;AAED,wBAAsB,kBAAkB,kBAWvC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/logger/index.ts"],"names":[],"mappings":"AAIA,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAkB;gBACzB,EAAE,WAAkB,EAAE;;KAAK;IAIvC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI9C,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI/C,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAIlD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAIhD,YAAY;CAGb;AAED,wBAAsB,kBAAkB,kBAWvC"}
@@ -3,39 +3,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CustomLogger = void 0;
4
4
  exports.waitForLogsToFlush = waitForLogsToFlush;
5
5
  const picocolors_1 = require("picocolors");
6
- const reporter_1 = require("../../reporter");
7
- const lib_1 = require("../../reporter/lib");
8
6
  let queuedReporterMessages = [];
9
7
  class CustomLogger {
10
8
  useReporter = false;
11
9
  constructor({ useReporter = true } = {}) {
12
10
  this.useReporter = useReporter;
13
11
  }
14
- logToReporter(message) {
15
- if (this.useReporter) {
16
- (() => {
17
- const promise = (0, reporter_1.getReporter)()?.report(new lib_1.MessageBuilder({ type: "message", message: message }));
18
- if (promise) {
19
- queuedReporterMessages.push(promise);
20
- }
21
- })();
22
- }
23
- }
24
12
  log(message, ...optionalParams) {
25
13
  console.log("🪵", (0, picocolors_1.cyan)(message), ...optionalParams);
26
- this.logToReporter(message);
27
14
  }
28
15
  warn(message, ...optionalParams) {
29
16
  console.log("🟡", (0, picocolors_1.yellow)(message), ...optionalParams);
30
- this.logToReporter(message);
31
17
  }
32
18
  success(message, ...optionalParams) {
33
19
  console.log("✅", (0, picocolors_1.green)(message), ...optionalParams);
34
- this.logToReporter(message);
35
20
  }
36
21
  error(message, ...optionalParams) {
37
22
  console.error("🚨", (0, picocolors_1.red)(message), ...optionalParams);
38
- this.logToReporter(message);
39
23
  }
40
24
  logEmptyLine() {
41
25
  console.log("\n\n");
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/bin/setup.ts"],"names":[],"mappings":"AAmIA,wBAAsB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,iBA4BhE"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/bin/setup.ts"],"names":[],"mappings":"AA2HA,wBAAsB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,iBA4BhE"}
package/dist/bin/setup.js CHANGED
@@ -48,17 +48,17 @@ async function installDependencies(targetDir) {
48
48
  async function installPlaywrightBrowser(targetDir) {
49
49
  console.log(`🎭 Installing Playwright browser...`);
50
50
  try {
51
- const { stderr: playwrightStderr } = await execAsync(`npx playwright install chromium --with-deps`, {
52
- cwd: targetDir,
53
- });
54
- if (playwrightStderr && !playwrightStderr.includes("Installing")) {
55
- console.error(`Playwright install error: ${playwrightStderr}`);
56
- process.exit(1);
51
+ const { stderr } = await execAsync(`npx playwright install chromium --with-deps`, { cwd: targetDir });
52
+ if (stderr && stderr.trim()) {
53
+ console.warn(`⚠️ Playwright installation warnings: ${stderr.trim()}`);
57
54
  }
58
55
  console.log(`✅ Playwright browser installed successfully`);
59
56
  }
60
- catch (playwrightError) {
61
- console.error(`❌ Failed to install Playwright browser: ${playwrightError.message}`);
57
+ catch (error) {
58
+ // execAsync already throws on non-zero exit codes
59
+ const errorMessage = error.message || "Unknown error";
60
+ const exitCode = error.code || "unknown";
61
+ console.error(`❌ Failed to install Playwright browser (exit code: ${exitCode}): ${errorMessage}`);
62
62
  process.exit(1);
63
63
  }
64
64
  }
@@ -73,8 +73,8 @@ async function cleanUpRepoCredSetup(repoPath) {
73
73
  }
74
74
  async function setupRepoCredentials(repoPath) {
75
75
  console.log(`🔑 Setting up repository credentials...`);
76
- const helperCommand = `!npx @empiricalrun/test-gen github-token --raw`;
77
- await execAsync(`git config credential."https://github.com".helper '${helperCommand}'`, { cwd: repoPath });
76
+ const helperCommand = `"!npx @empiricalrun/test-gen github-token --raw"`;
77
+ await execAsync(`git config credential."https://github.com".helper ${helperCommand}`, { cwd: repoPath });
78
78
  console.log(`✅ Repository credentials configured`);
79
79
  }
80
80
  async function validateAndSetupRepo(repoPath) {
@@ -0,0 +1,21 @@
1
+ export declare class HTTPError extends Error {
2
+ status: number;
3
+ constructor(message: string, status: number);
4
+ }
5
+ export declare class NonRetryableHTTPError extends HTTPError {
6
+ }
7
+ export declare class RetryableHTTPError extends HTTPError {
8
+ }
9
+ export interface RequestOptions {
10
+ params?: Record<string, string>;
11
+ body?: Record<string, unknown>;
12
+ method: "GET" | "POST";
13
+ headers?: Record<string, string>;
14
+ }
15
+ export declare function makeAuthenticatedRequest<T>(url: string, options: RequestOptions, secretKey?: string, dashboardDomain?: string): Promise<T>;
16
+ export declare function callGitHubProxy({ method, url, body, }: {
17
+ method: "GET" | "POST";
18
+ url: string;
19
+ body?: any;
20
+ }): Promise<unknown>;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAIA,qBAAa,SAAU,SAAQ,KAAK;IAClC,MAAM,EAAE,MAAM,CAAC;gBACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI5C;AAED,qBAAa,qBAAsB,SAAQ,SAAS;CAAG;AAEvD,qBAAa,kBAAmB,SAAQ,SAAS;CAAG;AAEpD,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,cAAc,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,CAAC,CAAC,CAqDZ;AAED,wBAAsB,eAAe,CAAC,EACpC,MAAM,EACN,GAAG,EACH,IAAI,GACL,EAAE;IACD,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ,oBAYA"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RetryableHTTPError = exports.NonRetryableHTTPError = exports.HTTPError = void 0;
7
+ exports.makeAuthenticatedRequest = makeAuthenticatedRequest;
8
+ exports.callGitHubProxy = callGitHubProxy;
9
+ const async_retry_1 = __importDefault(require("async-retry"));
10
+ const totp_1 = require("./totp");
11
+ class HTTPError extends Error {
12
+ status;
13
+ constructor(message, status) {
14
+ super(message);
15
+ this.status = status;
16
+ }
17
+ }
18
+ exports.HTTPError = HTTPError;
19
+ class NonRetryableHTTPError extends HTTPError {
20
+ }
21
+ exports.NonRetryableHTTPError = NonRetryableHTTPError;
22
+ class RetryableHTTPError extends HTTPError {
23
+ }
24
+ exports.RetryableHTTPError = RetryableHTTPError;
25
+ async function makeAuthenticatedRequest(url, options, secretKey, dashboardDomain) {
26
+ const baseUrl = dashboardDomain || process.env.DASHBOARD_DOMAIN;
27
+ const fullUrl = new URL(url, baseUrl);
28
+ return await (0, async_retry_1.default)(async (bail) => {
29
+ if (options.params) {
30
+ Object.entries(options.params).forEach(([key, value]) => {
31
+ fullUrl.searchParams.append(key, value);
32
+ });
33
+ }
34
+ const headers = {
35
+ ...options.headers,
36
+ "Content-Type": "application/json",
37
+ };
38
+ if (!headers["Authorization"]) {
39
+ // Use API key auth if provided, else use TOTP
40
+ const totp = await (0, totp_1.getTOTP)(secretKey);
41
+ headers["X-Empirical-Auth-TOTP"] = totp;
42
+ }
43
+ const response = await fetch(fullUrl.toString(), {
44
+ headers,
45
+ method: options.method,
46
+ body: options.body ? JSON.stringify(options.body) : undefined,
47
+ });
48
+ if (!response.ok) {
49
+ let error;
50
+ const msg = `HTTP error in ${options.method} request to ${fullUrl.toString()}! Status code: ${response.status}`;
51
+ if (response.status < 500) {
52
+ // Don't retry for status codes less than 500 (client errors)
53
+ error = new NonRetryableHTTPError(msg, response.status);
54
+ bail(error);
55
+ return;
56
+ }
57
+ else {
58
+ error = new RetryableHTTPError(msg, response.status);
59
+ }
60
+ throw error;
61
+ }
62
+ return response.json();
63
+ }, {
64
+ retries: 3,
65
+ factor: 2,
66
+ minTimeout: 1_000,
67
+ maxTimeout: 5_000,
68
+ onRetry: (error, retryCount) => {
69
+ console.log(`Retrying... ${retryCount}`);
70
+ console.log(error);
71
+ },
72
+ });
73
+ }
74
+ async function callGitHubProxy({ method, url, body, }) {
75
+ return await makeAuthenticatedRequest(`${process.env.DASHBOARD_DOMAIN}/api/github/proxy`, {
76
+ method: "POST",
77
+ body: {
78
+ method,
79
+ url,
80
+ body,
81
+ },
82
+ });
83
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getTOTP(secretKey?: string): Promise<string>;
2
+ //# sourceMappingURL=totp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../src/dashboard/totp.ts"],"names":[],"mappings":"AAAA,wBAAsB,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,mBAe/C"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTOTP = getTOTP;
4
+ async function getTOTP(secretKey) {
5
+ const secret = secretKey || process.env.EMPIRICAL_TOTP_SK;
6
+ if (!secret) {
7
+ throw new Error("EMPIRICAL_TOTP_SK is not set");
8
+ }
9
+ // NOTE: Had to import dynamically to avoid ECMA Script Modules error
10
+ const { generateTOTP } = await import("@epic-web/totp");
11
+ const totp = await generateTOTP({
12
+ secret,
13
+ digits: 6,
14
+ period: 30,
15
+ algorithm: "SHA-256",
16
+ });
17
+ return totp.otp;
18
+ }
@@ -0,0 +1,3 @@
1
+ import { FileInfo } from "@empiricalrun/shared-types";
2
+ export declare function getFileInfoFromFS(directory: string): Promise<FileInfo>;
3
+ //# sourceMappingURL=file-system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-system.d.ts","sourceRoot":"","sources":["../../src/file-info/file-system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAItD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgC5E"}
@@ -10,14 +10,10 @@ async function getFileInfoFromFS(directory) {
10
10
  // TODO: This traverses all node_modules - can be excluded with DEFAULT_EXCLUDE
11
11
  let currentDirName = path_1.default.basename(directory);
12
12
  let currentDir = {
13
- isDirectory: true,
14
- isFile: false,
13
+ type: "directory",
15
14
  path: currentDirName,
16
15
  name: currentDirName,
17
16
  children: [],
18
- getContent: async () => {
19
- return "";
20
- },
21
17
  };
22
18
  const files = await promises_1.default.readdir(directory);
23
19
  for (const file of files) {
@@ -29,11 +25,9 @@ async function getFileInfoFromFS(directory) {
29
25
  }
30
26
  else {
31
27
  currentDir.children.push({
32
- isDirectory: false,
33
- isFile: true,
28
+ type: "file",
34
29
  path: filePath,
35
30
  name: file,
36
- children: [],
37
31
  getContent: async () => {
38
32
  return await promises_1.default.readFile(filePath, "utf8");
39
33
  },
@@ -0,0 +1,3 @@
1
+ import { FileInfo } from "@empiricalrun/shared-types";
2
+ export declare function getFileInfoFromGitHub(repoName: string, secretKey: string, dashboardDomain?: string): Promise<FileInfo>;
3
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/file-info/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAuFtD,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,QAAQ,CAAC,CAyFnB"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getFileInfoFromGitHub = getFileInfoFromGitHub;
7
+ const path_1 = __importDefault(require("path"));
8
+ const dashboard_1 = require("../dashboard");
9
+ async function getFileContent(repoName, path, secretKey, dashboardDomain) {
10
+ // TODO: specify ref (branch name) for the chat session
11
+ const url = `/api/github/files?repo=${repoName}&path=${path}`;
12
+ const response = await (0, dashboard_1.makeAuthenticatedRequest)(url, {
13
+ method: "GET",
14
+ }, secretKey, dashboardDomain);
15
+ if (!response.data) {
16
+ throw new Error(`Unable to fetch file for FileInfo`);
17
+ }
18
+ return response.data.fileContents.content;
19
+ }
20
+ async function getContentsForDirectory({ repo, path, }, secretKey, dashboardDomain) {
21
+ const url = `/api/github/tree?repo=${repo}&path=${path}`;
22
+ const response = await (0, dashboard_1.makeAuthenticatedRequest)(url, {
23
+ method: "GET",
24
+ }, secretKey, dashboardDomain);
25
+ if (!response.data) {
26
+ throw new Error(`Unable to fetch file for FileInfo`);
27
+ }
28
+ return response.data.tree;
29
+ }
30
+ // TODO: use this helper method in the dashboard
31
+ async function getFileInfoFromGitHub(repoName, secretKey, dashboardDomain) {
32
+ const files = await getContentsForDirectory({ repo: repoName, path: "" }, secretKey, dashboardDomain);
33
+ const root = [];
34
+ const nodeMap = {};
35
+ if (!files) {
36
+ return {
37
+ type: "directory",
38
+ path: repoName,
39
+ name: repoName,
40
+ children: [],
41
+ };
42
+ }
43
+ files.tree.forEach((file) => {
44
+ if (!file.path) {
45
+ return;
46
+ }
47
+ const pathParts = file.path.split("/");
48
+ const fileName = path_1.default.basename(file.path);
49
+ const isFile = file.type === "blob";
50
+ // Create the current file/directory node
51
+ const currentPath = file.path;
52
+ const currentNode = isFile
53
+ ? {
54
+ type: "file",
55
+ path: currentPath,
56
+ name: fileName,
57
+ getContent: async () => getFileContent(repoName, currentPath, secretKey, dashboardDomain),
58
+ }
59
+ : {
60
+ type: "directory",
61
+ path: currentPath,
62
+ name: fileName,
63
+ children: [],
64
+ };
65
+ nodeMap[currentPath] = currentNode;
66
+ if (pathParts.length === 1) {
67
+ // This is a root-level file or directory
68
+ root.push(currentNode);
69
+ }
70
+ else {
71
+ // This is a nested file or directory
72
+ const parentPath = path_1.default.dirname(currentPath);
73
+ // Ensure parent exists
74
+ if (!nodeMap[parentPath]) {
75
+ // Create parent directory if it doesn't exist yet
76
+ const parentNode = {
77
+ type: "directory",
78
+ path: parentPath,
79
+ name: parentPath.split("/").pop() || "",
80
+ children: [],
81
+ };
82
+ nodeMap[parentPath] = parentNode;
83
+ // Add parent to its parent or root
84
+ const parentPathParts = parentPath.split("/");
85
+ if (parentPathParts.length === 1) {
86
+ root.push(parentNode);
87
+ }
88
+ else {
89
+ const grandparentPath = path_1.default.dirname(parentPath);
90
+ if (nodeMap[grandparentPath] &&
91
+ nodeMap[grandparentPath].type === "directory") {
92
+ nodeMap[grandparentPath].children.push(parentNode);
93
+ }
94
+ }
95
+ }
96
+ // Add current node to its parent
97
+ if (nodeMap[parentPath].type === "directory") {
98
+ nodeMap[parentPath].children.push(currentNode);
99
+ }
100
+ }
101
+ });
102
+ return {
103
+ type: "directory",
104
+ path: repoName,
105
+ name: repoName,
106
+ children: root,
107
+ };
108
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAchD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAsB7C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,YAAY,EAC5B,KAAK,CAAC,EAAE,SAAS,iBAwElB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,IAAI,iBAY7C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAahD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAsB7C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,YAAY,EAC5B,KAAK,CAAC,EAAE,SAAS,iBAmElB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,IAAI,iBAY7C"}
package/dist/index.js CHANGED
@@ -14,7 +14,6 @@ const run_1 = require("./agent/master/run");
14
14
  const scenarios_1 = require("./bin/utils/scenarios");
15
15
  const client_1 = __importDefault(require("./file/client"));
16
16
  const logger_1 = require("./logger");
17
- const reporter_1 = require("./reporter");
18
17
  const session_1 = require("./session");
19
18
  var test_build_1 = require("./test-build");
20
19
  Object.defineProperty(exports, "downloadBuild", { enumerable: true, get: function () { return test_build_1.downloadBuild; } });
@@ -47,11 +46,6 @@ async function createTest(task, pageRef, scope) {
47
46
  });
48
47
  }
49
48
  if (testGenConfig.options && testGenConfig.options.metadata) {
50
- (0, reporter_1.setReporterConfig)({
51
- projectRepoName: testGenConfig.options?.metadata.projectRepoName,
52
- testSessionId: testGenConfig.options?.metadata.testSessionId,
53
- generationId: testGenConfig.options?.metadata.generationId,
54
- });
55
49
  (0, session_1.setSessionDetails)({
56
50
  sessionId: testGenConfig.options?.metadata.testSessionId,
57
51
  generationId: testGenConfig.options?.metadata.generationId,
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createPullRequestTool = void 0;
4
4
  const child_process_1 = require("child_process");
5
5
  const zod_1 = require("zod");
6
- const git_1 = require("../utils/git");
7
- const utils_1 = require("./utils");
6
+ const utils_1 = require("./executor/utils");
7
+ const git_1 = require("./executor/utils/git");
8
8
  const createPullRequestSchema = zod_1.z.object({
9
9
  pullRequestTitle: zod_1.z
10
10
  .string()