@empiricalrun/test-gen 0.61.0 → 0.63.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 (98) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/agent/browsing/run.d.ts +2 -0
  3. package/dist/agent/browsing/run.d.ts.map +1 -1
  4. package/dist/agent/browsing/run.js +11 -8
  5. package/dist/agent/browsing/utils.d.ts.map +1 -1
  6. package/dist/agent/browsing/utils.js +1 -1
  7. package/dist/agent/chat/agent-loop.js +2 -3
  8. package/dist/agent/chat/exports.d.ts +2 -2
  9. package/dist/agent/chat/exports.d.ts.map +1 -1
  10. package/dist/agent/chat/exports.js +1 -1
  11. package/dist/agent/chat/index.d.ts.map +1 -1
  12. package/dist/agent/chat/index.js +24 -4
  13. package/dist/agent/chat/models.d.ts +1 -3
  14. package/dist/agent/chat/models.d.ts.map +1 -1
  15. package/dist/agent/chat/models.js +4 -25
  16. package/dist/agent/cua/computer.d.ts +6 -6
  17. package/dist/agent/cua/computer.d.ts.map +1 -1
  18. package/dist/agent/cua/computer.js +38 -83
  19. package/dist/agent/cua/index.d.ts +2 -1
  20. package/dist/agent/cua/index.d.ts.map +1 -1
  21. package/dist/agent/cua/index.js +26 -33
  22. package/dist/agent/cua/pw-codegen/element-from-point.d.ts +8 -0
  23. package/dist/agent/cua/pw-codegen/element-from-point.d.ts.map +1 -0
  24. package/dist/agent/cua/pw-codegen/element-from-point.js +118 -0
  25. package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts +15 -0
  26. package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts.map +1 -0
  27. package/dist/agent/cua/pw-codegen/pw-pause/index.js +84 -0
  28. package/dist/agent/cua/pw-codegen/pw-pause/utils.d.ts +16 -0
  29. package/dist/agent/cua/pw-codegen/pw-pause/utils.d.ts.map +1 -0
  30. package/dist/agent/cua/pw-codegen/pw-pause/utils.js +98 -0
  31. package/dist/agent/cua/pw-codegen/types.d.ts +46 -0
  32. package/dist/agent/cua/pw-codegen/types.d.ts.map +1 -0
  33. package/dist/agent/cua/pw-codegen/types.js +2 -0
  34. package/dist/agent/master/browser-tests/cua.spec.js +13 -1
  35. package/dist/artifacts/index.d.ts +52 -0
  36. package/dist/artifacts/index.d.ts.map +1 -0
  37. package/dist/artifacts/index.js +237 -0
  38. package/dist/bin/index.js +7 -11
  39. package/dist/bin/utils/index.d.ts +5 -3
  40. package/dist/bin/utils/index.d.ts.map +1 -1
  41. package/dist/bin/utils/index.js +13 -0
  42. package/dist/bin/utils/platform/web/index.d.ts +1 -1
  43. package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
  44. package/dist/bin/utils/platform/web/index.js +3 -2
  45. package/dist/bin/utils/scenarios/index.d.ts +3 -3
  46. package/dist/file/client.d.ts +2 -0
  47. package/dist/file/client.d.ts.map +1 -1
  48. package/dist/file/client.js +16 -0
  49. package/dist/file/server.d.ts +3 -1
  50. package/dist/file/server.d.ts.map +1 -1
  51. package/dist/file/server.js +27 -3
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +4 -1
  54. package/dist/test-build/index.d.ts +6 -2
  55. package/dist/test-build/index.d.ts.map +1 -1
  56. package/dist/test-build/index.js +9 -7
  57. package/dist/tool-call-service/index.d.ts +14 -7
  58. package/dist/tool-call-service/index.d.ts.map +1 -1
  59. package/dist/tool-call-service/index.js +36 -10
  60. package/dist/tools/commit-and-create-pr.d.ts.map +1 -1
  61. package/dist/tools/commit-and-create-pr.js +11 -4
  62. package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
  63. package/dist/tools/diagnosis-fetcher.js +4 -3
  64. package/dist/tools/download-build.d.ts.map +1 -1
  65. package/dist/tools/download-build.js +3 -3
  66. package/dist/tools/environment-crud.d.ts.map +1 -1
  67. package/dist/tools/environment-crud.js +6 -4
  68. package/dist/tools/grep/index.d.ts.map +1 -1
  69. package/dist/tools/grep/index.js +13 -11
  70. package/dist/tools/str_replace_editor.d.ts +1 -1
  71. package/dist/tools/str_replace_editor.d.ts.map +1 -1
  72. package/dist/tools/str_replace_editor.js +38 -28
  73. package/dist/tools/test-gen-browser.d.ts.map +1 -1
  74. package/dist/tools/test-gen-browser.js +18 -4
  75. package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
  76. package/dist/tools/test-run-fetcher/index.js +2 -1
  77. package/dist/tools/test-run.d.ts.map +1 -1
  78. package/dist/tools/test-run.js +10 -8
  79. package/dist/tools/utils/index.d.ts +17 -2
  80. package/dist/tools/utils/index.d.ts.map +1 -1
  81. package/dist/tools/utils/index.js +51 -7
  82. package/dist/utils/checkpoint.d.ts +5 -1
  83. package/dist/utils/checkpoint.d.ts.map +1 -1
  84. package/dist/utils/checkpoint.js +8 -3
  85. package/dist/utils/exec.d.ts +2 -0
  86. package/dist/utils/exec.d.ts.map +1 -1
  87. package/dist/utils/exec.js +4 -1
  88. package/dist/utils/git.d.ts +12 -7
  89. package/dist/utils/git.d.ts.map +1 -1
  90. package/dist/utils/git.js +27 -17
  91. package/dist/utils/slug.d.ts +16 -0
  92. package/dist/utils/slug.d.ts.map +1 -1
  93. package/dist/utils/slug.js +27 -1
  94. package/package.json +6 -4
  95. package/tsconfig.tsbuildinfo +1 -1
  96. package/dist/utils/pw-test.d.ts +0 -2
  97. package/dist/utils/pw-test.d.ts.map +0 -1
  98. package/dist/utils/pw-test.js +0 -13
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runTestTool = void 0;
4
4
  const test_run_1 = require("@empiricalrun/test-run");
5
5
  const zod_1 = require("zod");
6
+ const artifacts_1 = require("../artifacts");
7
+ const utils_1 = require("./utils");
6
8
  const RunTestSchema = zod_1.z.object({
7
9
  testName: zod_1.z.string().describe("The name of the test to run"),
8
10
  suites: zod_1.z
@@ -13,11 +15,6 @@ const RunTestSchema = zod_1.z.object({
13
15
  .describe("The name of the file where the test is located. File name must end with .spec.ts"),
14
16
  project: zod_1.z.string().describe("The project to run the test on"),
15
17
  });
16
- function hasCloudflareCredentials() {
17
- return (process.env.R2_ACCOUNT_ID &&
18
- process.env.R2_ACCESS_KEY_ID &&
19
- process.env.R2_SECRET_ACCESS_KEY);
20
- }
21
18
  function buildReportUrl(projectName, testRunId) {
22
19
  return `https://reports.empirical.run/${projectName}/${testRunId}/index.html`;
23
20
  }
@@ -37,10 +34,10 @@ exports.runTestTool = {
37
34
  description: "Run a test",
38
35
  parameters: RunTestSchema,
39
36
  },
40
- execute: async (input) => {
37
+ execute: async (input, repoPath, apiKey, trace, collectArtifacts) => {
41
38
  let reportUrl = undefined;
42
39
  let envOverrides = undefined;
43
- if (hasCloudflareCredentials()) {
40
+ if ((0, artifacts_1.isArtifactCollectionEnabled)()) {
44
41
  const projectName = "test-gen-chat-agent";
45
42
  const testRunId = Date.now().toString();
46
43
  reportUrl = buildReportUrl(projectName, testRunId);
@@ -53,6 +50,7 @@ exports.runTestTool = {
53
50
  console.warn("R2 credentials not found: report artifacts will not be uploaded");
54
51
  }
55
52
  const { testName, suites, fileName, project } = input;
53
+ const repoDir = repoPath;
56
54
  try {
57
55
  const result = await (0, test_run_1.runSingleTest)({
58
56
  testName,
@@ -60,20 +58,24 @@ exports.runTestTool = {
60
58
  fileName,
61
59
  projects: [project],
62
60
  envOverrides,
61
+ repoDir,
63
62
  });
63
+ const attachments = (0, utils_1.extractAttachmentsFromPlaywrightJSONReport)(result.summaryJson);
64
+ void collectArtifacts?.(attachments);
64
65
  return {
66
+ isError: false,
65
67
  result: buildResult({
66
68
  hasTestPassed: result.hasTestPassed,
67
69
  summaryJson: result.summaryJson,
68
70
  reportUrl: reportUrl,
69
71
  }),
70
- isError: false,
71
72
  };
72
73
  }
73
74
  catch (error) {
74
75
  // Ensure we capture the full error message regardless of error type
75
76
  const errorMessage = error instanceof Error ? error.message : String(error);
76
77
  return {
78
+ artifacts: null,
77
79
  result: JSON.stringify({ error: errorMessage }),
78
80
  isError: true,
79
81
  };
@@ -1,11 +1,26 @@
1
- export declare function makeDashboardRequest<T>({ path, method, body, }: {
1
+ import { JSONReport as PlaywrightJSONReport } from "@playwright/test/reporter";
2
+ export declare function makeDashboardRequest<T>({ path, method, body, apiKey, }: {
2
3
  path: string;
3
4
  method?: string;
4
5
  body?: any;
6
+ apiKey: string;
5
7
  }): Promise<T>;
6
- export declare function callGitHubProxy({ method, url, body, }: {
8
+ export declare function callGitHubProxy({ method, url, body, apiKey, }: {
7
9
  method: string;
8
10
  url: string;
9
11
  body?: any;
12
+ apiKey: string;
10
13
  }): Promise<unknown>;
14
+ type AttachmentInfo = {
15
+ name: string;
16
+ path: string;
17
+ contentType: string;
18
+ };
19
+ /**
20
+ * Extracts attachment information from a Playwright JSON report.
21
+ * @param report The Playwright JSON report to extract attachments from
22
+ * @returns An array of objects containing path and contentType for each attachment
23
+ */
24
+ export declare function extractAttachmentsFromPlaywrightJSONReport(report: PlaywrightJSONReport): AttachmentInfo[];
25
+ export {};
11
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/utils/index.ts"],"names":[],"mappings":"AAAA,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,EAC5C,IAAI,EACJ,MAAc,EACd,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ,GAAG,OAAO,CAAC,CAAC,CAAC,CAuBb;AAED,wBAAsB,eAAe,CAAC,EACpC,MAAM,EACN,GAAG,EACH,IAAI,GACL,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ,oBAWA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,IAAI,oBAAoB,EAEnC,MAAM,2BAA2B,CAAC;AAEnC,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,EAC5C,IAAI,EACJ,MAAc,EACd,IAAI,EACJ,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,CAAC,CAAC,CAmBb;AAED,wBAAsB,eAAe,CAAC,EACpC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,MAAM,GACP,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB,oBAYA;AAED,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,0CAA0C,CACxD,MAAM,EAAE,oBAAoB,GAC3B,cAAc,EAAE,CA4ClB"}
@@ -2,14 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeDashboardRequest = makeDashboardRequest;
4
4
  exports.callGitHubProxy = callGitHubProxy;
5
- async function makeDashboardRequest({ path, method = "GET", body, }) {
6
- const API_KEY = process.env.EMPIRICALRUN_API_KEY;
7
- if (!API_KEY) {
8
- throw new Error("EMPIRICALRUN_API_KEY is not found");
9
- }
5
+ exports.extractAttachmentsFromPlaywrightJSONReport = extractAttachmentsFromPlaywrightJSONReport;
6
+ async function makeDashboardRequest({ path, method = "GET", body, apiKey, }) {
10
7
  const requestHeaders = {
11
8
  "Content-Type": "application/json",
12
- Authorization: `Bearer ${API_KEY}`,
9
+ Authorization: `Bearer ${apiKey}`,
13
10
  "User-Agent": "empiricalrun/test-gen",
14
11
  };
15
12
  const baseUrl = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
@@ -24,7 +21,7 @@ async function makeDashboardRequest({ path, method = "GET", body, }) {
24
21
  }
25
22
  return await response.json();
26
23
  }
27
- async function callGitHubProxy({ method, url, body, }) {
24
+ async function callGitHubProxy({ method, url, body, apiKey, }) {
28
25
  const githubApiPath = url.replace("https://api.github.com", "");
29
26
  return makeDashboardRequest({
30
27
  path: "/api/github/proxy",
@@ -34,5 +31,52 @@ async function callGitHubProxy({ method, url, body, }) {
34
31
  url: githubApiPath,
35
32
  body,
36
33
  },
34
+ apiKey,
37
35
  });
38
36
  }
37
+ /**
38
+ * Extracts attachment information from a Playwright JSON report.
39
+ * @param report The Playwright JSON report to extract attachments from
40
+ * @returns An array of objects containing path and contentType for each attachment
41
+ */
42
+ function extractAttachmentsFromPlaywrightJSONReport(report) {
43
+ const attachments = [];
44
+ if (!report) {
45
+ return attachments;
46
+ }
47
+ function processSpec(spec) {
48
+ const testTitle = spec.title;
49
+ for (const test of spec.tests) {
50
+ for (const result of test.results) {
51
+ if (!result.attachments)
52
+ continue;
53
+ for (const attachment of result.attachments) {
54
+ if (attachment.path && attachment.contentType) {
55
+ attachments.push({
56
+ name: `${testTitle} ${attachment.name}`,
57
+ path: attachment.path,
58
+ contentType: attachment.contentType,
59
+ });
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ for (const suite of report.suites) {
66
+ // Process nested suites
67
+ if (suite.suites) {
68
+ for (const nestedSuite of suite.suites) {
69
+ for (const spec of nestedSuite.specs) {
70
+ processSpec(spec);
71
+ }
72
+ }
73
+ }
74
+ // Process specs in current suite
75
+ if (suite.specs) {
76
+ for (const spec of suite.specs) {
77
+ processSpec(spec);
78
+ }
79
+ }
80
+ }
81
+ return attachments;
82
+ }
@@ -1,3 +1,7 @@
1
1
  import { PendingToolCall } from "@empiricalrun/llm/chat";
2
- export declare function createCheckpoint(toolCalls: PendingToolCall[], branchName: string): Promise<void>;
2
+ export declare function createCheckpoint({ toolCalls, branchName, repoPath, }: {
3
+ toolCalls: PendingToolCall[];
4
+ branchName: string;
5
+ repoPath: string;
6
+ }): Promise<void>;
3
7
  //# sourceMappingURL=checkpoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/utils/checkpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,eAAe,EAAE,EAC5B,UAAU,EAAE,MAAM,iBAqBnB"}
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/utils/checkpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD,wBAAsB,gBAAgB,CAAC,EACrC,SAAS,EACT,UAAU,EACV,QAAQ,GACT,EAAE;IACD,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAyBA"}
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCheckpoint = createCheckpoint;
4
4
  const git_1 = require("./git");
5
- async function createCheckpoint(toolCalls, branchName) {
6
- const filesChanged = await (0, git_1.getFilesChanged)();
5
+ async function createCheckpoint({ toolCalls, branchName, repoPath, }) {
6
+ const filesChanged = await (0, git_1.getFilesChanged)(repoPath);
7
7
  const toolsWithUpdatedFiles = toolCalls
8
8
  .filter((tc) => "path" in tc.input &&
9
9
  tc.input.path &&
@@ -15,6 +15,11 @@ async function createCheckpoint(toolCalls, branchName) {
15
15
  const filesToCommit = toolsWithUpdatedFiles.map((tool) => tool.path);
16
16
  if (toolsWithUpdatedFiles.length > 0) {
17
17
  let commitMessage = `${toolsWithUpdatedFiles.map((tool) => `${tool.name} on ${tool.path}`).join(", ")}`;
18
- await (0, git_1.commitFilesAndPushBranch)(commitMessage, branchName, filesToCommit);
18
+ await (0, git_1.commitFilesAndPushBranch)({
19
+ commitMessage,
20
+ branchName,
21
+ files: filesToCommit,
22
+ repoPath,
23
+ });
19
24
  }
20
25
  }
@@ -2,11 +2,13 @@ export declare class ProcessManager {
2
2
  private childProcess;
3
3
  execute(command: string, args: string[], options: {
4
4
  env?: Record<string, string>;
5
+ cwd?: string;
5
6
  }): Promise<number>;
6
7
  terminate(): void;
7
8
  isRunning(): boolean;
8
9
  }
9
10
  export declare function cmd(command: string, args: string[], options: {
10
11
  env?: Record<string, string>;
12
+ cwd?: string;
11
13
  }): Promise<number>;
12
14
  //# sourceMappingURL=exec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAmBA,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAA6B;IAE3C,OAAO,CACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GACxC,OAAO,CAAC,MAAM,CAAC;IAmDlB,SAAS,IAAI,IAAI;IASjB,SAAS,IAAI,OAAO;CAGrB;AAED,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAGjB"}
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAmBA,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAA6B;IAE3C,OAAO,CACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EAEd,OAAO,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACtD,OAAO,CAAC,MAAM,CAAC;IAoDlB,SAAS,IAAI,IAAI;IASjB,SAAS,IAAI,OAAO;CAGrB;AAED,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC,MAAM,CAAC,CAGjB"}
@@ -21,7 +21,9 @@ function isAcceptableExit(exitCode, signal) {
21
21
  }
22
22
  class ProcessManager {
23
23
  childProcess = null;
24
- async execute(command, args, options) {
24
+ async execute(command, args,
25
+ // TODO: Make these required when all tools use repoPath
26
+ options) {
25
27
  console.log(`Executing command: ${command} with args: ${args}`);
26
28
  if (this.childProcess) {
27
29
  throw new Error("Process is already running");
@@ -34,6 +36,7 @@ class ProcessManager {
34
36
  }
35
37
  const p = (0, child_process_1.spawn)(command, args, {
36
38
  env: { ...process_1.default.env, ...options.env },
39
+ cwd: options.cwd,
37
40
  detached: true, // Create process group so we can terminate all child processes
38
41
  });
39
42
  this.childProcess = p;
@@ -1,8 +1,13 @@
1
- export declare function getGitDiff(filepath: string): string;
2
- export declare function checkoutBranch(branchName: string): Promise<void>;
3
- export declare function commitAsBotUser(commitMessage: string): Promise<void>;
4
- export declare function getCurrentBranchName(): Promise<string>;
5
- export declare function pullBranch(branchName: string): Promise<void>;
6
- export declare function commitFilesAndPushBranch(commitMessage: string, branchName: string, files: string[]): Promise<void>;
7
- export declare function getFilesChanged(): Promise<string[]>;
1
+ export declare function getGitDiff(filepath: string, cwd: string): string;
2
+ export declare function checkoutBranch(branchName: string, cwd: string): Promise<void>;
3
+ export declare function commitAsBotUser(commitMessage: string, cwd: string): Promise<void>;
4
+ export declare function getCurrentBranchName(repoPath: string): Promise<string>;
5
+ export declare function pullBranch(branchName: string, cwd: string): Promise<void>;
6
+ export declare function commitFilesAndPushBranch({ commitMessage, branchName, files, repoPath, }: {
7
+ commitMessage: string;
8
+ branchName: string;
9
+ files: string[];
10
+ repoPath: string;
11
+ }): Promise<void>;
12
+ export declare function getFilesChanged(cwd: string): Promise<string[]>;
8
13
  //# sourceMappingURL=git.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAKA,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,iBAQtD;AAED,wBAAsB,eAAe,CAAC,aAAa,EAAE,MAAM,iBAS1D;AAED,wBAAsB,oBAAoB,oBAGzC;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,iBAElD;AAED,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EAAE,iBAKhB;AAED,wBAAsB,eAAe,sBAUpC"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAKA,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,iBAQnE;AAED,wBAAsB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,iBAavE;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,mBAO1D;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,iBAE/D;AAED,wBAAsB,wBAAwB,CAAC,EAC7C,aAAa,EACb,UAAU,EACV,KAAK,EACL,QAAQ,GACT,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAIA;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,qBAUhD"}
package/dist/utils/git.js CHANGED
@@ -10,44 +10,54 @@ exports.getFilesChanged = getFilesChanged;
10
10
  const child_process_1 = require("child_process");
11
11
  const GIT_USER_NAME = "empiricalrun[bot]";
12
12
  const GIT_USER_EMAIL = "180257021+empiricalrun[bot]@users.noreply.github.com";
13
- function getGitDiff(filepath) {
13
+ function getGitDiff(filepath, cwd) {
14
14
  const diff = (0, child_process_1.execSync)(`git diff ${filepath}`, {
15
15
  encoding: "utf-8",
16
+ cwd,
16
17
  });
17
18
  return diff;
18
19
  }
19
- async function checkoutBranch(branchName) {
20
+ async function checkoutBranch(branchName, cwd) {
20
21
  // TODO: This assumes repoDir is process.cwd()
21
22
  try {
22
- (0, child_process_1.execSync)(`git checkout ${branchName}`);
23
+ (0, child_process_1.execSync)(`git checkout ${branchName}`, { cwd });
23
24
  }
24
25
  catch (e) {
25
26
  // If branch doesn't exist, create it
26
- (0, child_process_1.execSync)(`git checkout -b ${branchName}`);
27
+ (0, child_process_1.execSync)(`git checkout -b ${branchName}`, { cwd });
27
28
  }
28
29
  }
29
- async function commitAsBotUser(commitMessage) {
30
- const status = (0, child_process_1.execSync)("git status --porcelain", { encoding: "utf-8" });
30
+ async function commitAsBotUser(commitMessage, cwd) {
31
+ const status = (0, child_process_1.execSync)("git status --porcelain", {
32
+ encoding: "utf-8",
33
+ cwd,
34
+ });
31
35
  if (!status) {
32
36
  return; // Nothing to commit
33
37
  }
34
38
  const commitMessageWithSkipCi = `${commitMessage} [skip ci]`;
35
- (0, child_process_1.execSync)(`git -c user.name="${GIT_USER_NAME}" -c user.email="${GIT_USER_EMAIL}" commit -m "${commitMessageWithSkipCi}"`);
39
+ (0, child_process_1.execSync)(`git -c user.name="${GIT_USER_NAME}" -c user.email="${GIT_USER_EMAIL}" commit -m "${commitMessageWithSkipCi}"`, { cwd });
36
40
  }
37
- async function getCurrentBranchName() {
38
- const branchName = (0, child_process_1.execSync)("git branch --show-current").toString().trim();
41
+ async function getCurrentBranchName(repoPath) {
42
+ const branchName = (0, child_process_1.execSync)("git branch --show-current", {
43
+ cwd: repoPath,
44
+ })
45
+ .toString()
46
+ .trim();
39
47
  return branchName;
40
48
  }
41
- async function pullBranch(branchName) {
42
- (0, child_process_1.execSync)(`git pull origin ${branchName}`);
49
+ async function pullBranch(branchName, cwd) {
50
+ (0, child_process_1.execSync)(`git pull origin ${branchName}`, { cwd });
43
51
  }
44
- async function commitFilesAndPushBranch(commitMessage, branchName, files) {
45
- (0, child_process_1.execSync)(`git add ${files.join(" ")}`);
46
- await commitAsBotUser(commitMessage);
47
- (0, child_process_1.execSync)(`git push origin ${branchName}`);
52
+ async function commitFilesAndPushBranch({ commitMessage, branchName, files, repoPath, }) {
53
+ (0, child_process_1.execSync)(`git add ${files.join(" ")}`, { cwd: repoPath });
54
+ await commitAsBotUser(commitMessage, repoPath);
55
+ (0, child_process_1.execSync)(`git push origin ${branchName}`, { cwd: repoPath });
48
56
  }
49
- async function getFilesChanged() {
50
- const output = (0, child_process_1.execSync)("git status --porcelain --untracked-files").toString();
57
+ async function getFilesChanged(cwd) {
58
+ const output = (0, child_process_1.execSync)("git status --porcelain --untracked-files", {
59
+ cwd,
60
+ }).toString();
51
61
  let filesChanged = output
52
62
  .split("\n")
53
63
  .map((line) => line.trim().split(" ").pop())
@@ -1,2 +1,18 @@
1
1
  export declare const asyncGenerateRandomSlug: (size: number) => Promise<string>;
2
+ /**
3
+ * Converts a string into a URL-friendly slug by:
4
+ * 1. Converting to lowercase
5
+ * 2. Replacing non-alphanumeric characters with hyphens
6
+ * 3. Collapsing multiple hyphens into single hyphens
7
+ * 4. Removing empty segments
8
+ * 5. Removing leading and trailing hyphens
9
+ *
10
+ * @param str - The input string to convert into a slug
11
+ * @returns A URL-friendly slug string
12
+ * @example
13
+ * slugify("Hello World!") // returns "hello-world"
14
+ * slugify("Test & Case") // returns "test-case"
15
+ * slugify("Multiple---Hyphens") // returns "multiple-hyphens"
16
+ */
17
+ export declare const slugify: (str: string) => string;
2
18
  //# sourceMappingURL=slug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../src/utils/slug.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,uBAAuB,GAAU,MAAM,MAAM,oBAOzD,CAAC"}
1
+ {"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../src/utils/slug.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,uBAAuB,GAAU,MAAM,MAAM,oBAOzD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MASrC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.asyncGenerateRandomSlug = void 0;
3
+ exports.slugify = exports.asyncGenerateRandomSlug = void 0;
4
4
  // @ts-ignore
5
5
  let customAlphabet;
6
6
  const loadNanoid = async () => {
@@ -16,3 +16,29 @@ const asyncGenerateRandomSlug = async (size) => {
16
16
  return nanoid();
17
17
  };
18
18
  exports.asyncGenerateRandomSlug = asyncGenerateRandomSlug;
19
+ /**
20
+ * Converts a string into a URL-friendly slug by:
21
+ * 1. Converting to lowercase
22
+ * 2. Replacing non-alphanumeric characters with hyphens
23
+ * 3. Collapsing multiple hyphens into single hyphens
24
+ * 4. Removing empty segments
25
+ * 5. Removing leading and trailing hyphens
26
+ *
27
+ * @param str - The input string to convert into a slug
28
+ * @returns A URL-friendly slug string
29
+ * @example
30
+ * slugify("Hello World!") // returns "hello-world"
31
+ * slugify("Test & Case") // returns "test-case"
32
+ * slugify("Multiple---Hyphens") // returns "multiple-hyphens"
33
+ */
34
+ const slugify = (str) => {
35
+ const join = "-";
36
+ return str
37
+ .toLowerCase()
38
+ .replace(/[^a-z0-9-]+/g, join)
39
+ .replace(/-+/g, join)
40
+ .split(join)
41
+ .filter(Boolean)
42
+ .join(join);
43
+ };
44
+ exports.slugify = slugify;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.61.0",
3
+ "version": "0.63.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -50,6 +50,7 @@
50
50
  "inquirer": "^12.4.2",
51
51
  "istextorbinary": "^9.5.0",
52
52
  "jsdom": "^26.0.0",
53
+ "mime": "3.0.0",
53
54
  "minimatch": "^10.0.1",
54
55
  "nanoid": "^5.0.7",
55
56
  "openai": "4.87.3",
@@ -61,9 +62,9 @@
61
62
  "tsx": "^4.16.2",
62
63
  "typescript": "^5.3.3",
63
64
  "zod": "^3.23.8",
64
- "@empiricalrun/llm": "^0.16.1",
65
+ "@empiricalrun/llm": "^0.17.1",
65
66
  "@empiricalrun/r2-uploader": "^0.3.9",
66
- "@empiricalrun/test-run": "^0.9.2"
67
+ "@empiricalrun/test-run": "^0.9.4"
67
68
  },
68
69
  "devDependencies": {
69
70
  "@playwright/test": "1.47.1",
@@ -72,12 +73,13 @@
72
73
  "@types/express": "^4.17.21",
73
74
  "@types/js-levenshtein": "^1.1.3",
74
75
  "@types/jsdom": "^21.1.7",
76
+ "@types/mime": "3.0.0",
75
77
  "@types/serve-handler": "^6.1.4",
76
78
  "js-levenshtein": "^1.1.6",
77
79
  "playwright": "1.47.1",
78
80
  "serve-handler": "^6.1.6",
79
81
  "ts-patch": "^3.3.0",
80
- "@empiricalrun/shared-types": "0.2.0"
82
+ "@empiricalrun/shared-types": "0.4.0"
81
83
  },
82
84
  "scripts": {
83
85
  "dev": "tspc --build --watch",
@@ -1 +1 @@
1
- {"root":["./src/index.ts","./src/actions/assert.ts","./src/actions/click.ts","./src/actions/done.ts","./src/actions/fill.ts","./src/actions/goto.ts","./src/actions/hover.ts","./src/actions/index.ts","./src/actions/next-task.ts","./src/actions/press.ts","./src/actions/skill.ts","./src/actions/text-content.ts","./src/actions/constants/index.ts","./src/actions/utils/index.ts","./src/agent/browsing/index.ts","./src/agent/browsing/run.ts","./src/agent/browsing/utils.ts","./src/agent/chat/agent-loop.ts","./src/agent/chat/exports.ts","./src/agent/chat/index.ts","./src/agent/chat/models.ts","./src/agent/chat/prompt.ts","./src/agent/chat/repo.ts","./src/agent/chat/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/codegen/create-test-block.ts","./src/agent/codegen/fix-ts-errors.ts","./src/agent/codegen/generate-code-apply-changes.ts","./src/agent/codegen/lexical-scoped-vars.ts","./src/agent/codegen/repo-edit.ts","./src/agent/codegen/run.ts","./src/agent/codegen/skills-retriever.ts","./src/agent/codegen/test-update-feedback.ts","./src/agent/codegen/types.ts","./src/agent/codegen/update-flow.ts","./src/agent/codegen/use-skill.ts","./src/agent/codegen/utils.ts","./src/agent/cua/computer.ts","./src/agent/cua/index.ts","./src/agent/cua/model.ts","./src/agent/diagnosis-agent/index.ts","./src/agent/diagnosis-agent/strict-mode-violation.ts","./src/agent/enrich-prompt/index.ts","./src/agent/enrich-prompt/utils.ts","./src/agent/infer-agent/index.ts","./src/agent/master/action-tool-calls.ts","./src/agent/master/element-annotation.ts","./src/agent/master/execute-browser-action.ts","./src/agent/master/execute-skill-action.ts","./src/agent/master/next-action.ts","./src/agent/master/planner.ts","./src/agent/master/run.ts","./src/agent/master/scroller.ts","./src/agent/master/with-hints.ts","./src/agent/master/browser-tests/cua.spec.ts","./src/agent/master/browser-tests/fixtures.ts","./src/agent/master/browser-tests/index.spec.ts","./src/agent/master/browser-tests/skills.spec.ts","./src/agent/master/icon-descriptor/index.ts","./src/agent/master/icon-descriptor/normalize-svg.ts","./src/agent/planner/run-time-planner.ts","./src/agent/planner/run.ts","./src/bin/index.ts","./src/bin/logger/index.ts","./src/bin/utils/context.ts","./src/bin/utils/index.ts","./src/bin/utils/fs/index.ts","./src/bin/utils/platform/web/index.ts","./src/bin/utils/platform/web/test-files/ts-path-import-validate.ts","./src/bin/utils/scenarios/index.ts","./src/browser-injected-scripts/annotate-elements.spec.ts","./src/constants/index.ts","./src/errors/index.ts","./src/evals/add-scenario-agent.evals.ts","./src/evals/append-create-test-agent.evals.ts","./src/evals/fetch-pom-skills-agent.evals.ts","./src/evals/infer-master-or-code-agent.evals.ts","./src/evals/master-agent.evals.ts","./src/evals/type.ts","./src/evals/update-scenario-agent.evals.ts","./src/file/client.ts","./src/file/server.ts","./src/human-in-the-loop/cli.ts","./src/human-in-the-loop/index.ts","./src/human-in-the-loop/ipc.ts","./src/page/index.ts","./src/prompts/lib/ts-transformer.ts","./src/reporter/index.ts","./src/reporter/lib.ts","./src/session/index.ts","./src/test-build/index.ts","./src/tool-call-service/index.ts","./src/tool-call-service/utils.ts","./src/tools/codegen-agent.ts","./src/tools/commit-and-create-pr.ts","./src/tools/diagnosis-fetcher.ts","./src/tools/download-build.ts","./src/tools/environment-crud.ts","./src/tools/str_replace_editor.ts","./src/tools/test-gen-browser.ts","./src/tools/test-run.ts","./src/tools/grep/index.ts","./src/tools/grep/ripgrep/index.ts","./src/tools/grep/ripgrep/types.ts","./src/tools/test-run-fetcher/index.ts","./src/tools/test-run-fetcher/types.ts","./src/tools/utils/index.ts","./src/types/handlebars.d.ts","./src/types/index.ts","./src/uploader/index.ts","./src/uploader/utils.ts","./src/utils/checkpoint.ts","./src/utils/env.ts","./src/utils/exec.ts","./src/utils/file-tree.ts","./src/utils/file.ts","./src/utils/git.ts","./src/utils/html.ts","./src/utils/index.ts","./src/utils/pw-test.ts","./src/utils/repo-tree.ts","./src/utils/slug.ts","./src/utils/string.ts","./src/utils/stripAnsi.ts"],"version":"5.8.3"}
1
+ {"root":["./src/index.ts","./src/actions/assert.ts","./src/actions/click.ts","./src/actions/done.ts","./src/actions/fill.ts","./src/actions/goto.ts","./src/actions/hover.ts","./src/actions/index.ts","./src/actions/next-task.ts","./src/actions/press.ts","./src/actions/skill.ts","./src/actions/text-content.ts","./src/actions/constants/index.ts","./src/actions/utils/index.ts","./src/agent/browsing/index.ts","./src/agent/browsing/run.ts","./src/agent/browsing/utils.ts","./src/agent/chat/agent-loop.ts","./src/agent/chat/exports.ts","./src/agent/chat/index.ts","./src/agent/chat/models.ts","./src/agent/chat/prompt.ts","./src/agent/chat/repo.ts","./src/agent/chat/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/codegen/create-test-block.ts","./src/agent/codegen/fix-ts-errors.ts","./src/agent/codegen/generate-code-apply-changes.ts","./src/agent/codegen/lexical-scoped-vars.ts","./src/agent/codegen/repo-edit.ts","./src/agent/codegen/run.ts","./src/agent/codegen/skills-retriever.ts","./src/agent/codegen/test-update-feedback.ts","./src/agent/codegen/types.ts","./src/agent/codegen/update-flow.ts","./src/agent/codegen/use-skill.ts","./src/agent/codegen/utils.ts","./src/agent/cua/computer.ts","./src/agent/cua/index.ts","./src/agent/cua/model.ts","./src/agent/cua/pw-codegen/element-from-point.ts","./src/agent/cua/pw-codegen/types.ts","./src/agent/cua/pw-codegen/pw-pause/index.ts","./src/agent/cua/pw-codegen/pw-pause/utils.ts","./src/agent/diagnosis-agent/index.ts","./src/agent/diagnosis-agent/strict-mode-violation.ts","./src/agent/enrich-prompt/index.ts","./src/agent/enrich-prompt/utils.ts","./src/agent/infer-agent/index.ts","./src/agent/master/action-tool-calls.ts","./src/agent/master/element-annotation.ts","./src/agent/master/execute-browser-action.ts","./src/agent/master/execute-skill-action.ts","./src/agent/master/next-action.ts","./src/agent/master/planner.ts","./src/agent/master/run.ts","./src/agent/master/scroller.ts","./src/agent/master/with-hints.ts","./src/agent/master/browser-tests/cua.spec.ts","./src/agent/master/browser-tests/fixtures.ts","./src/agent/master/browser-tests/index.spec.ts","./src/agent/master/browser-tests/skills.spec.ts","./src/agent/master/icon-descriptor/index.ts","./src/agent/master/icon-descriptor/normalize-svg.ts","./src/agent/planner/run-time-planner.ts","./src/agent/planner/run.ts","./src/artifacts/index.ts","./src/bin/index.ts","./src/bin/logger/index.ts","./src/bin/utils/context.ts","./src/bin/utils/index.ts","./src/bin/utils/fs/index.ts","./src/bin/utils/platform/web/index.ts","./src/bin/utils/platform/web/test-files/ts-path-import-validate.ts","./src/bin/utils/scenarios/index.ts","./src/browser-injected-scripts/annotate-elements.spec.ts","./src/constants/index.ts","./src/errors/index.ts","./src/evals/add-scenario-agent.evals.ts","./src/evals/append-create-test-agent.evals.ts","./src/evals/fetch-pom-skills-agent.evals.ts","./src/evals/infer-master-or-code-agent.evals.ts","./src/evals/master-agent.evals.ts","./src/evals/type.ts","./src/evals/update-scenario-agent.evals.ts","./src/file/client.ts","./src/file/server.ts","./src/human-in-the-loop/cli.ts","./src/human-in-the-loop/index.ts","./src/human-in-the-loop/ipc.ts","./src/page/index.ts","./src/prompts/lib/ts-transformer.ts","./src/reporter/index.ts","./src/reporter/lib.ts","./src/session/index.ts","./src/test-build/index.ts","./src/tool-call-service/index.ts","./src/tool-call-service/utils.ts","./src/tools/codegen-agent.ts","./src/tools/commit-and-create-pr.ts","./src/tools/diagnosis-fetcher.ts","./src/tools/download-build.ts","./src/tools/environment-crud.ts","./src/tools/str_replace_editor.ts","./src/tools/test-gen-browser.ts","./src/tools/test-run.ts","./src/tools/grep/index.ts","./src/tools/grep/ripgrep/index.ts","./src/tools/grep/ripgrep/types.ts","./src/tools/test-run-fetcher/index.ts","./src/tools/test-run-fetcher/types.ts","./src/tools/utils/index.ts","./src/types/handlebars.d.ts","./src/types/index.ts","./src/uploader/index.ts","./src/uploader/utils.ts","./src/utils/checkpoint.ts","./src/utils/env.ts","./src/utils/exec.ts","./src/utils/file-tree.ts","./src/utils/file.ts","./src/utils/git.ts","./src/utils/html.ts","./src/utils/index.ts","./src/utils/repo-tree.ts","./src/utils/slug.ts","./src/utils/string.ts","./src/utils/stripAnsi.ts"],"version":"5.8.3"}
@@ -1,2 +0,0 @@
1
- export declare function getTestFixtureModuleFromRepo(repoDir: string): Promise<any>;
2
- //# sourceMappingURL=pw-test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,CAKd"}
@@ -1,13 +0,0 @@
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.getTestFixtureModuleFromRepo = getTestFixtureModuleFromRepo;
7
- const api_1 = __importDefault(require("tsx/cjs/api"));
8
- async function getTestFixtureModuleFromRepo(repoDir) {
9
- const [lastDir] = repoDir.split("/").reverse();
10
- const dir = `${repoDir}/${lastDir}`;
11
- const { test } = await api_1.default.require(`./tests/fixtures.ts`, dir);
12
- return test;
13
- }