wopee-mcp 1.26.2 → 1.28.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 +21 -3
- package/build/tools/index.js +6 -0
- package/build/tools/shared/gql-queries.js +39 -0
- package/build/tools/shared/schemas.js +12 -0
- package/build/tools/shared/types.js +8 -0
- package/build/tools/wopee_dispatch_agent/index.js +30 -3
- package/build/tools/wopee_dispatch_analysis/schema.js +1 -11
- package/build/tools/wopee_fetch_recent_executions/index.js +78 -0
- package/build/tools/wopee_fetch_variables/index.js +36 -0
- package/build/tools/wopee_fetch_variables/schema.js +12 -0
- package/build/tools/wopee_update_variables/factory.js +24 -0
- package/build/tools/wopee_update_variables/index.js +38 -0
- package/build/tools/wopee_update_variables/schema.js +16 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -290,7 +290,7 @@ Update app context file for the most recent suite with this content: <YourMarkdo
|
|
|
290
290
|
|
|
291
291
|
#### `wopee_dispatch_agent`
|
|
292
292
|
|
|
293
|
-
Dispatches an autonomous testing agent to execute test cases for a selected suite.
|
|
293
|
+
Dispatches an autonomous testing agent to execute test cases for a selected suite. Tests run **asynchronously** (typically 1-3 minutes). This tool confirms dispatch and returns tracking info — not final results.
|
|
294
294
|
|
|
295
295
|
- **Parameters:**
|
|
296
296
|
- `suiteUuid` - The UUID of the suite containing the test cases
|
|
@@ -298,7 +298,7 @@ Dispatches an autonomous testing agent to execute test cases for a selected suit
|
|
|
298
298
|
- `testCases` - Array of test case objects to execute, each containing:
|
|
299
299
|
- `testCaseId` - The ID of the test case
|
|
300
300
|
- `userStoryId` - The ID of the associated user story
|
|
301
|
-
- **Returns:**
|
|
301
|
+
- **Returns:** Dispatch confirmation with tracking info (suite UUID, analysis identifier, per-test-case execution status). Does NOT return pass/fail results — use `wopee_fetch_recent_executions` or `wopee_fetch_executed_test_cases` to check results later.
|
|
302
302
|
|
|
303
303
|
**Example Usage:**
|
|
304
304
|
|
|
@@ -308,6 +308,23 @@ Dispatch agent for my latest suite's user story US001 and test case TC003
|
|
|
308
308
|
|
|
309
309
|
### Test Results
|
|
310
310
|
|
|
311
|
+
#### `wopee_fetch_recent_executions`
|
|
312
|
+
|
|
313
|
+
Fetches the most recent test case executions for the current project (up to 20, newest first). Use this to quickly check the status of recently dispatched tests without needing to remember specific suite UUIDs.
|
|
314
|
+
|
|
315
|
+
- **Parameters:** None (uses `WOPEE_PROJECT_UUID` from environment)
|
|
316
|
+
- **Returns:** List of recent executions with execution status (IN_PROGRESS, IN_QUEUE, FINISHED, FAILED), agent reports, and pass/fail results
|
|
317
|
+
|
|
318
|
+
**Example Usage:**
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
What's the status of my recent test runs?
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
How did my tests go?
|
|
326
|
+
```
|
|
327
|
+
|
|
311
328
|
#### `wopee_fetch_executed_test_cases`
|
|
312
329
|
|
|
313
330
|
Fetches executed test cases and their results for a given analysis suite. Use this to check the status and reports of dispatched agent runs.
|
|
@@ -348,7 +365,8 @@ Show me the executed test cases for my latest analysis suite
|
|
|
348
365
|
- Use `wopee_dispatch_agent` to execute test cases with the autonomous testing agent
|
|
349
366
|
|
|
350
367
|
5. **Check results:**
|
|
351
|
-
- Use `
|
|
368
|
+
- Use `wopee_fetch_recent_executions` to quickly check status of recent test runs
|
|
369
|
+
- Use `wopee_fetch_executed_test_cases` to check detailed status and reports for a specific suite
|
|
352
370
|
- Or use the `fetch-test-results` prompt for a formatted summary of all test results
|
|
353
371
|
|
|
354
372
|
## Available Prompts
|
package/build/tools/index.js
CHANGED
|
@@ -6,13 +6,19 @@ import { wopeeDispatchAnalysis } from "./wopee_dispatch_analysis/index.js";
|
|
|
6
6
|
import { wopeeCreateBlankSuite } from "./wopee_create_blank_suite/index.js";
|
|
7
7
|
import { wopeeFetchAnalysisSuites } from "./wopee_fetch_analysis_suites/index.js";
|
|
8
8
|
import { wopeeFetchExecutedTestCases } from "./wopee_fetch_executed_test_cases/index.js";
|
|
9
|
+
import { wopeeFetchRecentExecutions } from "./wopee_fetch_recent_executions/index.js";
|
|
9
10
|
import { wopeeSendChatMessage } from "./wopee_send_chat_message/index.js";
|
|
10
11
|
import { wopeeReadChatHistory } from "./wopee_read_chat_history/index.js";
|
|
11
12
|
import { wopeeCreateGithubIssue } from "./wopee_create_github_issue/index.js";
|
|
13
|
+
import { wopeeFetchVariables } from "./wopee_fetch_variables/index.js";
|
|
14
|
+
import { wopeeUpdateVariables } from "./wopee_update_variables/index.js";
|
|
12
15
|
export const TOOLS = [
|
|
13
16
|
wopeeCreateBlankSuite,
|
|
14
17
|
wopeeFetchAnalysisSuites,
|
|
15
18
|
wopeeFetchExecutedTestCases,
|
|
19
|
+
wopeeFetchRecentExecutions,
|
|
20
|
+
wopeeFetchVariables,
|
|
21
|
+
wopeeUpdateVariables,
|
|
16
22
|
wopeeDispatchAnalysis,
|
|
17
23
|
wopeeDispatchAgent,
|
|
18
24
|
wopeeFetchArtifact,
|
|
@@ -13,6 +13,26 @@ export const UpdateArtifact = `
|
|
|
13
13
|
updateArtifact(input: $input)
|
|
14
14
|
}
|
|
15
15
|
`;
|
|
16
|
+
export const FetchProjectVariables = `
|
|
17
|
+
query FetchProjectVariables($projectUuid: ID!) {
|
|
18
|
+
fetchProjectVariables(projectUuid: $projectUuid)
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
export const FetchSuiteVariables = `
|
|
22
|
+
query FetchSuiteVariables($suiteUuid: ID!) {
|
|
23
|
+
fetchSuiteVariables(suiteUuid: $suiteUuid)
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
export const UpdateProjectVariables = `
|
|
27
|
+
mutation UpdateProjectVariables($input: UpdateProjectVariablesInput!) {
|
|
28
|
+
updateProjectVariables(input: $input)
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
export const UpdateSuiteVariables = `
|
|
32
|
+
mutation UpdateSuiteVariables($suiteUuid: ID!, $additionalVariables: String!) {
|
|
33
|
+
updateSuiteVariables(suiteUuid: $suiteUuid, additionalVariables: $additionalVariables)
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
16
36
|
export const DispatchAgent = `
|
|
17
37
|
mutation DispatchAgent(
|
|
18
38
|
$input: TestCasesInput!
|
|
@@ -249,6 +269,25 @@ export const FetchChatRoom = `
|
|
|
249
269
|
}
|
|
250
270
|
}
|
|
251
271
|
`;
|
|
272
|
+
export const FetchRecentExecutedTestCases = `
|
|
273
|
+
query FetchRecentExecutedTestCases($projectUuid: ID!) {
|
|
274
|
+
fetchRecentExecutedTestCases(projectUuid: $projectUuid) {
|
|
275
|
+
uuid
|
|
276
|
+
suiteUuid
|
|
277
|
+
analysisSuiteUuid
|
|
278
|
+
analysisIdentifier
|
|
279
|
+
userStoryId
|
|
280
|
+
testCaseId
|
|
281
|
+
executionStatus
|
|
282
|
+
agentReport
|
|
283
|
+
agentReportStatus
|
|
284
|
+
codeReport
|
|
285
|
+
codeReportStatus
|
|
286
|
+
createdAt
|
|
287
|
+
updatedAt
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
`;
|
|
252
291
|
export const CreateGitHubIssue = `
|
|
253
292
|
mutation CreateGitHubIssue($projectUuid: ID!, $title: String!, $body: String!, $labels: [String!]) {
|
|
254
293
|
createGitHubIssue(projectUuid: $projectUuid, title: $title, body: $body, labels: $labels) {
|
|
@@ -14,6 +14,18 @@ export const SuiteAnalysisConfigSchema = z.object({
|
|
|
14
14
|
additionalInstructions: z.string().nullable().default(null),
|
|
15
15
|
additionalVariables: z.string().nullable().default(null),
|
|
16
16
|
});
|
|
17
|
+
// Shared by wopee_dispatch_analysis and wopee_update_variables. Keys must be
|
|
18
|
+
// uppercase (server enforces the same EnvVarKeyRegex on write).
|
|
19
|
+
export const AdditionalVariableSchema = z.object({
|
|
20
|
+
key: z
|
|
21
|
+
.string({
|
|
22
|
+
description: "Variable name. Must be uppercase with underscores only (e.g. MY_VAR, BASE_URL).",
|
|
23
|
+
})
|
|
24
|
+
.regex(/^[A-Z_][A-Z0-9_]*$/, "Key must be uppercase alphanumeric with underscores, starting with a letter or underscore"),
|
|
25
|
+
value: z
|
|
26
|
+
.string({ description: "Variable value. Must be a non-empty string." })
|
|
27
|
+
.min(1, "Value must be a non-empty string"),
|
|
28
|
+
});
|
|
17
29
|
export const GenerateAIDataHandlerInputSchema = z.object({
|
|
18
30
|
type: z.nativeEnum(GenerateArtifactType, {
|
|
19
31
|
description: "Type of test artifact to generate. One of: APP_CONTEXT, GENERAL_USER_STORIES, USER_STORIES_WITH_TEST_CASES, TEST_CASES, TEST_CASE_STEPS, REUSABLE_TEST_CASES, REUSABLE_TEST_CASE_STEPS. Start with APP_CONTEXT, then generate stories and test cases from it.",
|
|
@@ -3,6 +3,7 @@ export var ToolName;
|
|
|
3
3
|
ToolName["WOPEE_CREATE_BLANK_SUITE"] = "wopee_create_blank_suite";
|
|
4
4
|
ToolName["WOPEE_FETCH_ANALYSIS_SUITES"] = "wopee_fetch_analysis_suites";
|
|
5
5
|
ToolName["WOPEE_FETCH_EXECUTED_TEST_CASES"] = "wopee_fetch_executed_test_cases";
|
|
6
|
+
ToolName["WOPEE_FETCH_RECENT_EXECUTIONS"] = "wopee_fetch_recent_executions";
|
|
6
7
|
ToolName["WOPEE_DISPATCH_ANALYSIS"] = "wopee_dispatch_analysis";
|
|
7
8
|
ToolName["WOPEE_DISPATCH_AGENT"] = "wopee_dispatch_agent";
|
|
8
9
|
ToolName["WOPEE_FETCH_ARTIFACT"] = "wopee_fetch_artifact";
|
|
@@ -11,7 +12,14 @@ export var ToolName;
|
|
|
11
12
|
ToolName["WOPEE_SEND_CHAT_MESSAGE"] = "wopee_send_chat_message";
|
|
12
13
|
ToolName["WOPEE_READ_CHAT_HISTORY"] = "wopee_read_chat_history";
|
|
13
14
|
ToolName["WOPEE_CREATE_GITHUB_ISSUE"] = "wopee_create_github_issue";
|
|
15
|
+
ToolName["WOPEE_FETCH_VARIABLES"] = "wopee_fetch_variables";
|
|
16
|
+
ToolName["WOPEE_UPDATE_VARIABLES"] = "wopee_update_variables";
|
|
14
17
|
})(ToolName || (ToolName = {}));
|
|
18
|
+
export var VariableLevel;
|
|
19
|
+
(function (VariableLevel) {
|
|
20
|
+
VariableLevel["PROJECT"] = "PROJECT";
|
|
21
|
+
VariableLevel["ANALYSIS"] = "ANALYSIS";
|
|
22
|
+
})(VariableLevel || (VariableLevel = {}));
|
|
15
23
|
export var GenerateArtifactType;
|
|
16
24
|
(function (GenerateArtifactType) {
|
|
17
25
|
GenerateArtifactType["APP_CONTEXT"] = "APP_CONTEXT";
|
|
@@ -5,11 +5,28 @@ import { createDispatchAgentInput } from "./factory.js";
|
|
|
5
5
|
import { DispatchAgent } from "../shared/gql-queries.js";
|
|
6
6
|
import { requestClient } from "../../utils/requestClient.js";
|
|
7
7
|
import { withRetry } from "../../utils/withRetry.js";
|
|
8
|
+
function formatDispatchSuccess(testCases, input) {
|
|
9
|
+
const lines = [
|
|
10
|
+
"DISPATCH SUCCESSFUL — tests are now RUNNING (not yet completed).",
|
|
11
|
+
"",
|
|
12
|
+
"Tracking:",
|
|
13
|
+
`- Suite UUID: ${testCases[0]?.suiteUuid ?? input.suiteUuid}`,
|
|
14
|
+
`- Analysis Suite UUID: ${testCases[0]?.analysisSuiteUuid ?? "N/A"}`,
|
|
15
|
+
`- Analysis Identifier: ${testCases[0]?.analysisIdentifier ?? input.analysisIdentifier}`,
|
|
16
|
+
"",
|
|
17
|
+
"Test cases dispatched:",
|
|
18
|
+
];
|
|
19
|
+
for (const tc of testCases) {
|
|
20
|
+
lines.push(`- ${tc.userStoryId}:${tc.testCaseId} → executionStatus: ${tc.executionStatus}`);
|
|
21
|
+
}
|
|
22
|
+
lines.push("", "IMPORTANT: These tests are RUNNING asynchronously. Do NOT report them as passed or failed.", "Tell the user their tests are running and results will be available shortly (typically 1-3 minutes).", "You will receive a follow-up notification in chat when tests complete with full results.");
|
|
23
|
+
return lines.join("\n");
|
|
24
|
+
}
|
|
8
25
|
export const wopeeDispatchAgent = {
|
|
9
26
|
name: ToolName.WOPEE_DISPATCH_AGENT,
|
|
10
27
|
config: {
|
|
11
28
|
title: "Dispatch autonomous testing agent",
|
|
12
|
-
description: "
|
|
29
|
+
description: "Dispatch an autonomous AI agent to execute specific test cases. The agent opens a real browser, navigates the app, follows test steps, and reports results. Tests run ASYNCHRONOUSLY (1-3 minutes). This tool returns tracking info confirming dispatch — NOT final results. Do NOT interpret the response as pass/fail. Results arrive later via chat notifications. Prerequisite: test cases must exist in the suite (generate with wopee_generate_artifact type USER_STORIES_WITH_TEST_CASES). Use wopee_fetch_recent_executions or wopee_fetch_executed_test_cases to check status later.",
|
|
13
30
|
inputSchema: WopeeDispatchAgentInputSchema.shape,
|
|
14
31
|
},
|
|
15
32
|
handler: async (input) => {
|
|
@@ -24,7 +41,7 @@ export const wopeeDispatchAgent = {
|
|
|
24
41
|
content: [
|
|
25
42
|
{
|
|
26
43
|
type: "text",
|
|
27
|
-
text: "
|
|
44
|
+
text: "DISPATCH FAILED — tests were NOT started.\nReason: No dispatch result returned from the API.\nSuggest the user try again or check that the suite and test cases exist.",
|
|
28
45
|
},
|
|
29
46
|
],
|
|
30
47
|
};
|
|
@@ -32,12 +49,22 @@ export const wopeeDispatchAgent = {
|
|
|
32
49
|
content: [
|
|
33
50
|
{
|
|
34
51
|
type: "text",
|
|
35
|
-
text:
|
|
52
|
+
text: formatDispatchSuccess(result.dispatchAgent, input),
|
|
36
53
|
},
|
|
37
54
|
],
|
|
38
55
|
};
|
|
39
56
|
}
|
|
40
57
|
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
return {
|
|
60
|
+
content: [
|
|
61
|
+
{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: `DISPATCH FAILED — tests were NOT started.\nReason: ${error.message}\nThis is a dispatch/infrastructure error, not a test failure. Suggest the user try again.`,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
41
68
|
return _parseError(error);
|
|
42
69
|
}
|
|
43
70
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { SuiteAnalysisConfigSchema } from "../shared/schemas.js";
|
|
2
|
+
import { SuiteAnalysisConfigSchema, AdditionalVariableSchema, } from "../shared/schemas.js";
|
|
3
3
|
var RerunMode;
|
|
4
4
|
(function (RerunMode) {
|
|
5
5
|
RerunMode["FULL"] = "FULL";
|
|
@@ -15,16 +15,6 @@ export const DispatchAnalysisInputSchema = z.object({
|
|
|
15
15
|
suiteAnalysisConfig: SuiteAnalysisConfigSchema,
|
|
16
16
|
rerun: RerunOptionsSchema.nullable().default(null),
|
|
17
17
|
});
|
|
18
|
-
const AdditionalVariableSchema = z.object({
|
|
19
|
-
key: z
|
|
20
|
-
.string({
|
|
21
|
-
description: "Variable name. Must be uppercase with underscores only (e.g. MY_VAR, BASE_URL).",
|
|
22
|
-
})
|
|
23
|
-
.regex(/^[A-Z_][A-Z0-9_]*$/, "Key must be uppercase alphanumeric with underscores, starting with a letter or underscore"),
|
|
24
|
-
value: z
|
|
25
|
-
.string({ description: "Variable value. Must be a non-empty string." })
|
|
26
|
-
.min(1, "Value must be a non-empty string"),
|
|
27
|
-
});
|
|
28
18
|
const WopeeRerunOptionsSchema = z.object({
|
|
29
19
|
suiteUuid: z
|
|
30
20
|
.string({
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
2
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
3
|
+
import { _parseError } from "../shared/helpers.js";
|
|
4
|
+
import { ToolName } from "../shared/types.js";
|
|
5
|
+
import { FetchRecentExecutedTestCases } from "../shared/gql-queries.js";
|
|
6
|
+
export const wopeeFetchRecentExecutions = {
|
|
7
|
+
name: ToolName.WOPEE_FETCH_RECENT_EXECUTIONS,
|
|
8
|
+
config: {
|
|
9
|
+
title: "Fetch recent test executions",
|
|
10
|
+
description: "Fetch the most recent test case executions for the current project (up to 20, newest first). Use this to check the status of recently dispatched tests without needing to remember specific suite UUIDs. Returns execution status (IN_PROGRESS, IN_QUEUE, FINISHED, FAILED), agent reports, and pass/fail results. Takes no input; uses WOPEE_PROJECT_UUID from environment. Prefer this tool when the user asks 'what's the status?' or 'how did the tests go?' and you don't have the specific suite UUID handy.",
|
|
11
|
+
},
|
|
12
|
+
handler: async () => {
|
|
13
|
+
try {
|
|
14
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
15
|
+
if (!WOPEE_PROJECT_UUID)
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: "WOPEE_PROJECT_UUID is not set",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
const result = await requestClient(FetchRecentExecutedTestCases, {
|
|
25
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
26
|
+
});
|
|
27
|
+
if (!result?.fetchRecentExecutedTestCases)
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: "text",
|
|
32
|
+
text: "No recent test executions found for this project.",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
const executions = result.fetchRecentExecutedTestCases;
|
|
37
|
+
if (executions.length === 0)
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: "No recent test executions found for this project.",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
const lines = [
|
|
47
|
+
`Recent test executions (${executions.length} most recent):`,
|
|
48
|
+
"",
|
|
49
|
+
];
|
|
50
|
+
for (const tc of executions) {
|
|
51
|
+
let status;
|
|
52
|
+
if (tc.executionStatus === "FINISHED") {
|
|
53
|
+
status = tc.agentReportStatus ?? "FINISHED";
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
status = tc.executionStatus;
|
|
57
|
+
}
|
|
58
|
+
lines.push(`- ${tc.userStoryId}:${tc.testCaseId} [${tc.analysisIdentifier}] → ${status} (${tc.updatedAt})`);
|
|
59
|
+
if (tc.executionStatus === "FINISHED" && tc.agentReport) {
|
|
60
|
+
const shortReport = tc.agentReport.slice(0, 200);
|
|
61
|
+
lines.push(` Report: ${shortReport}${tc.agentReport.length > 200 ? "..." : ""}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
lines.push("", `Suite UUID of most recent: ${executions[0].suiteUuid}`, `Analysis Identifier of most recent: ${executions[0].analysisIdentifier}`);
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: "text",
|
|
69
|
+
text: lines.join("\n"),
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return _parseError(error);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
2
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
3
|
+
import { _parseError } from "../shared/helpers.js";
|
|
4
|
+
import { ToolName, VariableLevel } from "../shared/types.js";
|
|
5
|
+
import { FetchProjectVariables, FetchSuiteVariables, } from "../shared/gql-queries.js";
|
|
6
|
+
import { WopeeFetchVariablesInputSchema, } from "./schema.js";
|
|
7
|
+
const textResult = (text) => ({
|
|
8
|
+
content: [{ type: "text", text }],
|
|
9
|
+
});
|
|
10
|
+
export const wopeeFetchVariables = {
|
|
11
|
+
name: ToolName.WOPEE_FETCH_VARIABLES,
|
|
12
|
+
config: {
|
|
13
|
+
title: "Fetch run-time variables",
|
|
14
|
+
description: "Read the run-time variables (additionalVariables) that drive analysis/agent runs, at either level. level: PROJECT returns the project-level variables (uses WOPEE_PROJECT_UUID from the environment); level: ANALYSIS returns a specific analysis suite's variables and requires suiteUuid. Read-only. Returns a JSON string array of { key, value, sourceType } entries, or [] when none are set. Use wopee_fetch_analysis_suites to discover suite UUIDs.",
|
|
15
|
+
inputSchema: WopeeFetchVariablesInputSchema.shape,
|
|
16
|
+
},
|
|
17
|
+
handler: async (input) => {
|
|
18
|
+
try {
|
|
19
|
+
const { level, suiteUuid } = input;
|
|
20
|
+
if (level === VariableLevel.ANALYSIS) {
|
|
21
|
+
if (!suiteUuid)
|
|
22
|
+
return textResult("suiteUuid is required when level is ANALYSIS");
|
|
23
|
+
const result = await requestClient(FetchSuiteVariables, { suiteUuid });
|
|
24
|
+
return textResult(result?.fetchSuiteVariables ?? "[]");
|
|
25
|
+
}
|
|
26
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
27
|
+
if (!WOPEE_PROJECT_UUID)
|
|
28
|
+
return textResult("WOPEE_PROJECT_UUID is not set");
|
|
29
|
+
const result = await requestClient(FetchProjectVariables, { projectUuid: WOPEE_PROJECT_UUID });
|
|
30
|
+
return textResult(result?.fetchProjectVariables ?? "[]");
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return _parseError(error);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { VariableLevel } from "../shared/types.js";
|
|
3
|
+
export const WopeeFetchVariablesInputSchema = z.object({
|
|
4
|
+
level: z.nativeEnum(VariableLevel, {
|
|
5
|
+
description: "Which variable set to read. PROJECT reads the project-level variables (uses WOPEE_PROJECT_UUID from the environment). ANALYSIS reads a specific analysis suite's variables and requires suiteUuid.",
|
|
6
|
+
}),
|
|
7
|
+
suiteUuid: z
|
|
8
|
+
.string({
|
|
9
|
+
description: "UUID of the analysis suite to read variables from. Required when level is ANALYSIS; ignored when level is PROJECT.",
|
|
10
|
+
})
|
|
11
|
+
.nullish(),
|
|
12
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
2
|
+
/**
|
|
3
|
+
* Wire payload for the updateSuiteVariables mutation. The handler guarantees
|
|
4
|
+
* suiteUuid is present before calling this (ANALYSIS level).
|
|
5
|
+
*/
|
|
6
|
+
export const createUpdateSuiteVariablesInput = (input) => ({
|
|
7
|
+
suiteUuid: input.suiteUuid,
|
|
8
|
+
additionalVariables: JSON.stringify(input.variables),
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Wire payload for the updateProjectVariables mutation, injecting
|
|
12
|
+
* WOPEE_PROJECT_UUID from the environment (PROJECT level).
|
|
13
|
+
*/
|
|
14
|
+
export const createUpdateProjectVariablesInput = (input) => {
|
|
15
|
+
const { WOPEE_PROJECT_UUID } = getConfig();
|
|
16
|
+
if (!WOPEE_PROJECT_UUID)
|
|
17
|
+
throw new Error("WOPEE_PROJECT_UUID is not set");
|
|
18
|
+
return {
|
|
19
|
+
input: {
|
|
20
|
+
projectUuid: WOPEE_PROJECT_UUID,
|
|
21
|
+
additionalVariables: JSON.stringify(input.variables),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { requestClient } from "../../utils/requestClient.js";
|
|
2
|
+
import { withRetry } from "../../utils/withRetry.js";
|
|
3
|
+
import { _parseError } from "../shared/helpers.js";
|
|
4
|
+
import { ToolName, VariableLevel } from "../shared/types.js";
|
|
5
|
+
import { UpdateProjectVariables, UpdateSuiteVariables, } from "../shared/gql-queries.js";
|
|
6
|
+
import { createUpdateProjectVariablesInput, createUpdateSuiteVariablesInput, } from "./factory.js";
|
|
7
|
+
import { WopeeUpdateVariablesInputSchema, } from "./schema.js";
|
|
8
|
+
const textResult = (text) => ({
|
|
9
|
+
content: [{ type: "text", text }],
|
|
10
|
+
});
|
|
11
|
+
export const wopeeUpdateVariables = {
|
|
12
|
+
name: ToolName.WOPEE_UPDATE_VARIABLES,
|
|
13
|
+
config: {
|
|
14
|
+
title: "Update run-time variables",
|
|
15
|
+
description: "Upsert the run-time variables (additionalVariables) that drive analysis/agent runs, at either level. level: PROJECT writes the project-level variables (uses WOPEE_PROJECT_UUID from the environment); level: ANALYSIS writes a specific analysis suite's variables and requires suiteUuid. Merge semantics: keys in variables[] are added or overwritten, existing keys not listed are preserved. Keys must be uppercase (e.g. BASE_URL); the server re-sanitizes and drops invalid keys. Returns a confirmation on success.",
|
|
16
|
+
inputSchema: WopeeUpdateVariablesInputSchema.shape,
|
|
17
|
+
},
|
|
18
|
+
handler: async (input) => {
|
|
19
|
+
try {
|
|
20
|
+
const { level, suiteUuid } = input;
|
|
21
|
+
if (level === VariableLevel.ANALYSIS) {
|
|
22
|
+
if (!suiteUuid)
|
|
23
|
+
return textResult("suiteUuid is required when level is ANALYSIS");
|
|
24
|
+
const result = await withRetry(() => requestClient(UpdateSuiteVariables, createUpdateSuiteVariablesInput(input)));
|
|
25
|
+
if (!result?.updateSuiteVariables)
|
|
26
|
+
return textResult("Failed to update suite variables");
|
|
27
|
+
return textResult("Suite variables updated successfully");
|
|
28
|
+
}
|
|
29
|
+
const result = await withRetry(() => requestClient(UpdateProjectVariables, createUpdateProjectVariablesInput(input)));
|
|
30
|
+
if (!result?.updateProjectVariables)
|
|
31
|
+
return textResult("Failed to update project variables");
|
|
32
|
+
return textResult("Project variables updated successfully");
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return _parseError(error);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { VariableLevel } from "../shared/types.js";
|
|
3
|
+
import { AdditionalVariableSchema } from "../shared/schemas.js";
|
|
4
|
+
export const WopeeUpdateVariablesInputSchema = z.object({
|
|
5
|
+
level: z.nativeEnum(VariableLevel, {
|
|
6
|
+
description: "Which variable set to write. PROJECT writes the project-level variables (uses WOPEE_PROJECT_UUID from the environment). ANALYSIS writes a specific analysis suite's variables and requires suiteUuid.",
|
|
7
|
+
}),
|
|
8
|
+
suiteUuid: z
|
|
9
|
+
.string({
|
|
10
|
+
description: "UUID of the analysis suite to write variables to. Required when level is ANALYSIS; ignored when level is PROJECT.",
|
|
11
|
+
})
|
|
12
|
+
.nullish(),
|
|
13
|
+
variables: z.array(AdditionalVariableSchema, {
|
|
14
|
+
description: "Variables to upsert. Each needs an uppercase key (e.g. BASE_URL) and a non-empty value. Merge semantics: keys listed here are added or overwritten; existing keys not listed here are preserved.",
|
|
15
|
+
}),
|
|
16
|
+
});
|
package/package.json
CHANGED