mason-context 0.16.3 → 0.17.1
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/CHANGELOG.md +26 -0
- package/README.md +1 -1
- package/dist/mason-audit.js +1728 -770
- package/dist/mason-audit.js.map +1 -1
- package/dist/mason-auto.js +1434 -822
- package/dist/mason-auto.js.map +1 -1
- package/dist/mason-mcp.js +3549 -2865
- package/dist/mason-mcp.js.map +1 -1
- package/dist/mason-review.js +80 -19
- package/dist/mason-review.js.map +1 -1
- package/dist/mason.js +1543 -946
- package/dist/mason.js.map +1 -1
- package/package.json +5 -1
package/dist/mason-review.js
CHANGED
|
@@ -688,7 +688,7 @@ async function findMissingPartners(resolvedRoot, changedFiles, existsOnDisk, all
|
|
|
688
688
|
|
|
689
689
|
// src/review/evidence.ts
|
|
690
690
|
import path10 from "path";
|
|
691
|
-
import { z as
|
|
691
|
+
import { z as z7 } from "zod";
|
|
692
692
|
|
|
693
693
|
// src/review/evidence/vitest.ts
|
|
694
694
|
import { z as z4 } from "zod";
|
|
@@ -904,20 +904,76 @@ function parseSarif(raw, sourceRoot) {
|
|
|
904
904
|
};
|
|
905
905
|
}
|
|
906
906
|
|
|
907
|
+
// src/review/evidence/check.ts
|
|
908
|
+
import { z as z6 } from "zod";
|
|
909
|
+
var schema3 = z6.object({
|
|
910
|
+
version: z6.literal(1),
|
|
911
|
+
commit: z6.string().regex(/^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/).optional(),
|
|
912
|
+
results: z6.array(z6.object({
|
|
913
|
+
name: z6.string().min(1).max(1e3),
|
|
914
|
+
status: z6.enum(["passed", "failed", "skipped"]),
|
|
915
|
+
message: z6.string().max(1e5).optional(),
|
|
916
|
+
locations: z6.array(z6.object({
|
|
917
|
+
file: z6.string().min(1).max(4e3),
|
|
918
|
+
line: z6.number().int().positive().optional(),
|
|
919
|
+
column: z6.number().int().positive().optional()
|
|
920
|
+
})).max(100).default([])
|
|
921
|
+
})).max(1e5)
|
|
922
|
+
});
|
|
923
|
+
function parseCheck(raw, sourceRoot) {
|
|
924
|
+
const report = schema3.parse(raw);
|
|
925
|
+
const diagnostics = [], findings = [];
|
|
926
|
+
const counts = { total: report.results.length, passed: 0, failed: 0, skipped: 0 };
|
|
927
|
+
for (const [index2, result] of report.results.entries()) {
|
|
928
|
+
counts[result.status]++;
|
|
929
|
+
const locations = result.locations.flatMap((location2) => {
|
|
930
|
+
const file = evidencePath(location2.file, sourceRoot);
|
|
931
|
+
if (!file) {
|
|
932
|
+
diagnostics.push(`Check location is outside the declared checkout or invalid: ${location2.file}`);
|
|
933
|
+
return [];
|
|
934
|
+
}
|
|
935
|
+
return [{ ...location2, file }];
|
|
936
|
+
});
|
|
937
|
+
if (result.status === "failed") findings.push({
|
|
938
|
+
id: String(index2),
|
|
939
|
+
...messagePreview([result.name, result.message].filter(Boolean).join("\n")),
|
|
940
|
+
severity: "error",
|
|
941
|
+
state: "active",
|
|
942
|
+
locations
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
if (!counts.total) diagnostics.push("No check results were recorded; an empty report is not passing evidence.");
|
|
946
|
+
if (counts.skipped) diagnostics.push(`${counts.skipped} checks were skipped; verification is incomplete.`);
|
|
947
|
+
return {
|
|
948
|
+
outcome: counts.failed ? "failed" : !counts.total ? "unavailable" : !counts.passed ? "skipped" : "passed",
|
|
949
|
+
counts,
|
|
950
|
+
findings,
|
|
951
|
+
incomplete: diagnostics.length > 0,
|
|
952
|
+
diagnostics,
|
|
953
|
+
...report.commit ? { reportedCommits: [report.commit] } : {}
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
|
|
907
957
|
// src/review/evidence.ts
|
|
908
|
-
var checkSchema =
|
|
909
|
-
id:
|
|
910
|
-
kind:
|
|
911
|
-
tool:
|
|
912
|
-
command:
|
|
913
|
-
commit:
|
|
914
|
-
workingTreeClean:
|
|
915
|
-
source:
|
|
916
|
-
sourceRoot:
|
|
917
|
-
status:
|
|
918
|
-
reason:
|
|
919
|
-
exitCode:
|
|
920
|
-
|
|
958
|
+
var checkSchema = z7.object({
|
|
959
|
+
id: z7.string().min(1).max(100),
|
|
960
|
+
kind: z7.enum(["tests", "static-analysis", "security", "complexity", "duplication", "documentation"]),
|
|
961
|
+
tool: z7.string().min(1).max(200),
|
|
962
|
+
command: z7.string().min(1).max(2e3),
|
|
963
|
+
commit: z7.string().regex(/^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/).nullable().optional(),
|
|
964
|
+
workingTreeClean: z7.boolean().optional(),
|
|
965
|
+
source: z7.string().max(2e3).optional(),
|
|
966
|
+
sourceRoot: z7.string().min(1).max(4e3).optional(),
|
|
967
|
+
status: z7.enum(["completed", "skipped", "unavailable"]).default("completed"),
|
|
968
|
+
reason: z7.string().min(1).max(2e3).optional(),
|
|
969
|
+
exitCode: z7.number().int().nullable().optional(),
|
|
970
|
+
environment: z7.object({
|
|
971
|
+
toolVersion: z7.string().min(1).max(200),
|
|
972
|
+
runtime: z7.string().min(1).max(200).optional(),
|
|
973
|
+
platform: z7.string().min(1).max(200).optional(),
|
|
974
|
+
configuration: z7.array(z7.string().min(1).max(4e3)).max(100).optional()
|
|
975
|
+
}).optional(),
|
|
976
|
+
report: z7.object({ format: z7.enum(["vitest-json", "sarif", "mason-check-json"]), path: z7.string().min(1).max(4e3) }).optional()
|
|
921
977
|
});
|
|
922
978
|
function relativeArtifact(root, file) {
|
|
923
979
|
const relative = path10.isAbsolute(file) ? path10.relative(root, file) : file;
|
|
@@ -959,7 +1015,7 @@ async function collectReviewEvidence(root, manifests, changedFiles, decisions, d
|
|
|
959
1015
|
let manifest, raw;
|
|
960
1016
|
try {
|
|
961
1017
|
manifest = relativeArtifact(root, supplied);
|
|
962
|
-
raw =
|
|
1018
|
+
raw = z7.object({ version: z7.literal(1), checks: z7.array(z7.unknown()) }).parse(await readStoreJson(root, manifest));
|
|
963
1019
|
} catch (error) {
|
|
964
1020
|
output.diagnostics.push(`${supplied}: ${String(error)}`);
|
|
965
1021
|
continue;
|
|
@@ -998,7 +1054,8 @@ async function collectReviewEvidence(root, manifests, changedFiles, decisions, d
|
|
|
998
1054
|
counts: {},
|
|
999
1055
|
incomplete: false,
|
|
1000
1056
|
diagnostics: [],
|
|
1001
|
-
truncated: false
|
|
1057
|
+
truncated: false,
|
|
1058
|
+
...check.environment ? { environment: check.environment } : {}
|
|
1002
1059
|
};
|
|
1003
1060
|
output.checks.push(result);
|
|
1004
1061
|
if (check.workingTreeClean !== true) result.diagnostics.push("The check's working tree was dirty or not recorded; its results cannot be attributed to the claimed commit alone.");
|
|
@@ -1011,13 +1068,13 @@ async function collectReviewEvidence(root, manifests, changedFiles, decisions, d
|
|
|
1011
1068
|
}
|
|
1012
1069
|
try {
|
|
1013
1070
|
if (!check.report) throw new Error("Completed check has no report artifact.");
|
|
1014
|
-
if (check.kind === "tests" !== (check.report.format === "vitest-json")) throw new Error("Test checks require vitest-json; analysis checks require sarif.");
|
|
1071
|
+
if (check.report.format !== "mason-check-json" && check.kind === "tests" !== (check.report.format === "vitest-json")) throw new Error("Test checks require vitest-json or mason-check-json; analysis checks require sarif or mason-check-json.");
|
|
1015
1072
|
const file = relativeArtifact(root, check.report.path);
|
|
1016
1073
|
const report = await readStoreJson(root, file);
|
|
1017
1074
|
if (report === null) throw new Error(`Report artifact is missing: ${file}`);
|
|
1018
1075
|
const sourceRoot = check.sourceRoot ?? root;
|
|
1019
1076
|
if (!path10.posix.isAbsolute(sourceRoot) && !/^[A-Za-z]:[\\/]/.test(sourceRoot)) throw new Error("sourceRoot must identify the absolute checkout root on the check runner.");
|
|
1020
|
-
const parsed = check.report.format === "vitest-json" ? parseVitest(report, sourceRoot) : parseSarif(report, sourceRoot);
|
|
1077
|
+
const parsed = check.report.format === "vitest-json" ? parseVitest(report, sourceRoot) : check.report.format === "mason-check-json" ? parseCheck(report, sourceRoot) : parseSarif(report, sourceRoot);
|
|
1021
1078
|
result.outcome = parsed.outcome;
|
|
1022
1079
|
result.counts = parsed.counts;
|
|
1023
1080
|
result.incomplete = parsed.incomplete;
|
|
@@ -1037,7 +1094,7 @@ async function collectReviewEvidence(root, manifests, changedFiles, decisions, d
|
|
|
1037
1094
|
result.outcome = "failed";
|
|
1038
1095
|
result.diagnostics.push(`Check command exited ${check.exitCode} despite a report with no active failures.`);
|
|
1039
1096
|
}
|
|
1040
|
-
if (check.
|
|
1097
|
+
if (check.kind === "tests" && pairs === void 0) {
|
|
1041
1098
|
try {
|
|
1042
1099
|
pairs = (await buildTestMap(root)).paired;
|
|
1043
1100
|
} catch (error) {
|
|
@@ -1259,6 +1316,10 @@ function evidenceSummary(report) {
|
|
|
1259
1316
|
for (const check of evidence.checks) {
|
|
1260
1317
|
lines.push(` [${check.kind}] ${display(check.id)}: ${check.outcome}, ${check.freshness} (${display(check.tool)})`);
|
|
1261
1318
|
lines.push(` command: ${display(check.command)}; tested commit: ${check.commit ?? "unknown"}`);
|
|
1319
|
+
if (check.environment) {
|
|
1320
|
+
lines.push(` environment: ${display(check.tool)} ${display(check.environment.toolVersion)}` + (check.environment.runtime ? `; ${display(check.environment.runtime)}` : "") + (check.environment.platform ? `; ${display(check.environment.platform)}` : ""));
|
|
1321
|
+
if (check.environment.configuration?.length) lines.push(" configuration: " + check.environment.configuration.map((value) => display(value)).join(", "));
|
|
1322
|
+
}
|
|
1262
1323
|
lines.push(` source: ${display(check.source ?? check.manifest)}; report: ${display(check.report?.path ?? "none")}`);
|
|
1263
1324
|
if (Object.keys(check.counts).length) lines.push(` counts: ${JSON.stringify(check.counts)}`);
|
|
1264
1325
|
for (const diagnostic of check.diagnostics.slice(0, 5)) lines.push(` note: ${display(diagnostic)}`);
|