@testchimp/cli 0.1.17 → 0.1.19
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 +64 -0
- package/dist/core/schemas.d.ts +307 -0
- package/dist/core/schemas.js +127 -0
- package/dist/core/tools.js +98 -0
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -673,6 +673,22 @@ export function buildCliProgram() {
|
|
|
673
673
|
const out = await runTool("get-release", { version: String(merged.version).trim() }, { postMcp });
|
|
674
674
|
console.log(out);
|
|
675
675
|
});
|
|
676
|
+
program
|
|
677
|
+
.command("get-release-details")
|
|
678
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-release-details").description)
|
|
679
|
+
.addOption(jsonInputOption())
|
|
680
|
+
.option("--version <version>", "Release version / label (McpGetReleaseDetailsRequest.version)")
|
|
681
|
+
.action(async (opts) => {
|
|
682
|
+
const body = {};
|
|
683
|
+
if (opts.version)
|
|
684
|
+
body.version = String(opts.version);
|
|
685
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
686
|
+
if (!merged.version || String(merged.version).trim() === "") {
|
|
687
|
+
throw new Error("version is required (--version or --json-input {\"version\":\"...\"})");
|
|
688
|
+
}
|
|
689
|
+
const out = await runTool("get-release-details", { version: String(merged.version).trim() }, { postMcp });
|
|
690
|
+
console.log(out);
|
|
691
|
+
});
|
|
676
692
|
program
|
|
677
693
|
.command("get-security-scan-config")
|
|
678
694
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-security-scan-config").description)
|
|
@@ -833,6 +849,54 @@ export function buildCliProgram() {
|
|
|
833
849
|
const out = await runTool("mark-semantic-tests-distinct", merged, { postMcp });
|
|
834
850
|
console.log(out);
|
|
835
851
|
});
|
|
852
|
+
program
|
|
853
|
+
.command("get-requirement-quality-report")
|
|
854
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-requirement-quality-report").description)
|
|
855
|
+
.addOption(jsonInputOption())
|
|
856
|
+
.option("--subject-type <STORY|SCENARIO>", "STORY for US-<n>, SCENARIO for TS-<n>")
|
|
857
|
+
.option("--subject-entity-id <id>", "Platform subject entity id")
|
|
858
|
+
.option("--ordinal-id <n>", "Numeric part of US-<n> or TS-<n>")
|
|
859
|
+
.action(async (opts) => {
|
|
860
|
+
const body = {};
|
|
861
|
+
if (opts.subjectType)
|
|
862
|
+
body.subjectType = String(opts.subjectType).trim();
|
|
863
|
+
if (opts.subjectEntityId)
|
|
864
|
+
body.subjectEntityId = String(opts.subjectEntityId).trim();
|
|
865
|
+
if (opts.ordinalId != null)
|
|
866
|
+
body.ordinalId = Number(opts.ordinalId);
|
|
867
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
868
|
+
if (!merged.subjectType || String(merged.subjectType).trim() === "") {
|
|
869
|
+
throw new Error("subjectType is required (STORY | SCENARIO)");
|
|
870
|
+
}
|
|
871
|
+
const out = await runTool("get-requirement-quality-report", {
|
|
872
|
+
subjectType: String(merged.subjectType).trim(),
|
|
873
|
+
...(merged.subjectEntityId ? { subjectEntityId: String(merged.subjectEntityId).trim() } : {}),
|
|
874
|
+
...(merged.ordinalId != null ? { ordinalId: Number(merged.ordinalId) } : {}),
|
|
875
|
+
}, { postMcp });
|
|
876
|
+
console.log(out);
|
|
877
|
+
});
|
|
878
|
+
program
|
|
879
|
+
.command("report-requirement-quality-findings")
|
|
880
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "report-requirement-quality-findings").description)
|
|
881
|
+
.addOption(jsonInputOption())
|
|
882
|
+
.option("--report-file <path>", "Path to RequirementQualityReport JSON (camelCase)")
|
|
883
|
+
.option("--subject-type <STORY|SCENARIO>", "Merge into report.subject when resolving entity id")
|
|
884
|
+
.option("--subject-entity-id <id>", "Platform subject entity id (story DB id or scenario UUID)")
|
|
885
|
+
.option("--ordinal-id <n>", "US-<n> or TS-<n> numeric id; resolves subjectEntityId via get-report")
|
|
886
|
+
.action(async (opts) => {
|
|
887
|
+
const body = {};
|
|
888
|
+
if (opts.reportFile)
|
|
889
|
+
body.reportFile = String(opts.reportFile);
|
|
890
|
+
if (opts.subjectType)
|
|
891
|
+
body.subjectType = String(opts.subjectType).trim();
|
|
892
|
+
if (opts.subjectEntityId)
|
|
893
|
+
body.subjectEntityId = String(opts.subjectEntityId).trim();
|
|
894
|
+
if (opts.ordinalId != null)
|
|
895
|
+
body.ordinalId = Number(opts.ordinalId);
|
|
896
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
897
|
+
const out = await runTool("report-requirement-quality-findings", merged, { postMcp });
|
|
898
|
+
console.log(out);
|
|
899
|
+
});
|
|
836
900
|
program.on("--help", () => {
|
|
837
901
|
/* default */
|
|
838
902
|
});
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -647,6 +647,9 @@ export declare const listScreenStatesInput: z.ZodObject<{
|
|
|
647
647
|
export declare const getReleaseInput: z.ZodObject<{
|
|
648
648
|
version: z.ZodString;
|
|
649
649
|
}, z.core.$strip>;
|
|
650
|
+
export declare const getReleaseDetailsInput: z.ZodObject<{
|
|
651
|
+
version: z.ZodString;
|
|
652
|
+
}, z.core.$strip>;
|
|
650
653
|
export declare const getSecurityScanConfigInput: z.ZodObject<{
|
|
651
654
|
id: z.ZodString;
|
|
652
655
|
}, z.core.$strip>;
|
|
@@ -708,3 +711,307 @@ export declare const markSemanticTestsDistinctInput: z.ZodObject<{
|
|
|
708
711
|
testName: z.ZodString;
|
|
709
712
|
}, z.core.$strip>;
|
|
710
713
|
}, z.core.$strip>;
|
|
714
|
+
/** RequirementSubjectType — proto enum names (JsonFormat camelCase on wire). */
|
|
715
|
+
export declare const requirementSubjectTypeSchema: z.ZodEnum<{
|
|
716
|
+
STORY: "STORY";
|
|
717
|
+
SCENARIO: "SCENARIO";
|
|
718
|
+
}>;
|
|
719
|
+
/** RequirementFindingSeverity — proto enum names. */
|
|
720
|
+
export declare const requirementFindingSeveritySchema: z.ZodEnum<{
|
|
721
|
+
CRITICAL: "CRITICAL";
|
|
722
|
+
MAJOR: "MAJOR";
|
|
723
|
+
MINOR: "MINOR";
|
|
724
|
+
}>;
|
|
725
|
+
/** RequirementFindingUserState — proto enum names. */
|
|
726
|
+
export declare const requirementFindingUserStateSchema: z.ZodEnum<{
|
|
727
|
+
ACTIVE: "ACTIVE";
|
|
728
|
+
IGNORED: "IGNORED";
|
|
729
|
+
APPLIED: "APPLIED";
|
|
730
|
+
}>;
|
|
731
|
+
/** RequirementQualityReportSource — proto enum names. */
|
|
732
|
+
export declare const requirementQualityReportSourceSchema: z.ZodEnum<{
|
|
733
|
+
CLOUD: "CLOUD";
|
|
734
|
+
LOCAL_AGENT: "LOCAL_AGENT";
|
|
735
|
+
}>;
|
|
736
|
+
/** SuggestedFixKind — proto enum names. */
|
|
737
|
+
export declare const suggestedFixKindSchema: z.ZodEnum<{
|
|
738
|
+
OTHER: "OTHER";
|
|
739
|
+
REWORD_EXCERPT: "REWORD_EXCERPT";
|
|
740
|
+
REWRITE_SECTION: "REWRITE_SECTION";
|
|
741
|
+
ADD_CONTENT: "ADD_CONTENT";
|
|
742
|
+
CREATE_SCENARIO: "CREATE_SCENARIO";
|
|
743
|
+
CREATE_STORY: "CREATE_STORY";
|
|
744
|
+
DELETE_SCENARIO: "DELETE_SCENARIO";
|
|
745
|
+
DELETE_STORY: "DELETE_STORY";
|
|
746
|
+
LINK_OR_UNLINK: "LINK_OR_UNLINK";
|
|
747
|
+
}>;
|
|
748
|
+
/** TextReplacement (requirement_quality.proto) — camelCase wire shape. */
|
|
749
|
+
export declare const textReplacementSchema: z.ZodObject<{
|
|
750
|
+
originalExcerpt: z.ZodOptional<z.ZodString>;
|
|
751
|
+
suggestedText: z.ZodOptional<z.ZodString>;
|
|
752
|
+
contextBefore: z.ZodOptional<z.ZodString>;
|
|
753
|
+
contextAfter: z.ZodOptional<z.ZodString>;
|
|
754
|
+
}, z.core.$strip>;
|
|
755
|
+
/** SuggestedFix (requirement_quality.proto). isDestructive is derived server-side from kind. */
|
|
756
|
+
export declare const suggestedFixSchema: z.ZodObject<{
|
|
757
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
758
|
+
OTHER: "OTHER";
|
|
759
|
+
REWORD_EXCERPT: "REWORD_EXCERPT";
|
|
760
|
+
REWRITE_SECTION: "REWRITE_SECTION";
|
|
761
|
+
ADD_CONTENT: "ADD_CONTENT";
|
|
762
|
+
CREATE_SCENARIO: "CREATE_SCENARIO";
|
|
763
|
+
CREATE_STORY: "CREATE_STORY";
|
|
764
|
+
DELETE_SCENARIO: "DELETE_SCENARIO";
|
|
765
|
+
DELETE_STORY: "DELETE_STORY";
|
|
766
|
+
LINK_OR_UNLINK: "LINK_OR_UNLINK";
|
|
767
|
+
}>>;
|
|
768
|
+
isDestructive: z.ZodOptional<z.ZodBoolean>;
|
|
769
|
+
targetEntityType: z.ZodOptional<z.ZodString>;
|
|
770
|
+
targetOrdinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
771
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
772
|
+
agentPrompt: z.ZodOptional<z.ZodString>;
|
|
773
|
+
replacements: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
774
|
+
originalExcerpt: z.ZodOptional<z.ZodString>;
|
|
775
|
+
suggestedText: z.ZodOptional<z.ZodString>;
|
|
776
|
+
contextBefore: z.ZodOptional<z.ZodString>;
|
|
777
|
+
contextAfter: z.ZodOptional<z.ZodString>;
|
|
778
|
+
}, z.core.$strip>>>;
|
|
779
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
780
|
+
}, z.core.$strip>;
|
|
781
|
+
/** RequirementQualityFinding (requirement_quality.proto). */
|
|
782
|
+
export declare const requirementQualityFindingSchema: z.ZodObject<{
|
|
783
|
+
id: z.ZodOptional<z.ZodString>;
|
|
784
|
+
fingerprint: z.ZodOptional<z.ZodString>;
|
|
785
|
+
analyst: z.ZodOptional<z.ZodString>;
|
|
786
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
787
|
+
CRITICAL: "CRITICAL";
|
|
788
|
+
MAJOR: "MAJOR";
|
|
789
|
+
MINOR: "MINOR";
|
|
790
|
+
}>>;
|
|
791
|
+
confidence: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
792
|
+
title: z.ZodOptional<z.ZodString>;
|
|
793
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
794
|
+
suggestedFix: z.ZodOptional<z.ZodObject<{
|
|
795
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
796
|
+
OTHER: "OTHER";
|
|
797
|
+
REWORD_EXCERPT: "REWORD_EXCERPT";
|
|
798
|
+
REWRITE_SECTION: "REWRITE_SECTION";
|
|
799
|
+
ADD_CONTENT: "ADD_CONTENT";
|
|
800
|
+
CREATE_SCENARIO: "CREATE_SCENARIO";
|
|
801
|
+
CREATE_STORY: "CREATE_STORY";
|
|
802
|
+
DELETE_SCENARIO: "DELETE_SCENARIO";
|
|
803
|
+
DELETE_STORY: "DELETE_STORY";
|
|
804
|
+
LINK_OR_UNLINK: "LINK_OR_UNLINK";
|
|
805
|
+
}>>;
|
|
806
|
+
isDestructive: z.ZodOptional<z.ZodBoolean>;
|
|
807
|
+
targetEntityType: z.ZodOptional<z.ZodString>;
|
|
808
|
+
targetOrdinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
809
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
810
|
+
agentPrompt: z.ZodOptional<z.ZodString>;
|
|
811
|
+
replacements: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
812
|
+
originalExcerpt: z.ZodOptional<z.ZodString>;
|
|
813
|
+
suggestedText: z.ZodOptional<z.ZodString>;
|
|
814
|
+
contextBefore: z.ZodOptional<z.ZodString>;
|
|
815
|
+
contextAfter: z.ZodOptional<z.ZodString>;
|
|
816
|
+
}, z.core.$strip>>>;
|
|
817
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
818
|
+
}, z.core.$strip>>;
|
|
819
|
+
userState: z.ZodOptional<z.ZodEnum<{
|
|
820
|
+
ACTIVE: "ACTIVE";
|
|
821
|
+
IGNORED: "IGNORED";
|
|
822
|
+
APPLIED: "APPLIED";
|
|
823
|
+
}>>;
|
|
824
|
+
}, z.core.$strip>;
|
|
825
|
+
/** RequirementQualityMetrics (requirement_quality.proto) — scores 0-100, counts among ACTIVE findings. */
|
|
826
|
+
export declare const requirementQualityMetricsSchema: z.ZodObject<{
|
|
827
|
+
overall: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
828
|
+
clarity: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
829
|
+
completeness: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
830
|
+
testability: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
831
|
+
consistency: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
832
|
+
ambiguityRisk: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
833
|
+
scenarioCoverage: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
834
|
+
criticalCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
835
|
+
majorCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
836
|
+
minorCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
837
|
+
}, z.core.$strip>;
|
|
838
|
+
/** RequirementQualitySubject (requirement_quality.proto). subjectEntityId is the platform-internal id. */
|
|
839
|
+
export declare const requirementQualitySubjectSchema: z.ZodObject<{
|
|
840
|
+
subjectType: z.ZodOptional<z.ZodEnum<{
|
|
841
|
+
STORY: "STORY";
|
|
842
|
+
SCENARIO: "SCENARIO";
|
|
843
|
+
}>>;
|
|
844
|
+
subjectEntityId: z.ZodOptional<z.ZodString>;
|
|
845
|
+
ordinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
846
|
+
title: z.ZodOptional<z.ZodString>;
|
|
847
|
+
}, z.core.$strip>;
|
|
848
|
+
/** RequirementQualityReport (requirement_quality.proto) — full upload body shape. */
|
|
849
|
+
export declare const requirementQualityReportSchema: z.ZodObject<{
|
|
850
|
+
id: z.ZodOptional<z.ZodString>;
|
|
851
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
852
|
+
subject: z.ZodOptional<z.ZodObject<{
|
|
853
|
+
subjectType: z.ZodOptional<z.ZodEnum<{
|
|
854
|
+
STORY: "STORY";
|
|
855
|
+
SCENARIO: "SCENARIO";
|
|
856
|
+
}>>;
|
|
857
|
+
subjectEntityId: z.ZodOptional<z.ZodString>;
|
|
858
|
+
ordinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
859
|
+
title: z.ZodOptional<z.ZodString>;
|
|
860
|
+
}, z.core.$strip>>;
|
|
861
|
+
source: z.ZodOptional<z.ZodEnum<{
|
|
862
|
+
CLOUD: "CLOUD";
|
|
863
|
+
LOCAL_AGENT: "LOCAL_AGENT";
|
|
864
|
+
}>>;
|
|
865
|
+
metrics: z.ZodOptional<z.ZodObject<{
|
|
866
|
+
overall: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
867
|
+
clarity: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
868
|
+
completeness: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
869
|
+
testability: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
870
|
+
consistency: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
871
|
+
ambiguityRisk: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
872
|
+
scenarioCoverage: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
873
|
+
criticalCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
874
|
+
majorCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
875
|
+
minorCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
876
|
+
}, z.core.$strip>>;
|
|
877
|
+
findings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
878
|
+
id: z.ZodOptional<z.ZodString>;
|
|
879
|
+
fingerprint: z.ZodOptional<z.ZodString>;
|
|
880
|
+
analyst: z.ZodOptional<z.ZodString>;
|
|
881
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
882
|
+
CRITICAL: "CRITICAL";
|
|
883
|
+
MAJOR: "MAJOR";
|
|
884
|
+
MINOR: "MINOR";
|
|
885
|
+
}>>;
|
|
886
|
+
confidence: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
887
|
+
title: z.ZodOptional<z.ZodString>;
|
|
888
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
889
|
+
suggestedFix: z.ZodOptional<z.ZodObject<{
|
|
890
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
891
|
+
OTHER: "OTHER";
|
|
892
|
+
REWORD_EXCERPT: "REWORD_EXCERPT";
|
|
893
|
+
REWRITE_SECTION: "REWRITE_SECTION";
|
|
894
|
+
ADD_CONTENT: "ADD_CONTENT";
|
|
895
|
+
CREATE_SCENARIO: "CREATE_SCENARIO";
|
|
896
|
+
CREATE_STORY: "CREATE_STORY";
|
|
897
|
+
DELETE_SCENARIO: "DELETE_SCENARIO";
|
|
898
|
+
DELETE_STORY: "DELETE_STORY";
|
|
899
|
+
LINK_OR_UNLINK: "LINK_OR_UNLINK";
|
|
900
|
+
}>>;
|
|
901
|
+
isDestructive: z.ZodOptional<z.ZodBoolean>;
|
|
902
|
+
targetEntityType: z.ZodOptional<z.ZodString>;
|
|
903
|
+
targetOrdinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
904
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
905
|
+
agentPrompt: z.ZodOptional<z.ZodString>;
|
|
906
|
+
replacements: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
907
|
+
originalExcerpt: z.ZodOptional<z.ZodString>;
|
|
908
|
+
suggestedText: z.ZodOptional<z.ZodString>;
|
|
909
|
+
contextBefore: z.ZodOptional<z.ZodString>;
|
|
910
|
+
contextAfter: z.ZodOptional<z.ZodString>;
|
|
911
|
+
}, z.core.$strip>>>;
|
|
912
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
913
|
+
}, z.core.$strip>>;
|
|
914
|
+
userState: z.ZodOptional<z.ZodEnum<{
|
|
915
|
+
ACTIVE: "ACTIVE";
|
|
916
|
+
IGNORED: "IGNORED";
|
|
917
|
+
APPLIED: "APPLIED";
|
|
918
|
+
}>>;
|
|
919
|
+
}, z.core.$strip>>>;
|
|
920
|
+
createdAtMillis: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
921
|
+
jobId: z.ZodOptional<z.ZodString>;
|
|
922
|
+
contentFingerprint: z.ZodOptional<z.ZodString>;
|
|
923
|
+
scoresUpdatedAtMillis: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
924
|
+
}, z.core.$strip>;
|
|
925
|
+
export declare const getRequirementQualityReportInput: z.ZodObject<{
|
|
926
|
+
subjectType: z.ZodEnum<{
|
|
927
|
+
STORY: "STORY";
|
|
928
|
+
SCENARIO: "SCENARIO";
|
|
929
|
+
}>;
|
|
930
|
+
subjectEntityId: z.ZodOptional<z.ZodString>;
|
|
931
|
+
ordinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
932
|
+
}, z.core.$strip>;
|
|
933
|
+
export declare const reportRequirementQualityFindingsInput: z.ZodObject<{
|
|
934
|
+
report: z.ZodOptional<z.ZodObject<{
|
|
935
|
+
id: z.ZodOptional<z.ZodString>;
|
|
936
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
937
|
+
subject: z.ZodOptional<z.ZodObject<{
|
|
938
|
+
subjectType: z.ZodOptional<z.ZodEnum<{
|
|
939
|
+
STORY: "STORY";
|
|
940
|
+
SCENARIO: "SCENARIO";
|
|
941
|
+
}>>;
|
|
942
|
+
subjectEntityId: z.ZodOptional<z.ZodString>;
|
|
943
|
+
ordinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
944
|
+
title: z.ZodOptional<z.ZodString>;
|
|
945
|
+
}, z.core.$strip>>;
|
|
946
|
+
source: z.ZodOptional<z.ZodEnum<{
|
|
947
|
+
CLOUD: "CLOUD";
|
|
948
|
+
LOCAL_AGENT: "LOCAL_AGENT";
|
|
949
|
+
}>>;
|
|
950
|
+
metrics: z.ZodOptional<z.ZodObject<{
|
|
951
|
+
overall: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
952
|
+
clarity: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
953
|
+
completeness: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
954
|
+
testability: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
955
|
+
consistency: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
956
|
+
ambiguityRisk: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
957
|
+
scenarioCoverage: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
958
|
+
criticalCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
959
|
+
majorCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
960
|
+
minorCount: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
961
|
+
}, z.core.$strip>>;
|
|
962
|
+
findings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
963
|
+
id: z.ZodOptional<z.ZodString>;
|
|
964
|
+
fingerprint: z.ZodOptional<z.ZodString>;
|
|
965
|
+
analyst: z.ZodOptional<z.ZodString>;
|
|
966
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
967
|
+
CRITICAL: "CRITICAL";
|
|
968
|
+
MAJOR: "MAJOR";
|
|
969
|
+
MINOR: "MINOR";
|
|
970
|
+
}>>;
|
|
971
|
+
confidence: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
972
|
+
title: z.ZodOptional<z.ZodString>;
|
|
973
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
974
|
+
suggestedFix: z.ZodOptional<z.ZodObject<{
|
|
975
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
976
|
+
OTHER: "OTHER";
|
|
977
|
+
REWORD_EXCERPT: "REWORD_EXCERPT";
|
|
978
|
+
REWRITE_SECTION: "REWRITE_SECTION";
|
|
979
|
+
ADD_CONTENT: "ADD_CONTENT";
|
|
980
|
+
CREATE_SCENARIO: "CREATE_SCENARIO";
|
|
981
|
+
CREATE_STORY: "CREATE_STORY";
|
|
982
|
+
DELETE_SCENARIO: "DELETE_SCENARIO";
|
|
983
|
+
DELETE_STORY: "DELETE_STORY";
|
|
984
|
+
LINK_OR_UNLINK: "LINK_OR_UNLINK";
|
|
985
|
+
}>>;
|
|
986
|
+
isDestructive: z.ZodOptional<z.ZodBoolean>;
|
|
987
|
+
targetEntityType: z.ZodOptional<z.ZodString>;
|
|
988
|
+
targetOrdinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
989
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
990
|
+
agentPrompt: z.ZodOptional<z.ZodString>;
|
|
991
|
+
replacements: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
992
|
+
originalExcerpt: z.ZodOptional<z.ZodString>;
|
|
993
|
+
suggestedText: z.ZodOptional<z.ZodString>;
|
|
994
|
+
contextBefore: z.ZodOptional<z.ZodString>;
|
|
995
|
+
contextAfter: z.ZodOptional<z.ZodString>;
|
|
996
|
+
}, z.core.$strip>>>;
|
|
997
|
+
rationale: z.ZodOptional<z.ZodString>;
|
|
998
|
+
}, z.core.$strip>>;
|
|
999
|
+
userState: z.ZodOptional<z.ZodEnum<{
|
|
1000
|
+
ACTIVE: "ACTIVE";
|
|
1001
|
+
IGNORED: "IGNORED";
|
|
1002
|
+
APPLIED: "APPLIED";
|
|
1003
|
+
}>>;
|
|
1004
|
+
}, z.core.$strip>>>;
|
|
1005
|
+
createdAtMillis: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1006
|
+
jobId: z.ZodOptional<z.ZodString>;
|
|
1007
|
+
contentFingerprint: z.ZodOptional<z.ZodString>;
|
|
1008
|
+
scoresUpdatedAtMillis: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1009
|
+
}, z.core.$strip>>;
|
|
1010
|
+
reportFile: z.ZodOptional<z.ZodString>;
|
|
1011
|
+
subjectType: z.ZodOptional<z.ZodEnum<{
|
|
1012
|
+
STORY: "STORY";
|
|
1013
|
+
SCENARIO: "SCENARIO";
|
|
1014
|
+
}>>;
|
|
1015
|
+
subjectEntityId: z.ZodOptional<z.ZodString>;
|
|
1016
|
+
ordinalId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1017
|
+
}, z.core.$strip>;
|
package/dist/core/schemas.js
CHANGED
|
@@ -324,6 +324,10 @@ export const getReleaseInput = z.object({
|
|
|
324
324
|
/** Release catalog version / label — maps to McpGetReleaseRequest.version */
|
|
325
325
|
version: z.string().min(1),
|
|
326
326
|
});
|
|
327
|
+
export const getReleaseDetailsInput = z.object({
|
|
328
|
+
/** Release catalog version / label — maps to McpGetReleaseDetailsRequest.version */
|
|
329
|
+
version: z.string().min(1),
|
|
330
|
+
});
|
|
327
331
|
export const getSecurityScanConfigInput = z.object({
|
|
328
332
|
id: z.string().min(1),
|
|
329
333
|
});
|
|
@@ -373,3 +377,126 @@ export const markSemanticTestsDistinctInput = z.object({
|
|
|
373
377
|
focusTest: testLocatorSchema,
|
|
374
378
|
distinctTest: testLocatorSchema,
|
|
375
379
|
});
|
|
380
|
+
/** RequirementSubjectType — proto enum names (JsonFormat camelCase on wire). */
|
|
381
|
+
export const requirementSubjectTypeSchema = z.enum(["STORY", "SCENARIO"]);
|
|
382
|
+
/** RequirementFindingSeverity — proto enum names. */
|
|
383
|
+
export const requirementFindingSeveritySchema = z.enum(["CRITICAL", "MAJOR", "MINOR"]);
|
|
384
|
+
/** RequirementFindingUserState — proto enum names. */
|
|
385
|
+
export const requirementFindingUserStateSchema = z.enum(["ACTIVE", "IGNORED", "APPLIED"]);
|
|
386
|
+
/** RequirementQualityReportSource — proto enum names. */
|
|
387
|
+
export const requirementQualityReportSourceSchema = z.enum(["CLOUD", "LOCAL_AGENT"]);
|
|
388
|
+
/** SuggestedFixKind — proto enum names. */
|
|
389
|
+
export const suggestedFixKindSchema = z.enum([
|
|
390
|
+
"REWORD_EXCERPT",
|
|
391
|
+
"REWRITE_SECTION",
|
|
392
|
+
"ADD_CONTENT",
|
|
393
|
+
"CREATE_SCENARIO",
|
|
394
|
+
"CREATE_STORY",
|
|
395
|
+
"DELETE_SCENARIO",
|
|
396
|
+
"DELETE_STORY",
|
|
397
|
+
"LINK_OR_UNLINK",
|
|
398
|
+
"OTHER",
|
|
399
|
+
]);
|
|
400
|
+
/** TextReplacement (requirement_quality.proto) — camelCase wire shape. */
|
|
401
|
+
export const textReplacementSchema = z.object({
|
|
402
|
+
originalExcerpt: z.string().optional(),
|
|
403
|
+
suggestedText: z.string().optional(),
|
|
404
|
+
contextBefore: z.string().optional(),
|
|
405
|
+
contextAfter: z.string().optional(),
|
|
406
|
+
});
|
|
407
|
+
/** SuggestedFix (requirement_quality.proto). isDestructive is derived server-side from kind. */
|
|
408
|
+
export const suggestedFixSchema = z.object({
|
|
409
|
+
kind: suggestedFixKindSchema.optional(),
|
|
410
|
+
isDestructive: z.boolean().optional(),
|
|
411
|
+
/** "STORY" | "SCENARIO" — target of the fix (may differ from the finding's own subject). */
|
|
412
|
+
targetEntityType: z.string().optional(),
|
|
413
|
+
targetOrdinalId: z.coerce.number().int().optional(),
|
|
414
|
+
summary: z.string().optional(),
|
|
415
|
+
agentPrompt: z.string().optional(),
|
|
416
|
+
replacements: z.array(textReplacementSchema).optional(),
|
|
417
|
+
rationale: z.string().optional(),
|
|
418
|
+
});
|
|
419
|
+
/** RequirementQualityFinding (requirement_quality.proto). */
|
|
420
|
+
export const requirementQualityFindingSchema = z.object({
|
|
421
|
+
id: z.string().optional(),
|
|
422
|
+
fingerprint: z.string().optional(),
|
|
423
|
+
analyst: z.string().optional(),
|
|
424
|
+
severity: requirementFindingSeveritySchema.optional(),
|
|
425
|
+
confidence: z.coerce.number().int().optional(),
|
|
426
|
+
title: z.string().optional(),
|
|
427
|
+
detail: z.string().optional(),
|
|
428
|
+
suggestedFix: suggestedFixSchema.optional(),
|
|
429
|
+
/** Omit (defaults ACTIVE server-side) for new findings; set explicitly to carry forward IGNORED/APPLIED. */
|
|
430
|
+
userState: requirementFindingUserStateSchema.optional(),
|
|
431
|
+
});
|
|
432
|
+
/** RequirementQualityMetrics (requirement_quality.proto) — scores 0-100, counts among ACTIVE findings. */
|
|
433
|
+
export const requirementQualityMetricsSchema = z.object({
|
|
434
|
+
overall: z.coerce.number().int().optional(),
|
|
435
|
+
clarity: z.coerce.number().int().optional(),
|
|
436
|
+
completeness: z.coerce.number().int().optional(),
|
|
437
|
+
testability: z.coerce.number().int().optional(),
|
|
438
|
+
consistency: z.coerce.number().int().optional(),
|
|
439
|
+
ambiguityRisk: z.coerce.number().int().optional(),
|
|
440
|
+
scenarioCoverage: z.coerce.number().int().optional(),
|
|
441
|
+
criticalCount: z.coerce.number().int().optional(),
|
|
442
|
+
majorCount: z.coerce.number().int().optional(),
|
|
443
|
+
minorCount: z.coerce.number().int().optional(),
|
|
444
|
+
});
|
|
445
|
+
/** RequirementQualitySubject (requirement_quality.proto). subjectEntityId is the platform-internal id. */
|
|
446
|
+
export const requirementQualitySubjectSchema = z.object({
|
|
447
|
+
subjectType: requirementSubjectTypeSchema.optional(),
|
|
448
|
+
subjectEntityId: z.string().optional(),
|
|
449
|
+
ordinalId: z.coerce.number().int().optional(),
|
|
450
|
+
title: z.string().optional(),
|
|
451
|
+
});
|
|
452
|
+
/** RequirementQualityReport (requirement_quality.proto) — full upload body shape. */
|
|
453
|
+
export const requirementQualityReportSchema = z.object({
|
|
454
|
+
id: z.string().optional(),
|
|
455
|
+
projectId: z.string().optional(),
|
|
456
|
+
subject: requirementQualitySubjectSchema.optional(),
|
|
457
|
+
source: requirementQualityReportSourceSchema.optional(),
|
|
458
|
+
metrics: requirementQualityMetricsSchema.optional(),
|
|
459
|
+
findings: z.array(requirementQualityFindingSchema).optional(),
|
|
460
|
+
createdAtMillis: z.coerce.number().optional(),
|
|
461
|
+
jobId: z.string().optional(),
|
|
462
|
+
contentFingerprint: z.string().optional(),
|
|
463
|
+
scoresUpdatedAtMillis: z.coerce.number().optional(),
|
|
464
|
+
});
|
|
465
|
+
const requirementSubjectRefinement = (v, ctx) => {
|
|
466
|
+
const entityId = (v.subjectEntityId ?? "").trim();
|
|
467
|
+
const ordinal = v.ordinalId;
|
|
468
|
+
if (entityId === "" && (ordinal == null || ordinal <= 0)) {
|
|
469
|
+
ctx.addIssue({
|
|
470
|
+
code: z.ZodIssueCode.custom,
|
|
471
|
+
message: "Provide subjectEntityId or ordinalId",
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
export const getRequirementQualityReportInput = z
|
|
476
|
+
.object({
|
|
477
|
+
subjectType: requirementSubjectTypeSchema,
|
|
478
|
+
subjectEntityId: z.string().optional(),
|
|
479
|
+
ordinalId: z.coerce.number().int().positive().optional(),
|
|
480
|
+
})
|
|
481
|
+
.superRefine(requirementSubjectRefinement);
|
|
482
|
+
export const reportRequirementQualityFindingsInput = z
|
|
483
|
+
.object({
|
|
484
|
+
/** Full RequirementQualityReport JSON object (camelCase, requirement_quality.proto). */
|
|
485
|
+
report: requirementQualityReportSchema.optional(),
|
|
486
|
+
/** Path to RequirementQualityReport JSON file. */
|
|
487
|
+
reportFile: z.string().optional(),
|
|
488
|
+
/** Convenience: merged into report.subject when report lacks subjectEntityId. */
|
|
489
|
+
subjectType: requirementSubjectTypeSchema.optional(),
|
|
490
|
+
subjectEntityId: z.string().optional(),
|
|
491
|
+
ordinalId: z.coerce.number().int().positive().optional(),
|
|
492
|
+
})
|
|
493
|
+
.superRefine((v, ctx) => {
|
|
494
|
+
const hasReport = v.report != null && Object.keys(v.report).length > 0;
|
|
495
|
+
const hasFile = (v.reportFile ?? "").trim() !== "";
|
|
496
|
+
if (!hasReport && !hasFile) {
|
|
497
|
+
ctx.addIssue({
|
|
498
|
+
code: z.ZodIssueCode.custom,
|
|
499
|
+
message: "Provide report object, reportFile path, or full body via --json-input",
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
});
|
package/dist/core/tools.js
CHANGED
|
@@ -85,6 +85,43 @@ function listExecutionBody(args) {
|
|
|
85
85
|
body.offset = args.offset;
|
|
86
86
|
return body;
|
|
87
87
|
}
|
|
88
|
+
function requirementQualitySubjectBody(subjectType, opts) {
|
|
89
|
+
const body = { subjectType };
|
|
90
|
+
const entityId = (opts.subjectEntityId ?? "").trim();
|
|
91
|
+
if (entityId !== "")
|
|
92
|
+
body.subjectEntityId = entityId;
|
|
93
|
+
if (opts.ordinalId != null && opts.ordinalId > 0)
|
|
94
|
+
body.ordinalId = opts.ordinalId;
|
|
95
|
+
return body;
|
|
96
|
+
}
|
|
97
|
+
/** Resolve platform subjectEntityId from explicit id or get-requirement-quality-report via ordinal. */
|
|
98
|
+
async function resolveRequirementSubjectEntityId(postMcp, subjectType, opts) {
|
|
99
|
+
const explicit = (opts.subjectEntityId ?? "").trim();
|
|
100
|
+
if (explicit !== "")
|
|
101
|
+
return explicit;
|
|
102
|
+
if (opts.ordinalId == null || opts.ordinalId <= 0) {
|
|
103
|
+
throw new Error("Provide subjectEntityId or ordinalId");
|
|
104
|
+
}
|
|
105
|
+
const json = await postMcp("/api/mcp/get_requirement_quality_report", requirementQualitySubjectBody(subjectType, { ordinalId: opts.ordinalId }));
|
|
106
|
+
const parsed = JSON.parse(json);
|
|
107
|
+
const resolved = (parsed.report?.subject?.subjectEntityId ?? "").trim();
|
|
108
|
+
if (resolved !== "")
|
|
109
|
+
return resolved;
|
|
110
|
+
throw new Error(`Cannot resolve subjectEntityId for ${subjectType} ordinal ${opts.ordinalId}. ` +
|
|
111
|
+
"Provide --subject-entity-id, or confirm the story/scenario ordinal exists in this project " +
|
|
112
|
+
"(get-requirement-quality-report resolves entity id by ordinal even when no prior report exists).");
|
|
113
|
+
}
|
|
114
|
+
async function loadRequirementQualityReportJson(args) {
|
|
115
|
+
if (args.report != null && Object.keys(args.report).length > 0) {
|
|
116
|
+
return { ...args.report };
|
|
117
|
+
}
|
|
118
|
+
if (args.reportFile != null && args.reportFile.trim() !== "") {
|
|
119
|
+
const { readFile } = await import("node:fs/promises");
|
|
120
|
+
const raw = await readFile(args.reportFile.trim(), "utf8");
|
|
121
|
+
return JSON.parse(raw);
|
|
122
|
+
}
|
|
123
|
+
return {};
|
|
124
|
+
}
|
|
88
125
|
export const TOOL_DEFINITIONS = [
|
|
89
126
|
{
|
|
90
127
|
kebab: "get-requirement-coverage",
|
|
@@ -552,6 +589,19 @@ export const TOOL_DEFINITIONS = [
|
|
|
552
589
|
return postMcp("/api/mcp/get_release", body);
|
|
553
590
|
},
|
|
554
591
|
},
|
|
592
|
+
{
|
|
593
|
+
kebab: "get-release-details",
|
|
594
|
+
description: "Fetch gate-oriented release details for a version/label: scope, per-environment " +
|
|
595
|
+
"priority×status test stats, open issue stats, scan summaries, and detailed in-scope " +
|
|
596
|
+
"scenario/issue records (McpGetReleaseDetailsRequest/Response). Pass version (CLI: --version). " +
|
|
597
|
+
"Use for CI/agent release gating. Authenticated via project API key.",
|
|
598
|
+
inputSchema: S.getReleaseDetailsInput,
|
|
599
|
+
execute: async (args, { postMcp }) => {
|
|
600
|
+
const a = args;
|
|
601
|
+
const body = { version: a.version.trim() };
|
|
602
|
+
return postMcp("/api/mcp/get_release_details", body);
|
|
603
|
+
},
|
|
604
|
+
},
|
|
555
605
|
{
|
|
556
606
|
kebab: "get-security-scan-config",
|
|
557
607
|
description: "Fetch security scan config by scan id (detail.dastCheckConfig / detail.sastCheckConfig / " +
|
|
@@ -678,6 +728,54 @@ export const TOOL_DEFINITIONS = [
|
|
|
678
728
|
});
|
|
679
729
|
},
|
|
680
730
|
},
|
|
731
|
+
{
|
|
732
|
+
kebab: "get-requirement-quality-report",
|
|
733
|
+
description: "Fetch the stored requirement quality report (metrics + findings with user states) for a user story or test scenario. " +
|
|
734
|
+
"Use before local DeFOSPAM to dedupe: do not re-report findings already IGNORED or APPLIED (match by fingerprint). " +
|
|
735
|
+
"Pass subjectType STORY|SCENARIO plus subjectEntityId or ordinalId (numeric part of US-<n> / TS-<n>). " +
|
|
736
|
+
"When no prior report exists, response still includes report.subject with resolved subjectEntityId.",
|
|
737
|
+
inputSchema: S.getRequirementQualityReportInput,
|
|
738
|
+
execute: async (args, { postMcp }) => {
|
|
739
|
+
const a = args;
|
|
740
|
+
return postMcp("/api/mcp/get_requirement_quality_report", requirementQualitySubjectBody(a.subjectType, {
|
|
741
|
+
subjectEntityId: a.subjectEntityId,
|
|
742
|
+
ordinalId: a.ordinalId,
|
|
743
|
+
}));
|
|
744
|
+
},
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
kebab: "report-requirement-quality-findings",
|
|
748
|
+
description: "Upload a DeFOSPAM / requirement quality analysis report for a user story or test scenario (local-agent path). " +
|
|
749
|
+
"Pass full RequirementQualityReport JSON via --report-file or --json-input {\"report\":{...}}. " +
|
|
750
|
+
"report.subject.subjectEntityId is required; use --subject-type + --ordinal-id to resolve via get-requirement-quality-report, " +
|
|
751
|
+
"or set subjectEntityId explicitly. Backend merges IGNORED/APPLIED findings carry-forward on re-report.",
|
|
752
|
+
inputSchema: S.reportRequirementQualityFindingsInput,
|
|
753
|
+
execute: async (args, { postMcp }) => {
|
|
754
|
+
const a = args;
|
|
755
|
+
const report = await loadRequirementQualityReportJson(a);
|
|
756
|
+
const subjectRaw = (report.subject ?? {});
|
|
757
|
+
const subjectType = (a.subjectType ?? subjectRaw.subjectType);
|
|
758
|
+
const ordinalId = a.ordinalId ??
|
|
759
|
+
(typeof subjectRaw.ordinalId === "number" ? subjectRaw.ordinalId : undefined);
|
|
760
|
+
let subjectEntityId = (a.subjectEntityId ?? (typeof subjectRaw.subjectEntityId === "string" ? subjectRaw.subjectEntityId : "")).trim();
|
|
761
|
+
if (subjectEntityId === "" && subjectType != null) {
|
|
762
|
+
subjectEntityId = await resolveRequirementSubjectEntityId(postMcp, subjectType, {
|
|
763
|
+
ordinalId,
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
if (subjectEntityId === "") {
|
|
767
|
+
throw new Error("report.subject.subjectEntityId is required (set in report JSON, --subject-entity-id, or resolvable via --ordinal-id)");
|
|
768
|
+
}
|
|
769
|
+
const mergedSubject = {
|
|
770
|
+
...subjectRaw,
|
|
771
|
+
...(subjectType != null ? { subjectType } : {}),
|
|
772
|
+
subjectEntityId,
|
|
773
|
+
...(ordinalId != null ? { ordinalId } : {}),
|
|
774
|
+
};
|
|
775
|
+
report.subject = mergedSubject;
|
|
776
|
+
return postMcp("/api/mcp/report_requirement_quality_findings", { report });
|
|
777
|
+
},
|
|
778
|
+
},
|
|
681
779
|
];
|
|
682
780
|
const TOOL_BY_KEBAB = new Map(TOOL_DEFINITIONS.map((t) => [t.kebab, t]));
|
|
683
781
|
export function getToolDefinition(kebab) {
|