@testchimp/cli 0.1.23 → 0.1.26
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/dist/cli/program.js +44 -1
- package/dist/core/schemas.d.ts +7 -1
- package/dist/core/schemas.js +12 -2
- package/dist/core/tools.js +30 -7
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -169,6 +169,7 @@ export function buildCliProgram() {
|
|
|
169
169
|
.option("--environment <s>")
|
|
170
170
|
.option("--branch-name <s>")
|
|
171
171
|
.option("--scenario-id <id>")
|
|
172
|
+
.option("--test-id <id>")
|
|
172
173
|
.option("--platform <web|ios|android>")
|
|
173
174
|
.option("--file-paths <csv>")
|
|
174
175
|
.option("--folder-path <path>")
|
|
@@ -182,6 +183,8 @@ export function buildCliProgram() {
|
|
|
182
183
|
body.branchName = opts.branchName;
|
|
183
184
|
if (opts.scenarioId)
|
|
184
185
|
body.scenarioId = opts.scenarioId;
|
|
186
|
+
if (opts.testId)
|
|
187
|
+
body.testId = opts.testId;
|
|
185
188
|
if (opts.platform)
|
|
186
189
|
body.platform = opts.platform;
|
|
187
190
|
const scope = {};
|
|
@@ -281,15 +284,33 @@ export function buildCliProgram() {
|
|
|
281
284
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-test-scenarios").description)
|
|
282
285
|
.addOption(jsonInputOption())
|
|
283
286
|
.option("--scenario-ordinal-ids <csv>", "comma-separated TS-<n> numeric ids")
|
|
287
|
+
.option("--external-ids <csv>", "comma-separated external TMS ids (e.g. C12345,PROJ-101); server matches exact then numerical part")
|
|
284
288
|
.action(async (opts) => {
|
|
285
289
|
const body = {};
|
|
286
290
|
if (opts.scenarioOrdinalIds) {
|
|
287
|
-
|
|
291
|
+
const ids = String(opts.scenarioOrdinalIds)
|
|
288
292
|
.split(",")
|
|
289
293
|
.map((s) => Number(s.trim()))
|
|
290
294
|
.filter((n) => Number.isFinite(n) && n > 0);
|
|
295
|
+
if (ids.length > 0)
|
|
296
|
+
body.scenarioOrdinalIds = ids;
|
|
297
|
+
}
|
|
298
|
+
if (opts.externalIds) {
|
|
299
|
+
const ids = String(opts.externalIds)
|
|
300
|
+
.split(",")
|
|
301
|
+
.map((s) => s.trim())
|
|
302
|
+
.filter((s) => s.length > 0);
|
|
303
|
+
if (ids.length > 0)
|
|
304
|
+
body.externalIds = ids;
|
|
291
305
|
}
|
|
292
306
|
const merged = mergeBodies(body, opts.jsonInput);
|
|
307
|
+
// Drop empty arrays so refine / merge with json-input does not fail misleadingly.
|
|
308
|
+
if (Array.isArray(merged.scenarioOrdinalIds) && merged.scenarioOrdinalIds.length === 0) {
|
|
309
|
+
delete merged.scenarioOrdinalIds;
|
|
310
|
+
}
|
|
311
|
+
if (Array.isArray(merged.externalIds) && merged.externalIds.length === 0) {
|
|
312
|
+
delete merged.externalIds;
|
|
313
|
+
}
|
|
293
314
|
const out = await runTool("get-test-scenarios", merged, { postMcp });
|
|
294
315
|
console.log(out);
|
|
295
316
|
});
|
|
@@ -1064,6 +1085,28 @@ export function buildCliProgram() {
|
|
|
1064
1085
|
}
|
|
1065
1086
|
console.log(await runTool("upsert-policy", merged, { postMcp }));
|
|
1066
1087
|
});
|
|
1088
|
+
program
|
|
1089
|
+
.command("upsert-plans-support-file")
|
|
1090
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "upsert-plans-support-file").description)
|
|
1091
|
+
.addOption(jsonInputOption())
|
|
1092
|
+
.option("--file-path <path>", "path relative to mapped plans root (e.g. knowledge/workflow_plans/run-qa/<ulid>.plan.md)")
|
|
1093
|
+
.option("--content <markdown>", "full file content")
|
|
1094
|
+
.option("--content-file <path>", "read content from local file")
|
|
1095
|
+
.action(async (opts) => {
|
|
1096
|
+
let content = opts.content;
|
|
1097
|
+
if (opts.contentFile)
|
|
1098
|
+
content = await readFile(String(opts.contentFile), "utf8");
|
|
1099
|
+
const body = {};
|
|
1100
|
+
if (opts.filePath)
|
|
1101
|
+
body.filePath = String(opts.filePath);
|
|
1102
|
+
if (content !== undefined)
|
|
1103
|
+
body.content = content;
|
|
1104
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
1105
|
+
if (!merged.filePath || merged.content === undefined || merged.content === null) {
|
|
1106
|
+
throw new Error("Provide --file-path and --content or --content-file (or full body via --json-input)");
|
|
1107
|
+
}
|
|
1108
|
+
console.log(await runTool("upsert-plans-support-file", merged, { postMcp }));
|
|
1109
|
+
});
|
|
1067
1110
|
program.on("--help", () => {
|
|
1068
1111
|
/* default */
|
|
1069
1112
|
});
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare const listExecutionInput: z.ZodObject<{
|
|
|
38
38
|
}, z.core.$strip>>;
|
|
39
39
|
branchName: z.ZodOptional<z.ZodString>;
|
|
40
40
|
scenarioId: z.ZodOptional<z.ZodString>;
|
|
41
|
+
testId: z.ZodOptional<z.ZodString>;
|
|
41
42
|
platform: z.ZodOptional<z.ZodEnum<{
|
|
42
43
|
web: "web";
|
|
43
44
|
ios: "ios";
|
|
@@ -225,7 +226,8 @@ export declare const getUserStoriesInput: z.ZodObject<{
|
|
|
225
226
|
userStoryOrdinalIds: z.ZodArray<z.ZodCoercedNumber<unknown>>;
|
|
226
227
|
}, z.core.$strip>;
|
|
227
228
|
export declare const getTestScenariosInput: z.ZodObject<{
|
|
228
|
-
scenarioOrdinalIds: z.ZodArray<z.ZodCoercedNumber<unknown
|
|
229
|
+
scenarioOrdinalIds: z.ZodOptional<z.ZodArray<z.ZodCoercedNumber<unknown>>>;
|
|
230
|
+
externalIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
229
231
|
}, z.core.$strip>;
|
|
230
232
|
export declare const getManualSessionDetailsInput: z.ZodObject<{
|
|
231
233
|
manualSessionId: z.ZodString;
|
|
@@ -1350,4 +1352,8 @@ export declare const upsertPolicyInput: z.ZodObject<{
|
|
|
1350
1352
|
policyFileName: z.ZodString;
|
|
1351
1353
|
content: z.ZodString;
|
|
1352
1354
|
}, z.core.$strip>;
|
|
1355
|
+
export declare const upsertPlansSupportFileInput: z.ZodObject<{
|
|
1356
|
+
filePath: z.ZodString;
|
|
1357
|
+
content: z.ZodString;
|
|
1358
|
+
}, z.core.$strip>;
|
|
1353
1359
|
export declare const listWorkflowCatalogInput: z.ZodObject<{}, z.core.$strip>;
|
package/dist/core/schemas.js
CHANGED
|
@@ -33,6 +33,7 @@ export const listExecutionInput = z.object({
|
|
|
33
33
|
scope: scopeSchema,
|
|
34
34
|
branchName: z.string().optional(),
|
|
35
35
|
scenarioId: z.string().optional(),
|
|
36
|
+
testId: z.string().optional(),
|
|
36
37
|
platform: executionPlatformSchema.optional(),
|
|
37
38
|
dimensionFilters: z.array(executionJobDimensionFilterSchema).optional(),
|
|
38
39
|
limit: z.number().int().positive().max(500).optional(),
|
|
@@ -110,8 +111,12 @@ export const getUserStoriesInput = z
|
|
|
110
111
|
});
|
|
111
112
|
export const getTestScenariosInput = z
|
|
112
113
|
.object({
|
|
113
|
-
scenarioOrdinalIds: z.array(z.coerce.number().int().positive()).min(1),
|
|
114
|
-
|
|
114
|
+
scenarioOrdinalIds: z.array(z.coerce.number().int().positive()).min(1).optional(),
|
|
115
|
+
/** Full TMS external ids (e.g. C12345, PROJ-101). Server matches exact then numerical part. */
|
|
116
|
+
externalIds: z.array(z.string().min(1)).min(1).optional(),
|
|
117
|
+
})
|
|
118
|
+
.refine((v) => (v.scenarioOrdinalIds != null && v.scenarioOrdinalIds.length > 0) ||
|
|
119
|
+
(v.externalIds != null && v.externalIds.length > 0), { message: "Provide scenarioOrdinalIds and/or externalIds (non-empty)" });
|
|
115
120
|
export const getManualSessionDetailsInput = z.object({
|
|
116
121
|
manualSessionId: z.string().min(1),
|
|
117
122
|
});
|
|
@@ -682,4 +687,9 @@ export const upsertPolicyInput = z.object({
|
|
|
682
687
|
policyFileName: z.string().min(1),
|
|
683
688
|
content: z.string().min(1),
|
|
684
689
|
});
|
|
690
|
+
export const upsertPlansSupportFileInput = z.object({
|
|
691
|
+
/** Path relative to mapped plans root (e.g. knowledge/workflow_plans/run-qa/<ulid>.plan.md). */
|
|
692
|
+
filePath: z.string().min(1),
|
|
693
|
+
content: z.string().min(1),
|
|
694
|
+
});
|
|
685
695
|
export const listWorkflowCatalogInput = z.object({});
|
package/dist/core/tools.js
CHANGED
|
@@ -69,6 +69,8 @@ function listExecutionBody(args) {
|
|
|
69
69
|
body.branchName = args.branchName.trim();
|
|
70
70
|
if (args.scenarioId != null && args.scenarioId.trim() !== "")
|
|
71
71
|
body.scenarioId = args.scenarioId.trim();
|
|
72
|
+
if (args.testId != null && args.testId.trim() !== "")
|
|
73
|
+
body.testId = args.testId.trim();
|
|
72
74
|
const dimensionFilters = [...(args.dimensionFilters ?? [])];
|
|
73
75
|
if (args.platform != null) {
|
|
74
76
|
const hasPlatformFilter = dimensionFilters.some((f) => f.dimension === "PLATFORM_EXECUTION_JOB_FILTER_DIMENSION");
|
|
@@ -139,7 +141,8 @@ export const TOOL_DEFINITIONS = [
|
|
|
139
141
|
},
|
|
140
142
|
{
|
|
141
143
|
kebab: "get-execution-history",
|
|
142
|
-
description: "Fetch SmartTest execution history for an optional platform-rooted folder scope, or
|
|
144
|
+
description: "Fetch SmartTest execution history for a testId (top 5 recent runs), an optional platform-rooted folder/file scope, or a scenario when scenarioId is set. " +
|
|
145
|
+
"Prefer testId when you have it from fetch-execution-report. Typically omit environment to avoid env scoping. " +
|
|
143
146
|
"Use branchName and scope.filePaths as for coverage. Optional platform (web|ios|android) and dimensionFilters narrow results.",
|
|
144
147
|
inputSchema: S.listExecutionInput,
|
|
145
148
|
execute: async (args, { postMcp }) => {
|
|
@@ -255,15 +258,20 @@ export const TOOL_DEFINITIONS = [
|
|
|
255
258
|
},
|
|
256
259
|
{
|
|
257
260
|
kebab: "get-test-scenarios",
|
|
258
|
-
description: "Fetch test scenarios from the TestChimp platform by ordinal id (numeric part of TS-<n>)
|
|
259
|
-
"
|
|
260
|
-
"
|
|
261
|
+
description: "Fetch test scenarios from the TestChimp platform by ordinal id (numeric part of TS-<n>) " +
|
|
262
|
+
"and/or external TMS ids (e.g. C12345, PROJ-101 — server strips prefixes and matches numerical part). " +
|
|
263
|
+
"Returns full plan markdown content, title, platform file path, linked user story ordinal ids, " +
|
|
264
|
+
"and external_source / external_system_id when present. " +
|
|
265
|
+
"Use when plan files are not yet synced to the repo, or when linking imported tests to scenarios by TMS id.",
|
|
261
266
|
inputSchema: S.getTestScenariosInput,
|
|
262
267
|
execute: async (args, { postMcp }) => {
|
|
263
268
|
const a = args;
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
269
|
+
const body = {};
|
|
270
|
+
if (a.scenarioOrdinalIds?.length)
|
|
271
|
+
body.scenarioOrdinalIds = a.scenarioOrdinalIds;
|
|
272
|
+
if (a.externalIds?.length)
|
|
273
|
+
body.externalIds = a.externalIds;
|
|
274
|
+
return postMcp("/api/mcp/get_test_scenarios", body);
|
|
267
275
|
},
|
|
268
276
|
},
|
|
269
277
|
{
|
|
@@ -975,6 +983,21 @@ export const TOOL_DEFINITIONS = [
|
|
|
975
983
|
});
|
|
976
984
|
},
|
|
977
985
|
},
|
|
986
|
+
{
|
|
987
|
+
kebab: "upsert-plans-support-file",
|
|
988
|
+
description: "Create or update any file under the mapped plans root on the platform by relative path (no git commit/push required). " +
|
|
989
|
+
"Primary use: upload workflow execution plans at knowledge/workflow_plans/<workflow-id>/<workflow_execution_id>.plan.md after the Plan phase. " +
|
|
990
|
+
"filePath is relative to the plans mapped root (leading plans/ is stripped). Under workflow_plans/, filenames are coerced to *.plan.md and stored as WORKFLOW_EXECUTION_PLAN. " +
|
|
991
|
+
"Response includes supportFileId, filePath (canonical), filetype, created. Blocking step before Execute for cloud agents.",
|
|
992
|
+
inputSchema: S.upsertPlansSupportFileInput,
|
|
993
|
+
execute: async (args, { postMcp }) => {
|
|
994
|
+
const a = args;
|
|
995
|
+
return postMcp("/api/mcp/upsert_plans_support_file", {
|
|
996
|
+
filePath: a.filePath,
|
|
997
|
+
content: a.content,
|
|
998
|
+
});
|
|
999
|
+
},
|
|
1000
|
+
},
|
|
978
1001
|
{
|
|
979
1002
|
kebab: "list-workflow-catalog",
|
|
980
1003
|
description: "List supported TestChimp workflows with Active / Disabled / Missing Config status for the project.",
|
package/package.json
CHANGED