wopee-mcp 1.2.1 → 1.2.2
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/build/index.js +19 -0
- package/build/tools/index.js +24 -0
- package/build/tools/shared/factories.js +32 -0
- package/build/tools/shared/gql-queries.js +106 -0
- package/build/tools/shared/handlers.js +123 -0
- package/build/tools/shared/schemas.js +40 -0
- package/build/tools/shared/types.js +60 -0
- package/build/tools/wopee_dispatch_agent/factory.js +13 -0
- package/build/tools/wopee_dispatch_agent/index.js +43 -0
- package/build/tools/wopee_dispatch_agent/schema.js +17 -0
- package/build/tools/wopee_dispatch_analysis/factory.js +18 -0
- package/build/tools/wopee_dispatch_analysis/index.js +42 -0
- package/build/tools/wopee_dispatch_analysis/schema.js +17 -0
- package/build/tools/wopee_fetch_analysis_suites/index.js +43 -0
- package/build/tools/wopee_fetch_app_context/index.js +15 -0
- package/build/tools/wopee_fetch_general_user_stories/index.js +15 -0
- package/build/tools/wopee_fetch_test_cases/index.js +15 -0
- package/build/tools/wopee_fetch_user_stories/index.js +15 -0
- package/build/tools/wopee_generate_app_context/index.js +12 -0
- package/build/tools/wopee_generate_general_user_stories/index.js +12 -0
- package/build/tools/wopee_generate_test_cases/index.js +12 -0
- package/build/tools/wopee_generate_user_stories/index.js +12 -0
- package/build/utils/getConfig.js +10 -0
- package/build/utils/requestClient.js +37 -0
- package/package.json +1 -1
package/build/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { TOOLS } from "./tools/index.js";
|
|
4
|
+
const server = new McpServer({
|
|
5
|
+
name: "wopee-mcp",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
});
|
|
8
|
+
for (const { name, config, handler } of TOOLS) {
|
|
9
|
+
server.registerTool(name, config, handler);
|
|
10
|
+
}
|
|
11
|
+
async function main() {
|
|
12
|
+
const transport = new StdioServerTransport();
|
|
13
|
+
await server.connect(transport);
|
|
14
|
+
console.error("Wopee MCP server running on stdio");
|
|
15
|
+
}
|
|
16
|
+
main().catch((error) => {
|
|
17
|
+
console.error("Error starting Wopee MCP server:", error);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { wopeeDispatchAgent } from "./wopee_dispatch_agent/index.js";
|
|
2
|
+
import { wopeeFetchTestCases } from "./wopee_fetch_test_cases/index.js";
|
|
3
|
+
import { wopeeFetchAppContext } from "./wopee_fetch_app_context/index.js";
|
|
4
|
+
import { wopeeDispatchAnalysis } from "./wopee_dispatch_analysis/index.js";
|
|
5
|
+
import { wopeeFetchUserStories } from "./wopee_fetch_user_stories/index.js";
|
|
6
|
+
import { wopeeGenerateTestCases } from "./wopee_generate_test_cases/index.js";
|
|
7
|
+
import { wopeeGenerateAppContext } from "./wopee_generate_app_context/index.js";
|
|
8
|
+
import { wopeeFetchAnalysisSuites } from "./wopee_fetch_analysis_suites/index.js";
|
|
9
|
+
import { wopeeGenerateUserStories } from "./wopee_generate_user_stories/index.js";
|
|
10
|
+
import { wopeeFetchGeneralUserStories } from "./wopee_fetch_general_user_stories/index.js";
|
|
11
|
+
import { wopeeGenerateGeneralUserStories } from "./wopee_generate_general_user_stories/index.js";
|
|
12
|
+
export const TOOLS = [
|
|
13
|
+
wopeeDispatchAnalysis,
|
|
14
|
+
wopeeDispatchAgent,
|
|
15
|
+
wopeeGenerateAppContext,
|
|
16
|
+
wopeeGenerateGeneralUserStories,
|
|
17
|
+
wopeeGenerateUserStories,
|
|
18
|
+
wopeeGenerateTestCases,
|
|
19
|
+
wopeeFetchAnalysisSuites,
|
|
20
|
+
wopeeFetchAppContext,
|
|
21
|
+
wopeeFetchGeneralUserStories,
|
|
22
|
+
wopeeFetchUserStories,
|
|
23
|
+
wopeeFetchTestCases,
|
|
24
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
2
|
+
export const createFetchFileInput = (input) => {
|
|
3
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
4
|
+
if (!WOPEE_PROJECT_UUID)
|
|
5
|
+
throw new Error("WOPEE_PROJECT_UUID is not set");
|
|
6
|
+
return {
|
|
7
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
8
|
+
suiteUuid: input.suiteUuid,
|
|
9
|
+
bucket: input.bucket,
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export const createGenerateAIDataInput = (input) => {
|
|
13
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
14
|
+
if (!WOPEE_PROJECT_UUID)
|
|
15
|
+
throw new Error("WOPEE_PROJECT_UUID is not set");
|
|
16
|
+
return {
|
|
17
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
18
|
+
suiteUuid: input.suiteUuid,
|
|
19
|
+
suiteAnalysisConfig: {
|
|
20
|
+
startingUrl: null,
|
|
21
|
+
username: null,
|
|
22
|
+
password: null,
|
|
23
|
+
cookiesPreference: null,
|
|
24
|
+
additionalInstructions: null,
|
|
25
|
+
additionalVariables: null,
|
|
26
|
+
},
|
|
27
|
+
continueGeneration: false,
|
|
28
|
+
extraPrompt: null,
|
|
29
|
+
selectedUserStories: null,
|
|
30
|
+
sourceSuiteUuid: null,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export const FetchFile = `
|
|
2
|
+
query FetchFile($projectUuid: ID!, $suiteUuid: ID!, $bucket: String!) {
|
|
3
|
+
fetchFile(projectUuid: $projectUuid, suiteUuid: $suiteUuid, bucket: $bucket)
|
|
4
|
+
}
|
|
5
|
+
`;
|
|
6
|
+
export const DispatchAgent = `
|
|
7
|
+
mutation DispatchAgent(
|
|
8
|
+
$input: TestCasesInput!
|
|
9
|
+
) {
|
|
10
|
+
dispatchAgent(input: $input)
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
export const DispatchAnalysis = `
|
|
14
|
+
mutation DispatchAnalysis($input: DispatchAnalysisInput!) {
|
|
15
|
+
dispatchAnalysis(input: $input) {
|
|
16
|
+
uuid
|
|
17
|
+
name
|
|
18
|
+
createdAt
|
|
19
|
+
updatedAt
|
|
20
|
+
suiteType
|
|
21
|
+
analysisIdentifier
|
|
22
|
+
suiteRunningStatus
|
|
23
|
+
generatedAnalysisDataState {
|
|
24
|
+
suiteUuid
|
|
25
|
+
appContext {
|
|
26
|
+
status
|
|
27
|
+
isGenerated
|
|
28
|
+
}
|
|
29
|
+
generalUserStories {
|
|
30
|
+
status
|
|
31
|
+
isGenerated
|
|
32
|
+
}
|
|
33
|
+
userStories {
|
|
34
|
+
status
|
|
35
|
+
isGenerated
|
|
36
|
+
}
|
|
37
|
+
testCases {
|
|
38
|
+
status
|
|
39
|
+
isGenerated
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
export const FetchAnalysisSuites = `
|
|
46
|
+
query FetchAnalysisSuites($projectUuid: ID!) {
|
|
47
|
+
fetchAnalysisSuites(projectUuid: $projectUuid) {
|
|
48
|
+
uuid
|
|
49
|
+
name
|
|
50
|
+
suiteType
|
|
51
|
+
executionStatus
|
|
52
|
+
analysisIdentifier
|
|
53
|
+
suiteRunningStatus
|
|
54
|
+
createdAt
|
|
55
|
+
updatedAt
|
|
56
|
+
generatedAnalysisDataState {
|
|
57
|
+
uuid
|
|
58
|
+
suiteUuid
|
|
59
|
+
appContext {
|
|
60
|
+
uuid
|
|
61
|
+
isGenerated
|
|
62
|
+
status
|
|
63
|
+
}
|
|
64
|
+
generalUserStories {
|
|
65
|
+
uuid
|
|
66
|
+
isGenerated
|
|
67
|
+
status
|
|
68
|
+
}
|
|
69
|
+
userStories {
|
|
70
|
+
uuid
|
|
71
|
+
isGenerated
|
|
72
|
+
status
|
|
73
|
+
}
|
|
74
|
+
testCases {
|
|
75
|
+
uuid
|
|
76
|
+
isGenerated
|
|
77
|
+
status
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
export const GenerateAppContext = `
|
|
84
|
+
mutation GenerateAppContext(
|
|
85
|
+
$input: GenerateAIDataInput!
|
|
86
|
+
) {
|
|
87
|
+
generateAppContext(input: $input)
|
|
88
|
+
}
|
|
89
|
+
`;
|
|
90
|
+
export const GenerateGeneralUserStories = `
|
|
91
|
+
mutation GenerateGeneralUserStories(
|
|
92
|
+
$input: GenerateAIDataInput!
|
|
93
|
+
) {
|
|
94
|
+
generateGeneralUserStories(input: $input)
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
export const GenerateTestCases = `
|
|
98
|
+
mutation GenerateTestCases($input: GenerateAIDataInput!) {
|
|
99
|
+
generateTestCases(input: $input)
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
export const GenerateUserStories = `
|
|
103
|
+
mutation GenerateUserStories($input: GenerateAIDataInput!) {
|
|
104
|
+
generateUserStories(input: $input)
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
@@ -0,0 +1,123 @@
|
|
|
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, GenerationType } from "./types.js";
|
|
6
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
7
|
+
export function parseError(error) {
|
|
8
|
+
console.error(error instanceof z.ZodError ? error.issues : error);
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: `Failed to parse input: ${error instanceof z.ZodError
|
|
14
|
+
? error.issues
|
|
15
|
+
.map((issue) => `${issue.path[0] ?? "Unknown"}: ${issue.message}`)
|
|
16
|
+
.join("\n")
|
|
17
|
+
: error instanceof Error
|
|
18
|
+
? error.message
|
|
19
|
+
: "Unknown zod validation error"}`,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function parseGenerationType(type) {
|
|
25
|
+
switch (type) {
|
|
26
|
+
case GenerationType.APP_CONTEXT:
|
|
27
|
+
return {
|
|
28
|
+
query: GenerateAppContext,
|
|
29
|
+
dataKey: "generateAppContext",
|
|
30
|
+
bucket: Bucket.APP_CONTEXT,
|
|
31
|
+
description: "application's context markdown file for selected suite",
|
|
32
|
+
};
|
|
33
|
+
case GenerationType.GENERAL_USER_STORIES:
|
|
34
|
+
return {
|
|
35
|
+
query: GenerateGeneralUserStories,
|
|
36
|
+
dataKey: "generateGeneralUserStories",
|
|
37
|
+
bucket: Bucket.GENERAL_USER_STORIES,
|
|
38
|
+
description: "general user stories markdown file for selected suite",
|
|
39
|
+
};
|
|
40
|
+
case GenerationType.USER_STORIES:
|
|
41
|
+
return {
|
|
42
|
+
query: GenerateUserStories,
|
|
43
|
+
dataKey: "generateUserStories",
|
|
44
|
+
bucket: Bucket.USER_STORIES,
|
|
45
|
+
description: "user stories JSON file for selected suite",
|
|
46
|
+
};
|
|
47
|
+
case GenerationType.TEST_CASES:
|
|
48
|
+
return {
|
|
49
|
+
query: GenerateTestCases,
|
|
50
|
+
dataKey: "generateTestCases",
|
|
51
|
+
bucket: Bucket.USER_STORIES,
|
|
52
|
+
description: "test cases for selected suite",
|
|
53
|
+
};
|
|
54
|
+
default:
|
|
55
|
+
return {
|
|
56
|
+
query: null,
|
|
57
|
+
dataKey: null,
|
|
58
|
+
description: null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function fetchFile(input) {
|
|
63
|
+
try {
|
|
64
|
+
const fetchFileInput = createFetchFileInput(input);
|
|
65
|
+
const parsedInput = FetchFileInputSchema.parse(fetchFileInput);
|
|
66
|
+
const result = await requestClient(FetchFile, parsedInput);
|
|
67
|
+
if (!result || !result.fetchFile)
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: "text",
|
|
72
|
+
text: "Failed to fetch file",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
content: [
|
|
78
|
+
{
|
|
79
|
+
type: "text",
|
|
80
|
+
text: result.fetchFile,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
return parseError(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export async function generateAIDataFile(type, input) {
|
|
90
|
+
const { query, dataKey, bucket, description } = parseGenerationType(type);
|
|
91
|
+
if (!query || !dataKey || !description || !bucket)
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: "text",
|
|
96
|
+
text: "Failed to parse generation type",
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
try {
|
|
101
|
+
const generateAIDataInput = createGenerateAIDataInput(input);
|
|
102
|
+
const parsedInput = GenerateAIDataInputSchema.parse(generateAIDataInput);
|
|
103
|
+
const generationResult = await requestClient(query, {
|
|
104
|
+
input: parsedInput,
|
|
105
|
+
});
|
|
106
|
+
if (!generationResult || !generationResult[dataKey])
|
|
107
|
+
return {
|
|
108
|
+
content: [
|
|
109
|
+
{
|
|
110
|
+
type: "text",
|
|
111
|
+
text: `Failed to generate ${description}`,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
return await fetchFile({
|
|
116
|
+
suiteUuid: parsedInput.suiteUuid,
|
|
117
|
+
bucket,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return parseError(error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Bucket } from "./types.js";
|
|
3
|
+
var CookiesPreference;
|
|
4
|
+
(function (CookiesPreference) {
|
|
5
|
+
CookiesPreference["ACCEPT_ALL"] = "ACCEPT_ALL";
|
|
6
|
+
CookiesPreference["DECLINE_ALL"] = "DECLINE_ALL";
|
|
7
|
+
CookiesPreference["IGNORE"] = "IGNORE";
|
|
8
|
+
})(CookiesPreference || (CookiesPreference = {}));
|
|
9
|
+
export const SuiteAnalysisConfigSchema = z.object({
|
|
10
|
+
startingUrl: z.string().nullable().default(null),
|
|
11
|
+
username: z.string().nullable().default(null),
|
|
12
|
+
password: z.string().nullable().default(null),
|
|
13
|
+
cookiesPreference: z.nativeEnum(CookiesPreference).nullable().default(null),
|
|
14
|
+
additionalInstructions: z.string().nullable().default(null),
|
|
15
|
+
additionalVariables: z.string().nullable().default(null),
|
|
16
|
+
});
|
|
17
|
+
export const GenerateAIDataHandlerInputSchema = z.object({
|
|
18
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
19
|
+
});
|
|
20
|
+
export const GenerateAIDataInputSchema = z.object({
|
|
21
|
+
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
22
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
23
|
+
extraPrompt: z.string().nullish(),
|
|
24
|
+
sourceSuiteUuid: z.string().nullish(),
|
|
25
|
+
selectedUserStories: z.array(z.string()).nullish(),
|
|
26
|
+
suiteAnalysisConfig: SuiteAnalysisConfigSchema,
|
|
27
|
+
continueGeneration: z.boolean().nullish().default(false),
|
|
28
|
+
});
|
|
29
|
+
export const FetchFileHandlerInputSchema = z.object({
|
|
30
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
31
|
+
});
|
|
32
|
+
export const FetchFileFactoryInputSchema = z.object({
|
|
33
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
34
|
+
bucket: z.nativeEnum(Bucket),
|
|
35
|
+
});
|
|
36
|
+
export const FetchFileInputSchema = z.object({
|
|
37
|
+
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
38
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
39
|
+
bucket: z.nativeEnum(Bucket),
|
|
40
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export var ToolName;
|
|
2
|
+
(function (ToolName) {
|
|
3
|
+
ToolName["WOPEE_DISPATCH_ANALYSIS"] = "wopee_dispatch_analysis";
|
|
4
|
+
ToolName["WOPEE_DISPATCH_AGENT"] = "wopee_dispatch_agent";
|
|
5
|
+
ToolName["WOPEE_FETCH_ANALYSIS_SUITES"] = "wopee_fetch_analysis_suites";
|
|
6
|
+
ToolName["WOPEE_FETCH_APP_CONTEXT"] = "wopee_fetch_app_context";
|
|
7
|
+
ToolName["WOPEE_FETCH_GENERAL_USER_STORIES"] = "wopee_fetch_general_user_stories";
|
|
8
|
+
ToolName["WOPEE_FETCH_USER_STORIES"] = "wopee_fetch_user_stories";
|
|
9
|
+
ToolName["WOPEE_FETCH_TEST_CASES"] = "wopee_fetch_test_cases";
|
|
10
|
+
ToolName["WOPEE_GENERATE_APP_CONTEXT"] = "wopee_generate_app_context";
|
|
11
|
+
ToolName["WOPEE_GENERATE_GENERAL_USER_STORIES"] = "wopee_generate_general_user_stories";
|
|
12
|
+
ToolName["WOPEE_GENERATE_USER_STORIES"] = "wopee_generate_user_stories";
|
|
13
|
+
ToolName["WOPEE_GENERATE_TEST_CASES"] = "wopee_generate_test_cases";
|
|
14
|
+
})(ToolName || (ToolName = {}));
|
|
15
|
+
export const Bucket = {
|
|
16
|
+
APP_CONTEXT: "project-suite-app-context",
|
|
17
|
+
GENERAL_USER_STORIES: "project-suite-general-user-stories",
|
|
18
|
+
USER_STORIES: "project-suite-user-stories",
|
|
19
|
+
PAGE_CONTENT: "screen-instance-page-content",
|
|
20
|
+
PROMPTS: "project-prompts",
|
|
21
|
+
PLAYWRIGHT_CODE: "project-suite-playwright-code",
|
|
22
|
+
UPLOADED_PAGE_DATA: "project-uploaded-page-data",
|
|
23
|
+
};
|
|
24
|
+
export var GenerationType;
|
|
25
|
+
(function (GenerationType) {
|
|
26
|
+
GenerationType["APP_CONTEXT"] = "APP_CONTEXT";
|
|
27
|
+
GenerationType["GENERAL_USER_STORIES"] = "GENERAL_USER_STORIES";
|
|
28
|
+
GenerationType["USER_STORIES"] = "USER_STORIES";
|
|
29
|
+
GenerationType["TEST_CASES"] = "TEST_CASES";
|
|
30
|
+
})(GenerationType || (GenerationType = {}));
|
|
31
|
+
export var SuiteType;
|
|
32
|
+
(function (SuiteType) {
|
|
33
|
+
SuiteType["BOT"] = "BOT";
|
|
34
|
+
SuiteType["CODE"] = "CODE";
|
|
35
|
+
SuiteType["AGENT"] = "AGENT";
|
|
36
|
+
SuiteType["ANALYSIS"] = "ANALYSIS";
|
|
37
|
+
SuiteType["INTEGRATION"] = "INTEGRATION";
|
|
38
|
+
SuiteType["UPLOADED_PAGE_DATA"] = "UPLOADED_PAGE_DATA";
|
|
39
|
+
})(SuiteType || (SuiteType = {}));
|
|
40
|
+
export var SuiteRunningStatus;
|
|
41
|
+
(function (SuiteRunningStatus) {
|
|
42
|
+
SuiteRunningStatus["IDLE"] = "IDLE";
|
|
43
|
+
SuiteRunningStatus["FINISHED"] = "FINISHED";
|
|
44
|
+
SuiteRunningStatus["IN_PROGRESS"] = "IN_PROGRESS";
|
|
45
|
+
SuiteRunningStatus["IN_PROGRESS_MERGE"] = "IN_PROGRESS_MERGE";
|
|
46
|
+
})(SuiteRunningStatus || (SuiteRunningStatus = {}));
|
|
47
|
+
export var ExecutionStatus;
|
|
48
|
+
(function (ExecutionStatus) {
|
|
49
|
+
ExecutionStatus["IN_PROGRESS"] = "IN_PROGRESS";
|
|
50
|
+
ExecutionStatus["FINISHED"] = "FINISHED";
|
|
51
|
+
ExecutionStatus["FAILED"] = "FAILED";
|
|
52
|
+
})(ExecutionStatus || (ExecutionStatus = {}));
|
|
53
|
+
export var GenerationStatus;
|
|
54
|
+
(function (GenerationStatus) {
|
|
55
|
+
GenerationStatus["NOT_STARTED"] = "NOT_STARTED";
|
|
56
|
+
GenerationStatus["IN_QUEUE"] = "IN_QUEUE";
|
|
57
|
+
GenerationStatus["IN_PROGRESS"] = "IN_PROGRESS";
|
|
58
|
+
GenerationStatus["FINISHED"] = "FINISHED";
|
|
59
|
+
GenerationStatus["FAILED"] = "FAILED";
|
|
60
|
+
})(GenerationStatus || (GenerationStatus = {}));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
2
|
+
export const createDispatchAgentInput = (input) => {
|
|
3
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
4
|
+
if (!WOPEE_PROJECT_UUID)
|
|
5
|
+
throw new Error("WOPEE_PROJECT_UUID is not set");
|
|
6
|
+
return {
|
|
7
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
8
|
+
suiteUuid: input.suiteUuid,
|
|
9
|
+
analysisIdentifier: input.analysisIdentifier,
|
|
10
|
+
testCases: input.testCases,
|
|
11
|
+
skipRateLimitCheck: true,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DispatchAgentInputSchema, WopeeDispatchAgentInputSchema, } from "./schema.js";
|
|
2
|
+
import { ToolName } from "../shared/types.js";
|
|
3
|
+
import { parseError } from "../shared/handlers.js";
|
|
4
|
+
import { createDispatchAgentInput } from "./factory.js";
|
|
5
|
+
import { DispatchAgent } from "../shared/gql-queries.js";
|
|
6
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
7
|
+
export const wopeeDispatchAgent = {
|
|
8
|
+
name: ToolName.WOPEE_DISPATCH_AGENT,
|
|
9
|
+
config: {
|
|
10
|
+
title: "Dispatch agent",
|
|
11
|
+
description: "Dispatch agent testing for selected suite's test cases",
|
|
12
|
+
inputSchema: WopeeDispatchAgentInputSchema.shape,
|
|
13
|
+
},
|
|
14
|
+
handler: async (input) => {
|
|
15
|
+
try {
|
|
16
|
+
const dispatchAgentInput = createDispatchAgentInput(input);
|
|
17
|
+
const parsedInput = DispatchAgentInputSchema.parse(dispatchAgentInput);
|
|
18
|
+
const result = await requestClient(DispatchAgent, {
|
|
19
|
+
input: parsedInput,
|
|
20
|
+
});
|
|
21
|
+
if (!result || !result.dispatchAgent)
|
|
22
|
+
return {
|
|
23
|
+
content: [
|
|
24
|
+
{
|
|
25
|
+
type: "text",
|
|
26
|
+
text: "Failed to dispatch agent",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Agent dispatched successfully",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return parseError(error);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const SelectedTestCasesSchema = z.object({
|
|
3
|
+
testCaseId: z.string().min(1, "Test case ID is required"),
|
|
4
|
+
userStoryId: z.string().min(1, "User story ID is required"),
|
|
5
|
+
});
|
|
6
|
+
export const WopeeDispatchAgentInputSchema = z.object({
|
|
7
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
8
|
+
analysisIdentifier: z.string().min(1, "Analysis identifier is required"),
|
|
9
|
+
testCases: z.array(SelectedTestCasesSchema),
|
|
10
|
+
});
|
|
11
|
+
export const DispatchAgentInputSchema = z.object({
|
|
12
|
+
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
13
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
14
|
+
analysisIdentifier: z.string().min(1, "Analysis identifier is required"),
|
|
15
|
+
testCases: z.array(SelectedTestCasesSchema),
|
|
16
|
+
skipRateLimitCheck: z.boolean().nullable().default(true),
|
|
17
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
2
|
+
export const createDispatchAnalysisInput = () => {
|
|
3
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
4
|
+
if (!WOPEE_PROJECT_UUID)
|
|
5
|
+
throw new Error("WOPEE_PROJECT_UUID is not set");
|
|
6
|
+
return {
|
|
7
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
8
|
+
suiteAnalysisConfig: {
|
|
9
|
+
startingUrl: null,
|
|
10
|
+
username: null,
|
|
11
|
+
password: null,
|
|
12
|
+
cookiesPreference: null,
|
|
13
|
+
additionalInstructions: null,
|
|
14
|
+
additionalVariables: null,
|
|
15
|
+
},
|
|
16
|
+
rerun: null,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { parseError } from "../shared/handlers.js";
|
|
2
|
+
import { DispatchAnalysisInputSchema } from "./schema.js";
|
|
3
|
+
import { createDispatchAnalysisInput } from "./factory.js";
|
|
4
|
+
import { DispatchAnalysis } from "../shared/gql-queries.js";
|
|
5
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
6
|
+
import { ToolName } from "../shared/types.js";
|
|
7
|
+
export const wopeeDispatchAnalysis = {
|
|
8
|
+
name: ToolName.WOPEE_DISPATCH_ANALYSIS,
|
|
9
|
+
config: {
|
|
10
|
+
title: "Dispatch analysis",
|
|
11
|
+
description: "Create and dispatch analysis/crawling suite for a project",
|
|
12
|
+
},
|
|
13
|
+
handler: async () => {
|
|
14
|
+
try {
|
|
15
|
+
const input = createDispatchAnalysisInput();
|
|
16
|
+
const parsedInput = DispatchAnalysisInputSchema.parse(input);
|
|
17
|
+
const result = await requestClient(DispatchAnalysis, {
|
|
18
|
+
input: parsedInput,
|
|
19
|
+
});
|
|
20
|
+
if (!result || !result.dispatchAnalysis)
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: "Failed to dispatch agent",
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: "Agent dispatched successfully",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return parseError(error);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { SuiteAnalysisConfigSchema } from "../shared/schemas.js";
|
|
3
|
+
var RerunMode;
|
|
4
|
+
(function (RerunMode) {
|
|
5
|
+
RerunMode["FULL"] = "FULL";
|
|
6
|
+
RerunMode["CRAWLING"] = "CRAWLING";
|
|
7
|
+
})(RerunMode || (RerunMode = {}));
|
|
8
|
+
const RerunOptionsSchema = z.object({
|
|
9
|
+
suiteUuid: z.string().min(1, "Suite UUID is required"),
|
|
10
|
+
analysisIdentifier: z.string().min(1, "Analysis identifier is required"),
|
|
11
|
+
mode: z.nativeEnum(RerunMode),
|
|
12
|
+
});
|
|
13
|
+
export const DispatchAnalysisInputSchema = z.object({
|
|
14
|
+
projectUuid: z.string().min(1, "Project UUID is required"),
|
|
15
|
+
suiteAnalysisConfig: SuiteAnalysisConfigSchema,
|
|
16
|
+
rerun: RerunOptionsSchema.nullable().default(null),
|
|
17
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
2
|
+
import { ToolName } from "../shared/types.js";
|
|
3
|
+
import { FetchAnalysisSuites } from "../shared/gql-queries.js";
|
|
4
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
5
|
+
export const wopeeFetchAnalysisSuites = {
|
|
6
|
+
name: ToolName.WOPEE_FETCH_ANALYSIS_SUITES,
|
|
7
|
+
config: {
|
|
8
|
+
title: "Fetch Analysis Suites",
|
|
9
|
+
description: "Fetch project's analysis suites from Woopee",
|
|
10
|
+
},
|
|
11
|
+
handler: async () => {
|
|
12
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
13
|
+
if (!WOPEE_PROJECT_UUID)
|
|
14
|
+
return {
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: "text",
|
|
18
|
+
text: "WOPEE_PROJECT_UUID is not set",
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
const result = await requestClient(FetchAnalysisSuites, {
|
|
23
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
24
|
+
});
|
|
25
|
+
if (!result || !result.fetchAnalysisSuites)
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: "Failed to fetch analysis suites",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: JSON.stringify(result.fetchAnalysisSuites, null, 2),
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { fetchFile } from "../shared/handlers.js";
|
|
2
|
+
import { Bucket, ToolName } from "../shared/types.js";
|
|
3
|
+
import { FetchFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
4
|
+
export const wopeeFetchAppContext = {
|
|
5
|
+
name: ToolName.WOPEE_FETCH_APP_CONTEXT,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Fetch app context",
|
|
8
|
+
description: "Fetch suite's application context markdown file for selected project",
|
|
9
|
+
inputSchema: FetchFileHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await fetchFile({
|
|
12
|
+
...input,
|
|
13
|
+
bucket: Bucket.APP_CONTEXT,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FetchFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { fetchFile } from "../shared/handlers.js";
|
|
3
|
+
import { Bucket, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeFetchGeneralUserStories = {
|
|
5
|
+
name: ToolName.WOPEE_FETCH_GENERAL_USER_STORIES,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Fetch general user stories",
|
|
8
|
+
description: "Fetch suite's general user stories markdown file for selected project",
|
|
9
|
+
inputSchema: FetchFileHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await fetchFile({
|
|
12
|
+
...input,
|
|
13
|
+
bucket: Bucket.GENERAL_USER_STORIES,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FetchFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { fetchFile } from "../shared/handlers.js";
|
|
3
|
+
import { Bucket, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeFetchTestCases = {
|
|
5
|
+
name: ToolName.WOPEE_FETCH_TEST_CASES,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Fetch test cases",
|
|
8
|
+
description: "Fetch suite's test cases JSON file for selected project",
|
|
9
|
+
inputSchema: FetchFileHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await fetchFile({
|
|
12
|
+
...input,
|
|
13
|
+
bucket: Bucket.USER_STORIES,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FetchFileHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { fetchFile } from "../shared/handlers.js";
|
|
3
|
+
import { Bucket, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeFetchUserStories = {
|
|
5
|
+
name: ToolName.WOPEE_FETCH_USER_STORIES,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Fetch user stories",
|
|
8
|
+
description: "Fetch suite's user stories JSON file for selected project",
|
|
9
|
+
inputSchema: FetchFileHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await fetchFile({
|
|
12
|
+
...input,
|
|
13
|
+
bucket: Bucket.USER_STORIES,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
+
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeGenerateAppContext = {
|
|
5
|
+
name: ToolName.WOPEE_GENERATE_APP_CONTEXT,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Generate app context",
|
|
8
|
+
description: "Generate application's context markdown file for selected suite",
|
|
9
|
+
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await generateAIDataFile(GenerationType.APP_CONTEXT, input),
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
+
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeGenerateGeneralUserStories = {
|
|
5
|
+
name: ToolName.WOPEE_GENERATE_GENERAL_USER_STORIES,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Generate general user stories",
|
|
8
|
+
description: "Generate general user stories markdown file for selected suite",
|
|
9
|
+
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await generateAIDataFile(GenerationType.GENERAL_USER_STORIES, input),
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
+
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeGenerateTestCases = {
|
|
5
|
+
name: ToolName.WOPEE_GENERATE_TEST_CASES,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Generate test cases",
|
|
8
|
+
description: "Generate test cases for selected suite",
|
|
9
|
+
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await generateAIDataFile(GenerationType.TEST_CASES, input),
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GenerateAIDataHandlerInputSchema, } from "../shared/schemas.js";
|
|
2
|
+
import { generateAIDataFile } from "../shared/handlers.js";
|
|
3
|
+
import { GenerationType, ToolName } from "../shared/types.js";
|
|
4
|
+
export const wopeeGenerateUserStories = {
|
|
5
|
+
name: ToolName.WOPEE_GENERATE_USER_STORIES,
|
|
6
|
+
config: {
|
|
7
|
+
title: "Generate user stories",
|
|
8
|
+
description: "Generate user stories JSON file for selected suite",
|
|
9
|
+
inputSchema: GenerateAIDataHandlerInputSchema.shape,
|
|
10
|
+
},
|
|
11
|
+
handler: async (input) => await generateAIDataFile(GenerationType.USER_STORIES, input),
|
|
12
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const getConfig = () => {
|
|
2
|
+
const WOPEE_API_URL = process.env.WOPEE_API_URL ?? "https://api.wopee.io";
|
|
3
|
+
const WOPEE_API_KEY = process.env.WOPEE_API_KEY ?? null;
|
|
4
|
+
const WOPEE_PROJECT_UUID = process.env.WOPEE_PROJECT_UUID ?? null;
|
|
5
|
+
return {
|
|
6
|
+
WOPEE_API_URL,
|
|
7
|
+
WOPEE_API_KEY,
|
|
8
|
+
WOPEE_PROJECT_UUID,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getConfig } from "./getConfig.js";
|
|
2
|
+
export const requestClient = async (query, variables) => {
|
|
3
|
+
const { WOPEE_API_URL, WOPEE_API_KEY } = getConfig();
|
|
4
|
+
try {
|
|
5
|
+
if (!WOPEE_API_KEY) {
|
|
6
|
+
console.error("[REQUEST_CLIENT_ERROR]: WOPEE_API_KEY is not set");
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const headers = {
|
|
10
|
+
api_key: WOPEE_API_KEY,
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
};
|
|
13
|
+
const response = await fetch(`${WOPEE_API_URL}`, {
|
|
14
|
+
method: "POST",
|
|
15
|
+
headers,
|
|
16
|
+
body: JSON.stringify({
|
|
17
|
+
query,
|
|
18
|
+
variables,
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const errorText = await response.text();
|
|
23
|
+
console.error("[REQUEST_CLIENT_ERROR]:", errorText);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const result = (await response.json());
|
|
27
|
+
if (result.errors && result.errors.length > 0) {
|
|
28
|
+
console.error("GraphQL errors:", result.errors);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return result.data || null;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error("[REQUEST_CLIENT_ERROR]:", error);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
};
|