@smartbear/mcp 0.19.0 → 0.20.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 +15 -2
- package/assets/icon.png +0 -0
- package/dist/bugsnag/client.js +19 -12
- package/dist/collaborator/client.js +10 -10
- package/dist/common/client-registry.js +2 -2
- package/dist/common/server.js +74 -111
- package/dist/common/shutdown.js +165 -0
- package/dist/common/transport-http.js +94 -12
- package/dist/common/transport-stdio.js +16 -2
- package/dist/common/zod-utils.js +62 -7
- package/dist/index.js +2 -0
- package/dist/package.json.js +1 -1
- package/dist/pactflow/client/prompts.js +19 -18
- package/dist/pactflow/client/tools.js +8 -13
- package/dist/pactflow/client.js +26 -12
- package/dist/qmetry/client/tools/testsuite-tools.js +2 -2
- package/dist/qmetry/client.js +1 -1
- package/dist/reflect/client.js +3 -3
- package/dist/reflect/prompt/sap-test.js +5 -5
- package/dist/reflect/tool/recording/add-prompt-step.js +6 -14
- package/dist/reflect/tool/recording/add-segment.js +4 -14
- package/dist/reflect/tool/recording/connect-to-session.js +3 -8
- package/dist/reflect/tool/recording/delete-previous-step.js +3 -8
- package/dist/reflect/tool/recording/get-screenshot.js +4 -14
- package/dist/reflect/tool/suites/cancel-suite-execution.js +4 -14
- package/dist/reflect/tool/suites/execute-suite.js +3 -8
- package/dist/reflect/tool/suites/get-suite-execution-status.js +4 -14
- package/dist/reflect/tool/suites/list-suite-executions.js +3 -8
- package/dist/reflect/tool/suites/list-suites.js +2 -1
- package/dist/reflect/tool/tests/get-test-status.js +3 -8
- package/dist/reflect/tool/tests/list-segments.js +5 -20
- package/dist/reflect/tool/tests/list-tests.js +2 -1
- package/dist/reflect/tool/tests/run-test.js +3 -8
- package/dist/swagger/client/api.js +11 -2
- package/dist/swagger/client/portal-types.js +0 -3
- package/dist/swagger/client/tools.js +0 -1
- package/dist/swagger/client.js +1 -1
- package/dist/zephyr/client.js +1 -1
- package/dist/zephyr/common/rest-api-schemas.js +8 -28
- package/dist/zephyr/tool/test-case/update-test-case.js +23 -1
- package/dist/zephyr/tool/test-cycle/update-test-cycle.js +17 -2
- package/package.json +5 -4
|
@@ -8,14 +8,9 @@ class DeletePreviousStep extends Tool {
|
|
|
8
8
|
readOnly: false,
|
|
9
9
|
idempotent: false,
|
|
10
10
|
destructive: true,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type: z.string(),
|
|
15
|
-
description: "The ID of the Reflect recording session",
|
|
16
|
-
required: true
|
|
17
|
-
}
|
|
18
|
-
]
|
|
11
|
+
inputSchema: z.object({
|
|
12
|
+
sessionId: z.string().describe("The ID of the Reflect recording session")
|
|
13
|
+
})
|
|
19
14
|
};
|
|
20
15
|
handle = async (args) => {
|
|
21
16
|
const { sessionId } = args;
|
|
@@ -7,20 +7,10 @@ class GetScreenshot extends Tool {
|
|
|
7
7
|
summary: "Capture a screenshot from the current state of an active Reflect recording session",
|
|
8
8
|
readOnly: true,
|
|
9
9
|
idempotent: true,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
description: "The ID of the Reflect recording session",
|
|
15
|
-
required: true
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "format",
|
|
19
|
-
type: z.enum(["png", "jpeg"]),
|
|
20
|
-
description: "The image format for the screenshot (png or jpeg)",
|
|
21
|
-
required: false
|
|
22
|
-
}
|
|
23
|
-
]
|
|
10
|
+
inputSchema: z.object({
|
|
11
|
+
sessionId: z.string().describe("The ID of the Reflect recording session"),
|
|
12
|
+
format: z.enum(["png", "jpeg"]).optional().describe("The image format for the screenshot (png or jpeg)")
|
|
13
|
+
})
|
|
24
14
|
};
|
|
25
15
|
handle = async (args) => {
|
|
26
16
|
const { sessionId, format } = args;
|
|
@@ -5,20 +5,10 @@ class CancelSuiteExecution extends Tool {
|
|
|
5
5
|
specification = {
|
|
6
6
|
title: "Cancel Suite Execution",
|
|
7
7
|
summary: "Cancel a reflect suite execution",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
description: "ID of the reflect suite to cancel execution for",
|
|
13
|
-
required: true
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
name: "executionId",
|
|
17
|
-
type: z.string(),
|
|
18
|
-
description: "ID of the reflect suite execution to cancel",
|
|
19
|
-
required: true
|
|
20
|
-
}
|
|
21
|
-
]
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
suiteId: z.string().describe("ID of the reflect suite to cancel execution for"),
|
|
10
|
+
executionId: z.string().describe("ID of the reflect suite execution to cancel")
|
|
11
|
+
})
|
|
22
12
|
};
|
|
23
13
|
handle = async (args) => {
|
|
24
14
|
const { suiteId, executionId } = args;
|
|
@@ -5,14 +5,9 @@ class ExecuteSuite extends Tool {
|
|
|
5
5
|
specification = {
|
|
6
6
|
title: "Execute Suite",
|
|
7
7
|
summary: "Execute a reflect suite",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type: z.string(),
|
|
12
|
-
description: "ID of the reflect suite to execute",
|
|
13
|
-
required: true
|
|
14
|
-
}
|
|
15
|
-
]
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
suiteId: z.string().describe("ID of the reflect suite to execute")
|
|
10
|
+
})
|
|
16
11
|
};
|
|
17
12
|
handle = async (args) => {
|
|
18
13
|
const { suiteId } = args;
|
|
@@ -5,20 +5,10 @@ class GetSuiteExecutionStatus extends Tool {
|
|
|
5
5
|
specification = {
|
|
6
6
|
title: "Get Suite Execution Status",
|
|
7
7
|
summary: "Get the status of a reflect suite execution",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
description: "ID of the reflect suite to get execution status for",
|
|
13
|
-
required: true
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
name: "executionId",
|
|
17
|
-
type: z.string(),
|
|
18
|
-
description: "ID of the reflect suite execution to get status for",
|
|
19
|
-
required: true
|
|
20
|
-
}
|
|
21
|
-
]
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
suiteId: z.string().describe("ID of the reflect suite to get execution status for"),
|
|
10
|
+
executionId: z.string().describe("ID of the reflect suite execution to get status for")
|
|
11
|
+
})
|
|
22
12
|
};
|
|
23
13
|
handle = async (args) => {
|
|
24
14
|
const { suiteId, executionId } = args;
|
|
@@ -5,14 +5,9 @@ class ListSuiteExecutions extends Tool {
|
|
|
5
5
|
specification = {
|
|
6
6
|
title: "List Suite Executions",
|
|
7
7
|
summary: "List all executions for a given suite",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type: z.string(),
|
|
12
|
-
description: "ID of the reflect suite to list executions for",
|
|
13
|
-
required: true
|
|
14
|
-
}
|
|
15
|
-
]
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
suiteId: z.string().describe("ID of the reflect suite to list executions for")
|
|
10
|
+
})
|
|
16
11
|
};
|
|
17
12
|
handle = async (args) => {
|
|
18
13
|
const { suiteId } = args;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { Tool, ToolError } from "../../../common/tools.js";
|
|
2
3
|
import { API_HOSTNAME } from "../../config/constants.js";
|
|
3
4
|
class ListSuites extends Tool {
|
|
4
5
|
specification = {
|
|
5
6
|
title: "List Suites",
|
|
6
7
|
summary: "Retrieve a list of all reflect suites available",
|
|
7
|
-
|
|
8
|
+
inputSchema: z.object({})
|
|
8
9
|
};
|
|
9
10
|
handle = async (_args) => {
|
|
10
11
|
const response = await fetch(`https://${API_HOSTNAME}/v1/suites`, {
|
|
@@ -5,14 +5,9 @@ class GetTestStatus extends Tool {
|
|
|
5
5
|
specification = {
|
|
6
6
|
title: "Get Test Status",
|
|
7
7
|
summary: "Get the status of a reflect test execution",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type: z.string(),
|
|
12
|
-
description: "ID of the reflect test execution to get status for",
|
|
13
|
-
required: true
|
|
14
|
-
}
|
|
15
|
-
]
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
executionId: z.string().describe("ID of the reflect test execution to get status for")
|
|
10
|
+
})
|
|
16
11
|
};
|
|
17
12
|
handle = async (args) => {
|
|
18
13
|
const { executionId } = args;
|
|
@@ -7,26 +7,11 @@ class ListSegments extends Tool {
|
|
|
7
7
|
summary: "Retrieve available reusable test segments for the given platform type. Segments are reusable test steps with an optional set of parameters that can used across multiple tests.",
|
|
8
8
|
readOnly: true,
|
|
9
9
|
idempotent: true,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
required: true
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "offset",
|
|
19
|
-
type: z.number(),
|
|
20
|
-
description: "Offset for pagination",
|
|
21
|
-
required: false
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: "limit",
|
|
25
|
-
type: z.number(),
|
|
26
|
-
description: "Maximum number of segments to return",
|
|
27
|
-
required: false
|
|
28
|
-
}
|
|
29
|
-
]
|
|
10
|
+
inputSchema: z.object({
|
|
11
|
+
platform: z.enum(["api", "native-mobile", "web"]).describe("The platform type to retrieve segments for"),
|
|
12
|
+
offset: z.number().optional().describe("Offset for pagination"),
|
|
13
|
+
limit: z.number().optional().describe("Maximum number of segments to return")
|
|
14
|
+
})
|
|
30
15
|
};
|
|
31
16
|
handle = async (args) => {
|
|
32
17
|
const {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { Tool, ToolError } from "../../../common/tools.js";
|
|
2
3
|
import { API_HOSTNAME } from "../../config/constants.js";
|
|
3
4
|
class ListTests extends Tool {
|
|
4
5
|
specification = {
|
|
5
6
|
title: "List Tests",
|
|
6
7
|
summary: "List all reflect tests",
|
|
7
|
-
|
|
8
|
+
inputSchema: z.object({})
|
|
8
9
|
};
|
|
9
10
|
handle = async (_args) => {
|
|
10
11
|
const response = await fetch(`https://${API_HOSTNAME}/v1/tests`, {
|
|
@@ -5,14 +5,9 @@ class RunTest extends Tool {
|
|
|
5
5
|
specification = {
|
|
6
6
|
title: "Run Test",
|
|
7
7
|
summary: "Run a reflect test",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type: z.string(),
|
|
12
|
-
description: "ID of the reflect test to run",
|
|
13
|
-
required: true
|
|
14
|
-
}
|
|
15
|
-
]
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
testId: z.string().describe("ID of the reflect test to run")
|
|
10
|
+
})
|
|
16
11
|
};
|
|
17
12
|
handle = async (args) => {
|
|
18
13
|
const { testId } = args;
|
|
@@ -37,7 +37,7 @@ class SwaggerAPI {
|
|
|
37
37
|
return defaultReturn;
|
|
38
38
|
}
|
|
39
39
|
const contentType = response.headers.get("content-type");
|
|
40
|
-
if (contentType?.includes("application/json")) {
|
|
40
|
+
if (contentType?.includes("application/json") || contentType?.includes("application/problem+json")) {
|
|
41
41
|
try {
|
|
42
42
|
return await response.json();
|
|
43
43
|
} catch (error) {
|
|
@@ -69,7 +69,16 @@ class SwaggerAPI {
|
|
|
69
69
|
*/
|
|
70
70
|
async handleResponse(response, defaultReturn = {}) {
|
|
71
71
|
if (!response.ok) {
|
|
72
|
-
|
|
72
|
+
const errorBody = await this.parseResponse(
|
|
73
|
+
response,
|
|
74
|
+
{}
|
|
75
|
+
);
|
|
76
|
+
const detail = typeof errorBody === "object" && errorBody !== null && String(
|
|
77
|
+
errorBody.detail ?? errorBody.message ?? ""
|
|
78
|
+
) || response.statusText;
|
|
79
|
+
throw new ToolError(
|
|
80
|
+
`HTTP ${response.status}${detail ? `: ${detail}` : ""}`
|
|
81
|
+
);
|
|
73
82
|
}
|
|
74
83
|
return this.parseResponse(
|
|
75
84
|
response,
|
|
@@ -157,9 +157,6 @@ const CreateProductArgsSchema = PortalArgsSchema.extend({
|
|
|
157
157
|
),
|
|
158
158
|
hidden: z.boolean().optional().describe(
|
|
159
159
|
"Whether the product is hidden from the portal landing page navigation menus - useful for internal or draft products"
|
|
160
|
-
),
|
|
161
|
-
role: z.boolean().optional().describe(
|
|
162
|
-
"Whether the product has role-based access restrictions - controls if specific user roles are required to access the product"
|
|
163
160
|
)
|
|
164
161
|
});
|
|
165
162
|
const UpdateProductArgsSchema = ProductArgsSchema.extend({
|
|
@@ -5,7 +5,6 @@ const TOOLS = [
|
|
|
5
5
|
{
|
|
6
6
|
title: "List Portals",
|
|
7
7
|
summary: "Search for available portals within Swagger. Only portals where you have at least a designer role, either at the product level or organization level, are returned.",
|
|
8
|
-
parameters: [],
|
|
9
8
|
handler: "getPortals"
|
|
10
9
|
},
|
|
11
10
|
{
|
package/dist/swagger/client.js
CHANGED
package/dist/zephyr/client.js
CHANGED
|
@@ -411,10 +411,7 @@ const UpdateTestCaseBody = zod.object({
|
|
|
411
411
|
precondition: zod.string().nullish().describe("Any conditions that need to be met."),
|
|
412
412
|
estimatedTime: zod.number().min(updateTestCaseBodyEstimatedTimeMin).nullish().describe("Estimated duration in milliseconds."),
|
|
413
413
|
labels: zod.array(zod.string()).max(updateTestCaseBodyLabelsMax).optional().describe("Array of labels associated to this entity."),
|
|
414
|
-
component: zod.
|
|
415
|
-
id: zod.number().min(1).describe("The ID of the entity"),
|
|
416
|
-
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
417
|
-
}).strict().nullish().describe("ID and link to the Jira component resource."),
|
|
414
|
+
component: zod.number().min(1).nullable().optional().describe("ID and link to the Jira component resource."),
|
|
418
415
|
priority: zod.object({
|
|
419
416
|
id: zod.number().min(1).describe("The ID of the entity"),
|
|
420
417
|
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
@@ -423,16 +420,10 @@ const UpdateTestCaseBody = zod.object({
|
|
|
423
420
|
id: zod.number().min(1).describe("The ID of the entity"),
|
|
424
421
|
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
425
422
|
}).strict().describe("ID and link to the status resource."),
|
|
426
|
-
folder: zod.
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
owner: zod.object({
|
|
431
|
-
accountId: zod.string().regex(updateTestCaseBodyOwnerAccountIdRegExp).nullable().describe("Atlassian Account ID of the Jira user."),
|
|
432
|
-
self: zod.string().url().optional().describe(
|
|
433
|
-
"The Jira REST API endpoint to get the full representation of the Jira user."
|
|
434
|
-
)
|
|
435
|
-
}).strict().nullish(),
|
|
423
|
+
folder: zod.number().min(1).nullable().optional().describe(
|
|
424
|
+
"The ID of the folder, to remove folder set it's value to null"
|
|
425
|
+
),
|
|
426
|
+
owner: zod.string().regex(updateTestCaseBodyOwnerAccountIdRegExp).nullable().describe("Atlassian Account ID of the Jira user."),
|
|
436
427
|
customFields: zod.record(zod.string(), zod.unknown()).optional().describe(
|
|
437
428
|
"Multi-line text fields support HTML and should denote new lines with the \\<br\\> tag.\nDates should be in the format 'yyyy-MM-dd'.\nUsers should have values of Jira User Account IDs.\n"
|
|
438
429
|
)
|
|
@@ -1110,20 +1101,14 @@ const UpdateTestCycleBody = zod.object({
|
|
|
1110
1101
|
id: zod.number().min(1).describe("The ID of the entity"),
|
|
1111
1102
|
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
1112
1103
|
}).strict().describe("ID and link relative to Zephyr project."),
|
|
1113
|
-
jiraProjectVersion: zod.
|
|
1114
|
-
id: zod.number().min(1).describe("The ID of the entity"),
|
|
1115
|
-
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
1116
|
-
}).strict().nullish().describe(
|
|
1104
|
+
jiraProjectVersion: zod.number().min(1).nullable().optional().describe(
|
|
1117
1105
|
"ID and Link to fetch information about Jira Project version. Relates to 'Version' or 'Releases' in Jira projects."
|
|
1118
1106
|
),
|
|
1119
1107
|
status: zod.object({
|
|
1120
1108
|
id: zod.number().min(1).describe("The ID of the entity"),
|
|
1121
1109
|
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
1122
1110
|
}).strict().describe("ID and link to the status resource."),
|
|
1123
|
-
folder: zod.
|
|
1124
|
-
id: zod.number().min(1).describe("The ID of the entity"),
|
|
1125
|
-
self: zod.string().url().optional().describe("The REST API endpoint to get more resource details.")
|
|
1126
|
-
}).strict().nullish().describe("ID and link to the folder resource."),
|
|
1111
|
+
folder: zod.number().min(1).nullable().optional().describe("ID and link to the folder resource."),
|
|
1127
1112
|
description: zod.string().nullish().describe("Description outlining the scope."),
|
|
1128
1113
|
plannedStartDate: zod.string().datetime({}).nullish().describe(
|
|
1129
1114
|
"Planned start date of the test cycle. This field cannot be blank. Setting it as null or excluding it from the request will leave the field values unchanged. ISO 8601 Format (i.e., yyyy-MM-dd'T'HH:mm:ss'Z')"
|
|
@@ -1131,12 +1116,7 @@ const UpdateTestCycleBody = zod.object({
|
|
|
1131
1116
|
plannedEndDate: zod.string().datetime({}).nullish().describe(
|
|
1132
1117
|
"The planned end date of the test cycle. This field cannot be blank. Setting it as null or excluding it from the request will leave the field values unchanged. ISO 8601 Format (i.e., yyyy-MM-dd'T'HH:mm:ss'Z')"
|
|
1133
1118
|
),
|
|
1134
|
-
owner: zod.
|
|
1135
|
-
accountId: zod.string().regex(updateTestCycleBodyOwnerAccountIdRegExp).nullable().describe("Atlassian Account ID of the Jira user."),
|
|
1136
|
-
self: zod.string().url().optional().describe(
|
|
1137
|
-
"The Jira REST API endpoint to get the full representation of the Jira user."
|
|
1138
|
-
)
|
|
1139
|
-
}).strict().nullish(),
|
|
1119
|
+
owner: zod.string().regex(updateTestCycleBodyOwnerAccountIdRegExp).nullable().describe("Atlassian Account ID of the Jira user."),
|
|
1140
1120
|
customFields: zod.record(zod.string(), zod.unknown()).optional().describe(
|
|
1141
1121
|
"Multi-line text fields support HTML and should denote new lines with the \\<br\\> tag.\nDates should be in the format 'yyyy-MM-dd'.\nUsers should have values of Jira User Account IDs.\n"
|
|
1142
1122
|
)
|
|
@@ -57,6 +57,14 @@ class UpdateTestCase extends Tool {
|
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
expectedOutput: "The test case should be updated, but no output is expected."
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
description: "Remove test case from folder",
|
|
63
|
+
parameters: {
|
|
64
|
+
testCaseKey: "SA-T15",
|
|
65
|
+
folder: null
|
|
66
|
+
},
|
|
67
|
+
expectedOutput: "The test case should be updated, but no output is expected."
|
|
60
68
|
}
|
|
61
69
|
]
|
|
62
70
|
};
|
|
@@ -64,7 +72,21 @@ class UpdateTestCase extends Tool {
|
|
|
64
72
|
const parsed = UpdateTestCaseParams.and(UpdateTestCaseBody.partial()).parse(
|
|
65
73
|
args
|
|
66
74
|
);
|
|
67
|
-
const { testCaseKey, ...
|
|
75
|
+
const { testCaseKey, ...rawUpdates } = parsed;
|
|
76
|
+
const nullValuesObject = {};
|
|
77
|
+
if (rawUpdates.folder) {
|
|
78
|
+
nullValuesObject.folder = { id: rawUpdates.folder };
|
|
79
|
+
}
|
|
80
|
+
if (rawUpdates.owner) {
|
|
81
|
+
nullValuesObject.owner = { accountId: rawUpdates.owner };
|
|
82
|
+
}
|
|
83
|
+
if (rawUpdates.component) {
|
|
84
|
+
nullValuesObject.component = { id: rawUpdates.component };
|
|
85
|
+
}
|
|
86
|
+
const updates = {
|
|
87
|
+
...rawUpdates,
|
|
88
|
+
...nullValuesObject
|
|
89
|
+
};
|
|
68
90
|
const existingTestCase = await this.client.getApiClient().get(`/testcases/${testCaseKey}`);
|
|
69
91
|
const mergedBody = deepMerge(existingTestCase, updates);
|
|
70
92
|
delete mergedBody.createdOn;
|
|
@@ -72,8 +72,23 @@ class UpdateTestCycle extends Tool {
|
|
|
72
72
|
const parsed = UpdateTestCycleParams.and(
|
|
73
73
|
UpdateTestCycleBody.partial()
|
|
74
74
|
).parse(args);
|
|
75
|
-
const { testCycleIdOrKey, ...
|
|
76
|
-
const
|
|
75
|
+
const { testCycleIdOrKey, ...rawUpdates } = parsed;
|
|
76
|
+
const nullValuesObject = {};
|
|
77
|
+
if (rawUpdates.folder) {
|
|
78
|
+
nullValuesObject.folder = { id: rawUpdates.folder };
|
|
79
|
+
}
|
|
80
|
+
if (rawUpdates.owner) {
|
|
81
|
+
nullValuesObject.owner = { accountId: rawUpdates.owner };
|
|
82
|
+
}
|
|
83
|
+
if (rawUpdates.jiraProjectVersion) {
|
|
84
|
+
nullValuesObject.jiraProjectVersion = {
|
|
85
|
+
id: rawUpdates.jiraProjectVersion
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const updates = {
|
|
89
|
+
...rawUpdates,
|
|
90
|
+
...nullValuesObject
|
|
91
|
+
};
|
|
77
92
|
if (updates.plannedStartDate === null) delete updates.plannedStartDate;
|
|
78
93
|
if (updates.plannedEndDate === null) delete updates.plannedEndDate;
|
|
79
94
|
const existingTestCycle = await this.client.getApiClient().get(`/testcycles/${testCycleIdOrKey}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartbear/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "MCP server for interacting SmartBear Products",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"smartbear",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"mcpServerName": "SmartBear MCP Server"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
|
-
"build": "vite build && shx chmod +x dist/*.js",
|
|
34
|
+
"build": "tsc && vite build && shx chmod +x dist/*.js",
|
|
35
35
|
"lint": "biome lint .",
|
|
36
36
|
"lint:fix": "biome lint . --fix",
|
|
37
37
|
"format": "biome format . --write",
|
|
@@ -43,8 +43,9 @@
|
|
|
43
43
|
"test:coverage": "vitest --coverage",
|
|
44
44
|
"test:coverage:ci": "vitest --coverage --reporter=verbose",
|
|
45
45
|
"test:run": "vitest run",
|
|
46
|
-
"coverage:check": "vitest --coverage --reporter=verbose
|
|
47
|
-
"bump": "node scripts/bump.js"
|
|
46
|
+
"coverage:check": "vitest --coverage --reporter=verbose",
|
|
47
|
+
"bump": "node scripts/bump.js",
|
|
48
|
+
"postpack": "node scripts/pack-mcpb.js"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
51
|
"@bugsnag/js": "^8.8.1",
|