@testchimp/cli 0.1.28 → 0.1.30
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 +108 -2
- package/dist/core/agentTraceability.d.ts +18 -1
- package/dist/core/agentTraceability.js +32 -1
- package/dist/core/schemas.d.ts +62 -0
- package/dist/core/schemas.js +34 -0
- package/dist/core/tools.js +119 -7
- package/package.json +2 -2
package/dist/cli/program.js
CHANGED
|
@@ -55,7 +55,9 @@ function addAgentTraceabilityOptions(cmd) {
|
|
|
55
55
|
.option("--actor-type <type>", "LOCAL_AGENT | CLOUD_AGENT")
|
|
56
56
|
.option("--user-id <id>", "Optional user id")
|
|
57
57
|
.option("--branch-name <name>", "Git branch name")
|
|
58
|
-
.option("--agent-model <model>", "Optional agent model id (agent/CLI only)")
|
|
58
|
+
.option("--agent-model <model>", "Optional agent model id (agent/CLI only)")
|
|
59
|
+
.option("--skill-version <semver>", "TestChimp skill version from SKILL.md frontmatter")
|
|
60
|
+
.option("--cli-version <semver>", "CLI version (defaults to this package version)");
|
|
59
61
|
}
|
|
60
62
|
function collectAgentTraceabilityFlags(opts) {
|
|
61
63
|
const body = {};
|
|
@@ -77,6 +79,10 @@ function collectAgentTraceabilityFlags(opts) {
|
|
|
77
79
|
body.branchName = String(opts.branchName).trim();
|
|
78
80
|
if (opts.agentModel)
|
|
79
81
|
body.agentModel = String(opts.agentModel).trim();
|
|
82
|
+
if (opts.skillVersion)
|
|
83
|
+
body.skillVersion = String(opts.skillVersion).trim();
|
|
84
|
+
if (opts.cliVersion)
|
|
85
|
+
body.cliVersion = String(opts.cliVersion).trim();
|
|
80
86
|
return body;
|
|
81
87
|
}
|
|
82
88
|
function stderrProgress(msg) {
|
|
@@ -127,8 +133,14 @@ export function buildCliProgram() {
|
|
|
127
133
|
.option("--branch-name <s>")
|
|
128
134
|
.option("--platform <web|ios|android>")
|
|
129
135
|
.option("--record-types <csv>", "coverage sources: smart_test,manual (aliases: automated,smarttest)")
|
|
130
|
-
.option("--include-manual", "include manual
|
|
136
|
+
.option("--include-manual", "include manual session coverage in addition to automated SmartTests")
|
|
131
137
|
.option("--manual-only", "manual-only coverage (no automated)")
|
|
138
|
+
.option("--lifecycle-statuses <csv>", "scenario lifecycle allowlist (e.g. ready or draft,ready)")
|
|
139
|
+
.option("--limit <n>", "top N gaps after filter+rank into rankedScenarios (max 200)", (v) => parseInt(v, 10))
|
|
140
|
+
.option("--consider-scenario-priority", "rank by scenario priority high→medium→low→unset")
|
|
141
|
+
.option("--consider-semantic-coverage", "reserved ranking signal (accepted; no server effect yet)")
|
|
142
|
+
.option("--auto-verification-only", "exclude verification_strategy=manual (server default when unset)")
|
|
143
|
+
.option("--include-manual-verification", "include verification_strategy=manual (overrides --auto-verification-only)")
|
|
132
144
|
.option("--file-paths <csv>", "comma-separated paths under platform tests root")
|
|
133
145
|
.option("--folder-path <path>", "folder under tests root, slash-separated")
|
|
134
146
|
.action(async (opts) => {
|
|
@@ -150,6 +162,22 @@ export function buildCliProgram() {
|
|
|
150
162
|
recordTypes = ["manual"];
|
|
151
163
|
if (recordTypes && recordTypes.length > 0)
|
|
152
164
|
body.recordTypes = recordTypes;
|
|
165
|
+
if (opts.lifecycleStatuses) {
|
|
166
|
+
body.scenarioLifecycleStatuses = String(opts.lifecycleStatuses)
|
|
167
|
+
.split(",")
|
|
168
|
+
.map((s) => s.trim())
|
|
169
|
+
.filter(Boolean);
|
|
170
|
+
}
|
|
171
|
+
if (opts.limit != null && !Number.isNaN(opts.limit))
|
|
172
|
+
body.limit = opts.limit;
|
|
173
|
+
if (opts.considerScenarioPriority)
|
|
174
|
+
body.considerScenarioPriority = true;
|
|
175
|
+
if (opts.considerSemanticCoverage)
|
|
176
|
+
body.considerSemanticCoverage = true;
|
|
177
|
+
if (opts.includeManualVerification)
|
|
178
|
+
body.autoVerificationOnly = false;
|
|
179
|
+
else if (opts.autoVerificationOnly)
|
|
180
|
+
body.autoVerificationOnly = true;
|
|
153
181
|
const scope = {};
|
|
154
182
|
if (opts.filePaths)
|
|
155
183
|
scope.filePaths = String(opts.filePaths).split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -198,6 +226,43 @@ export function buildCliProgram() {
|
|
|
198
226
|
const out = await runTool("get-execution-history", merged, { postMcp });
|
|
199
227
|
console.log(out);
|
|
200
228
|
});
|
|
229
|
+
program
|
|
230
|
+
.command("get-suite-execution-stats")
|
|
231
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-suite-execution-stats").description)
|
|
232
|
+
.addOption(jsonInputOption())
|
|
233
|
+
.option("--release <s>")
|
|
234
|
+
.option("--environment <s>")
|
|
235
|
+
.option("--branch-name <s>")
|
|
236
|
+
.option("--scenario-id <id>")
|
|
237
|
+
.option("--test-id <id>")
|
|
238
|
+
.option("--platform <web|ios|android>")
|
|
239
|
+
.option("--file-paths <csv>")
|
|
240
|
+
.option("--folder-path <path>")
|
|
241
|
+
.action(async (opts) => {
|
|
242
|
+
const body = {};
|
|
243
|
+
if (opts.release)
|
|
244
|
+
body.release = opts.release;
|
|
245
|
+
if (opts.environment)
|
|
246
|
+
body.environment = opts.environment;
|
|
247
|
+
if (opts.branchName)
|
|
248
|
+
body.branchName = opts.branchName;
|
|
249
|
+
if (opts.scenarioId)
|
|
250
|
+
body.scenarioId = opts.scenarioId;
|
|
251
|
+
if (opts.testId)
|
|
252
|
+
body.testId = opts.testId;
|
|
253
|
+
if (opts.platform)
|
|
254
|
+
body.platform = opts.platform;
|
|
255
|
+
const scope = {};
|
|
256
|
+
if (opts.filePaths)
|
|
257
|
+
scope.filePaths = String(opts.filePaths).split(",").map((s) => s.trim()).filter(Boolean);
|
|
258
|
+
if (opts.folderPath)
|
|
259
|
+
scope.folderPath = opts.folderPath;
|
|
260
|
+
if (Object.keys(scope).length)
|
|
261
|
+
body.scope = scope;
|
|
262
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
263
|
+
const out = await runTool("get-suite-execution-stats", merged, { postMcp });
|
|
264
|
+
console.log(out);
|
|
265
|
+
});
|
|
201
266
|
program
|
|
202
267
|
.command("fetch-execution-report")
|
|
203
268
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "fetch-execution-report").description)
|
|
@@ -481,6 +546,40 @@ export function buildCliProgram() {
|
|
|
481
546
|
}, { postMcp });
|
|
482
547
|
console.log(out);
|
|
483
548
|
});
|
|
549
|
+
program
|
|
550
|
+
.command("get-spec-lifecycle-details")
|
|
551
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-spec-lifecycle-details").description)
|
|
552
|
+
.addOption(jsonInputOption())
|
|
553
|
+
.option("--scenario-ids <csv>", "comma-separated scenario ordinals (bare 107 or TS-107 / #TS-107)")
|
|
554
|
+
.option("--story-ids <csv>", "comma-separated story ordinals (bare 12 or US-12 / #US-12)")
|
|
555
|
+
.action(async (opts) => {
|
|
556
|
+
const body = {};
|
|
557
|
+
if (opts.scenarioIds) {
|
|
558
|
+
const ids = String(opts.scenarioIds)
|
|
559
|
+
.split(",")
|
|
560
|
+
.map((s) => s.trim())
|
|
561
|
+
.filter((s) => s.length > 0);
|
|
562
|
+
if (ids.length > 0)
|
|
563
|
+
body.scenarioIds = ids;
|
|
564
|
+
}
|
|
565
|
+
if (opts.storyIds) {
|
|
566
|
+
const ids = String(opts.storyIds)
|
|
567
|
+
.split(",")
|
|
568
|
+
.map((s) => s.trim())
|
|
569
|
+
.filter((s) => s.length > 0);
|
|
570
|
+
if (ids.length > 0)
|
|
571
|
+
body.storyIds = ids;
|
|
572
|
+
}
|
|
573
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
574
|
+
if (Array.isArray(merged.scenarioIds) && merged.scenarioIds.length === 0) {
|
|
575
|
+
delete merged.scenarioIds;
|
|
576
|
+
}
|
|
577
|
+
if (Array.isArray(merged.storyIds) && merged.storyIds.length === 0) {
|
|
578
|
+
delete merged.storyIds;
|
|
579
|
+
}
|
|
580
|
+
const out = await runTool("get-spec-lifecycle-details", merged, { postMcp });
|
|
581
|
+
console.log(out);
|
|
582
|
+
});
|
|
484
583
|
addAgentTraceabilityOptions(program
|
|
485
584
|
.command("update-test-scenario")
|
|
486
585
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "update-test-scenario").description)
|
|
@@ -1026,6 +1125,8 @@ export function buildCliProgram() {
|
|
|
1026
1125
|
.option("--user-id <id>", "Optional user id for traceability")
|
|
1027
1126
|
.option("--branch-name <name>", "Git branch")
|
|
1028
1127
|
.option("--agent-model <model>", "Optional agent model id (agent/CLI only)")
|
|
1128
|
+
.option("--skill-version <semver>", "TestChimp skill version from SKILL.md frontmatter")
|
|
1129
|
+
.option("--cli-version <semver>", "CLI version (defaults to this package version)")
|
|
1029
1130
|
.requiredOption("--entity-type <type>", "USER_STORY|SCENARIO|SMART_TEST|POLICY|ISSUE|TEST_EXECUTION|TEST_INVOCATION_BATCH|EXPLORATION|EVENT|WORKFLOW")
|
|
1030
1131
|
.option("--entity-identity <ordinal>", "Project-scoped ordinal id (mutually exclusive with --test-json)")
|
|
1031
1132
|
.option("--test-json <json>", "TestLocator JSON (folderPath/fileName/testSuite/testName)")
|
|
@@ -1051,6 +1152,10 @@ export function buildCliProgram() {
|
|
|
1051
1152
|
body.branchName = String(opts.branchName);
|
|
1052
1153
|
if (opts.agentModel)
|
|
1053
1154
|
body.agentModel = String(opts.agentModel).trim();
|
|
1155
|
+
if (opts.skillVersion)
|
|
1156
|
+
body.skillVersion = String(opts.skillVersion).trim();
|
|
1157
|
+
if (opts.cliVersion)
|
|
1158
|
+
body.cliVersion = String(opts.cliVersion).trim();
|
|
1054
1159
|
if (opts.entityIdentity)
|
|
1055
1160
|
body.entityIdentity = String(opts.entityIdentity);
|
|
1056
1161
|
if (opts.testJson)
|
|
@@ -1075,6 +1180,7 @@ export function buildCliProgram() {
|
|
|
1075
1180
|
console.log(await runTool("get-last-run-workflow-detail", merged, { postMcp }));
|
|
1076
1181
|
});
|
|
1077
1182
|
for (const kebab of [
|
|
1183
|
+
"get-org-capabilities",
|
|
1078
1184
|
"list-workflow-executions",
|
|
1079
1185
|
"get-workflow-execution",
|
|
1080
1186
|
"get-policy",
|
|
@@ -9,14 +9,31 @@ export type AgentTraceabilityFields = {
|
|
|
9
9
|
userId?: string;
|
|
10
10
|
branchName?: string;
|
|
11
11
|
agentModel?: string;
|
|
12
|
+
skillVersion?: string;
|
|
13
|
+
cliVersion?: string;
|
|
12
14
|
/** Nested form (wins over flat when both present and non-empty). */
|
|
13
15
|
agentTraceability?: Record<string, unknown>;
|
|
14
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Resolve skill / CLI versions for traceability payloads.
|
|
19
|
+
* CLI version defaults to this package's version; skill version from flag/env only.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveToolchainVersions(a: {
|
|
22
|
+
skillVersion?: string;
|
|
23
|
+
cliVersion?: string;
|
|
24
|
+
nested?: Record<string, unknown> | null;
|
|
25
|
+
}): {
|
|
26
|
+
skillVersion?: string;
|
|
27
|
+
cliVersion?: string;
|
|
28
|
+
};
|
|
15
29
|
/**
|
|
16
30
|
* Build camelCase AgentActionTraceability for MCP JSON bodies.
|
|
17
31
|
* Returns undefined unless the caller supplied explicit traceability intent
|
|
18
32
|
* **and** a non-empty workflowId (server requires workflow_id for inline Activity).
|
|
19
|
-
*
|
|
33
|
+
* For Activity/timeline attachment the server also requires workflowExecutionId
|
|
34
|
+
* (stable Plan ULID for the whole run) — omit it and the mutation still succeeds
|
|
35
|
+
* but no workflow_executions / Activity row is recorded (server does not auto-mint).
|
|
36
|
+
* Auto-fills gitSha / agentModel / userId / cliVersion only after the workflowId bar is met.
|
|
20
37
|
* Non-empty nested `agentTraceability` wins over flat for overlapping keys.
|
|
21
38
|
*/
|
|
22
39
|
export declare function buildAgentTraceabilityPayload(a: AgentTraceabilityFields): Record<string, unknown> | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveGitHeadSha } from "./gitSha.js";
|
|
2
|
+
import { PACKAGE_VERSION } from "./version.js";
|
|
2
3
|
function nonEmptyString(v) {
|
|
3
4
|
if (v == null)
|
|
4
5
|
return undefined;
|
|
@@ -24,6 +25,10 @@ function hasExplicitTraceabilityIntent(a) {
|
|
|
24
25
|
return true;
|
|
25
26
|
if (nonEmptyString(a.agentModel))
|
|
26
27
|
return true;
|
|
28
|
+
if (nonEmptyString(a.skillVersion))
|
|
29
|
+
return true;
|
|
30
|
+
if (nonEmptyString(a.cliVersion))
|
|
31
|
+
return true;
|
|
27
32
|
if (a.agentTraceability && typeof a.agentTraceability === "object") {
|
|
28
33
|
return Object.keys(a.agentTraceability).some((k) => nonEmptyString(a.agentTraceability[k]) != null);
|
|
29
34
|
}
|
|
@@ -39,11 +44,28 @@ function normalizeActorType(raw) {
|
|
|
39
44
|
return "LOCAL_AGENT";
|
|
40
45
|
return undefined;
|
|
41
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve skill / CLI versions for traceability payloads.
|
|
49
|
+
* CLI version defaults to this package's version; skill version from flag/env only.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveToolchainVersions(a) {
|
|
52
|
+
const skillVersion = nonEmptyString(a.nested?.skillVersion) ??
|
|
53
|
+
nonEmptyString(a.skillVersion) ??
|
|
54
|
+
nonEmptyString(process.env.TESTCHIMP_SKILL_VERSION);
|
|
55
|
+
const cliVersion = nonEmptyString(a.nested?.cliVersion) ??
|
|
56
|
+
nonEmptyString(a.cliVersion) ??
|
|
57
|
+
nonEmptyString(process.env.TESTCHIMP_CLI_VERSION) ??
|
|
58
|
+
PACKAGE_VERSION;
|
|
59
|
+
return { skillVersion, cliVersion };
|
|
60
|
+
}
|
|
42
61
|
/**
|
|
43
62
|
* Build camelCase AgentActionTraceability for MCP JSON bodies.
|
|
44
63
|
* Returns undefined unless the caller supplied explicit traceability intent
|
|
45
64
|
* **and** a non-empty workflowId (server requires workflow_id for inline Activity).
|
|
46
|
-
*
|
|
65
|
+
* For Activity/timeline attachment the server also requires workflowExecutionId
|
|
66
|
+
* (stable Plan ULID for the whole run) — omit it and the mutation still succeeds
|
|
67
|
+
* but no workflow_executions / Activity row is recorded (server does not auto-mint).
|
|
68
|
+
* Auto-fills gitSha / agentModel / userId / cliVersion only after the workflowId bar is met.
|
|
47
69
|
* Non-empty nested `agentTraceability` wins over flat for overlapping keys.
|
|
48
70
|
*/
|
|
49
71
|
export function buildAgentTraceabilityPayload(a) {
|
|
@@ -69,6 +91,11 @@ export function buildAgentTraceabilityPayload(a) {
|
|
|
69
91
|
const agentModel = nonEmptyString(nested?.agentModel) ??
|
|
70
92
|
nonEmptyString(a.agentModel) ??
|
|
71
93
|
nonEmptyString(process.env.TESTCHIMP_AGENT_MODEL);
|
|
94
|
+
const { skillVersion, cliVersion } = resolveToolchainVersions({
|
|
95
|
+
skillVersion: a.skillVersion,
|
|
96
|
+
cliVersion: a.cliVersion,
|
|
97
|
+
nested,
|
|
98
|
+
});
|
|
72
99
|
// Server requires workflow_id for inline mutation Activity — do not send orphan payloads.
|
|
73
100
|
if (!workflowId) {
|
|
74
101
|
return undefined;
|
|
@@ -91,5 +118,9 @@ export function buildAgentTraceabilityPayload(a) {
|
|
|
91
118
|
out.branchName = branchName;
|
|
92
119
|
if (agentModel)
|
|
93
120
|
out.agentModel = agentModel;
|
|
121
|
+
if (skillVersion)
|
|
122
|
+
out.skillVersion = skillVersion;
|
|
123
|
+
if (cliVersion)
|
|
124
|
+
out.cliVersion = cliVersion;
|
|
94
125
|
return out;
|
|
95
126
|
}
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -28,6 +28,11 @@ export declare const listCoverageInput: z.ZodObject<{
|
|
|
28
28
|
SMART_TEST: "SMART_TEST";
|
|
29
29
|
MANUAL: "MANUAL";
|
|
30
30
|
}>>>;
|
|
31
|
+
scenarioLifecycleStatuses: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
considerScenarioPriority: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
considerSemanticCoverage: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
autoVerificationOnly: z.ZodOptional<z.ZodBoolean>;
|
|
31
36
|
}, z.core.$strip>;
|
|
32
37
|
export declare const listExecutionInput: z.ZodObject<{
|
|
33
38
|
release: z.ZodOptional<z.ZodString>;
|
|
@@ -51,6 +56,29 @@ export declare const listExecutionInput: z.ZodObject<{
|
|
|
51
56
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
52
57
|
offset: z.ZodOptional<z.ZodNumber>;
|
|
53
58
|
}, z.core.$strip>;
|
|
59
|
+
/** Same filters as get-execution-history; rolls up list_execution_history testStats. */
|
|
60
|
+
export declare const suiteExecutionStatsInput: z.ZodObject<{
|
|
61
|
+
release: z.ZodOptional<z.ZodString>;
|
|
62
|
+
environment: z.ZodOptional<z.ZodString>;
|
|
63
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
64
|
+
filePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
65
|
+
folderPath: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodString]>>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
branchName: z.ZodOptional<z.ZodString>;
|
|
68
|
+
scenarioId: z.ZodOptional<z.ZodString>;
|
|
69
|
+
testId: z.ZodOptional<z.ZodString>;
|
|
70
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
71
|
+
web: "web";
|
|
72
|
+
ios: "ios";
|
|
73
|
+
android: "android";
|
|
74
|
+
}>>;
|
|
75
|
+
dimensionFilters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
76
|
+
dimension: z.ZodString;
|
|
77
|
+
values: z.ZodArray<z.ZodString>;
|
|
78
|
+
}, z.core.$strip>>>;
|
|
79
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
81
|
+
}, z.core.$strip>;
|
|
54
82
|
export declare const fetchExecutionReportInput: z.ZodObject<{
|
|
55
83
|
batchInvocationId: z.ZodOptional<z.ZodString>;
|
|
56
84
|
jobId: z.ZodOptional<z.ZodString>;
|
|
@@ -77,6 +105,8 @@ export declare const agentActionTraceabilitySchema: z.ZodObject<{
|
|
|
77
105
|
userId: z.ZodOptional<z.ZodString>;
|
|
78
106
|
branchName: z.ZodOptional<z.ZodString>;
|
|
79
107
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
108
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
109
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
80
110
|
}, z.core.$strict>;
|
|
81
111
|
/** Flat + nested traceability fields shared by create/update MCP tools. */
|
|
82
112
|
export declare const agentTraceabilityFieldsSchema: z.ZodObject<{
|
|
@@ -94,6 +124,8 @@ export declare const agentTraceabilityFieldsSchema: z.ZodObject<{
|
|
|
94
124
|
userId: z.ZodOptional<z.ZodString>;
|
|
95
125
|
branchName: z.ZodOptional<z.ZodString>;
|
|
96
126
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
127
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
128
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
97
129
|
agentTraceability: z.ZodOptional<z.ZodObject<{
|
|
98
130
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
99
131
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -109,6 +141,8 @@ export declare const agentTraceabilityFieldsSchema: z.ZodObject<{
|
|
|
109
141
|
userId: z.ZodOptional<z.ZodString>;
|
|
110
142
|
branchName: z.ZodOptional<z.ZodString>;
|
|
111
143
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
144
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
145
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
112
146
|
}, z.core.$strict>>;
|
|
113
147
|
}, z.core.$strip>;
|
|
114
148
|
export declare const createUserStoryInput: z.ZodObject<{
|
|
@@ -128,6 +162,8 @@ export declare const createUserStoryInput: z.ZodObject<{
|
|
|
128
162
|
userId: z.ZodOptional<z.ZodString>;
|
|
129
163
|
branchName: z.ZodOptional<z.ZodString>;
|
|
130
164
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
165
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
166
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
131
167
|
agentTraceability: z.ZodOptional<z.ZodObject<{
|
|
132
168
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
133
169
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -143,6 +179,8 @@ export declare const createUserStoryInput: z.ZodObject<{
|
|
|
143
179
|
userId: z.ZodOptional<z.ZodString>;
|
|
144
180
|
branchName: z.ZodOptional<z.ZodString>;
|
|
145
181
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
182
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
183
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
146
184
|
}, z.core.$strict>>;
|
|
147
185
|
}, z.core.$strip>;
|
|
148
186
|
export declare const createTestScenarioInput: z.ZodObject<{
|
|
@@ -163,6 +201,8 @@ export declare const createTestScenarioInput: z.ZodObject<{
|
|
|
163
201
|
userId: z.ZodOptional<z.ZodString>;
|
|
164
202
|
branchName: z.ZodOptional<z.ZodString>;
|
|
165
203
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
204
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
205
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
166
206
|
agentTraceability: z.ZodOptional<z.ZodObject<{
|
|
167
207
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
168
208
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -178,6 +218,8 @@ export declare const createTestScenarioInput: z.ZodObject<{
|
|
|
178
218
|
userId: z.ZodOptional<z.ZodString>;
|
|
179
219
|
branchName: z.ZodOptional<z.ZodString>;
|
|
180
220
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
221
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
222
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
181
223
|
}, z.core.$strict>>;
|
|
182
224
|
}, z.core.$strip>;
|
|
183
225
|
export declare const updatePlanMarkdownInput: z.ZodObject<{
|
|
@@ -196,6 +238,8 @@ export declare const updatePlanMarkdownInput: z.ZodObject<{
|
|
|
196
238
|
userId: z.ZodOptional<z.ZodString>;
|
|
197
239
|
branchName: z.ZodOptional<z.ZodString>;
|
|
198
240
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
241
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
242
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
199
243
|
agentTraceability: z.ZodOptional<z.ZodObject<{
|
|
200
244
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
201
245
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -211,6 +255,8 @@ export declare const updatePlanMarkdownInput: z.ZodObject<{
|
|
|
211
255
|
userId: z.ZodOptional<z.ZodString>;
|
|
212
256
|
branchName: z.ZodOptional<z.ZodString>;
|
|
213
257
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
258
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
259
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
214
260
|
}, z.core.$strict>>;
|
|
215
261
|
}, z.core.$strip>;
|
|
216
262
|
export declare const markPlanItemsImplementationDoneInput: z.ZodObject<{
|
|
@@ -222,6 +268,10 @@ export declare const updatePlanItemsLifecycleStatusInput: z.ZodObject<{
|
|
|
222
268
|
ordinalId: z.ZodCoercedNumber<unknown>;
|
|
223
269
|
status: z.ZodString;
|
|
224
270
|
}, z.core.$strip>;
|
|
271
|
+
export declare const getSpecLifecycleDetailsInput: z.ZodObject<{
|
|
272
|
+
scenarioIds: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodString>>>;
|
|
273
|
+
storyIds: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>, z.ZodString>>>;
|
|
274
|
+
}, z.core.$strip>;
|
|
225
275
|
export declare const getUserStoriesInput: z.ZodObject<{
|
|
226
276
|
userStoryOrdinalIds: z.ZodArray<z.ZodCoercedNumber<unknown>>;
|
|
227
277
|
}, z.core.$strip>;
|
|
@@ -265,6 +315,8 @@ export declare const updateIssueStatusInput: z.ZodObject<{
|
|
|
265
315
|
userId: z.ZodOptional<z.ZodString>;
|
|
266
316
|
branchName: z.ZodOptional<z.ZodString>;
|
|
267
317
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
318
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
319
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
268
320
|
agentTraceability: z.ZodOptional<z.ZodObject<{
|
|
269
321
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
270
322
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -280,6 +332,8 @@ export declare const updateIssueStatusInput: z.ZodObject<{
|
|
|
280
332
|
userId: z.ZodOptional<z.ZodString>;
|
|
281
333
|
branchName: z.ZodOptional<z.ZodString>;
|
|
282
334
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
335
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
336
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
283
337
|
}, z.core.$strict>>;
|
|
284
338
|
}, z.core.$strip>;
|
|
285
339
|
export declare const createIssueInput: z.ZodObject<{
|
|
@@ -361,6 +415,8 @@ export declare const createIssueInput: z.ZodObject<{
|
|
|
361
415
|
userId: z.ZodOptional<z.ZodString>;
|
|
362
416
|
branchName: z.ZodOptional<z.ZodString>;
|
|
363
417
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
418
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
419
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
364
420
|
agentTraceability: z.ZodOptional<z.ZodObject<{
|
|
365
421
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
366
422
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -376,6 +432,8 @@ export declare const createIssueInput: z.ZodObject<{
|
|
|
376
432
|
userId: z.ZodOptional<z.ZodString>;
|
|
377
433
|
branchName: z.ZodOptional<z.ZodString>;
|
|
378
434
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
435
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
436
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
379
437
|
}, z.core.$strict>>;
|
|
380
438
|
}, z.core.$strip>;
|
|
381
439
|
export declare const emptyInput: z.ZodObject<{}, z.core.$strip>;
|
|
@@ -1332,6 +1390,8 @@ export declare const reportAgentActionInput: z.ZodObject<{
|
|
|
1332
1390
|
userId: z.ZodOptional<z.ZodString>;
|
|
1333
1391
|
branchName: z.ZodOptional<z.ZodString>;
|
|
1334
1392
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
1393
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
1394
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
1335
1395
|
traceability: z.ZodOptional<z.ZodObject<{
|
|
1336
1396
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
1337
1397
|
workflowExecutionId: z.ZodOptional<z.ZodString>;
|
|
@@ -1347,6 +1407,8 @@ export declare const reportAgentActionInput: z.ZodObject<{
|
|
|
1347
1407
|
userId: z.ZodOptional<z.ZodString>;
|
|
1348
1408
|
branchName: z.ZodOptional<z.ZodString>;
|
|
1349
1409
|
agentModel: z.ZodOptional<z.ZodString>;
|
|
1410
|
+
skillVersion: z.ZodOptional<z.ZodString>;
|
|
1411
|
+
cliVersion: z.ZodOptional<z.ZodString>;
|
|
1350
1412
|
}, z.core.$strict>>;
|
|
1351
1413
|
entityType: z.ZodEnum<{
|
|
1352
1414
|
SMART_TEST: "SMART_TEST";
|
package/dist/core/schemas.js
CHANGED
|
@@ -26,6 +26,19 @@ export const listCoverageInput = z.object({
|
|
|
26
26
|
* When provided, send proto enum names ("SMART_TEST", "MANUAL") or CLI-friendly aliases ("smart_test", "manual").
|
|
27
27
|
*/
|
|
28
28
|
recordTypes: z.array(requirementCoverageRecordTypeSchema).optional(),
|
|
29
|
+
/** Allowlist of scenario lifecycle statuses (e.g. ["ready"] or ["draft","ready"]). Empty/omit = no status filter. */
|
|
30
|
+
scenarioLifecycleStatuses: z.array(z.string().min(1)).optional(),
|
|
31
|
+
/** When set (>0), truncate rankedScenarios to top N after filter+rank (server clamps to 200). */
|
|
32
|
+
limit: z.number().int().positive().max(200).optional(),
|
|
33
|
+
/** Rank by scenario priority high > medium > low > unset. */
|
|
34
|
+
considerScenarioPriority: z.boolean().optional(),
|
|
35
|
+
/** Reserved for future semantic-gap ranking; accepted by server, ignored in v1. */
|
|
36
|
+
considerSemanticCoverage: z.boolean().optional(),
|
|
37
|
+
/**
|
|
38
|
+
* Exclude scenarios with verification_strategy=manual. Server defaults to true when unset.
|
|
39
|
+
* Prefer --include-manual-verification (sets false) over setting this explicitly.
|
|
40
|
+
*/
|
|
41
|
+
autoVerificationOnly: z.boolean().optional(),
|
|
29
42
|
});
|
|
30
43
|
export const listExecutionInput = z.object({
|
|
31
44
|
release: z.string().optional(),
|
|
@@ -39,6 +52,8 @@ export const listExecutionInput = z.object({
|
|
|
39
52
|
limit: z.number().int().positive().max(500).optional(),
|
|
40
53
|
offset: z.number().int().nonnegative().optional(),
|
|
41
54
|
});
|
|
55
|
+
/** Same filters as get-execution-history; rolls up list_execution_history testStats. */
|
|
56
|
+
export const suiteExecutionStatsInput = listExecutionInput;
|
|
42
57
|
export const fetchExecutionReportInput = z
|
|
43
58
|
.object({
|
|
44
59
|
batchInvocationId: z.string().optional(),
|
|
@@ -67,6 +82,8 @@ export const agentActionTraceabilitySchema = z
|
|
|
67
82
|
userId: z.string().optional(),
|
|
68
83
|
branchName: z.string().optional(),
|
|
69
84
|
agentModel: z.string().optional(),
|
|
85
|
+
skillVersion: z.string().optional(),
|
|
86
|
+
cliVersion: z.string().optional(),
|
|
70
87
|
})
|
|
71
88
|
.strict();
|
|
72
89
|
/** Flat + nested traceability fields shared by create/update MCP tools. */
|
|
@@ -80,6 +97,8 @@ export const agentTraceabilityFieldsSchema = z.object({
|
|
|
80
97
|
userId: z.string().optional(),
|
|
81
98
|
branchName: z.string().optional(),
|
|
82
99
|
agentModel: z.string().optional(),
|
|
100
|
+
skillVersion: z.string().optional(),
|
|
101
|
+
cliVersion: z.string().optional(),
|
|
83
102
|
agentTraceability: agentActionTraceabilitySchema.optional(),
|
|
84
103
|
});
|
|
85
104
|
export const createUserStoryInput = z.object({
|
|
@@ -105,6 +124,19 @@ export const updatePlanItemsLifecycleStatusInput = z.object({
|
|
|
105
124
|
/** draft | ready | in progress | blocked | done | archived */
|
|
106
125
|
status: z.string().min(1),
|
|
107
126
|
});
|
|
127
|
+
export const getSpecLifecycleDetailsInput = z
|
|
128
|
+
.object({
|
|
129
|
+
/** Bare ordinals or TS-/ #TS- forms; numbers coerced to strings. */
|
|
130
|
+
scenarioIds: z
|
|
131
|
+
.array(z.union([z.string(), z.number()]).transform((v) => String(v).trim()).pipe(z.string().min(1)))
|
|
132
|
+
.optional(),
|
|
133
|
+
/** Bare ordinals or US-/ #US- forms; numbers coerced to strings. */
|
|
134
|
+
storyIds: z
|
|
135
|
+
.array(z.union([z.string(), z.number()]).transform((v) => String(v).trim()).pipe(z.string().min(1)))
|
|
136
|
+
.optional(),
|
|
137
|
+
})
|
|
138
|
+
.refine((v) => (v.scenarioIds != null && v.scenarioIds.length > 0) ||
|
|
139
|
+
(v.storyIds != null && v.storyIds.length > 0), { message: "Provide scenarioIds and/or storyIds (non-empty)" });
|
|
108
140
|
export const getUserStoriesInput = z
|
|
109
141
|
.object({
|
|
110
142
|
userStoryOrdinalIds: z.array(z.coerce.number().int().positive()).min(1),
|
|
@@ -659,6 +691,8 @@ export const reportAgentActionInput = z
|
|
|
659
691
|
userId: z.string().optional(),
|
|
660
692
|
branchName: z.string().optional(),
|
|
661
693
|
agentModel: z.string().optional(),
|
|
694
|
+
skillVersion: z.string().optional(),
|
|
695
|
+
cliVersion: z.string().optional(),
|
|
662
696
|
traceability: agentActionTraceabilitySchema.optional(),
|
|
663
697
|
entityType: agentActionEntityTypeSchema,
|
|
664
698
|
/** Project-scoped ordinal id (or explicitly provided execution/batch id). Mutually exclusive with `test`. */
|
package/dist/core/tools.js
CHANGED
|
@@ -2,7 +2,7 @@ import { normalizeScope } from "./normalize.js";
|
|
|
2
2
|
import { runProvisionEphemeralEnvironmentAndWait } from "./ephemeralWait.js";
|
|
3
3
|
import * as S from "./schemas.js";
|
|
4
4
|
import { resolveGitHeadSha } from "./gitSha.js";
|
|
5
|
-
import { buildAgentTraceabilityPayload } from "./agentTraceability.js";
|
|
5
|
+
import { buildAgentTraceabilityPayload, resolveToolchainVersions } from "./agentTraceability.js";
|
|
6
6
|
function platformToProtoEnum(platform) {
|
|
7
7
|
switch (platform) {
|
|
8
8
|
case "ios":
|
|
@@ -55,6 +55,17 @@ function listCoverageBody(args) {
|
|
|
55
55
|
});
|
|
56
56
|
body.recordTypes = normalized;
|
|
57
57
|
}
|
|
58
|
+
if (args.scenarioLifecycleStatuses != null && args.scenarioLifecycleStatuses.length > 0) {
|
|
59
|
+
body.scenarioLifecycleStatuses = args.scenarioLifecycleStatuses.map((s) => String(s).trim()).filter(Boolean);
|
|
60
|
+
}
|
|
61
|
+
if (args.limit != null)
|
|
62
|
+
body.limit = args.limit;
|
|
63
|
+
if (args.considerScenarioPriority != null)
|
|
64
|
+
body.considerScenarioPriority = args.considerScenarioPriority;
|
|
65
|
+
if (args.considerSemanticCoverage != null)
|
|
66
|
+
body.considerSemanticCoverage = args.considerSemanticCoverage;
|
|
67
|
+
if (args.autoVerificationOnly != null)
|
|
68
|
+
body.autoVerificationOnly = args.autoVerificationOnly;
|
|
58
69
|
return body;
|
|
59
70
|
}
|
|
60
71
|
function listExecutionBody(args) {
|
|
@@ -89,6 +100,45 @@ function listExecutionBody(args) {
|
|
|
89
100
|
body.offset = args.offset;
|
|
90
101
|
return body;
|
|
91
102
|
}
|
|
103
|
+
/** Mean success duration above this counts as a slow test (mirrors UI ExecutionTimingSummary). */
|
|
104
|
+
const SLOW_TEST_MEAN_SECS = 30;
|
|
105
|
+
function parseMeanSecs(raw) {
|
|
106
|
+
if (raw == null)
|
|
107
|
+
return null;
|
|
108
|
+
const n = Number(raw);
|
|
109
|
+
return Number.isFinite(n) && !Number.isNaN(n) && n >= 0 ? n : null;
|
|
110
|
+
}
|
|
111
|
+
/** Suite rollup from list_execution_history testStats (sum of success means = UI Total time). */
|
|
112
|
+
function aggregateSuiteExecutionStats(testStats) {
|
|
113
|
+
const stats = Array.isArray(testStats) ? testStats : [];
|
|
114
|
+
let timedTestCount = 0;
|
|
115
|
+
let sumSuccessMeanSecs = 0;
|
|
116
|
+
let sumFailMeanSecs = 0;
|
|
117
|
+
let maxSuccessMeanSecs = 0;
|
|
118
|
+
let slowTestCount = 0;
|
|
119
|
+
for (const s of stats) {
|
|
120
|
+
const successMean = parseMeanSecs(s.successTiming?.meanSecs);
|
|
121
|
+
if (successMean != null) {
|
|
122
|
+
timedTestCount += 1;
|
|
123
|
+
sumSuccessMeanSecs += successMean;
|
|
124
|
+
if (successMean > maxSuccessMeanSecs)
|
|
125
|
+
maxSuccessMeanSecs = successMean;
|
|
126
|
+
if (successMean > SLOW_TEST_MEAN_SECS)
|
|
127
|
+
slowTestCount += 1;
|
|
128
|
+
}
|
|
129
|
+
const failMean = parseMeanSecs(s.failTiming?.meanSecs);
|
|
130
|
+
if (failMean != null)
|
|
131
|
+
sumFailMeanSecs += failMean;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
testCount: stats.length,
|
|
135
|
+
timedTestCount,
|
|
136
|
+
sumSuccessMeanSecs,
|
|
137
|
+
sumFailMeanSecs,
|
|
138
|
+
maxSuccessMeanSecs: timedTestCount > 0 ? maxSuccessMeanSecs : 0,
|
|
139
|
+
slowTestCount,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
92
142
|
function requirementQualitySubjectBody(subjectType, opts) {
|
|
93
143
|
const body = { subjectType };
|
|
94
144
|
const entityId = (opts.subjectEntityId ?? "").trim();
|
|
@@ -127,12 +177,22 @@ async function loadRequirementQualityReportJson(args) {
|
|
|
127
177
|
return {};
|
|
128
178
|
}
|
|
129
179
|
export const TOOL_DEFINITIONS = [
|
|
180
|
+
{
|
|
181
|
+
kebab: "get-org-capabilities",
|
|
182
|
+
description: "Fetch the organization's enabled capabilities (e.g. TRUE_COVERAGE, API_CONTRACT_COVERAGE) and " +
|
|
183
|
+
"freeTrialActive flag. Call before relying on TrueCoverage / API contract coverage features so " +
|
|
184
|
+
"playbooks can soft-skip gated insights instead of failing. Authenticated via project API key.",
|
|
185
|
+
inputSchema: S.emptyInput,
|
|
186
|
+
execute: async (_args, { postMcp }) => postMcp("/api/mcp/get_org_capabilities", {}),
|
|
187
|
+
},
|
|
130
188
|
{
|
|
131
189
|
kebab: "get-requirement-coverage",
|
|
132
190
|
description: "Fetch requirement (scenario) coverage under an optional platform-rooted folder scope (tests/... or plans/...). " +
|
|
133
191
|
"Use scope.filePaths or scope.folderPath (platform tests/plans roots). Omit branchName for cross-branch coverage " +
|
|
134
192
|
"(aggregates branch copies; execution jobs deduped by stable hash of tests-root-relative path + test name). " +
|
|
135
|
-
"Pass branchName only when results must be limited to one Git branch. Optional platform (web|ios|android) filters rollup."
|
|
193
|
+
"Pass branchName only when results must be limited to one Git branch. Optional platform (web|ios|android) filters rollup. " +
|
|
194
|
+
"For top-N gap recommendations: set scenarioLifecycleStatuses, considerScenarioPriority / considerSemanticCoverage, and limit; " +
|
|
195
|
+
"prefer response rankedScenarios (gaps only). Server excludes verification_strategy=manual by default (autoVerificationOnly).",
|
|
136
196
|
inputSchema: S.listCoverageInput,
|
|
137
197
|
execute: async (args, { postMcp }) => {
|
|
138
198
|
const json = await postMcp("/api/mcp/list_requirement_coverage", listCoverageBody(args));
|
|
@@ -150,6 +210,20 @@ export const TOOL_DEFINITIONS = [
|
|
|
150
210
|
return json;
|
|
151
211
|
},
|
|
152
212
|
},
|
|
213
|
+
{
|
|
214
|
+
kebab: "get-suite-execution-stats",
|
|
215
|
+
description: "Aggregate suite timing from list_execution_history testStats (same filters as get-execution-history). " +
|
|
216
|
+
"Returns testCount, timedTestCount, sumSuccessMeanSecs (UI ExecutionTimingSummary total), sumFailMeanSecs, " +
|
|
217
|
+
"maxSuccessMeanSecs, slowTestCount (success mean > 30s). " +
|
|
218
|
+
"Sum of means is aggregate test CPU-time, not CI wall-clock under parallelism. " +
|
|
219
|
+
"Compare sumSuccessMeanSecs against any suite budget in the agent — this tool only returns stats.",
|
|
220
|
+
inputSchema: S.suiteExecutionStatsInput,
|
|
221
|
+
execute: async (args, { postMcp }) => {
|
|
222
|
+
const json = await postMcp("/api/mcp/list_execution_history", listExecutionBody(args));
|
|
223
|
+
const parsed = JSON.parse(json);
|
|
224
|
+
return JSON.stringify(aggregateSuiteExecutionStats(parsed.testStats));
|
|
225
|
+
},
|
|
226
|
+
},
|
|
153
227
|
{
|
|
154
228
|
kebab: "fetch-execution-report",
|
|
155
229
|
description: "Fetch a detailed execution report for failing SmartTests, given a batchInvocationId (batch run) or jobId (single run). " +
|
|
@@ -306,7 +380,8 @@ export const TOOL_DEFINITIONS = [
|
|
|
306
380
|
"status must be one of: ACTIVE, IGNORED, FIXED, DUPLICATE, IN_PROGRESS_BUG, ARCHIVED_BUG, BLOCKED. " +
|
|
307
381
|
"For /testchimp fix issue: set IN_PROGRESS_BUG after applying a code fix; set FIXED only after user confirmation / commits pushed. " +
|
|
308
382
|
"Optional ignoreReason when status is IGNORED: INTENDED_BEHAVIOUR | INACCURATE_ASSESSMENT | NOT_IMPORTANT. " +
|
|
309
|
-
"Optional agentTraceability records UPDATED Activity inline
|
|
383
|
+
"Optional agentTraceability records UPDATED Activity inline " +
|
|
384
|
+
"(requires both workflowId and workflowExecutionId for Activity attachment).",
|
|
310
385
|
inputSchema: S.updateIssueStatusInput,
|
|
311
386
|
execute: async (args, { postMcp }) => {
|
|
312
387
|
const a = args;
|
|
@@ -330,8 +405,10 @@ export const TOOL_DEFINITIONS = [
|
|
|
330
405
|
"linkTargets, labels, source, environment, attachments, artifactReference). " +
|
|
331
406
|
"For /testchimp implement TASK_ISSUE creates: set labels=[\"TestChimp Implement\"] (not source), " +
|
|
332
407
|
"severity from task priority, category (e.g. FUNCTIONAL), and linkTargets for STORY and/or SCENARIO ordinals. " +
|
|
333
|
-
"Optional agentTraceability (or flat workflowId/policyFile/…) records CREATED Activity inline — " +
|
|
408
|
+
"Optional agentTraceability (or flat workflowId/workflowExecutionId/policyFile/…) records CREATED Activity inline — " +
|
|
334
409
|
"prefer this over a separate report-agent-action for issue creates. " +
|
|
410
|
+
"For Activity/timeline attachment both workflowId and workflowExecutionId (stable Plan ULID) are required; " +
|
|
411
|
+
"do not omit workflowExecutionId or mint a new ULID per issue. " +
|
|
335
412
|
"Authenticated via project API key; project is resolved from the key.",
|
|
336
413
|
inputSchema: S.createIssueInput,
|
|
337
414
|
execute: async (args, { postMcp }) => {
|
|
@@ -401,6 +478,22 @@ export const TOOL_DEFINITIONS = [
|
|
|
401
478
|
});
|
|
402
479
|
},
|
|
403
480
|
},
|
|
481
|
+
{
|
|
482
|
+
kebab: "get-spec-lifecycle-details",
|
|
483
|
+
description: "Fetch lifecycle_fields for user stories and/or test scenarios by ordinal id (DB only; no markdown). " +
|
|
484
|
+
"Pass scenarioIds / storyIds as lists of bare ordinals (canonical) or prefixed forms (TS-107, #US-12). " +
|
|
485
|
+
"Use after identifying scenarios in scope for create-tests to read verification_strategy (auto|manual) and skip manual ones.",
|
|
486
|
+
inputSchema: S.getSpecLifecycleDetailsInput,
|
|
487
|
+
execute: async (args, { postMcp }) => {
|
|
488
|
+
const a = args;
|
|
489
|
+
const body = {};
|
|
490
|
+
if (a.scenarioIds?.length)
|
|
491
|
+
body.scenarioIds = a.scenarioIds;
|
|
492
|
+
if (a.storyIds?.length)
|
|
493
|
+
body.storyIds = a.storyIds;
|
|
494
|
+
return postMcp("/api/mcp/get_spec_lifecycle_details", body);
|
|
495
|
+
},
|
|
496
|
+
},
|
|
404
497
|
{
|
|
405
498
|
kebab: "get-eaas-config",
|
|
406
499
|
description: "Return the project's BunnyShell (Environment-as-a-Service) settings. Secrets are never returned.",
|
|
@@ -947,7 +1040,15 @@ export const TOOL_DEFINITIONS = [
|
|
|
947
1040
|
body.userId = process.env.TESTCHIMP_USER_ID;
|
|
948
1041
|
if (a.branchName)
|
|
949
1042
|
body.branchName = a.branchName;
|
|
950
|
-
// Nested traceability wins for agentModel
|
|
1043
|
+
// Nested traceability wins for agentModel / skillVersion / cliVersion;
|
|
1044
|
+
// fill from flat/env/package when nested omits them.
|
|
1045
|
+
const { skillVersion, cliVersion } = resolveToolchainVersions({
|
|
1046
|
+
skillVersion: a.skillVersion,
|
|
1047
|
+
cliVersion: a.cliVersion,
|
|
1048
|
+
nested: a.traceability && typeof a.traceability === "object"
|
|
1049
|
+
? a.traceability
|
|
1050
|
+
: null,
|
|
1051
|
+
});
|
|
951
1052
|
if (a.traceability && typeof a.traceability === "object") {
|
|
952
1053
|
const nested = { ...a.traceability };
|
|
953
1054
|
const nestedModel = nested.agentModel != null && String(nested.agentModel).trim() !== ""
|
|
@@ -960,12 +1061,23 @@ export const TOOL_DEFINITIONS = [
|
|
|
960
1061
|
else if (flatModel) {
|
|
961
1062
|
nested.agentModel = flatModel;
|
|
962
1063
|
}
|
|
1064
|
+
if (skillVersion)
|
|
1065
|
+
nested.skillVersion = skillVersion;
|
|
1066
|
+
if (cliVersion)
|
|
1067
|
+
nested.cliVersion = cliVersion;
|
|
963
1068
|
body.traceability = nested;
|
|
964
1069
|
}
|
|
965
1070
|
else {
|
|
966
1071
|
const model = a.agentModel?.trim() || process.env.TESTCHIMP_AGENT_MODEL?.trim();
|
|
967
|
-
|
|
968
|
-
|
|
1072
|
+
const nested = {};
|
|
1073
|
+
if (model)
|
|
1074
|
+
nested.agentModel = model;
|
|
1075
|
+
if (skillVersion)
|
|
1076
|
+
nested.skillVersion = skillVersion;
|
|
1077
|
+
if (cliVersion)
|
|
1078
|
+
nested.cliVersion = cliVersion;
|
|
1079
|
+
if (Object.keys(nested).length > 0) {
|
|
1080
|
+
body.traceability = nested;
|
|
969
1081
|
}
|
|
970
1082
|
}
|
|
971
1083
|
if (a.test) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testchimp/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "TestChimp CLI and MCP server
|
|
3
|
+
"version": "0.1.30",
|
|
4
|
+
"description": "TestChimp CLI and MCP server — coverage, plans, EaaS, TrueCoverage, API operations (calls /api/mcp/*)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/bin/testchimp.js",
|
|
7
7
|
"types": "dist/bin/testchimp.d.ts",
|