@empiricalrun/test-gen 0.69.7 → 0.70.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.
- package/CHANGELOG.md +21 -0
- package/dist/agent/chat/index.d.ts +0 -4
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +0 -71
- package/dist/agent/cua/pw-codegen/pw-pause/for-recorder.d.ts.map +1 -1
- package/dist/agent/cua/pw-codegen/pw-pause/for-recorder.js +22 -21
- package/dist/auth/api-client.d.ts +3 -1
- package/dist/auth/api-client.d.ts.map +1 -1
- package/dist/bin/environments.d.ts +2 -0
- package/dist/bin/environments.d.ts.map +1 -0
- package/dist/bin/environments.js +66 -0
- package/dist/bin/index.js +4 -46
- package/dist/recorder/index.d.ts.map +1 -1
- package/dist/recorder/index.js +11 -2
- package/dist/recorder/temp-files.d.ts +2 -1
- package/dist/recorder/temp-files.d.ts.map +1 -1
- package/dist/recorder/temp-files.js +57 -27
- package/dist/recorder/upload.d.ts +1 -0
- package/dist/recorder/upload.d.ts.map +1 -1
- package/dist/recorder/upload.js +24 -1
- package/dist/tools/upgrade-packages/index.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/index.js +30 -23
- package/dist/tools/upgrade-packages/utils.d.ts +10 -1
- package/dist/tools/upgrade-packages/utils.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/utils.js +55 -47
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/recorder/glob.d.ts +0 -2
- package/dist/recorder/glob.d.ts.map +0 -1
- package/dist/recorder/glob.js +0 -74
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.70.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2daef2d: feat: upgrade-pkgs tool schema and PR details updated
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 1348b1a: chore: refactor slack client into internal vs external usage
|
|
12
|
+
- 4274dc5: fix: json report output should exist for video upload
|
|
13
|
+
- 39b105b: fix: auto-merge checks in upgrade package tool
|
|
14
|
+
|
|
15
|
+
## 0.69.8
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- a2ce1ec: fix: glass pane removal across browser context
|
|
20
|
+
- ff7d9e6: fix: temp file computation for recorder
|
|
21
|
+
- 5e9aeb7: fix: environments list command in test-gen cli
|
|
22
|
+
- @empiricalrun/llm@0.19.3
|
|
23
|
+
|
|
3
24
|
## 0.69.7
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -5,8 +5,4 @@ export declare function runChatAgentForCLI({ useDiskForChatState, selectedModel,
|
|
|
5
5
|
useDiskForChatState: boolean;
|
|
6
6
|
initialPromptContent: string | undefined;
|
|
7
7
|
}): Promise<void>;
|
|
8
|
-
export declare function runChatAgentForDashboard({ chatSessionId, selectedModel, }: {
|
|
9
|
-
selectedModel: SupportedChatModels;
|
|
10
|
-
chatSessionId: number;
|
|
11
|
-
}): Promise<void>;
|
|
12
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAoCpC,wBAAsB,yBAAyB,IAAI,OAAO,CACxD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CACvB,CAwBA;AAED,wBAAsB,kBAAkB,CAAC,EACvC,mBAAmB,EACnB,aAAa,EACb,oBAAoB,GACrB,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,iBAkIA"}
|
package/dist/agent/chat/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchEnvironmentVariables = fetchEnvironmentVariables;
|
|
4
4
|
exports.runChatAgentForCLI = runChatAgentForCLI;
|
|
5
|
-
exports.runChatAgentForDashboard = runChatAgentForDashboard;
|
|
6
5
|
const llm_1 = require("@empiricalrun/llm");
|
|
7
6
|
const chat_1 = require("@empiricalrun/llm/chat");
|
|
8
7
|
const picocolors_1 = require("picocolors");
|
|
@@ -159,73 +158,3 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
159
158
|
const usageSummary = chatModel.getUsageSummary();
|
|
160
159
|
console.log(`\n${(0, picocolors_1.gray)("Usage summary -> " + usageSummary)}`);
|
|
161
160
|
}
|
|
162
|
-
async function getChatSessionFromDashboard(chatSessionId) {
|
|
163
|
-
const response = await fetch(`${DASHBOARD_DOMAIN}/api/chat-sessions/${chatSessionId}`, {
|
|
164
|
-
headers: {
|
|
165
|
-
"Content-Type": "application/json",
|
|
166
|
-
Authorization: `Bearer ${process.env.EMPIRICALRUN_API_KEY}`,
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
if (!response.ok) {
|
|
170
|
-
throw new Error(`Failed to get chat session: ${response.statusText}`);
|
|
171
|
-
}
|
|
172
|
-
const data = await response.json();
|
|
173
|
-
return data.data.chat_session;
|
|
174
|
-
}
|
|
175
|
-
async function runChatAgentForDashboard({ chatSessionId, selectedModel, }) {
|
|
176
|
-
const chatSession = await getChatSessionFromDashboard(chatSessionId);
|
|
177
|
-
let chatState = chatSession.chat_state;
|
|
178
|
-
// If not already canonical, migrate to canonical format
|
|
179
|
-
if (!chatState.version || chatState.version !== state_1.LATEST_CHAT_STATE_VERSION) {
|
|
180
|
-
chatState = (0, state_1.migrateChatState)(chatState);
|
|
181
|
-
}
|
|
182
|
-
const branchName = chatSession.branch_name;
|
|
183
|
-
const trace = llm_1.langfuseInstance?.trace({
|
|
184
|
-
id: chatSession.langfuse_trace_id,
|
|
185
|
-
name: "chat_agent",
|
|
186
|
-
input: chatState,
|
|
187
|
-
tags: [selectedModel, "chat_agent"],
|
|
188
|
-
metadata: {
|
|
189
|
-
chatSessionId,
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
if (!process.env.EMPIRICALRUN_API_KEY) {
|
|
193
|
-
throw new Error("EMPIRICALRUN_API_KEY is not set");
|
|
194
|
-
}
|
|
195
|
-
const toolCallService = new tool_call_service_1.ToolCallService({
|
|
196
|
-
chatSessionId,
|
|
197
|
-
selectedModel,
|
|
198
|
-
branchName,
|
|
199
|
-
repoPath: process.cwd(),
|
|
200
|
-
apiKey: process.env.EMPIRICALRUN_API_KEY,
|
|
201
|
-
trace,
|
|
202
|
-
featureFlags: [],
|
|
203
|
-
});
|
|
204
|
-
await (0, git_1.checkoutBranch)(branchName, process.cwd());
|
|
205
|
-
let chatModel = (0, chat_1.createChatModel)(chatState.messages, selectedModel);
|
|
206
|
-
let reporterFunc = async (chatState, latest) => {
|
|
207
|
-
const response = await fetch(`${DASHBOARD_DOMAIN}/api/chat-sessions/${chatSessionId}`, {
|
|
208
|
-
method: "PATCH",
|
|
209
|
-
body: JSON.stringify({
|
|
210
|
-
chat_state: chatState,
|
|
211
|
-
last_assistant_message: latest?.textMessage,
|
|
212
|
-
}),
|
|
213
|
-
headers: {
|
|
214
|
-
"Content-Type": "application/json",
|
|
215
|
-
Authorization: `Bearer ${process.env.EMPIRICALRUN_API_KEY}`,
|
|
216
|
-
},
|
|
217
|
-
});
|
|
218
|
-
const data = await response.json();
|
|
219
|
-
console.log(`Patch request sent for chat session: ${JSON.stringify(data)}`);
|
|
220
|
-
};
|
|
221
|
-
const fileInfo = await (0, file_tree_1.getFileInfoFromFS)(process.cwd());
|
|
222
|
-
await (0, agent_loop_1.chatAgentLoop)({
|
|
223
|
-
chatModel,
|
|
224
|
-
selectedModel,
|
|
225
|
-
reporter: reporterFunc,
|
|
226
|
-
trace,
|
|
227
|
-
toolCallService,
|
|
228
|
-
fileInfo,
|
|
229
|
-
isToolExecutionRemote: false,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"for-recorder.d.ts","sourceRoot":"","sources":["../../../../../src/agent/cua/pw-codegen/pw-pause/for-recorder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIvC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,qBAAa,iCAAiC;IAO1C,OAAO,CAAC,eAAe;IANzB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,MAAM,CAA4C;IAC1D,OAAO,CAAC,iBAAiB,CAAqB;gBAGpC,eAAe,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC;YAKtD,QAAQ;IAWhB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBrC,sBAAsB,CAAC,IAAI,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"for-recorder.d.ts","sourceRoot":"","sources":["../../../../../src/agent/cua/pw-codegen/pw-pause/for-recorder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIvC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,qBAAa,iCAAiC;IAO1C,OAAO,CAAC,eAAe;IANzB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,MAAM,CAA4C;IAC1D,OAAO,CAAC,iBAAiB,CAAqB;gBAGpC,eAAe,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC;YAKtD,QAAQ;IAWhB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBrC,sBAAsB,CAAC,IAAI,EAAE,IAAI;CA0CxC"}
|
|
@@ -47,27 +47,8 @@ class PlaywrightPauseCodegenForRecorder {
|
|
|
47
47
|
}
|
|
48
48
|
async startPlaywrightCodegen(page) {
|
|
49
49
|
// TODO: Merge this with the other page.pause oriented codegen
|
|
50
|
-
const
|
|
51
|
-
await
|
|
52
|
-
const evaluatePromise = page.evaluate(() => {
|
|
53
|
-
// @ts-ignore
|
|
54
|
-
console.log(window["__pw_recorderSetMode"]("recording"));
|
|
55
|
-
// Remove playwright's glass pane
|
|
56
|
-
/**
|
|
57
|
-
* x-pw-glass
|
|
58
|
-
* # inside shadow DOM (closed)
|
|
59
|
-
* |----> x-pw-overlay (controls)
|
|
60
|
-
* |----> x-pw-highlight (red highlight)
|
|
61
|
-
* |----> x-pw-tooltip
|
|
62
|
-
*/
|
|
63
|
-
const glassPane = document.querySelector("x-pw-glass");
|
|
64
|
-
if (glassPane) {
|
|
65
|
-
const styles = glassPane.getAttribute("style") || "";
|
|
66
|
-
glassPane.setAttribute("style", styles + "; display: none;");
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
await Promise.all([pausePromise, evaluatePromise]);
|
|
70
|
-
await page.addInitScript(() => {
|
|
50
|
+
const browserContext = page.context();
|
|
51
|
+
await browserContext.addInitScript(() => {
|
|
71
52
|
let displayNoneSet = false;
|
|
72
53
|
function setDisplayNone() {
|
|
73
54
|
const glassPane = document.querySelector("x-pw-glass");
|
|
@@ -85,6 +66,26 @@ class PlaywrightPauseCodegenForRecorder {
|
|
|
85
66
|
setDisplayNone();
|
|
86
67
|
}, 100);
|
|
87
68
|
});
|
|
69
|
+
const pausePromise = page.pause();
|
|
70
|
+
await (0, utils_1.sleep)(5_000);
|
|
71
|
+
const startRecordingWithoutGlassPane = page.evaluate(() => {
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
window["__pw_recorderSetMode"]("recording");
|
|
74
|
+
// Remove playwright's glass pane
|
|
75
|
+
/**
|
|
76
|
+
* x-pw-glass
|
|
77
|
+
* # inside shadow DOM (closed)
|
|
78
|
+
* |----> x-pw-overlay (controls)
|
|
79
|
+
* |----> x-pw-highlight (red highlight)
|
|
80
|
+
* |----> x-pw-tooltip
|
|
81
|
+
*/
|
|
82
|
+
const glassPane = document.querySelector("x-pw-glass");
|
|
83
|
+
if (glassPane) {
|
|
84
|
+
const styles = glassPane.getAttribute("style") || "";
|
|
85
|
+
glassPane.setAttribute("style", styles + "; display: none;");
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
await Promise.all([pausePromise, startRecordingWithoutGlassPane]);
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
exports.PlaywrightPauseCodegenForRecorder = PlaywrightPauseCodegenForRecorder;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
declare class APIClient {
|
|
2
2
|
private appUrl;
|
|
3
3
|
constructor();
|
|
4
|
-
request(endpoint: string, options?: RequestInit): Promise<Response
|
|
4
|
+
request<T>(endpoint: string, options?: RequestInit): Promise<Response & {
|
|
5
|
+
json(): Promise<T>;
|
|
6
|
+
}>;
|
|
5
7
|
private makeRequest;
|
|
6
8
|
ensureAuthenticated(): Promise<void>;
|
|
7
9
|
private refreshToken;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/auth/api-client.ts"],"names":[],"mappings":"AAQA,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAS;;IAMjB,OAAO,
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/auth/api-client.ts"],"names":[],"mappings":"AAQA,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAS;;IAMjB,OAAO,CAAC,CAAC,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,QAAQ,GAAG;QAAE,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC;YA2B/B,WAAW;IAuBnB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;YAiB5B,YAAY;CA4C3B;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/bin/environments.ts"],"names":[],"mappings":"AAQA,wBAAsB,gBAAgB,kBAiErC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listEnvironments = listEnvironments;
|
|
4
|
+
const api_client_1 = require("../auth/api-client");
|
|
5
|
+
const validation_1 = require("../recorder/validation");
|
|
6
|
+
async function listEnvironments() {
|
|
7
|
+
try {
|
|
8
|
+
let repoName = await (0, validation_1.validatePackageJson)(process.cwd());
|
|
9
|
+
const response = await api_client_1.apiClient.request(`/api/environments/list?project_repo_name=${encodeURIComponent(repoName)}`);
|
|
10
|
+
if (!response.ok) {
|
|
11
|
+
console.error(`❌ Failed to fetch environments for repo ${repoName}:`, response.statusText);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const result = await response.json();
|
|
15
|
+
if (result.data?.environments && result.data.environments.length > 0) {
|
|
16
|
+
result.data.environments.forEach((env, index) => {
|
|
17
|
+
if (index > 0) {
|
|
18
|
+
console.log(""); // Add spacing between environments
|
|
19
|
+
}
|
|
20
|
+
console.log(`Environment: ${env.name}`);
|
|
21
|
+
if (env.latest_build) {
|
|
22
|
+
const commit = env.latest_build.commit
|
|
23
|
+
? env.latest_build.commit.substring(0, 7)
|
|
24
|
+
: "N/A";
|
|
25
|
+
const branch = env.latest_build.branch || "N/A";
|
|
26
|
+
// Calculate relative time
|
|
27
|
+
const createdAt = new Date(env.latest_build.created_at);
|
|
28
|
+
const now = new Date();
|
|
29
|
+
const diffMs = now.getTime() - createdAt.getTime();
|
|
30
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
31
|
+
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
32
|
+
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
|
33
|
+
let timeAgo;
|
|
34
|
+
if (diffDays > 0) {
|
|
35
|
+
timeAgo = `${diffDays} day${diffDays > 1 ? "s" : ""} ago`;
|
|
36
|
+
}
|
|
37
|
+
else if (diffHours > 0) {
|
|
38
|
+
timeAgo = `${diffHours} hour${diffHours > 1 ? "s" : ""} ago`;
|
|
39
|
+
}
|
|
40
|
+
else if (diffMinutes > 0) {
|
|
41
|
+
timeAgo = `${diffMinutes} minute${diffMinutes > 1 ? "s" : ""} ago`;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
timeAgo = "Just now";
|
|
45
|
+
}
|
|
46
|
+
console.log(` ┌─ Latest build`);
|
|
47
|
+
console.log(` │ Commit: ${commit}`);
|
|
48
|
+
console.log(` │ Branch: ${branch}`);
|
|
49
|
+
console.log(` │ Created: ${timeAgo}`);
|
|
50
|
+
console.log(` │ URL: ${env.latest_build.build_url}`);
|
|
51
|
+
console.log(` └─`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(` └─ No builds available`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.log(`No environments found for repository: ${repoName}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error("❌ Error fetching environments:", error.message);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
package/dist/bin/index.js
CHANGED
|
@@ -20,10 +20,10 @@ const run_3 = require("../agent/planner/run");
|
|
|
20
20
|
const auth_1 = require("../auth");
|
|
21
21
|
const api_client_1 = require("../auth/api-client");
|
|
22
22
|
const recorder_1 = require("../recorder");
|
|
23
|
-
const validation_1 = require("../recorder/validation");
|
|
24
23
|
const reporter_1 = require("../reporter");
|
|
25
24
|
const session_1 = require("../session");
|
|
26
25
|
const test_build_1 = require("../test-build");
|
|
26
|
+
const environments_1 = require("./environments");
|
|
27
27
|
const logger_1 = require("./logger");
|
|
28
28
|
const setup_1 = require("./setup");
|
|
29
29
|
const utils_2 = require("./utils");
|
|
@@ -31,20 +31,12 @@ const scenarios_1 = require("./utils/scenarios");
|
|
|
31
31
|
dotenv_1.default.config({
|
|
32
32
|
path: [".env.local", ".env"],
|
|
33
33
|
});
|
|
34
|
-
async function runChatAgent({ modelInput,
|
|
34
|
+
async function runChatAgent({ modelInput, useDiskForChatState, initialPromptPath, }) {
|
|
35
35
|
if (modelInput && !utils_2.ARGS_TO_MODEL_MAP[modelInput]) {
|
|
36
36
|
throw new Error(`Invalid chat model: ${modelInput}`);
|
|
37
37
|
}
|
|
38
38
|
const defaultModel = "claude-3-7-sonnet-20250219";
|
|
39
39
|
const specifiedModel = modelInput && utils_2.ARGS_TO_MODEL_MAP[modelInput];
|
|
40
|
-
if (chatSessionId) {
|
|
41
|
-
// If --chat-session-id is provided, we run the chat agent for the dashboard
|
|
42
|
-
// and not CLI (where user can input their own prompt)
|
|
43
|
-
return await (0, chat_1.runChatAgentForDashboard)({
|
|
44
|
-
chatSessionId: Number(chatSessionId),
|
|
45
|
-
selectedModel: specifiedModel || defaultModel,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
40
|
let initialPromptContent = undefined;
|
|
49
41
|
if (initialPromptPath) {
|
|
50
42
|
try {
|
|
@@ -290,40 +282,8 @@ async function main() {
|
|
|
290
282
|
program
|
|
291
283
|
.command("environments")
|
|
292
284
|
.description("List environments and their latest builds")
|
|
293
|
-
.
|
|
294
|
-
|
|
295
|
-
try {
|
|
296
|
-
let repoName;
|
|
297
|
-
if (opts.repoName) {
|
|
298
|
-
repoName = opts.repoName;
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
// Auto-detect repo name from current directory
|
|
302
|
-
repoName = await (0, validation_1.validatePackageJson)(process.cwd());
|
|
303
|
-
}
|
|
304
|
-
const response = await api_client_1.apiClient.request(`/api/environments/list?project_repo_name=${encodeURIComponent(repoName)}`);
|
|
305
|
-
if (!response.ok) {
|
|
306
|
-
console.log(await response.text());
|
|
307
|
-
console.error(`❌ Failed to fetch environments for repo ${repoName}:`, response.statusText);
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
const result = await response.json();
|
|
311
|
-
if (result.data.environments && result.data.environments.length > 0) {
|
|
312
|
-
result.data.environments.forEach((env) => {
|
|
313
|
-
console.log(` Environment: ${env.name}`);
|
|
314
|
-
if (env.latest_build) {
|
|
315
|
-
console.log(` Latest build: ${env.latest_build.url}`);
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
console.log(`No environments found for repository: ${repoName}`);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
catch (error) {
|
|
324
|
-
console.error("❌ Error fetching environments:", error.message);
|
|
325
|
-
process.exit(1);
|
|
326
|
-
}
|
|
285
|
+
.action(async () => {
|
|
286
|
+
await (0, environments_1.listEnvironments)();
|
|
327
287
|
process.exit(0);
|
|
328
288
|
});
|
|
329
289
|
program
|
|
@@ -350,10 +310,8 @@ async function main() {
|
|
|
350
310
|
.option("--chat-model <model>", "LLM to use (claude-3-7, claude-4 or gemini-2.5)")
|
|
351
311
|
.option("--use-disk-for-chat-state", "Save and load chat state from disk")
|
|
352
312
|
.option("--initial-prompt <path>", "Path to an initial prompt file (e.g. prompt.md)")
|
|
353
|
-
.option("--chat-session-id <chat-session-id>", "Identifier for chat session (fetched from dash.empirical.run)")
|
|
354
313
|
.action(async (options) => {
|
|
355
314
|
await runChatAgent({
|
|
356
|
-
chatSessionId: options.chatSessionId,
|
|
357
315
|
modelInput: options.chatModel,
|
|
358
316
|
useDiskForChatState: options.useDiskForChatState,
|
|
359
317
|
initialPromptPath: options.initialPrompt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":"AAgCA,wBAAsB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,iBA+I3D"}
|
package/dist/recorder/index.js
CHANGED
|
@@ -29,7 +29,7 @@ async function runRecorder({ name }) {
|
|
|
29
29
|
const repoDir = process.cwd();
|
|
30
30
|
let repoName = "";
|
|
31
31
|
let fileServer = null;
|
|
32
|
-
let tempTestFilePath = "tests/temp-
|
|
32
|
+
let tempTestFilePath = "tests/temp-file.spec.ts";
|
|
33
33
|
process.on("SIGINT", async () => {
|
|
34
34
|
try {
|
|
35
35
|
await (0, temp_files_1.deleteTempTestFile)(repoDir, tempTestFilePath);
|
|
@@ -86,7 +86,15 @@ async function runRecorder({ name }) {
|
|
|
86
86
|
selectedProjects = [selectedProject];
|
|
87
87
|
selectedProjectObj = projects.find((p) => p.name === selectedProject);
|
|
88
88
|
if (selectedProjectObj) {
|
|
89
|
-
|
|
89
|
+
const projectSpecificFile = (0, temp_files_1.getTempTestFileLocation)(selectedProjectObj, repoDir);
|
|
90
|
+
logger_1.logger.debug(`Project specific temp test file path: ${projectSpecificFile}`);
|
|
91
|
+
if (!projectSpecificFile) {
|
|
92
|
+
logger_1.logger.error(`No suitable test directory found for project ${selectedProject}.`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
tempTestFilePath = projectSpecificFile;
|
|
97
|
+
}
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
100
|
// Create temp test file in the determined location
|
|
@@ -106,6 +114,7 @@ async function runRecorder({ name }) {
|
|
|
106
114
|
IPC_FILE_SERVICE_PORT: availablePort.toString(),
|
|
107
115
|
},
|
|
108
116
|
});
|
|
117
|
+
await (0, upload_1.waitForSummaryJson)(repoDir);
|
|
109
118
|
const videoPaths = (0, upload_1.extractVideoAttachments)(repoDir);
|
|
110
119
|
let attachments = [];
|
|
111
120
|
if (videoPaths.length === 0) {
|
|
@@ -6,7 +6,8 @@ export type PlaywrightProject = {
|
|
|
6
6
|
testDir: string | undefined;
|
|
7
7
|
teardown: string | undefined;
|
|
8
8
|
};
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function findSubDirs(dir: string, subDirs?: string[], rootDir?: string): void;
|
|
10
|
+
export declare function getTempTestFileLocation(selectedProject: PlaywrightProject, repoDir: string): string | undefined;
|
|
10
11
|
export declare function createTempTestFile(port: number, repoDir: string, tempFileRelativePath: string): Promise<void>;
|
|
11
12
|
export declare function deleteTempTestFile(repoDir: string, tempFileRelativePath: string): Promise<void>;
|
|
12
13
|
//# sourceMappingURL=temp-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temp-files.d.ts","sourceRoot":"","sources":["../../src/recorder/temp-files.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"temp-files.d.ts","sourceRoot":"","sources":["../../src/recorder/temp-files.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,EAAO,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAcN;AAED,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,iBAAiB,EAClC,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAsDpB;AAqBD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,oBAAoB,EAAE,MAAM,iBAkB7B;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,oBAAoB,EAAE,MAAM,iBAS7B"}
|
|
@@ -3,40 +3,70 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.findSubDirs = findSubDirs;
|
|
6
7
|
exports.getTempTestFileLocation = getTempTestFileLocation;
|
|
7
8
|
exports.createTempTestFile = createTempTestFile;
|
|
8
9
|
exports.deleteTempTestFile = deleteTempTestFile;
|
|
9
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const minimatch_1 = require("minimatch");
|
|
10
12
|
const path_1 = __importDefault(require("path"));
|
|
11
13
|
const logger_1 = require("../logger");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
function findSubDirs(dir, subDirs = [], rootDir) {
|
|
15
|
+
const root = rootDir || dir;
|
|
16
|
+
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
const fullPath = path_1.default.join(dir, entry.name);
|
|
20
|
+
// Calculate relative path from root directory
|
|
21
|
+
const relativePath = path_1.default.relative(root, fullPath);
|
|
22
|
+
subDirs.push(relativePath);
|
|
23
|
+
// Recursively search subdirectories
|
|
24
|
+
findSubDirs(fullPath, subDirs, root);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getTempTestFileLocation(selectedProject, repoDir) {
|
|
29
|
+
const testsDir = path_1.default.join(repoDir, "tests");
|
|
30
|
+
if (!fs_1.default.existsSync(testsDir)) {
|
|
31
|
+
throw new Error(`Tests directory not found: ${testsDir}`);
|
|
32
|
+
}
|
|
33
|
+
const subDirs = [""];
|
|
34
|
+
findSubDirs(testsDir, subDirs);
|
|
35
|
+
const candidatesForTemp = subDirs.map((subDir) => {
|
|
36
|
+
return path_1.default.join("tests", subDir, "temp-file.spec.ts");
|
|
37
|
+
});
|
|
38
|
+
const { testDir, testMatch, testIgnore } = selectedProject;
|
|
39
|
+
for (const candidate of candidatesForTemp) {
|
|
40
|
+
const fullPath = path_1.default.join(repoDir, candidate);
|
|
41
|
+
if (testDir) {
|
|
42
|
+
const fullTestDir = path_1.default.join(repoDir, testDir);
|
|
43
|
+
if (!fullPath.startsWith(fullTestDir)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (testMatch) {
|
|
48
|
+
const testMatchArray = Array.isArray(testMatch) ? testMatch : [testMatch];
|
|
49
|
+
const withStarStar = testMatchArray.map((pattern) =>
|
|
50
|
+
// Playwright adds `**/` prefix to all string patterns
|
|
51
|
+
// https://github.com/microsoft/playwright/blob/3fb78b65847bd4ee373792f0778d51824a4a150b/packages/playwright/src/util.ts#L109
|
|
52
|
+
pattern.startsWith("**/") ? pattern : `**/${pattern}`);
|
|
53
|
+
const matches = withStarStar.some((pattern) => (0, minimatch_1.minimatch)(fullPath, pattern, { dot: true, nocase: true }));
|
|
54
|
+
if (!matches) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (testIgnore) {
|
|
59
|
+
const testIgnoreArray = Array.isArray(testIgnore)
|
|
60
|
+
? testIgnore
|
|
61
|
+
: [testIgnore];
|
|
62
|
+
const withStarStar = testIgnoreArray.map((pattern) => pattern.startsWith("**/") ? pattern : `**/${pattern}`);
|
|
63
|
+
const matches = withStarStar.some((pattern) => (0, minimatch_1.minimatch)(fullPath, pattern, { dot: true, nocase: true }));
|
|
64
|
+
if (matches) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return candidate;
|
|
38
69
|
}
|
|
39
|
-
return common;
|
|
40
70
|
}
|
|
41
71
|
function getFixturesImportPath(tempFileRelativePath) {
|
|
42
72
|
const tempFileStartsWithSlash = tempFileRelativePath.startsWith("/")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare function waitForSummaryJson(repoDir: string): Promise<void>;
|
|
1
2
|
export declare function extractVideoAttachments(repoDir: string): string[];
|
|
2
3
|
export declare function uploadVideosWithSpinner(videoPaths: string[], testName: string): Promise<void | string[]>;
|
|
3
4
|
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/recorder/upload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/recorder/upload.ts"],"names":[],"mappings":"AAcA,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,iBAmBvD;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBjE;AA6FD,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAiB1B"}
|
package/dist/recorder/upload.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.waitForSummaryJson = waitForSummaryJson;
|
|
6
7
|
exports.extractVideoAttachments = extractVideoAttachments;
|
|
7
8
|
exports.uploadVideosWithSpinner = uploadVideosWithSpinner;
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -15,9 +16,31 @@ const BUCKET_DOMAINS = {
|
|
|
15
16
|
"empirical-assets-staging": "assets-staging.empirical.run",
|
|
16
17
|
"empirical-assets-production": "assets.empirical.run",
|
|
17
18
|
};
|
|
19
|
+
const SUMMARY_JSON = (repoDir) => path_1.default.join(repoDir, "summary.json");
|
|
20
|
+
async function waitForSummaryJson(repoDir) {
|
|
21
|
+
const summaryPath = SUMMARY_JSON(repoDir);
|
|
22
|
+
const maxTimeout = 5_000;
|
|
23
|
+
const timerPromise = new Promise((resolve, reject) => {
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
reject(new Error("Timeout waiting for summary.json"));
|
|
26
|
+
}, maxTimeout);
|
|
27
|
+
});
|
|
28
|
+
const fsExistsPromise = new Promise((resolve) => {
|
|
29
|
+
const checkFile = () => {
|
|
30
|
+
if (fs_1.default.existsSync(summaryPath)) {
|
|
31
|
+
resolve();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
setTimeout(checkFile, 100);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
checkFile();
|
|
38
|
+
});
|
|
39
|
+
return Promise.race([timerPromise, fsExistsPromise]);
|
|
40
|
+
}
|
|
18
41
|
function extractVideoAttachments(repoDir) {
|
|
19
42
|
try {
|
|
20
|
-
const summaryPath =
|
|
43
|
+
const summaryPath = SUMMARY_JSON(repoDir);
|
|
21
44
|
if (!fs_1.default.existsSync(summaryPath)) {
|
|
22
45
|
console.log("summary.json not found");
|
|
23
46
|
return [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/upgrade-packages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/upgrade-packages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAuBvD,eAAO,MAAM,mBAAmB,EAAE,IAiIjC,CAAC"}
|
|
@@ -10,58 +10,65 @@ const zod_1 = require("zod");
|
|
|
10
10
|
const git_1 = require("../../utils/git");
|
|
11
11
|
const utils_1 = require("../utils");
|
|
12
12
|
const utils_2 = require("./utils");
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
];
|
|
18
|
-
const packageSpecSchema = zod_1.z.union([
|
|
19
|
-
zod_1.z.string(),
|
|
20
|
-
zod_1.z.object({
|
|
21
|
-
name: zod_1.z.string(),
|
|
22
|
-
version: zod_1.z.string().optional(),
|
|
23
|
-
}),
|
|
24
|
-
]);
|
|
13
|
+
const packageSpecSchema = zod_1.z.object({
|
|
14
|
+
name: zod_1.z.string(),
|
|
15
|
+
version: zod_1.z.string(),
|
|
16
|
+
});
|
|
25
17
|
const upgradePackagesSchema = zod_1.z.object({
|
|
26
|
-
packages: zod_1.z.array(packageSpecSchema),
|
|
18
|
+
packages: zod_1.z.array(packageSpecSchema).min(1),
|
|
27
19
|
});
|
|
28
20
|
exports.upgradePackagesTool = {
|
|
29
21
|
schema: {
|
|
30
22
|
name: "upgradePackages",
|
|
31
|
-
description: `
|
|
23
|
+
description: `This tool can be used to upgrade NPM packages in this repository. To run this tool, specify a list of packages with their names and version strings. At least one package must be specified.
|
|
24
|
+
This tool handles the entire workflow: editing the package.json file, running "npm install", generating lockfile, committing the changes and creating a pull request. For patch updates (e.g., 1.0.1 → 1.0.2), the tool will automatically merge the PR for minor updates. For major updates, the user needs to review the PR and merge it manually.`,
|
|
32
25
|
parameters: upgradePackagesSchema,
|
|
33
26
|
},
|
|
34
27
|
needsBrowser: false,
|
|
35
28
|
execute: async ({ input, repoPath, apiKey, }) => {
|
|
36
|
-
const { packages } = input;
|
|
37
|
-
let packagesToUpdate = packages.length ? packages : pkgs;
|
|
38
|
-
const packageSpecs = packagesToUpdate.map((p) => typeof p === "string" ? { name: p, version: undefined } : p);
|
|
29
|
+
const { packages: packagesToUpdate } = input;
|
|
39
30
|
try {
|
|
40
31
|
const repoName = path_1.default.basename(repoPath);
|
|
41
32
|
const branchName = await (0, git_1.getCurrentBranchName)(repoPath);
|
|
42
33
|
const packageJsonPath = path_1.default.join(repoPath, "package.json");
|
|
43
34
|
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, "utf-8"));
|
|
44
|
-
|
|
35
|
+
const changes = [];
|
|
36
|
+
for (let { name: pkgName, version } of packagesToUpdate) {
|
|
45
37
|
const isDevDep = !!packageJson.devDependencies?.[pkgName];
|
|
46
38
|
try {
|
|
47
|
-
await (0, utils_2.upgradeAndStagePackage)({
|
|
39
|
+
const updatedPackage = await (0, utils_2.upgradeAndStagePackage)({
|
|
48
40
|
repoPath,
|
|
49
41
|
pkgName,
|
|
50
42
|
version,
|
|
51
43
|
isDevDep,
|
|
52
44
|
});
|
|
45
|
+
changes.push(updatedPackage);
|
|
53
46
|
}
|
|
54
47
|
catch (err) {
|
|
55
48
|
console.error(`Failed to upgrade ${pkgName}:`, err);
|
|
49
|
+
return {
|
|
50
|
+
result: `Failed to upgrade ${pkgName}: ${err.message}`,
|
|
51
|
+
isError: true,
|
|
52
|
+
};
|
|
56
53
|
}
|
|
57
54
|
}
|
|
55
|
+
const filesChanged = await (0, git_1.getFilesChanged)(repoPath);
|
|
56
|
+
const hasChanges = filesChanged.length > 0;
|
|
57
|
+
if (!hasChanges) {
|
|
58
|
+
return {
|
|
59
|
+
result: "Success: No package changes detected, nothing to commit. Skipping PR creation.",
|
|
60
|
+
isError: false,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
58
63
|
await (0, git_1.commitFilesAndPushBranch)({
|
|
59
|
-
commitMessage:
|
|
64
|
+
commitMessage: `[upgrade-packages] upgrade ${changes.length} packages [skip ci]`,
|
|
60
65
|
branchName,
|
|
61
66
|
files: ["package.json", "package-lock.json"],
|
|
62
67
|
repoPath,
|
|
63
68
|
});
|
|
64
69
|
await new Promise((resolve) => setTimeout(resolve, 5_000));
|
|
70
|
+
const prBody = `Upgraded the following packages:\n\n${changes.map((c) => `- \`${c.name}\` → ${c.version ? c.version : "latest"}`).join("\n")}`;
|
|
71
|
+
const prTitle = `chore: upgrade ${changes.length} package(s)`;
|
|
65
72
|
let shouldMerge = false;
|
|
66
73
|
let prNumber = null;
|
|
67
74
|
let merged = false;
|
|
@@ -71,8 +78,8 @@ exports.upgradePackagesTool = {
|
|
|
71
78
|
repo: repoName,
|
|
72
79
|
apiKey,
|
|
73
80
|
branchName,
|
|
74
|
-
title:
|
|
75
|
-
body:
|
|
81
|
+
title: prTitle,
|
|
82
|
+
body: prBody,
|
|
76
83
|
labels: ["automated"],
|
|
77
84
|
});
|
|
78
85
|
prNumber = pr.number;
|
|
@@ -109,7 +116,7 @@ exports.upgradePackagesTool = {
|
|
|
109
116
|
? "created but merge failed"
|
|
110
117
|
: "created but not merged (non-patch updates)";
|
|
111
118
|
return {
|
|
112
|
-
result: `Success: PR ${status}. Link: ${prLink}`,
|
|
119
|
+
result: `Success: Successfully upgraded ${changes.length} package(s). PR ${status}. Link: ${prLink}`,
|
|
113
120
|
isError: false,
|
|
114
121
|
};
|
|
115
122
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export declare function getLatestVersion(packageName: string): Promise<any>;
|
|
2
|
+
export declare function parsePackageJsonDiff({ diff, }: {
|
|
3
|
+
diff: string;
|
|
4
|
+
}): Record<string, {
|
|
5
|
+
old?: string;
|
|
6
|
+
new?: string;
|
|
7
|
+
}>;
|
|
2
8
|
export declare function shouldMergePR({ repoName, prNumber, apiKey, }: {
|
|
3
9
|
repoName: string;
|
|
4
10
|
prNumber: number;
|
|
@@ -9,5 +15,8 @@ export declare function upgradeAndStagePackage({ repoPath, pkgName, version, isD
|
|
|
9
15
|
pkgName: string;
|
|
10
16
|
version?: string;
|
|
11
17
|
isDevDep: boolean;
|
|
12
|
-
}): Promise<
|
|
18
|
+
}): Promise<{
|
|
19
|
+
name: string;
|
|
20
|
+
version: any;
|
|
21
|
+
}>;
|
|
13
22
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/upgrade-packages/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/upgrade-packages/utils.ts"],"names":[],"mappings":"AAoBA,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,gBAkBzD;AA8BD,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBjD;AAED,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,oBA8BA;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;;;GAcA"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getLatestVersion = getLatestVersion;
|
|
4
|
+
exports.parsePackageJsonDiff = parsePackageJsonDiff;
|
|
4
5
|
exports.shouldMergePR = shouldMergePR;
|
|
5
6
|
exports.upgradeAndStagePackage = upgradeAndStagePackage;
|
|
6
7
|
const child_process_1 = require("child_process");
|
|
7
8
|
const utils_1 = require("../utils");
|
|
8
9
|
function isPatchUpdate(currentVersion, newVersion) {
|
|
10
|
+
if (!currentVersion || !newVersion) {
|
|
11
|
+
// If current is undefined, we might be installing a new package
|
|
12
|
+
// Both must be truthy for this to be a patch version update
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
9
15
|
const current = currentVersion.replace(/^[\^~]/, "").split(".");
|
|
10
16
|
const next = newVersion.replace(/^[\^~]/, "").split(".");
|
|
11
17
|
return (current[0] === next[0] && current[1] === next[1] && current[2] !== next[2]);
|
|
@@ -15,7 +21,10 @@ async function getLatestVersion(packageName) {
|
|
|
15
21
|
try {
|
|
16
22
|
const response = await fetch(url);
|
|
17
23
|
if (!response.ok) {
|
|
18
|
-
|
|
24
|
+
const errorMsg = response.status === 404
|
|
25
|
+
? `Package '${packageName}' not found on npm registry`
|
|
26
|
+
: `Failed to fetch data for package: ${packageName}`;
|
|
27
|
+
throw new Error(errorMsg);
|
|
19
28
|
}
|
|
20
29
|
const packageInfo = await response.json();
|
|
21
30
|
console.log(`Latest version of ${packageName}: ${packageInfo.version}`);
|
|
@@ -26,68 +35,63 @@ async function getLatestVersion(packageName) {
|
|
|
26
35
|
throw error;
|
|
27
36
|
}
|
|
28
37
|
}
|
|
29
|
-
async function
|
|
38
|
+
async function getGitDiffForPackageJson({ repoName, prNumber, apiKey, }) {
|
|
30
39
|
const url = `${utils_1.GITHUB_API_BASE}/${repoName}/pulls/${prNumber}/files`;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
changes[pkg][changeType] = version;
|
|
40
|
+
const files = await (0, utils_1.callGitHubProxy)({
|
|
41
|
+
method: "GET",
|
|
42
|
+
url: url,
|
|
43
|
+
apiKey,
|
|
44
|
+
});
|
|
45
|
+
if (!files) {
|
|
46
|
+
throw new Error("Failed to fetch PR files via proxy");
|
|
47
|
+
}
|
|
48
|
+
const packageJsonChanges = files.find((file) => file.filename === "package.json");
|
|
49
|
+
if (!packageJsonChanges) {
|
|
50
|
+
console.log("No package.json changes found in PR");
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return packageJsonChanges.patch;
|
|
54
|
+
}
|
|
55
|
+
function parsePackageJsonDiff({ diff, }) {
|
|
56
|
+
const patchLines = diff.split("\n");
|
|
57
|
+
const changes = {};
|
|
58
|
+
for (let i = 0; i < patchLines.length; i++) {
|
|
59
|
+
const line = patchLines[i];
|
|
60
|
+
// Look for lines that change version numbers
|
|
61
|
+
const match = line.match(/^[-+]\s*"([^"]+)":\s*"([^"]+)"/);
|
|
62
|
+
if (match) {
|
|
63
|
+
const [, pkg, version] = match;
|
|
64
|
+
if (!pkg) {
|
|
65
|
+
console.warn("No package name found in line:", line);
|
|
66
|
+
continue;
|
|
59
67
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
for (const [pkg, versions] of Object.entries(changes)) {
|
|
64
|
-
if (versions.old && versions.new) {
|
|
65
|
-
validChanges[pkg] = {
|
|
66
|
-
oldVersion: versions.old,
|
|
67
|
-
newVersion: versions.new,
|
|
68
|
-
};
|
|
68
|
+
const changeType = line.startsWith("+") ? "new" : "old";
|
|
69
|
+
if (!changes[pkg]) {
|
|
70
|
+
changes[pkg] = {};
|
|
69
71
|
}
|
|
72
|
+
changes[pkg][changeType] = version;
|
|
70
73
|
}
|
|
71
|
-
return validChanges;
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
console.error(`Error fetching PR changes: ${error.message}`);
|
|
75
|
-
throw error;
|
|
76
74
|
}
|
|
75
|
+
return changes;
|
|
77
76
|
}
|
|
78
77
|
async function shouldMergePR({ repoName, prNumber, apiKey, }) {
|
|
79
|
-
const
|
|
78
|
+
const gitDiff = await getGitDiffForPackageJson({
|
|
80
79
|
repoName,
|
|
81
80
|
prNumber,
|
|
82
81
|
apiKey,
|
|
83
82
|
});
|
|
84
|
-
if (!
|
|
83
|
+
if (!gitDiff) {
|
|
84
|
+
console.log("No package.json changes found, skipping merge");
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const changes = parsePackageJsonDiff({ diff: gitDiff });
|
|
88
|
+
if (Object.keys(changes).length === 0) {
|
|
85
89
|
console.log("No package.json changes found, skipping merge");
|
|
86
90
|
return false;
|
|
87
91
|
}
|
|
88
92
|
let allPatchUpdates = true;
|
|
89
93
|
for (const [pkg, versions] of Object.entries(changes)) {
|
|
90
|
-
const { oldVersion, newVersion } = versions;
|
|
94
|
+
const { old: oldVersion, new: newVersion } = versions;
|
|
91
95
|
if (!isPatchUpdate(oldVersion, newVersion)) {
|
|
92
96
|
console.log(`${pkg}: ${oldVersion} -> ${newVersion} is not a patch update`);
|
|
93
97
|
allPatchUpdates = false;
|
|
@@ -103,4 +107,8 @@ async function upgradeAndStagePackage({ repoPath, pkgName, version, isDevDep, })
|
|
|
103
107
|
(0, child_process_1.execSync)(`npm i ${pkgName}@${pkgVersion} ${isDevDep ? "--save-dev" : "--save"}`, { cwd: repoPath });
|
|
104
108
|
console.log(`Updated package: ${pkgName} version to ${pkgVersion} in ${repoPath}`);
|
|
105
109
|
(0, child_process_1.execSync)("git add package.json package-lock.json", { cwd: repoPath });
|
|
110
|
+
return {
|
|
111
|
+
name: pkgName,
|
|
112
|
+
version: pkgVersion,
|
|
113
|
+
};
|
|
106
114
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.70.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"playwright": "1.53.0",
|
|
83
83
|
"serve-handler": "^6.1.6",
|
|
84
84
|
"ts-patch": "^3.3.0",
|
|
85
|
-
"@empiricalrun/shared-types": "0.6.
|
|
85
|
+
"@empiricalrun/shared-types": "0.6.2"
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"dev": "tspc --build --watch",
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/logger.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/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/chat/prompt/index.ts","./src/agent/chat/prompt/pw-utils-docs.ts","./src/agent/chat/prompt/repo.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/for-recorder.ts","./src/agent/cua/pw-codegen/pw-pause/index.ts","./src/agent/cua/pw-codegen/pw-pause/ipc.ts","./src/agent/cua/pw-codegen/pw-pause/patch.ts","./src/agent/cua/pw-codegen/pw-pause/types.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/artifacts/utils.ts","./src/auth/api-client.ts","./src/auth/cli-auth.ts","./src/auth/index.ts","./src/auth/token-store.ts","./src/bin/index.ts","./src/bin/setup.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/recorder/env-variables.ts","./src/recorder/
|
|
1
|
+
{"root":["./src/index.ts","./src/logger.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/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/chat/prompt/index.ts","./src/agent/chat/prompt/pw-utils-docs.ts","./src/agent/chat/prompt/repo.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/for-recorder.ts","./src/agent/cua/pw-codegen/pw-pause/index.ts","./src/agent/cua/pw-codegen/pw-pause/ipc.ts","./src/agent/cua/pw-codegen/pw-pause/patch.ts","./src/agent/cua/pw-codegen/pw-pause/types.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/artifacts/utils.ts","./src/auth/api-client.ts","./src/auth/cli-auth.ts","./src/auth/index.ts","./src/auth/token-store.ts","./src/bin/environments.ts","./src/bin/index.ts","./src/bin/setup.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/recorder/env-variables.ts","./src/recorder/index.ts","./src/recorder/request.ts","./src/recorder/temp-files.ts","./src/recorder/upload.ts","./src/recorder/validation.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/commit-and-create-pr.ts","./src/tools/diagnosis-fetcher.ts","./src/tools/download-build.ts","./src/tools/list-environments.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/upgrade-packages/index.ts","./src/tools/upgrade-packages/utils.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/json.ts","./src/utils/repo-tree.ts","./src/utils/slug.ts","./src/utils/string.ts","./src/utils/stripAnsi.ts"],"version":"5.8.3"}
|
package/dist/recorder/glob.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/recorder/glob.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CA8FxE"}
|
package/dist/recorder/glob.js
DELETED
|
@@ -1,74 +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.generateMatchingString = generateMatchingString;
|
|
7
|
-
const minimatch_1 = require("minimatch");
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
function generateMatchingString(patterns) {
|
|
10
|
-
// Separate positive and negative patterns
|
|
11
|
-
const positivePatterns = patterns.filter((p) => !p.startsWith("!"));
|
|
12
|
-
const negativePatterns = patterns
|
|
13
|
-
.filter((p) => p.startsWith("!"))
|
|
14
|
-
.map((p) => p.slice(1));
|
|
15
|
-
// Start with the most specific pattern - temp-test.spec.ts
|
|
16
|
-
const tempTestPattern = positivePatterns.find((p) => p.includes("temp-test.spec.ts"));
|
|
17
|
-
if (!tempTestPattern) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
// Extract the base directory from the testDirPattern
|
|
21
|
-
const testDirPattern = positivePatterns.find((p) => p.includes("/**"));
|
|
22
|
-
if (!testDirPattern) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
// Get the base directory (everything before /**)
|
|
26
|
-
const baseDir = testDirPattern.replace("/**", "");
|
|
27
|
-
// Generate a simple path that matches all positive patterns
|
|
28
|
-
let candidatePath = path_1.default.join(baseDir, "temp-test.spec.ts");
|
|
29
|
-
// Check if it matches all positive patterns
|
|
30
|
-
for (const pattern of positivePatterns) {
|
|
31
|
-
if (!(0, minimatch_1.minimatch)(candidatePath, pattern)) {
|
|
32
|
-
// If it doesn't match, try to adjust the path
|
|
33
|
-
// For patterns like **/*.spec.ts, we might need to add subdirectories
|
|
34
|
-
if (pattern.includes("**/")) {
|
|
35
|
-
// Try adding a subdirectory
|
|
36
|
-
candidatePath = path_1.default.join(baseDir, "e2e", "temp-test.spec.ts");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Check against negative patterns
|
|
41
|
-
for (const pattern of negativePatterns) {
|
|
42
|
-
if ((0, minimatch_1.minimatch)(candidatePath, pattern)) {
|
|
43
|
-
// If it matches a negative pattern, try to find an alternative path
|
|
44
|
-
// Add a different subdirectory or modify the path
|
|
45
|
-
candidatePath = path_1.default.join(baseDir, "integration", "temp-test.spec.ts");
|
|
46
|
-
// Re-check against all patterns
|
|
47
|
-
const matchesAllPositive = positivePatterns.every((p) => (0, minimatch_1.minimatch)(candidatePath, p));
|
|
48
|
-
const matchesNoNegative = !negativePatterns.some((p) => (0, minimatch_1.minimatch)(candidatePath, p));
|
|
49
|
-
if (!matchesAllPositive || !matchesNoNegative) {
|
|
50
|
-
// Try another path
|
|
51
|
-
candidatePath = path_1.default.join(baseDir, "specs", "temp-test.spec.ts");
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// Final validation
|
|
56
|
-
const matchesAllPositive = positivePatterns.every((p) => (0, minimatch_1.minimatch)(candidatePath, p));
|
|
57
|
-
const matchesNoNegative = !negativePatterns.some((p) => (0, minimatch_1.minimatch)(candidatePath, p));
|
|
58
|
-
if (matchesAllPositive && matchesNoNegative) {
|
|
59
|
-
return candidatePath;
|
|
60
|
-
}
|
|
61
|
-
// If we still can't find a valid path, try a more systematic approach
|
|
62
|
-
const subdirs = ["", "e2e", "integration", "specs", "playwright", "tests"];
|
|
63
|
-
for (const subdir of subdirs) {
|
|
64
|
-
const testPath = subdir
|
|
65
|
-
? path_1.default.join(baseDir, subdir, "temp-test.spec.ts")
|
|
66
|
-
: path_1.default.join(baseDir, "temp-test.spec.ts");
|
|
67
|
-
const matchesAllPositive = positivePatterns.every((p) => (0, minimatch_1.minimatch)(testPath, p));
|
|
68
|
-
const matchesNoNegative = !negativePatterns.some((p) => (0, minimatch_1.minimatch)(testPath, p));
|
|
69
|
-
if (matchesAllPositive && matchesNoNegative) {
|
|
70
|
-
return testPath;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return null;
|
|
74
|
-
}
|