@testchimp/cli 0.1.20 → 0.1.22
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 +62 -9
- package/dist/core/gitSha.d.ts +2 -0
- package/dist/core/gitSha.js +14 -0
- package/dist/core/schemas.d.ts +38 -2
- package/dist/core/schemas.js +94 -5
- package/dist/core/tools.js +42 -11
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -5,6 +5,7 @@ import { DEFAULT_BACKEND, postMcp } from "../core/client.js";
|
|
|
5
5
|
import { deepMerge } from "../core/merge.js";
|
|
6
6
|
import { runTool } from "../core/tools.js";
|
|
7
7
|
import { TOOL_DEFINITIONS } from "../core/tools.js";
|
|
8
|
+
import { resolveGitHeadSha } from "../core/gitSha.js";
|
|
8
9
|
import { PACKAGE_VERSION } from "../core/version.js";
|
|
9
10
|
export { PACKAGE_VERSION };
|
|
10
11
|
function parseRecordTypesCsv(raw) {
|
|
@@ -393,6 +394,39 @@ export function buildCliProgram() {
|
|
|
393
394
|
const out = await runTool("mark-plan-items-implementation-done", merged, { postMcp });
|
|
394
395
|
console.log(out);
|
|
395
396
|
});
|
|
397
|
+
program
|
|
398
|
+
.command("update-plan-items-lifecycle-status")
|
|
399
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "update-plan-items-lifecycle-status").description)
|
|
400
|
+
.addOption(jsonInputOption())
|
|
401
|
+
.option("--entity-type <type>", "story | scenario")
|
|
402
|
+
.option("--ordinal-id <n>", "numeric US-/TS- ordinal")
|
|
403
|
+
.option("--status <status>", "draft | ready | in progress | blocked | done | archived")
|
|
404
|
+
.action(async (opts) => {
|
|
405
|
+
const body = {};
|
|
406
|
+
if (opts.entityType)
|
|
407
|
+
body.entityType = String(opts.entityType).trim();
|
|
408
|
+
if (opts.ordinalId != null && String(opts.ordinalId).trim() !== "") {
|
|
409
|
+
body.ordinalId = Number(String(opts.ordinalId).trim());
|
|
410
|
+
}
|
|
411
|
+
if (opts.status)
|
|
412
|
+
body.status = String(opts.status).trim();
|
|
413
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
414
|
+
if (!merged.entityType || String(merged.entityType).trim() === "") {
|
|
415
|
+
throw new Error("entity-type is required (story | scenario)");
|
|
416
|
+
}
|
|
417
|
+
if (merged.ordinalId == null || !Number.isFinite(merged.ordinalId) || merged.ordinalId <= 0) {
|
|
418
|
+
throw new Error("ordinal-id is required (positive integer)");
|
|
419
|
+
}
|
|
420
|
+
if (!merged.status || String(merged.status).trim() === "") {
|
|
421
|
+
throw new Error("status is required (draft | ready | in progress | blocked | done | archived)");
|
|
422
|
+
}
|
|
423
|
+
const out = await runTool("update-plan-items-lifecycle-status", {
|
|
424
|
+
entityType: String(merged.entityType).trim(),
|
|
425
|
+
ordinalId: merged.ordinalId,
|
|
426
|
+
status: String(merged.status).trim(),
|
|
427
|
+
}, { postMcp });
|
|
428
|
+
console.log(out);
|
|
429
|
+
});
|
|
396
430
|
program
|
|
397
431
|
.command("update-test-scenario")
|
|
398
432
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "update-test-scenario").description)
|
|
@@ -904,43 +938,40 @@ export function buildCliProgram() {
|
|
|
904
938
|
.addOption(jsonInputOption())
|
|
905
939
|
.requiredOption("--workflow-id <id>", "Catalog workflow id")
|
|
906
940
|
.requiredOption("--workflow-execution-id <ulid>", "Stable ULID for the whole run")
|
|
907
|
-
.requiredOption("--action-type <type>", "CREATED|UPDATED|DELETED|ANALYZED|ACTION_COMPLETED|ACTION_FAILED")
|
|
941
|
+
.requiredOption("--action-type <type>", "CREATED|UPDATED|DELETED|ANALYZED|IMPLEMENTED|ACTION_COMPLETED|ACTION_FAILED")
|
|
908
942
|
.option("--policy-file <name>", "Policy filename")
|
|
909
943
|
.option("--policy-version <semver>", "Policy version from frontmatter")
|
|
910
944
|
.option("--git-sha <sha>", "Current HEAD sha")
|
|
911
945
|
.option("--actor-type <type>", "LOCAL_AGENT|CLOUD_AGENT (or local-agent|cloud-agent)")
|
|
912
946
|
.option("--user-id <id>", "Optional user id for traceability")
|
|
913
947
|
.option("--branch-name <name>", "Git branch")
|
|
914
|
-
.
|
|
948
|
+
.requiredOption("--entity-type <type>", "USER_STORY|SCENARIO|SMART_TEST|POLICY|ISSUE|TEST_EXECUTION|TEST_INVOCATION_BATCH|EXPLORATION|EVENT|WORKFLOW")
|
|
915
949
|
.option("--entity-identity <ordinal>", "Project-scoped ordinal id (mutually exclusive with --test-json)")
|
|
916
950
|
.option("--test-json <json>", "TestLocator JSON (folderPath/fileName/testSuite/testName)")
|
|
917
|
-
.option("--detail-json <json>", "Optional detail payload")
|
|
918
951
|
.action(async (opts) => {
|
|
919
952
|
const body = {
|
|
920
953
|
workflowId: String(opts.workflowId),
|
|
921
954
|
workflowExecutionId: String(opts.workflowExecutionId),
|
|
922
955
|
actionType: String(opts.actionType),
|
|
956
|
+
entityType: String(opts.entityType),
|
|
923
957
|
};
|
|
924
958
|
if (opts.policyFile)
|
|
925
959
|
body.policyFile = String(opts.policyFile);
|
|
926
960
|
if (opts.policyVersion)
|
|
927
961
|
body.policyVersion = String(opts.policyVersion);
|
|
928
|
-
|
|
929
|
-
|
|
962
|
+
const gitSha = resolveGitHeadSha(opts.gitSha ? String(opts.gitSha) : undefined);
|
|
963
|
+
if (gitSha)
|
|
964
|
+
body.gitSha = gitSha;
|
|
930
965
|
if (opts.actorType)
|
|
931
966
|
body.actorType = String(opts.actorType);
|
|
932
967
|
if (opts.userId)
|
|
933
968
|
body.userId = String(opts.userId);
|
|
934
969
|
if (opts.branchName)
|
|
935
970
|
body.branchName = String(opts.branchName);
|
|
936
|
-
if (opts.entityType)
|
|
937
|
-
body.entityType = String(opts.entityType);
|
|
938
971
|
if (opts.entityIdentity)
|
|
939
972
|
body.entityIdentity = String(opts.entityIdentity);
|
|
940
973
|
if (opts.testJson)
|
|
941
974
|
body.test = JSON.parse(String(opts.testJson));
|
|
942
|
-
if (opts.detailJson)
|
|
943
|
-
body.detailJson = String(opts.detailJson);
|
|
944
975
|
const merged = mergeBodies(body, opts.jsonInput);
|
|
945
976
|
console.log(await runTool("report-agent-action", merged, { postMcp }));
|
|
946
977
|
});
|
|
@@ -976,6 +1007,28 @@ export function buildCliProgram() {
|
|
|
976
1007
|
console.log(await runTool(kebab, merged, { postMcp }));
|
|
977
1008
|
});
|
|
978
1009
|
}
|
|
1010
|
+
program
|
|
1011
|
+
.command("upsert-policy")
|
|
1012
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "upsert-policy").description)
|
|
1013
|
+
.addOption(jsonInputOption())
|
|
1014
|
+
.option("--policy-file-name <name>", "e.g. connect-to-test-env.policy.md")
|
|
1015
|
+
.option("--content <markdown>", "full markdown including frontmatter")
|
|
1016
|
+
.option("--content-file <path>", "read markdown from file")
|
|
1017
|
+
.action(async (opts) => {
|
|
1018
|
+
let content = opts.content;
|
|
1019
|
+
if (opts.contentFile)
|
|
1020
|
+
content = await readFile(String(opts.contentFile), "utf8");
|
|
1021
|
+
const body = {};
|
|
1022
|
+
if (opts.policyFileName)
|
|
1023
|
+
body.policyFileName = String(opts.policyFileName);
|
|
1024
|
+
if (content)
|
|
1025
|
+
body.content = content;
|
|
1026
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
1027
|
+
if (!merged.policyFileName || !merged.content) {
|
|
1028
|
+
throw new Error("Provide --policy-file-name and --content or --content-file (or full body via --json-input)");
|
|
1029
|
+
}
|
|
1030
|
+
console.log(await runTool("upsert-policy", merged, { postMcp }));
|
|
1031
|
+
});
|
|
979
1032
|
program.on("--help", () => {
|
|
980
1033
|
/* default */
|
|
981
1034
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
/** Current git HEAD when running in a repo; used when agents omit git_sha on report-agent-action. */
|
|
3
|
+
export function resolveGitHeadSha(provided) {
|
|
4
|
+
const trimmed = provided?.trim();
|
|
5
|
+
if (trimmed) {
|
|
6
|
+
return trimmed;
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
return execSync("git rev-parse HEAD", { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
}
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -70,6 +70,11 @@ export declare const markPlanItemsImplementationDoneInput: z.ZodObject<{
|
|
|
70
70
|
scenarioOrdinalIds: z.ZodOptional<z.ZodArray<z.ZodCoercedNumber<unknown>>>;
|
|
71
71
|
userStoryOrdinalIds: z.ZodOptional<z.ZodArray<z.ZodCoercedNumber<unknown>>>;
|
|
72
72
|
}, z.core.$strip>;
|
|
73
|
+
export declare const updatePlanItemsLifecycleStatusInput: z.ZodObject<{
|
|
74
|
+
entityType: z.ZodString;
|
|
75
|
+
ordinalId: z.ZodCoercedNumber<unknown>;
|
|
76
|
+
status: z.ZodString;
|
|
77
|
+
}, z.core.$strip>;
|
|
73
78
|
export declare const getUserStoriesInput: z.ZodObject<{
|
|
74
79
|
userStoryOrdinalIds: z.ZodArray<z.ZodCoercedNumber<unknown>>;
|
|
75
80
|
}, z.core.$strip>;
|
|
@@ -1021,6 +1026,19 @@ export declare const agentActorTypeSchema: z.ZodEnum<{
|
|
|
1021
1026
|
"local-agent": "local-agent";
|
|
1022
1027
|
"cloud-agent": "cloud-agent";
|
|
1023
1028
|
}>;
|
|
1029
|
+
/** Closed vocabulary for report-agent-action entity_type (agent_workflow.proto AgentActionEntityType). */
|
|
1030
|
+
export declare const agentActionEntityTypeSchema: z.ZodEnum<{
|
|
1031
|
+
SMART_TEST: "SMART_TEST";
|
|
1032
|
+
SCENARIO: "SCENARIO";
|
|
1033
|
+
ISSUE: "ISSUE";
|
|
1034
|
+
TEST_EXECUTION: "TEST_EXECUTION";
|
|
1035
|
+
USER_STORY: "USER_STORY";
|
|
1036
|
+
POLICY: "POLICY";
|
|
1037
|
+
TEST_INVOCATION_BATCH: "TEST_INVOCATION_BATCH";
|
|
1038
|
+
EXPLORATION: "EXPLORATION";
|
|
1039
|
+
EVENT: "EVENT";
|
|
1040
|
+
WORKFLOW: "WORKFLOW";
|
|
1041
|
+
}>;
|
|
1024
1042
|
export declare const agentActionTypeSchema: z.ZodEnum<{
|
|
1025
1043
|
failed: "failed";
|
|
1026
1044
|
CREATED: "CREATED";
|
|
@@ -1029,6 +1047,7 @@ export declare const agentActionTypeSchema: z.ZodEnum<{
|
|
|
1029
1047
|
ANALYZED: "ANALYZED";
|
|
1030
1048
|
ACTION_COMPLETED: "ACTION_COMPLETED";
|
|
1031
1049
|
ACTION_FAILED: "ACTION_FAILED";
|
|
1050
|
+
IMPLEMENTED: "IMPLEMENTED";
|
|
1032
1051
|
created: "created";
|
|
1033
1052
|
updated: "updated";
|
|
1034
1053
|
deleted: "deleted";
|
|
@@ -1036,6 +1055,7 @@ export declare const agentActionTypeSchema: z.ZodEnum<{
|
|
|
1036
1055
|
completed: "completed";
|
|
1037
1056
|
action_completed: "action_completed";
|
|
1038
1057
|
action_failed: "action_failed";
|
|
1058
|
+
implemented: "implemented";
|
|
1039
1059
|
}>;
|
|
1040
1060
|
export declare const reportAgentActionInput: z.ZodObject<{
|
|
1041
1061
|
workflowId: z.ZodString;
|
|
@@ -1051,7 +1071,18 @@ export declare const reportAgentActionInput: z.ZodObject<{
|
|
|
1051
1071
|
}>>;
|
|
1052
1072
|
userId: z.ZodOptional<z.ZodString>;
|
|
1053
1073
|
branchName: z.ZodOptional<z.ZodString>;
|
|
1054
|
-
entityType: z.
|
|
1074
|
+
entityType: z.ZodEnum<{
|
|
1075
|
+
SMART_TEST: "SMART_TEST";
|
|
1076
|
+
SCENARIO: "SCENARIO";
|
|
1077
|
+
ISSUE: "ISSUE";
|
|
1078
|
+
TEST_EXECUTION: "TEST_EXECUTION";
|
|
1079
|
+
USER_STORY: "USER_STORY";
|
|
1080
|
+
POLICY: "POLICY";
|
|
1081
|
+
TEST_INVOCATION_BATCH: "TEST_INVOCATION_BATCH";
|
|
1082
|
+
EXPLORATION: "EXPLORATION";
|
|
1083
|
+
EVENT: "EVENT";
|
|
1084
|
+
WORKFLOW: "WORKFLOW";
|
|
1085
|
+
}>;
|
|
1055
1086
|
entityIdentity: z.ZodOptional<z.ZodString>;
|
|
1056
1087
|
test: z.ZodOptional<z.ZodObject<{
|
|
1057
1088
|
folderPath: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -1067,6 +1098,7 @@ export declare const reportAgentActionInput: z.ZodObject<{
|
|
|
1067
1098
|
ANALYZED: "ANALYZED";
|
|
1068
1099
|
ACTION_COMPLETED: "ACTION_COMPLETED";
|
|
1069
1100
|
ACTION_FAILED: "ACTION_FAILED";
|
|
1101
|
+
IMPLEMENTED: "IMPLEMENTED";
|
|
1070
1102
|
created: "created";
|
|
1071
1103
|
updated: "updated";
|
|
1072
1104
|
deleted: "deleted";
|
|
@@ -1074,8 +1106,8 @@ export declare const reportAgentActionInput: z.ZodObject<{
|
|
|
1074
1106
|
completed: "completed";
|
|
1075
1107
|
action_completed: "action_completed";
|
|
1076
1108
|
action_failed: "action_failed";
|
|
1109
|
+
implemented: "implemented";
|
|
1077
1110
|
}>;
|
|
1078
|
-
detailJson: z.ZodOptional<z.ZodString>;
|
|
1079
1111
|
}, z.core.$strip>;
|
|
1080
1112
|
export declare const getLastRunWorkflowDetailInput: z.ZodObject<{
|
|
1081
1113
|
workflowId: z.ZodString;
|
|
@@ -1097,4 +1129,8 @@ export declare const getPolicyInput: z.ZodObject<{
|
|
|
1097
1129
|
export declare const listPoliciesInput: z.ZodObject<{
|
|
1098
1130
|
workflowId: z.ZodOptional<z.ZodString>;
|
|
1099
1131
|
}, z.core.$strip>;
|
|
1132
|
+
export declare const upsertPolicyInput: z.ZodObject<{
|
|
1133
|
+
policyFileName: z.ZodString;
|
|
1134
|
+
content: z.ZodString;
|
|
1135
|
+
}, z.core.$strip>;
|
|
1100
1136
|
export declare const listWorkflowCatalogInput: z.ZodObject<{}, z.core.$strip>;
|
package/dist/core/schemas.js
CHANGED
|
@@ -69,6 +69,13 @@ export const markPlanItemsImplementationDoneInput = z.object({
|
|
|
69
69
|
scenarioOrdinalIds: z.array(z.coerce.number().int().positive()).optional(),
|
|
70
70
|
userStoryOrdinalIds: z.array(z.coerce.number().int().positive()).optional(),
|
|
71
71
|
});
|
|
72
|
+
export const updatePlanItemsLifecycleStatusInput = z.object({
|
|
73
|
+
/** story | scenario (also accepts user_story / USER_STORY / SCENARIO) */
|
|
74
|
+
entityType: z.string().min(1),
|
|
75
|
+
ordinalId: z.coerce.number().int().positive(),
|
|
76
|
+
/** draft | ready | in progress | blocked | done | archived */
|
|
77
|
+
status: z.string().min(1),
|
|
78
|
+
});
|
|
72
79
|
export const getUserStoriesInput = z
|
|
73
80
|
.object({
|
|
74
81
|
userStoryOrdinalIds: z.array(z.coerce.number().int().positive()).min(1),
|
|
@@ -501,6 +508,19 @@ export const reportRequirementQualityFindingsInput = z
|
|
|
501
508
|
}
|
|
502
509
|
});
|
|
503
510
|
export const agentActorTypeSchema = z.enum(["LOCAL_AGENT", "CLOUD_AGENT", "local-agent", "cloud-agent"]);
|
|
511
|
+
/** Closed vocabulary for report-agent-action entity_type (agent_workflow.proto AgentActionEntityType). */
|
|
512
|
+
export const agentActionEntityTypeSchema = z.enum([
|
|
513
|
+
"USER_STORY",
|
|
514
|
+
"SCENARIO",
|
|
515
|
+
"SMART_TEST",
|
|
516
|
+
"POLICY",
|
|
517
|
+
"ISSUE",
|
|
518
|
+
"TEST_EXECUTION",
|
|
519
|
+
"TEST_INVOCATION_BATCH",
|
|
520
|
+
"EXPLORATION",
|
|
521
|
+
"EVENT",
|
|
522
|
+
"WORKFLOW",
|
|
523
|
+
]);
|
|
504
524
|
export const agentActionTypeSchema = z.enum([
|
|
505
525
|
"CREATED",
|
|
506
526
|
"UPDATED",
|
|
@@ -508,6 +528,7 @@ export const agentActionTypeSchema = z.enum([
|
|
|
508
528
|
"ANALYZED",
|
|
509
529
|
"ACTION_COMPLETED",
|
|
510
530
|
"ACTION_FAILED",
|
|
531
|
+
"IMPLEMENTED",
|
|
511
532
|
"created",
|
|
512
533
|
"updated",
|
|
513
534
|
"deleted",
|
|
@@ -516,6 +537,7 @@ export const agentActionTypeSchema = z.enum([
|
|
|
516
537
|
"failed",
|
|
517
538
|
"action_completed",
|
|
518
539
|
"action_failed",
|
|
540
|
+
"implemented",
|
|
519
541
|
]);
|
|
520
542
|
export const reportAgentActionInput = z
|
|
521
543
|
.object({
|
|
@@ -527,20 +549,83 @@ export const reportAgentActionInput = z
|
|
|
527
549
|
actorType: agentActorTypeSchema.optional(),
|
|
528
550
|
userId: z.string().optional(),
|
|
529
551
|
branchName: z.string().optional(),
|
|
530
|
-
entityType:
|
|
552
|
+
entityType: agentActionEntityTypeSchema,
|
|
531
553
|
/** Project-scoped ordinal id (or explicitly provided execution/batch id). Mutually exclusive with `test`. */
|
|
532
554
|
entityIdentity: z.string().optional(),
|
|
533
555
|
/** SmartTest TestLocator. Mutually exclusive with `entityIdentity`. */
|
|
534
556
|
test: testLocatorSchema.optional(),
|
|
535
557
|
actionType: agentActionTypeSchema,
|
|
536
|
-
detailJson: z.string().optional(),
|
|
537
558
|
})
|
|
538
559
|
.superRefine((val, ctx) => {
|
|
539
|
-
|
|
560
|
+
const actionNorm = val.actionType.toString().toUpperCase().replace(/-/g, "_");
|
|
561
|
+
const isCompletion = actionNorm === "ACTION_COMPLETED" ||
|
|
562
|
+
actionNorm === "ACTION_FAILED" ||
|
|
563
|
+
actionNorm === "COMPLETED" ||
|
|
564
|
+
actionNorm === "FAILED";
|
|
565
|
+
if (isCompletion) {
|
|
566
|
+
if (val.entityType !== "WORKFLOW") {
|
|
567
|
+
ctx.addIssue({
|
|
568
|
+
code: z.ZodIssueCode.custom,
|
|
569
|
+
message: "ACTION_COMPLETED / ACTION_FAILED require entityType WORKFLOW",
|
|
570
|
+
path: ["entityType"],
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
const identity = (val.entityIdentity ?? "").trim();
|
|
574
|
+
if (identity === "" || identity !== val.workflowId.trim()) {
|
|
575
|
+
ctx.addIssue({
|
|
576
|
+
code: z.ZodIssueCode.custom,
|
|
577
|
+
message: "entityIdentity must equal workflowId for WORKFLOW completion",
|
|
578
|
+
path: ["entityIdentity"],
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
if (val.test) {
|
|
582
|
+
ctx.addIssue({
|
|
583
|
+
code: z.ZodIssueCode.custom,
|
|
584
|
+
message: "test must not be set for WORKFLOW completion",
|
|
585
|
+
path: ["test"],
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
if (val.entityType === "WORKFLOW") {
|
|
591
|
+
ctx.addIssue({
|
|
592
|
+
code: z.ZodIssueCode.custom,
|
|
593
|
+
message: "WORKFLOW entityType is only valid with ACTION_COMPLETED / ACTION_FAILED",
|
|
594
|
+
path: ["entityType"],
|
|
595
|
+
});
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
if (actionNorm === "IMPLEMENTED" &&
|
|
599
|
+
val.entityType !== "USER_STORY" &&
|
|
600
|
+
val.entityType !== "SCENARIO") {
|
|
540
601
|
ctx.addIssue({
|
|
541
602
|
code: z.ZodIssueCode.custom,
|
|
542
|
-
message: "
|
|
543
|
-
path: ["
|
|
603
|
+
message: "IMPLEMENTED is only valid for USER_STORY or SCENARIO",
|
|
604
|
+
path: ["entityType"],
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
if (val.entityType === "SMART_TEST") {
|
|
608
|
+
if (!val.test) {
|
|
609
|
+
ctx.addIssue({
|
|
610
|
+
code: z.ZodIssueCode.custom,
|
|
611
|
+
message: "SMART_TEST requires test (TestLocator)",
|
|
612
|
+
path: ["test"],
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
if (val.entityIdentity != null && val.entityIdentity.trim() !== "") {
|
|
616
|
+
ctx.addIssue({
|
|
617
|
+
code: z.ZodIssueCode.custom,
|
|
618
|
+
message: "SMART_TEST forbids entityIdentity; use test (TestLocator)",
|
|
619
|
+
path: ["entityIdentity"],
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
if (!(val.entityIdentity ?? "").trim()) {
|
|
625
|
+
ctx.addIssue({
|
|
626
|
+
code: z.ZodIssueCode.custom,
|
|
627
|
+
message: `entityIdentity is required for ${val.entityType}`,
|
|
628
|
+
path: ["entityIdentity"],
|
|
544
629
|
});
|
|
545
630
|
}
|
|
546
631
|
});
|
|
@@ -564,4 +649,8 @@ export const getPolicyInput = z.object({
|
|
|
564
649
|
export const listPoliciesInput = z.object({
|
|
565
650
|
workflowId: z.string().optional(),
|
|
566
651
|
});
|
|
652
|
+
export const upsertPolicyInput = z.object({
|
|
653
|
+
policyFileName: z.string().min(1),
|
|
654
|
+
content: z.string().min(1),
|
|
655
|
+
});
|
|
567
656
|
export const listWorkflowCatalogInput = z.object({});
|
package/dist/core/tools.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { normalizeScope } from "./normalize.js";
|
|
2
2
|
import { runProvisionEphemeralEnvironmentAndWait } from "./ephemeralWait.js";
|
|
3
3
|
import * as S from "./schemas.js";
|
|
4
|
+
import { resolveGitHeadSha } from "./gitSha.js";
|
|
4
5
|
function platformToProtoEnum(platform) {
|
|
5
6
|
switch (platform) {
|
|
6
7
|
case "ios":
|
|
@@ -344,6 +345,21 @@ export const TOOL_DEFINITIONS = [
|
|
|
344
345
|
return postMcp("/api/mcp/mark_plan_items_implementation_done", body);
|
|
345
346
|
},
|
|
346
347
|
},
|
|
348
|
+
{
|
|
349
|
+
kebab: "update-plan-items-lifecycle-status",
|
|
350
|
+
description: "Update lifecycle_fields.status for one user story or test scenario (DB only; does not rewrite plan markdown). " +
|
|
351
|
+
"entityType: story | scenario; ordinalId: numeric US-/TS- ordinal; status: draft | ready | in progress | blocked | done | archived. " +
|
|
352
|
+
"Used after /testchimp implement to set status to ready (unless policy overrides).",
|
|
353
|
+
inputSchema: S.updatePlanItemsLifecycleStatusInput,
|
|
354
|
+
execute: async (args, { postMcp }) => {
|
|
355
|
+
const a = args;
|
|
356
|
+
return postMcp("/api/mcp/update_plan_items_lifecycle_status", {
|
|
357
|
+
entityType: a.entityType,
|
|
358
|
+
ordinalId: a.ordinalId,
|
|
359
|
+
status: a.status,
|
|
360
|
+
});
|
|
361
|
+
},
|
|
362
|
+
},
|
|
347
363
|
{
|
|
348
364
|
kebab: "get-eaas-config",
|
|
349
365
|
description: "Return the project's BunnyShell (Environment-as-a-Service) settings. Secrets are never returned.",
|
|
@@ -779,10 +795,15 @@ export const TOOL_DEFINITIONS = [
|
|
|
779
795
|
{
|
|
780
796
|
kebab: "report-agent-action",
|
|
781
797
|
description: "Report a mutating agent action under a stable workflow-execution-id (ULID). " +
|
|
782
|
-
"First call for an id creates the workflow_executions row; later calls append
|
|
783
|
-
"
|
|
784
|
-
"
|
|
785
|
-
"
|
|
798
|
+
"First call for an id creates the workflow_executions row; later calls append Activity " +
|
|
799
|
+
"timeline rows (AGENT_WORKFLOW_ACTIVITY). " +
|
|
800
|
+
"Actions land on the entity's Activity timeline (plans, issues, SmartTest file). " +
|
|
801
|
+
"entityType: USER_STORY | SCENARIO | SMART_TEST | POLICY | ISSUE | TEST_EXECUTION | " +
|
|
802
|
+
"TEST_INVOCATION_BATCH | EXPLORATION | EVENT | WORKFLOW. " +
|
|
803
|
+
"actionType: CREATED | UPDATED | DELETED | ANALYZED | IMPLEMENTED | ACTION_COMPLETED | ACTION_FAILED. " +
|
|
804
|
+
"Identity: SMART_TEST uses `test` (TestLocator: folderPath/fileName/testSuite/testName); " +
|
|
805
|
+
"other artifact types use `entityIdentity` (ordinal / filename / opaque id). Do not use platform UUIDs. " +
|
|
806
|
+
"Completion (ACTION_COMPLETED / ACTION_FAILED): entityType WORKFLOW and entityIdentity = catalog workflow_id.",
|
|
786
807
|
inputSchema: S.reportAgentActionInput,
|
|
787
808
|
execute: async (args, { postMcp }) => {
|
|
788
809
|
const a = args;
|
|
@@ -801,29 +822,27 @@ export const TOOL_DEFINITIONS = [
|
|
|
801
822
|
workflowExecutionId: a.workflowExecutionId,
|
|
802
823
|
actionType,
|
|
803
824
|
actorType,
|
|
825
|
+
entityType: a.entityType,
|
|
804
826
|
};
|
|
805
827
|
if (a.policyFile)
|
|
806
828
|
body.policyFile = a.policyFile;
|
|
807
829
|
if (a.policyVersion)
|
|
808
830
|
body.policyVersion = a.policyVersion;
|
|
809
|
-
|
|
810
|
-
|
|
831
|
+
const gitSha = resolveGitHeadSha(a.gitSha);
|
|
832
|
+
if (gitSha)
|
|
833
|
+
body.gitSha = gitSha;
|
|
811
834
|
if (a.userId)
|
|
812
835
|
body.userId = a.userId;
|
|
813
836
|
else if (process.env.TESTCHIMP_USER_ID)
|
|
814
837
|
body.userId = process.env.TESTCHIMP_USER_ID;
|
|
815
838
|
if (a.branchName)
|
|
816
839
|
body.branchName = a.branchName;
|
|
817
|
-
if (a.entityType)
|
|
818
|
-
body.entityType = a.entityType;
|
|
819
840
|
if (a.test) {
|
|
820
841
|
body.test = a.test;
|
|
821
842
|
}
|
|
822
843
|
else if (a.entityIdentity) {
|
|
823
844
|
body.entityIdentity = a.entityIdentity;
|
|
824
845
|
}
|
|
825
|
-
if (a.detailJson)
|
|
826
|
-
body.detailJson = a.detailJson;
|
|
827
846
|
return postMcp("/api/mcp/report_agent_action", body);
|
|
828
847
|
},
|
|
829
848
|
},
|
|
@@ -873,7 +892,7 @@ export const TOOL_DEFINITIONS = [
|
|
|
873
892
|
},
|
|
874
893
|
{
|
|
875
894
|
kebab: "get-policy",
|
|
876
|
-
description: "Fetch a workflow policy file by name (e.g. run-qa.policy.md) from the platform POLICY_FILE store.",
|
|
895
|
+
description: "Fetch a workflow policy file by name (e.g. run-qa.policy.md) from the platform POLICY_FILE store. Filename is coerced to *.policy.md (same as upsert-policy).",
|
|
877
896
|
inputSchema: S.getPolicyInput,
|
|
878
897
|
execute: async (args, { postMcp }) => {
|
|
879
898
|
const a = args;
|
|
@@ -892,6 +911,18 @@ export const TOOL_DEFINITIONS = [
|
|
|
892
911
|
return postMcp("/api/mcp/list_policies", body);
|
|
893
912
|
},
|
|
894
913
|
},
|
|
914
|
+
{
|
|
915
|
+
kebab: "upsert-policy",
|
|
916
|
+
description: "Create or update a workflow policy file on the platform (plans/knowledge/policies/*.policy.md). policyFileName is coerced to *.policy.md (same as get-policy). Prefer after writing the file locally so the policy is available immediately (git sync also works later).",
|
|
917
|
+
inputSchema: S.upsertPolicyInput,
|
|
918
|
+
execute: async (args, { postMcp }) => {
|
|
919
|
+
const a = args;
|
|
920
|
+
return postMcp("/api/mcp/upsert_policy", {
|
|
921
|
+
policyFileName: a.policyFileName,
|
|
922
|
+
content: a.content,
|
|
923
|
+
});
|
|
924
|
+
},
|
|
925
|
+
},
|
|
895
926
|
{
|
|
896
927
|
kebab: "list-workflow-catalog",
|
|
897
928
|
description: "List supported TestChimp workflows with Active / Disabled / Missing Config status for the project.",
|