wopee-mcp 1.3.0 → 1.4.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/README.md +20 -0
- package/build/tools/index.js +2 -0
- package/build/tools/shared/factories.js +11 -0
- package/build/tools/shared/gql-queries.js +5 -0
- package/build/tools/shared/handlers.js +60 -10
- package/build/tools/shared/schemas.js +31 -3
- package/build/tools/shared/types.js +8 -7
- package/build/tools/wopee_dispatch_agent/schema.js +21 -5
- package/build/tools/wopee_fetch_analysis_suites/index.js +1 -1
- package/build/tools/wopee_fetch_app_context/index.js +1 -1
- package/build/tools/wopee_generate_app_context/index.js +2 -2
- package/build/tools/wopee_generate_general_user_stories/index.js +2 -2
- package/build/tools/wopee_generate_test_cases/index.js +2 -2
- package/build/tools/wopee_generate_user_stories/index.js +2 -2
- package/build/tools/wopee_update_file/index.js +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,6 +210,26 @@ Fetches the test cases JSON file for a suite.
|
|
|
210
210
|
Fetch test cases for suite abc-123-def-456
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
+
### Update Tools
|
|
214
|
+
|
|
215
|
+
These tools are used to update or set certain files(artifacts) for a specific suite. `suiteUuid`, `fileType` and `fileContent` is required.
|
|
216
|
+
|
|
217
|
+
#### `wopee_update_file`
|
|
218
|
+
|
|
219
|
+
Updates/replaces existing file(artifact) for a specific suite
|
|
220
|
+
|
|
221
|
+
- **Parameters:**
|
|
222
|
+
- `suiteUuid` - The UUID of the suite
|
|
223
|
+
- `fileType` - `"APP_CONTEXT" | "GENERAL_USER_STORIES" | "USER_STORIES" | "TEST_CASES"`
|
|
224
|
+
- `fileContent` - Markdown content for `app context` and `general user stories`, structured JSON for `user stories` and `test cases`
|
|
225
|
+
- **Returns:** Boolean based of success status of the tool call
|
|
226
|
+
|
|
227
|
+
**Example Usage:**
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
Update app context file for the most recent suite with this content: <YourMarkdown>
|
|
231
|
+
```
|
|
232
|
+
|
|
213
233
|
### Agent Testing
|
|
214
234
|
|
|
215
235
|
#### `wopee_dispatch_agent`
|
package/build/tools/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { wopeeUpdateFile } from "./wopee_update_file/index.js";
|
|
1
2
|
import { wopeeDispatchAgent } from "./wopee_dispatch_agent/index.js";
|
|
2
3
|
import { wopeeFetchTestCases } from "./wopee_fetch_test_cases/index.js";
|
|
3
4
|
import { wopeeFetchAppContext } from "./wopee_fetch_app_context/index.js";
|
|
@@ -21,4 +22,5 @@ export const TOOLS = [
|
|
|
21
22
|
wopeeFetchGeneralUserStories,
|
|
22
23
|
wopeeFetchUserStories,
|
|
23
24
|
wopeeFetchTestCases,
|
|
25
|
+
wopeeUpdateFile,
|
|
24
26
|
];
|
|
@@ -30,3 +30,14 @@ export const createGenerateAIDataInput = (input) => {
|
|
|
30
30
|
sourceSuiteUuid: null,
|
|
31
31
|
};
|
|
32
32
|
};
|
|
33
|
+
export const createUpdateFileInput = (input) => {
|
|
34
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
35
|
+
if (!WOPEE_PROJECT_UUID)
|
|
36
|
+
throw new Error("WOPEE_PROJECT_UUID is not set");
|
|
37
|
+
return {
|
|
38
|
+
bucket: input.bucket,
|
|
39
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
40
|
+
suiteUuid: input.suiteUuid,
|
|
41
|
+
[input.type === "markdown" ? "code" : "json"]: input.fileContent,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { FetchFileInputSchema, GenerateAIDataInputSchema, } from "./schemas.js";
|
|
3
|
-
import { FetchFile, GenerateTestCases, GenerateAppContext, GenerateUserStories, GenerateGeneralUserStories, } from "./gql-queries.js";
|
|
4
|
-
import { createFetchFileInput, createGenerateAIDataInput, } from "./factories.js";
|
|
5
|
-
import { Bucket,
|
|
2
|
+
import { FetchFileInputSchema, UpdateFileInputSchema, GenerateAIDataInputSchema, } from "./schemas.js";
|
|
3
|
+
import { FetchFile, UpdateFile, GenerateTestCases, GenerateAppContext, GenerateUserStories, GenerateGeneralUserStories, } from "./gql-queries.js";
|
|
4
|
+
import { createFetchFileInput, createUpdateFileInput, createGenerateAIDataInput, } from "./factories.js";
|
|
5
|
+
import { Bucket, FileType } from "./types.js";
|
|
6
6
|
import { requestClient } from "../../utils/requestClient.js";
|
|
7
7
|
export function parseError(error) {
|
|
8
8
|
console.error(error instanceof z.ZodError ? error.issues : error);
|
|
@@ -21,40 +21,46 @@ export function parseError(error) {
|
|
|
21
21
|
],
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function parseFileType(type) {
|
|
25
25
|
switch (type) {
|
|
26
|
-
case
|
|
26
|
+
case FileType.APP_CONTEXT:
|
|
27
27
|
return {
|
|
28
28
|
query: GenerateAppContext,
|
|
29
29
|
dataKey: "generateAppContext",
|
|
30
30
|
bucket: Bucket.APP_CONTEXT,
|
|
31
|
+
type: "markdown",
|
|
31
32
|
description: "application's context markdown file for selected suite",
|
|
32
33
|
};
|
|
33
|
-
case
|
|
34
|
+
case FileType.GENERAL_USER_STORIES:
|
|
34
35
|
return {
|
|
35
36
|
query: GenerateGeneralUserStories,
|
|
36
37
|
dataKey: "generateGeneralUserStories",
|
|
37
38
|
bucket: Bucket.GENERAL_USER_STORIES,
|
|
39
|
+
type: "markdown",
|
|
38
40
|
description: "general user stories markdown file for selected suite",
|
|
39
41
|
};
|
|
40
|
-
case
|
|
42
|
+
case FileType.USER_STORIES:
|
|
41
43
|
return {
|
|
42
44
|
query: GenerateUserStories,
|
|
43
45
|
dataKey: "generateUserStories",
|
|
44
46
|
bucket: Bucket.USER_STORIES,
|
|
47
|
+
type: "json",
|
|
45
48
|
description: "user stories JSON file for selected suite",
|
|
46
49
|
};
|
|
47
|
-
case
|
|
50
|
+
case FileType.TEST_CASES:
|
|
48
51
|
return {
|
|
49
52
|
query: GenerateTestCases,
|
|
50
53
|
dataKey: "generateTestCases",
|
|
51
54
|
bucket: Bucket.USER_STORIES,
|
|
55
|
+
type: "json",
|
|
52
56
|
description: "test cases for selected suite",
|
|
53
57
|
};
|
|
54
58
|
default:
|
|
55
59
|
return {
|
|
56
60
|
query: null,
|
|
57
61
|
dataKey: null,
|
|
62
|
+
bucket: null,
|
|
63
|
+
type: null,
|
|
58
64
|
description: null,
|
|
59
65
|
};
|
|
60
66
|
}
|
|
@@ -87,7 +93,7 @@ export async function fetchFile(input) {
|
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
export async function generateAIDataFile(type, input) {
|
|
90
|
-
const { query, dataKey, bucket, description } =
|
|
96
|
+
const { query, dataKey, bucket, description } = parseFileType(type);
|
|
91
97
|
if (!query || !dataKey || !description || !bucket)
|
|
92
98
|
return {
|
|
93
99
|
content: [
|
|
@@ -121,3 +127,47 @@ export async function generateAIDataFile(type, input) {
|
|
|
121
127
|
return parseError(error);
|
|
122
128
|
}
|
|
123
129
|
}
|
|
130
|
+
export async function updateFile(input) {
|
|
131
|
+
try {
|
|
132
|
+
const { bucket, type } = parseFileType(input.fileType);
|
|
133
|
+
if (!bucket || !type)
|
|
134
|
+
return {
|
|
135
|
+
content: [
|
|
136
|
+
{
|
|
137
|
+
type: "text",
|
|
138
|
+
text: "Failed to parse file type",
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
const updateFileInput = createUpdateFileInput({
|
|
143
|
+
type,
|
|
144
|
+
bucket,
|
|
145
|
+
suiteUuid: input.suiteUuid,
|
|
146
|
+
fileContent: input.fileContent,
|
|
147
|
+
});
|
|
148
|
+
const parsedInput = UpdateFileInputSchema.parse(updateFileInput);
|
|
149
|
+
const updateFileResult = await requestClient(UpdateFile, {
|
|
150
|
+
input: parsedInput,
|
|
151
|
+
});
|
|
152
|
+
if (!updateFileResult || !updateFileResult.updateFile)
|
|
153
|
+
return {
|
|
154
|
+
content: [
|
|
155
|
+
{
|
|
156
|
+
type: "text",
|
|
157
|
+
text: "Failed to update file",
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
content: [
|
|
163
|
+
{
|
|
164
|
+
type: "text",
|
|
165
|
+
text: "File updated successfully",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return parseError(error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { Bucket } from "./types.js";
|
|
2
|
+
import { Bucket, FileType } from "./types.js";
|
|
3
3
|
var CookiesPreference;
|
|
4
4
|
(function (CookiesPreference) {
|
|
5
5
|
CookiesPreference["ACCEPT_ALL"] = "ACCEPT_ALL";
|
|
@@ -15,7 +15,9 @@ export const SuiteAnalysisConfigSchema = z.object({
|
|
|
15
15
|
additionalVariables: z.string().nullable().default(null),
|
|
16
16
|
});
|
|
17
17
|
export const GenerateAIDataHandlerInputSchema = z.object({
|
|
18
|
-
suiteUuid: z
|
|
18
|
+
suiteUuid: z
|
|
19
|
+
.string({ description: "UUID of the suite to generate AI data for" })
|
|
20
|
+
.min(1, "Suite UUID is required"),
|
|
19
21
|
});
|
|
20
22
|
export const GenerateAIDataInputSchema = z.object({
|
|
21
23
|
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
@@ -27,7 +29,9 @@ export const GenerateAIDataInputSchema = z.object({
|
|
|
27
29
|
continueGeneration: z.boolean().nullish().default(false),
|
|
28
30
|
});
|
|
29
31
|
export const FetchFileHandlerInputSchema = z.object({
|
|
30
|
-
suiteUuid: z
|
|
32
|
+
suiteUuid: z
|
|
33
|
+
.string({ description: "UUID of the suite to fetch the file from" })
|
|
34
|
+
.min(1, "Suite UUID is required"),
|
|
31
35
|
});
|
|
32
36
|
export const FetchFileFactoryInputSchema = z.object({
|
|
33
37
|
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
@@ -38,3 +42,27 @@ export const FetchFileInputSchema = z.object({
|
|
|
38
42
|
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
39
43
|
bucket: z.nativeEnum(Bucket),
|
|
40
44
|
});
|
|
45
|
+
export const UpdateFileHandlerInputSchema = z.object({
|
|
46
|
+
fileType: z.nativeEnum(FileType, {
|
|
47
|
+
description: "Chosen file/artifact to update",
|
|
48
|
+
}),
|
|
49
|
+
fileContent: z.string({
|
|
50
|
+
description: "Content of the file/artifact to update",
|
|
51
|
+
}),
|
|
52
|
+
suiteUuid: z
|
|
53
|
+
.string({ description: "UUID of the suite to update the file for" })
|
|
54
|
+
.min(1, "Suite UUID is required"),
|
|
55
|
+
});
|
|
56
|
+
export const UpdateFileFactoryInputSchema = z.object({
|
|
57
|
+
bucket: z.nativeEnum(Bucket),
|
|
58
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
59
|
+
fileContent: z.string(),
|
|
60
|
+
type: z.enum(["markdown", "json"]),
|
|
61
|
+
});
|
|
62
|
+
export const UpdateFileInputSchema = z.object({
|
|
63
|
+
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
64
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
65
|
+
bucket: z.nativeEnum(Bucket),
|
|
66
|
+
json: z.string().nullish(),
|
|
67
|
+
code: z.string().nullish(),
|
|
68
|
+
});
|
|
@@ -11,6 +11,7 @@ export var ToolName;
|
|
|
11
11
|
ToolName["WOPEE_GENERATE_GENERAL_USER_STORIES"] = "wopee_generate_general_user_stories";
|
|
12
12
|
ToolName["WOPEE_GENERATE_USER_STORIES"] = "wopee_generate_user_stories";
|
|
13
13
|
ToolName["WOPEE_GENERATE_TEST_CASES"] = "wopee_generate_test_cases";
|
|
14
|
+
ToolName["WOPEE_UPDATE_FILE"] = "wopee_update_file";
|
|
14
15
|
})(ToolName || (ToolName = {}));
|
|
15
16
|
export const Bucket = {
|
|
16
17
|
APP_CONTEXT: "project-suite-app-context",
|
|
@@ -21,13 +22,13 @@ export const Bucket = {
|
|
|
21
22
|
PLAYWRIGHT_CODE: "project-suite-playwright-code",
|
|
22
23
|
UPLOADED_PAGE_DATA: "project-uploaded-page-data",
|
|
23
24
|
};
|
|
24
|
-
export var
|
|
25
|
-
(function (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
})(
|
|
25
|
+
export var FileType;
|
|
26
|
+
(function (FileType) {
|
|
27
|
+
FileType["APP_CONTEXT"] = "APP_CONTEXT";
|
|
28
|
+
FileType["GENERAL_USER_STORIES"] = "GENERAL_USER_STORIES";
|
|
29
|
+
FileType["USER_STORIES"] = "USER_STORIES";
|
|
30
|
+
FileType["TEST_CASES"] = "TEST_CASES";
|
|
31
|
+
})(FileType || (FileType = {}));
|
|
31
32
|
export var SuiteType;
|
|
32
33
|
(function (SuiteType) {
|
|
33
34
|
SuiteType["BOT"] = "BOT";
|
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
const SelectedTestCasesSchema = z.object({
|
|
3
|
-
testCaseId: z
|
|
4
|
-
|
|
3
|
+
testCaseId: z
|
|
4
|
+
.string({
|
|
5
|
+
description: "ID of the test case belonging to the user story to dispatch the agent for (ex. TC001)",
|
|
6
|
+
})
|
|
7
|
+
.min(1, "Test case ID is required"),
|
|
8
|
+
userStoryId: z
|
|
9
|
+
.string({
|
|
10
|
+
description: "ID of the user story that the test case belongs to (ex. US001)",
|
|
11
|
+
})
|
|
12
|
+
.min(1, "User story ID is required"),
|
|
5
13
|
});
|
|
6
14
|
export const WopeeDispatchAgentInputSchema = z.object({
|
|
7
|
-
suiteUuid: z
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
suiteUuid: z
|
|
16
|
+
.string({ description: "UUID of the suite to dispatch the agent for" })
|
|
17
|
+
.min(1, "Suite UUID is required"),
|
|
18
|
+
analysisIdentifier: z
|
|
19
|
+
.string({
|
|
20
|
+
description: "Analysis identifier of the suite to dispatch the agent for",
|
|
21
|
+
})
|
|
22
|
+
.min(1, "Analysis identifier is required"),
|
|
23
|
+
testCases: z.array(SelectedTestCasesSchema, {
|
|
24
|
+
description: "Chosen test cases to dispatch the agent for",
|
|
25
|
+
}),
|
|
10
26
|
});
|
|
11
27
|
export const DispatchAgentInputSchema = z.object({
|
|
12
28
|
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
1
2
|
import { requestClient } from "../../utils/requestClient.js";
|
|
2
3
|
import { ToolName } from "../shared/types.js";
|
|
3
4
|
import { FetchAnalysisSuites } from "../shared/gql-queries.js";
|
|
4
|
-
import { getConfig } from "../../utils/getConfig.js";
|
|
5
5
|
export const wopeeFetchAnalysisSuites = {
|
|
6
6
|
name: ToolName.WOPEE_FETCH_ANALYSIS_SUITES,
|
|
7
7
|
config: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { FetchFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
1
2
|
import { fetchFile } from "../shared/handlers.js";
|
|
2
3
|
import { Bucket, ToolName } from "../shared/types.js";
|
|
3
|
-
import { FetchFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
4
4
|
export const wopeeFetchAppContext = {
|
|
5
5
|
name: ToolName.WOPEE_FETCH_APP_CONTEXT,
|
|
6
6
|
config: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { FileType, ToolName } from "../shared/types.js";
|
|
2
3
|
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
-
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
4
|
export const wopeeGenerateAppContext = {
|
|
5
5
|
name: ToolName.WOPEE_GENERATE_APP_CONTEXT,
|
|
6
6
|
config: {
|
|
@@ -8,5 +8,5 @@ export const wopeeGenerateAppContext = {
|
|
|
8
8
|
description: "Generate application's context markdown file for selected suite",
|
|
9
9
|
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
10
|
},
|
|
11
|
-
handler: async (input) => await generateAIDataFile(
|
|
11
|
+
handler: async (input) => await generateAIDataFile(FileType.APP_CONTEXT, input),
|
|
12
12
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { FileType, ToolName } from "../shared/types.js";
|
|
2
3
|
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
-
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
4
|
export const wopeeGenerateGeneralUserStories = {
|
|
5
5
|
name: ToolName.WOPEE_GENERATE_GENERAL_USER_STORIES,
|
|
6
6
|
config: {
|
|
@@ -8,5 +8,5 @@ export const wopeeGenerateGeneralUserStories = {
|
|
|
8
8
|
description: "Generate general user stories markdown file for selected suite",
|
|
9
9
|
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
10
|
},
|
|
11
|
-
handler: async (input) => await generateAIDataFile(
|
|
11
|
+
handler: async (input) => await generateAIDataFile(FileType.GENERAL_USER_STORIES, input),
|
|
12
12
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { FileType, ToolName } from "../shared/types.js";
|
|
2
3
|
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
-
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
4
|
export const wopeeGenerateTestCases = {
|
|
5
5
|
name: ToolName.WOPEE_GENERATE_TEST_CASES,
|
|
6
6
|
config: {
|
|
@@ -8,5 +8,5 @@ export const wopeeGenerateTestCases = {
|
|
|
8
8
|
description: "Generate test cases for selected suite",
|
|
9
9
|
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
10
|
},
|
|
11
|
-
handler: async (input) => await generateAIDataFile(
|
|
11
|
+
handler: async (input) => await generateAIDataFile(FileType.TEST_CASES, input),
|
|
12
12
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { FileType, ToolName } from "../shared/types.js";
|
|
2
3
|
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
-
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
4
|
export const wopeeGenerateUserStories = {
|
|
5
5
|
name: ToolName.WOPEE_GENERATE_USER_STORIES,
|
|
6
6
|
config: {
|
|
@@ -8,5 +8,5 @@ export const wopeeGenerateUserStories = {
|
|
|
8
8
|
description: "Generate user stories JSON file for selected suite",
|
|
9
9
|
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
10
|
},
|
|
11
|
-
handler: async (input) => await generateAIDataFile(
|
|
11
|
+
handler: async (input) => await generateAIDataFile(FileType.USER_STORIES, input),
|
|
12
12
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UpdateFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { ToolName } from "../shared/types.js";
|
|
3
|
+
import { updateFile } from "../shared/handlers.js";
|
|
4
|
+
export const wopeeUpdateFile = {
|
|
5
|
+
name: ToolName.WOPEE_UPDATE_FILE,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Update file",
|
|
8
|
+
description: "Update file(artifact) in the project",
|
|
9
|
+
inputSchema: UpdateFileHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await updateFile(input),
|
|
12
|
+
};
|