@testchimp/cli 0.1.19 → 0.1.20
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 +79 -0
- package/dist/core/schemas.d.ts +83 -0
- package/dist/core/schemas.js +65 -0
- package/dist/core/tools.js +122 -0
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -897,6 +897,85 @@ export function buildCliProgram() {
|
|
|
897
897
|
const out = await runTool("report-requirement-quality-findings", merged, { postMcp });
|
|
898
898
|
console.log(out);
|
|
899
899
|
});
|
|
900
|
+
// Workflow policy + traceability tools (US-181). Prefer --json-input for nested TestLocator.
|
|
901
|
+
program
|
|
902
|
+
.command("report-agent-action")
|
|
903
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "report-agent-action").description)
|
|
904
|
+
.addOption(jsonInputOption())
|
|
905
|
+
.requiredOption("--workflow-id <id>", "Catalog workflow id")
|
|
906
|
+
.requiredOption("--workflow-execution-id <ulid>", "Stable ULID for the whole run")
|
|
907
|
+
.requiredOption("--action-type <type>", "CREATED|UPDATED|DELETED|ANALYZED|ACTION_COMPLETED|ACTION_FAILED")
|
|
908
|
+
.option("--policy-file <name>", "Policy filename")
|
|
909
|
+
.option("--policy-version <semver>", "Policy version from frontmatter")
|
|
910
|
+
.option("--git-sha <sha>", "Current HEAD sha")
|
|
911
|
+
.option("--actor-type <type>", "LOCAL_AGENT|CLOUD_AGENT (or local-agent|cloud-agent)")
|
|
912
|
+
.option("--user-id <id>", "Optional user id for traceability")
|
|
913
|
+
.option("--branch-name <name>", "Git branch")
|
|
914
|
+
.option("--entity-type <type>", "test|story|scenario|issue|workflow|…")
|
|
915
|
+
.option("--entity-identity <ordinal>", "Project-scoped ordinal id (mutually exclusive with --test-json)")
|
|
916
|
+
.option("--test-json <json>", "TestLocator JSON (folderPath/fileName/testSuite/testName)")
|
|
917
|
+
.option("--detail-json <json>", "Optional detail payload")
|
|
918
|
+
.action(async (opts) => {
|
|
919
|
+
const body = {
|
|
920
|
+
workflowId: String(opts.workflowId),
|
|
921
|
+
workflowExecutionId: String(opts.workflowExecutionId),
|
|
922
|
+
actionType: String(opts.actionType),
|
|
923
|
+
};
|
|
924
|
+
if (opts.policyFile)
|
|
925
|
+
body.policyFile = String(opts.policyFile);
|
|
926
|
+
if (opts.policyVersion)
|
|
927
|
+
body.policyVersion = String(opts.policyVersion);
|
|
928
|
+
if (opts.gitSha)
|
|
929
|
+
body.gitSha = String(opts.gitSha);
|
|
930
|
+
if (opts.actorType)
|
|
931
|
+
body.actorType = String(opts.actorType);
|
|
932
|
+
if (opts.userId)
|
|
933
|
+
body.userId = String(opts.userId);
|
|
934
|
+
if (opts.branchName)
|
|
935
|
+
body.branchName = String(opts.branchName);
|
|
936
|
+
if (opts.entityType)
|
|
937
|
+
body.entityType = String(opts.entityType);
|
|
938
|
+
if (opts.entityIdentity)
|
|
939
|
+
body.entityIdentity = String(opts.entityIdentity);
|
|
940
|
+
if (opts.testJson)
|
|
941
|
+
body.test = JSON.parse(String(opts.testJson));
|
|
942
|
+
if (opts.detailJson)
|
|
943
|
+
body.detailJson = String(opts.detailJson);
|
|
944
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
945
|
+
console.log(await runTool("report-agent-action", merged, { postMcp }));
|
|
946
|
+
});
|
|
947
|
+
program
|
|
948
|
+
.command("get-last-run-workflow-detail")
|
|
949
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-last-run-workflow-detail").description)
|
|
950
|
+
.addOption(jsonInputOption())
|
|
951
|
+
.requiredOption("--workflow-id <id>", "Catalog workflow id")
|
|
952
|
+
.option("--branch-name <name>", "Optional branch filter (omit for any branch)")
|
|
953
|
+
.option("--user-id <id>", "Optional per-user last run")
|
|
954
|
+
.action(async (opts) => {
|
|
955
|
+
const body = { workflowId: String(opts.workflowId) };
|
|
956
|
+
if (opts.branchName)
|
|
957
|
+
body.branchName = String(opts.branchName);
|
|
958
|
+
if (opts.userId)
|
|
959
|
+
body.userId = String(opts.userId);
|
|
960
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
961
|
+
console.log(await runTool("get-last-run-workflow-detail", merged, { postMcp }));
|
|
962
|
+
});
|
|
963
|
+
for (const kebab of [
|
|
964
|
+
"list-workflow-executions",
|
|
965
|
+
"get-workflow-execution",
|
|
966
|
+
"get-policy",
|
|
967
|
+
"list-policies",
|
|
968
|
+
"list-workflow-catalog",
|
|
969
|
+
]) {
|
|
970
|
+
program
|
|
971
|
+
.command(kebab)
|
|
972
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === kebab).description)
|
|
973
|
+
.addOption(jsonInputOption())
|
|
974
|
+
.action(async (opts) => {
|
|
975
|
+
const merged = mergeBodies({}, opts.jsonInput);
|
|
976
|
+
console.log(await runTool(kebab, merged, { postMcp }));
|
|
977
|
+
});
|
|
978
|
+
}
|
|
900
979
|
program.on("--help", () => {
|
|
901
980
|
/* default */
|
|
902
981
|
});
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -1015,3 +1015,86 @@ export declare const reportRequirementQualityFindingsInput: z.ZodObject<{
|
|
|
1015
1015
|
subjectEntityId: z.ZodOptional<z.ZodString>;
|
|
1016
1016
|
ordinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1017
1017
|
}, z.core.$strip>;
|
|
1018
|
+
export declare const agentActorTypeSchema: z.ZodEnum<{
|
|
1019
|
+
LOCAL_AGENT: "LOCAL_AGENT";
|
|
1020
|
+
CLOUD_AGENT: "CLOUD_AGENT";
|
|
1021
|
+
"local-agent": "local-agent";
|
|
1022
|
+
"cloud-agent": "cloud-agent";
|
|
1023
|
+
}>;
|
|
1024
|
+
export declare const agentActionTypeSchema: z.ZodEnum<{
|
|
1025
|
+
failed: "failed";
|
|
1026
|
+
CREATED: "CREATED";
|
|
1027
|
+
UPDATED: "UPDATED";
|
|
1028
|
+
DELETED: "DELETED";
|
|
1029
|
+
ANALYZED: "ANALYZED";
|
|
1030
|
+
ACTION_COMPLETED: "ACTION_COMPLETED";
|
|
1031
|
+
ACTION_FAILED: "ACTION_FAILED";
|
|
1032
|
+
created: "created";
|
|
1033
|
+
updated: "updated";
|
|
1034
|
+
deleted: "deleted";
|
|
1035
|
+
analyzed: "analyzed";
|
|
1036
|
+
completed: "completed";
|
|
1037
|
+
action_completed: "action_completed";
|
|
1038
|
+
action_failed: "action_failed";
|
|
1039
|
+
}>;
|
|
1040
|
+
export declare const reportAgentActionInput: z.ZodObject<{
|
|
1041
|
+
workflowId: z.ZodString;
|
|
1042
|
+
workflowExecutionId: z.ZodString;
|
|
1043
|
+
policyFile: z.ZodOptional<z.ZodString>;
|
|
1044
|
+
policyVersion: z.ZodOptional<z.ZodString>;
|
|
1045
|
+
gitSha: z.ZodOptional<z.ZodString>;
|
|
1046
|
+
actorType: z.ZodOptional<z.ZodEnum<{
|
|
1047
|
+
LOCAL_AGENT: "LOCAL_AGENT";
|
|
1048
|
+
CLOUD_AGENT: "CLOUD_AGENT";
|
|
1049
|
+
"local-agent": "local-agent";
|
|
1050
|
+
"cloud-agent": "cloud-agent";
|
|
1051
|
+
}>>;
|
|
1052
|
+
userId: z.ZodOptional<z.ZodString>;
|
|
1053
|
+
branchName: z.ZodOptional<z.ZodString>;
|
|
1054
|
+
entityType: z.ZodOptional<z.ZodString>;
|
|
1055
|
+
entityIdentity: z.ZodOptional<z.ZodString>;
|
|
1056
|
+
test: z.ZodOptional<z.ZodObject<{
|
|
1057
|
+
folderPath: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1058
|
+
fileName: z.ZodString;
|
|
1059
|
+
testSuite: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1060
|
+
testName: z.ZodString;
|
|
1061
|
+
}, z.core.$strip>>;
|
|
1062
|
+
actionType: z.ZodEnum<{
|
|
1063
|
+
failed: "failed";
|
|
1064
|
+
CREATED: "CREATED";
|
|
1065
|
+
UPDATED: "UPDATED";
|
|
1066
|
+
DELETED: "DELETED";
|
|
1067
|
+
ANALYZED: "ANALYZED";
|
|
1068
|
+
ACTION_COMPLETED: "ACTION_COMPLETED";
|
|
1069
|
+
ACTION_FAILED: "ACTION_FAILED";
|
|
1070
|
+
created: "created";
|
|
1071
|
+
updated: "updated";
|
|
1072
|
+
deleted: "deleted";
|
|
1073
|
+
analyzed: "analyzed";
|
|
1074
|
+
completed: "completed";
|
|
1075
|
+
action_completed: "action_completed";
|
|
1076
|
+
action_failed: "action_failed";
|
|
1077
|
+
}>;
|
|
1078
|
+
detailJson: z.ZodOptional<z.ZodString>;
|
|
1079
|
+
}, z.core.$strip>;
|
|
1080
|
+
export declare const getLastRunWorkflowDetailInput: z.ZodObject<{
|
|
1081
|
+
workflowId: z.ZodString;
|
|
1082
|
+
branchName: z.ZodOptional<z.ZodString>;
|
|
1083
|
+
userId: z.ZodOptional<z.ZodString>;
|
|
1084
|
+
}, z.core.$strip>;
|
|
1085
|
+
export declare const listWorkflowExecutionsInput: z.ZodObject<{
|
|
1086
|
+
workflowId: z.ZodOptional<z.ZodString>;
|
|
1087
|
+
limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1088
|
+
offset: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1089
|
+
}, z.core.$strip>;
|
|
1090
|
+
export declare const getWorkflowExecutionInput: z.ZodObject<{
|
|
1091
|
+
workflowExecutionId: z.ZodString;
|
|
1092
|
+
includeActions: z.ZodOptional<z.ZodBoolean>;
|
|
1093
|
+
}, z.core.$strip>;
|
|
1094
|
+
export declare const getPolicyInput: z.ZodObject<{
|
|
1095
|
+
policyFileName: z.ZodString;
|
|
1096
|
+
}, z.core.$strip>;
|
|
1097
|
+
export declare const listPoliciesInput: z.ZodObject<{
|
|
1098
|
+
workflowId: z.ZodOptional<z.ZodString>;
|
|
1099
|
+
}, z.core.$strip>;
|
|
1100
|
+
export declare const listWorkflowCatalogInput: z.ZodObject<{}, z.core.$strip>;
|
package/dist/core/schemas.js
CHANGED
|
@@ -500,3 +500,68 @@ export const reportRequirementQualityFindingsInput = z
|
|
|
500
500
|
});
|
|
501
501
|
}
|
|
502
502
|
});
|
|
503
|
+
export const agentActorTypeSchema = z.enum(["LOCAL_AGENT", "CLOUD_AGENT", "local-agent", "cloud-agent"]);
|
|
504
|
+
export const agentActionTypeSchema = z.enum([
|
|
505
|
+
"CREATED",
|
|
506
|
+
"UPDATED",
|
|
507
|
+
"DELETED",
|
|
508
|
+
"ANALYZED",
|
|
509
|
+
"ACTION_COMPLETED",
|
|
510
|
+
"ACTION_FAILED",
|
|
511
|
+
"created",
|
|
512
|
+
"updated",
|
|
513
|
+
"deleted",
|
|
514
|
+
"analyzed",
|
|
515
|
+
"completed",
|
|
516
|
+
"failed",
|
|
517
|
+
"action_completed",
|
|
518
|
+
"action_failed",
|
|
519
|
+
]);
|
|
520
|
+
export const reportAgentActionInput = z
|
|
521
|
+
.object({
|
|
522
|
+
workflowId: z.string().min(1),
|
|
523
|
+
workflowExecutionId: z.string().min(1),
|
|
524
|
+
policyFile: z.string().optional(),
|
|
525
|
+
policyVersion: z.string().optional(),
|
|
526
|
+
gitSha: z.string().optional(),
|
|
527
|
+
actorType: agentActorTypeSchema.optional(),
|
|
528
|
+
userId: z.string().optional(),
|
|
529
|
+
branchName: z.string().optional(),
|
|
530
|
+
entityType: z.string().optional(),
|
|
531
|
+
/** Project-scoped ordinal id (or explicitly provided execution/batch id). Mutually exclusive with `test`. */
|
|
532
|
+
entityIdentity: z.string().optional(),
|
|
533
|
+
/** SmartTest TestLocator. Mutually exclusive with `entityIdentity`. */
|
|
534
|
+
test: testLocatorSchema.optional(),
|
|
535
|
+
actionType: agentActionTypeSchema,
|
|
536
|
+
detailJson: z.string().optional(),
|
|
537
|
+
})
|
|
538
|
+
.superRefine((val, ctx) => {
|
|
539
|
+
if (val.test && val.entityIdentity) {
|
|
540
|
+
ctx.addIssue({
|
|
541
|
+
code: z.ZodIssueCode.custom,
|
|
542
|
+
message: "Provide either test (TestLocator) or entityIdentity (ordinal), not both",
|
|
543
|
+
path: ["test"],
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
export const getLastRunWorkflowDetailInput = z.object({
|
|
548
|
+
workflowId: z.string().min(1),
|
|
549
|
+
branchName: z.string().optional(),
|
|
550
|
+
userId: z.string().optional(),
|
|
551
|
+
});
|
|
552
|
+
export const listWorkflowExecutionsInput = z.object({
|
|
553
|
+
workflowId: z.string().optional(),
|
|
554
|
+
limit: z.coerce.number().int().positive().max(200).optional(),
|
|
555
|
+
offset: z.coerce.number().int().nonnegative().optional(),
|
|
556
|
+
});
|
|
557
|
+
export const getWorkflowExecutionInput = z.object({
|
|
558
|
+
workflowExecutionId: z.string().min(1),
|
|
559
|
+
includeActions: z.boolean().optional(),
|
|
560
|
+
});
|
|
561
|
+
export const getPolicyInput = z.object({
|
|
562
|
+
policyFileName: z.string().min(1),
|
|
563
|
+
});
|
|
564
|
+
export const listPoliciesInput = z.object({
|
|
565
|
+
workflowId: z.string().optional(),
|
|
566
|
+
});
|
|
567
|
+
export const listWorkflowCatalogInput = z.object({});
|
package/dist/core/tools.js
CHANGED
|
@@ -776,6 +776,128 @@ export const TOOL_DEFINITIONS = [
|
|
|
776
776
|
return postMcp("/api/mcp/report_requirement_quality_findings", { report });
|
|
777
777
|
},
|
|
778
778
|
},
|
|
779
|
+
{
|
|
780
|
+
kebab: "report-agent-action",
|
|
781
|
+
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 agent_actions. " +
|
|
783
|
+
"Identity: pass `test` (TestLocator: folderPath/fileName/testSuite/testName) for SmartTests, " +
|
|
784
|
+
"or `entityIdentity` as a project-scoped ordinal id for stories/scenarios/issues " +
|
|
785
|
+
"(or an execution/batch id only when the prompt explicitly provided it). Do not use platform UUIDs.",
|
|
786
|
+
inputSchema: S.reportAgentActionInput,
|
|
787
|
+
execute: async (args, { postMcp }) => {
|
|
788
|
+
const a = args;
|
|
789
|
+
const actorRaw = (a.actorType ?? "local-agent").toString();
|
|
790
|
+
const actorType = actorRaw.toUpperCase().replace(/-/g, "_") === "CLOUD_AGENT" ? "CLOUD_AGENT" : "LOCAL_AGENT";
|
|
791
|
+
const actionNorm = a.actionType.toString().toUpperCase().replace(/-/g, "_");
|
|
792
|
+
let actionType = actionNorm;
|
|
793
|
+
if (actionNorm === "COMPLETED" || actionNorm === "ACTION_COMPLETED") {
|
|
794
|
+
actionType = "ACTION_COMPLETED";
|
|
795
|
+
}
|
|
796
|
+
else if (actionNorm === "FAILED" || actionNorm === "ACTION_FAILED") {
|
|
797
|
+
actionType = "ACTION_FAILED";
|
|
798
|
+
}
|
|
799
|
+
const body = {
|
|
800
|
+
workflowId: a.workflowId,
|
|
801
|
+
workflowExecutionId: a.workflowExecutionId,
|
|
802
|
+
actionType,
|
|
803
|
+
actorType,
|
|
804
|
+
};
|
|
805
|
+
if (a.policyFile)
|
|
806
|
+
body.policyFile = a.policyFile;
|
|
807
|
+
if (a.policyVersion)
|
|
808
|
+
body.policyVersion = a.policyVersion;
|
|
809
|
+
if (a.gitSha)
|
|
810
|
+
body.gitSha = a.gitSha;
|
|
811
|
+
if (a.userId)
|
|
812
|
+
body.userId = a.userId;
|
|
813
|
+
else if (process.env.TESTCHIMP_USER_ID)
|
|
814
|
+
body.userId = process.env.TESTCHIMP_USER_ID;
|
|
815
|
+
if (a.branchName)
|
|
816
|
+
body.branchName = a.branchName;
|
|
817
|
+
if (a.entityType)
|
|
818
|
+
body.entityType = a.entityType;
|
|
819
|
+
if (a.test) {
|
|
820
|
+
body.test = a.test;
|
|
821
|
+
}
|
|
822
|
+
else if (a.entityIdentity) {
|
|
823
|
+
body.entityIdentity = a.entityIdentity;
|
|
824
|
+
}
|
|
825
|
+
if (a.detailJson)
|
|
826
|
+
body.detailJson = a.detailJson;
|
|
827
|
+
return postMcp("/api/mcp/report_agent_action", body);
|
|
828
|
+
},
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
kebab: "get-last-run-workflow-detail",
|
|
832
|
+
description: "Fetch the last workflow execution for a workflow-id on a branch (optional userId for per-user last run). " +
|
|
833
|
+
"Used for since-last-run scoping.",
|
|
834
|
+
inputSchema: S.getLastRunWorkflowDetailInput,
|
|
835
|
+
execute: async (args, { postMcp }) => {
|
|
836
|
+
const a = args;
|
|
837
|
+
const body = {
|
|
838
|
+
workflowId: a.workflowId,
|
|
839
|
+
branchName: a.branchName,
|
|
840
|
+
};
|
|
841
|
+
if (a.userId)
|
|
842
|
+
body.userId = a.userId;
|
|
843
|
+
return postMcp("/api/mcp/get_last_run_workflow_detail", body);
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
kebab: "list-workflow-executions",
|
|
848
|
+
description: "List recent workflow executions for the project, optionally filtered by workflowId.",
|
|
849
|
+
inputSchema: S.listWorkflowExecutionsInput,
|
|
850
|
+
execute: async (args, { postMcp }) => {
|
|
851
|
+
const a = args;
|
|
852
|
+
const body = {};
|
|
853
|
+
if (a.workflowId)
|
|
854
|
+
body.workflowId = a.workflowId;
|
|
855
|
+
if (a.limit != null)
|
|
856
|
+
body.limit = a.limit;
|
|
857
|
+
if (a.offset != null)
|
|
858
|
+
body.offset = a.offset;
|
|
859
|
+
return postMcp("/api/mcp/list_workflow_executions", body);
|
|
860
|
+
},
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
kebab: "get-workflow-execution",
|
|
864
|
+
description: "Get a workflow execution by id; pass includeActions=true for the action timeline.",
|
|
865
|
+
inputSchema: S.getWorkflowExecutionInput,
|
|
866
|
+
execute: async (args, { postMcp }) => {
|
|
867
|
+
const a = args;
|
|
868
|
+
return postMcp("/api/mcp/get_workflow_execution", {
|
|
869
|
+
workflowExecutionId: a.workflowExecutionId,
|
|
870
|
+
includeActions: a.includeActions ?? true,
|
|
871
|
+
});
|
|
872
|
+
},
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
kebab: "get-policy",
|
|
876
|
+
description: "Fetch a workflow policy file by name (e.g. run-qa.policy.md) from the platform POLICY_FILE store.",
|
|
877
|
+
inputSchema: S.getPolicyInput,
|
|
878
|
+
execute: async (args, { postMcp }) => {
|
|
879
|
+
const a = args;
|
|
880
|
+
return postMcp("/api/mcp/get_policy", { policyFileName: a.policyFileName });
|
|
881
|
+
},
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
kebab: "list-policies",
|
|
885
|
+
description: "List policy files for an optional workflow-id. Marks isDefault when filename is <workflow-id>.policy.md.",
|
|
886
|
+
inputSchema: S.listPoliciesInput,
|
|
887
|
+
execute: async (args, { postMcp }) => {
|
|
888
|
+
const a = args;
|
|
889
|
+
const body = {};
|
|
890
|
+
if (a.workflowId)
|
|
891
|
+
body.workflowId = a.workflowId;
|
|
892
|
+
return postMcp("/api/mcp/list_policies", body);
|
|
893
|
+
},
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
kebab: "list-workflow-catalog",
|
|
897
|
+
description: "List supported TestChimp workflows with Active / Disabled / Missing Config status for the project.",
|
|
898
|
+
inputSchema: S.listWorkflowCatalogInput,
|
|
899
|
+
execute: async (_args, { postMcp }) => postMcp("/api/mcp/list_workflow_catalog", {}),
|
|
900
|
+
},
|
|
779
901
|
];
|
|
780
902
|
const TOOL_BY_KEBAB = new Map(TOOL_DEFINITIONS.map((t) => [t.kebab, t]));
|
|
781
903
|
export function getToolDefinition(kebab) {
|