@empiricalrun/test-gen 0.71.2 → 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 (102) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/agent/chat/agent-loop.d.ts +11 -9
  3. package/dist/agent/chat/agent-loop.d.ts.map +1 -1
  4. package/dist/agent/chat/agent-loop.js +20 -10
  5. package/dist/agent/chat/exports.d.ts +2 -2
  6. package/dist/agent/chat/exports.d.ts.map +1 -1
  7. package/dist/agent/chat/exports.js +6 -1
  8. package/dist/agent/chat/index.d.ts.map +1 -1
  9. package/dist/agent/chat/index.js +48 -13
  10. package/dist/agent/chat/prompt/index.d.ts +2 -2
  11. package/dist/agent/chat/prompt/index.d.ts.map +1 -1
  12. package/dist/agent/chat/prompt/index.js +2 -2
  13. package/dist/agent/chat/prompt/repo.d.ts +2 -2
  14. package/dist/agent/chat/prompt/repo.d.ts.map +1 -1
  15. package/dist/agent/chat/prompt/repo.js +20 -11
  16. package/dist/agent/chat/state.d.ts +2 -2
  17. package/dist/agent/chat/state.d.ts.map +1 -1
  18. package/dist/agent/chat/types.d.ts +0 -6
  19. package/dist/agent/chat/types.d.ts.map +1 -1
  20. package/dist/agent/chat/utils/tool-calls.d.ts +21 -0
  21. package/dist/agent/chat/utils/tool-calls.d.ts.map +1 -0
  22. package/dist/agent/chat/utils/tool-calls.js +64 -0
  23. package/dist/agent/chat/utils.d.ts +2 -4
  24. package/dist/agent/chat/utils.d.ts.map +1 -1
  25. package/dist/agent/chat/utils.js +5 -11
  26. package/dist/agent/master/browser-tests/index.spec.js +1 -1
  27. package/dist/auth/api-client.d.ts.map +1 -1
  28. package/dist/auth/api-client.js +6 -2
  29. package/dist/bin/environments.d.ts +1 -1
  30. package/dist/bin/environments.d.ts.map +1 -1
  31. package/dist/bin/environments.js +70 -36
  32. package/dist/bin/index.js +1 -1
  33. package/dist/bin/setup.d.ts.map +1 -1
  34. package/dist/bin/setup.js +10 -10
  35. package/dist/dashboard/index.d.ts +21 -0
  36. package/dist/dashboard/index.d.ts.map +1 -0
  37. package/dist/dashboard/index.js +83 -0
  38. package/dist/dashboard/totp.d.ts +2 -0
  39. package/dist/dashboard/totp.d.ts.map +1 -0
  40. package/dist/dashboard/totp.js +18 -0
  41. package/dist/file-info/file-system.d.ts +3 -0
  42. package/dist/file-info/file-system.d.ts.map +1 -0
  43. package/dist/{utils/file-tree.js → file-info/file-system.js} +2 -8
  44. package/dist/file-info/github.d.ts +3 -0
  45. package/dist/file-info/github.d.ts.map +1 -0
  46. package/dist/file-info/github.js +108 -0
  47. package/dist/tools/commit-and-create-pr.js +2 -2
  48. package/dist/tools/definitions/index.d.ts +22 -0
  49. package/dist/tools/definitions/index.d.ts.map +1 -0
  50. package/dist/tools/definitions/index.js +61 -0
  51. package/dist/tools/definitions/run-test.d.ts +23 -0
  52. package/dist/tools/definitions/run-test.d.ts.map +1 -0
  53. package/dist/tools/definitions/run-test.js +28 -0
  54. package/dist/tools/definitions/str_replace_editor.d.ts +3 -0
  55. package/dist/tools/definitions/str_replace_editor.d.ts.map +1 -0
  56. package/dist/tools/definitions/str_replace_editor.js +74 -0
  57. package/dist/tools/definitions/test-gen-browser.d.ts +26 -0
  58. package/dist/tools/definitions/test-gen-browser.d.ts.map +1 -0
  59. package/dist/tools/definitions/test-gen-browser.js +88 -0
  60. package/dist/{tool-call-service/utils.d.ts → tools/definitions/utils/queue.d.ts} +6 -4
  61. package/dist/tools/definitions/utils/queue.d.ts.map +1 -0
  62. package/dist/{tool-call-service/utils.js → tools/definitions/utils/queue.js} +20 -19
  63. package/dist/tools/diagnosis-fetcher.js +1 -1
  64. package/dist/{tool-call-service → tools/executor}/index.d.ts +2 -7
  65. package/dist/tools/executor/index.d.ts.map +1 -0
  66. package/dist/{tool-call-service → tools/executor}/index.js +15 -29
  67. package/dist/tools/executor/utils/checkpoint.d.ts.map +1 -0
  68. package/dist/tools/executor/utils/git.d.ts.map +1 -0
  69. package/dist/{utils → tools/executor/utils}/git.js +5 -5
  70. package/dist/tools/executor/utils/index.d.ts.map +1 -0
  71. package/dist/tools/list-environments.js +1 -1
  72. package/dist/tools/run-test.d.ts.map +1 -1
  73. package/dist/tools/run-test.js +2 -23
  74. package/dist/tools/str_replace_editor.d.ts.map +1 -1
  75. package/dist/tools/str_replace_editor.js +6 -58
  76. package/dist/tools/test-gen-browser.d.ts.map +1 -1
  77. package/dist/tools/test-gen-browser.js +2 -83
  78. package/dist/tools/test-run-fetcher/index.js +1 -1
  79. package/dist/tools/upgrade-packages/index.js +2 -2
  80. package/dist/tools/upgrade-packages/utils.js +1 -1
  81. package/dist/types/index.d.ts +0 -8
  82. package/dist/types/index.d.ts.map +1 -1
  83. package/dist/utils/SQSClient.d.ts +14 -0
  84. package/dist/utils/SQSClient.d.ts.map +1 -0
  85. package/dist/utils/SQSClient.js +116 -0
  86. package/dist/utils/repo-tree.d.ts +1 -1
  87. package/dist/utils/repo-tree.d.ts.map +1 -1
  88. package/dist/utils/repo-tree.js +7 -7
  89. package/package.json +16 -8
  90. package/tsconfig.tsbuildinfo +1 -1
  91. package/dist/tool-call-service/index.d.ts.map +0 -1
  92. package/dist/tool-call-service/utils.d.ts.map +0 -1
  93. package/dist/tools/utils/index.d.ts.map +0 -1
  94. package/dist/utils/checkpoint.d.ts.map +0 -1
  95. package/dist/utils/file-tree.d.ts +0 -3
  96. package/dist/utils/file-tree.d.ts.map +0 -1
  97. package/dist/utils/git.d.ts.map +0 -1
  98. /package/dist/{utils → tools/executor/utils}/checkpoint.d.ts +0 -0
  99. /package/dist/{utils → tools/executor/utils}/checkpoint.js +0 -0
  100. /package/dist/{utils → tools/executor/utils}/git.d.ts +0 -0
  101. /package/dist/tools/{utils → executor/utils}/index.d.ts +0 -0
  102. /package/dist/tools/{utils → executor/utils}/index.js +0 -0
@@ -9,6 +9,10 @@ class APIClient {
9
9
  this.appUrl = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
10
10
  }
11
11
  async request(endpoint, options = {}) {
12
+ const apiKey = process.env.EMPIRICALRUN_API_KEY;
13
+ if (apiKey) {
14
+ return this.makeRequest(endpoint, options, apiKey);
15
+ }
12
16
  await this.ensureAuthenticated();
13
17
  const tokens = await (0, token_store_1.getStoredTokens)();
14
18
  if (!tokens) {
@@ -28,13 +32,13 @@ class APIClient {
28
32
  }
29
33
  return response;
30
34
  }
31
- async makeRequest(endpoint, options, accessToken) {
35
+ async makeRequest(endpoint, options, authToken) {
32
36
  const url = endpoint.startsWith("http")
33
37
  ? endpoint
34
38
  : `${this.appUrl}${endpoint}`;
35
39
  // Don't set Content-Type for FormData (let browser set it automatically)
36
40
  const headers = {
37
- Authorization: `Bearer ${accessToken}`,
41
+ Authorization: `Bearer ${authToken}`,
38
42
  ...options.headers,
39
43
  };
40
44
  // Only set Content-Type to application/json if body is not FormData
@@ -1,2 +1,2 @@
1
- export declare function listEnvironments(): Promise<void>;
1
+ export declare function listEnvironments(repoDir: string): Promise<void>;
2
2
  //# sourceMappingURL=environments.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/bin/environments.ts"],"names":[],"mappings":"AASA,wBAAsB,gBAAgB,kBAiErC"}
1
+ {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/bin/environments.ts"],"names":[],"mappings":"AAkEA,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,iBAqDrD"}
@@ -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
@@ -269,7 +269,7 @@ async function main() {
269
269
  .command("environments")
270
270
  .description("List environments and their latest builds")
271
271
  .action(async () => {
272
- await (0, environments_1.listEnvironments)();
272
+ await (0, environments_1.listEnvironments)(process.cwd());
273
273
  process.exit(0);
274
274
  });
275
275
  program
@@ -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
+ }
@@ -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()
@@ -0,0 +1,22 @@
1
+ import { PendingToolCall } from "@empiricalrun/llm/chat";
2
+ import { SupportedChatModels, ToolDefinition } from "@empiricalrun/shared-types";
3
+ export declare class ToolCaller {
4
+ tools: ToolDefinition[];
5
+ selectedModel: SupportedChatModels;
6
+ branchName: string;
7
+ chatSessionId: number | null;
8
+ workerEnv?: Record<string, string>;
9
+ constructor({ chatSessionId, selectedModel, branchName, workerEnv, }: {
10
+ chatSessionId: number | null;
11
+ selectedModel: SupportedChatModels;
12
+ branchName: string;
13
+ workerEnv?: Record<string, string>;
14
+ });
15
+ schemas(): {
16
+ name: string;
17
+ description: string;
18
+ parameters: import("zod").ZodType;
19
+ }[];
20
+ sendToQueue(requestId: string, toolCalls: PendingToolCall[]): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EACL,mBAAmB,EACnB,cAAc,EACf,MAAM,4BAA4B,CAAC;AAcpC,qBAAa,UAAU;IACrB,KAAK,EAAE,cAAc,EAAE,CAAM;IAC7B,aAAa,EAAE,mBAAmB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACvB,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,SAAS,GACV,EAAE;QACD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,EAAE,mBAAmB,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC;IAsBD,OAAO;;;;;IAID,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC;CAcjB"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolCaller = void 0;
4
+ const chat_1 = require("@empiricalrun/llm/chat");
5
+ const commit_and_create_pr_1 = require("../commit-and-create-pr");
6
+ const diagnosis_fetcher_1 = require("../diagnosis-fetcher");
7
+ const download_build_1 = require("../download-build");
8
+ const grep_1 = require("../grep");
9
+ const list_environments_1 = require("../list-environments");
10
+ const test_run_fetcher_1 = require("../test-run-fetcher");
11
+ const upgrade_packages_1 = require("../upgrade-packages");
12
+ const run_test_1 = require("./run-test");
13
+ const str_replace_editor_1 = require("./str_replace_editor");
14
+ const test_gen_browser_1 = require("./test-gen-browser");
15
+ const queue_1 = require("./utils/queue");
16
+ class ToolCaller {
17
+ tools = [];
18
+ selectedModel;
19
+ branchName;
20
+ chatSessionId;
21
+ workerEnv;
22
+ constructor({ chatSessionId, selectedModel, branchName, workerEnv, }) {
23
+ this.chatSessionId = chatSessionId;
24
+ this.selectedModel = selectedModel;
25
+ this.branchName = branchName;
26
+ this.workerEnv = workerEnv;
27
+ // TODO: Keep this list in sync with the ToolExecutor
28
+ this.tools = [
29
+ run_test_1.runTestTool,
30
+ test_gen_browser_1.generateTestWithBrowserAgent,
31
+ grep_1.grepTool,
32
+ test_run_fetcher_1.fetchTestRunReportTool,
33
+ diagnosis_fetcher_1.fetchDiagnosisReportTool,
34
+ commit_and_create_pr_1.createPullRequestTool,
35
+ list_environments_1.listEnvironmentsTool,
36
+ download_build_1.downloadBuildTool,
37
+ upgrade_packages_1.upgradePackagesTool,
38
+ ];
39
+ if ((0, chat_1.getProviderForModel)(this.selectedModel) !== "claude") {
40
+ this.tools.push(...Object.values(str_replace_editor_1.textEditorTools));
41
+ }
42
+ }
43
+ schemas() {
44
+ return this.tools.map((tool) => tool.schema);
45
+ }
46
+ async sendToQueue(requestId, toolCalls) {
47
+ const queueUrl = (0, queue_1.getQueueUrl)(toolCalls, this.tools, this.workerEnv);
48
+ if (!queueUrl) {
49
+ throw new Error(`queueUrl is required for remote execution.`);
50
+ }
51
+ await (0, queue_1.sendToolRequestToRemoteQueue)(queueUrl, {
52
+ toolCalls,
53
+ requestId,
54
+ chatSessionId: this.chatSessionId,
55
+ selectedModel: this.selectedModel,
56
+ branchName: this.branchName,
57
+ workerEnv: this.workerEnv,
58
+ });
59
+ }
60
+ }
61
+ exports.ToolCaller = ToolCaller;
@@ -0,0 +1,23 @@
1
+ import { ToolDefinition } from "@empiricalrun/shared-types";
2
+ import { z } from "zod";
3
+ export declare const RunTestSchema: z.ZodObject<{
4
+ testName: z.ZodString;
5
+ suites: z.ZodArray<z.ZodString, "many">;
6
+ filePath: z.ZodString;
7
+ project: z.ZodString;
8
+ buildUrl: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ suites: string[];
11
+ testName: string;
12
+ filePath: string;
13
+ project: string;
14
+ buildUrl?: string | undefined;
15
+ }, {
16
+ suites: string[];
17
+ testName: string;
18
+ filePath: string;
19
+ project: string;
20
+ buildUrl?: string | undefined;
21
+ }>;
22
+ export declare const runTestTool: ToolDefinition;
23
+ //# sourceMappingURL=run-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-test.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/run-test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EAmBxB,CAAC;AAEH,eAAO,MAAM,WAAW,EAAE,cAOzB,CAAC"}