fix: restore scrolling and validator enforcement
ForgeFlow quality gate / quality (push) Canceled after 0s

This commit is contained in:
NuklearRabbit
2026-08-01 12:44:31 +02:00
parent f8c505e525
commit 258f0b1324
9 changed files with 127 additions and 25 deletions
+3 -1
View File
@@ -20,6 +20,8 @@ function normalizePolicy(policy = {}) {
enabledChecks: Array.isArray(custom.enabledChecks) ? [...new Set(custom.enabledChecks.map(String))] : null,
severityOverrides: custom.severityOverrides && typeof custom.severityOverrides === "object" ? { ...custom.severityOverrides } : {},
blockingChecks: [...new Set((custom.blockingChecks || policy.blockingChecks || []).map(String))],
blockingSeverities: [...new Set((custom.blockingSeverities || policy.blockingSeverities || base.severities || ["error"]).map(String))]
.filter((severity) => ["warning", "error"].includes(severity)),
allowSuppressions: custom.allowSuppressions ?? base.allowSuppressions ?? true,
maxSuppressionDays: Math.max(1, Number(custom.maxSuppressionDays ?? base.maxSuppressionDays ?? 30)),
};
@@ -57,7 +59,7 @@ function applyPolicy(checks, policyInput, suppressions = [], now = new Date()) {
suppressed: Boolean(suppression),
suppression: suppression || null,
expiredSuppression: expiredSuppression || null,
blocking: !suppression && status !== "pass" && (status === "error" || policy.blockingChecks.includes(check.id)),
blocking: !suppression && status !== "pass" && (policy.blockingSeverities.includes(status) || policy.blockingChecks.includes(check.id)),
};
});
return { policy, checks: relevant };
+15 -3
View File
@@ -484,12 +484,23 @@ class GitValidatorService {
throw new Error("Unsupported Git Validator repair action.");
}
async resolveRepairCheck(repository, candidate) {
const checkId = String(candidate?.id || candidate?.checkId || "").trim();
if (!checkId) throw new Error("A current Git Validator check ID is required.");
const report = await this.scan(repository);
const current = report.checks.find((check) => check.id === checkId);
if (!current?.fixAction)
throw new Error("This finding is resolved, suppressed or no longer repairable. Scan again before repairing.");
if (candidate?.fixAction && candidate.fixAction !== current.fixAction)
throw new Error("The Git Validator repair request is stale. Scan again before repairing.");
return current;
}
summarize(repository, checks) {
const totalWeight = checks.reduce((sum, check) => sum + check.weight, 0);
const earned = checks.reduce(
(sum, check) =>
sum +
(check.status === "pass"
(check.status === "pass" || check.suppressed
? check.weight
: check.status === "warning"
? check.weight * 0.45
@@ -512,8 +523,9 @@ class GitValidatorService {
checks,
summary: {
passed: checks.filter((check) => check.status === "pass").length,
warnings: checks.filter((check) => check.status === "warning").length,
errors: checks.filter((check) => check.status === "error").length,
warnings: checks.filter((check) => check.status === "warning" && !check.suppressed).length,
errors: checks.filter((check) => check.status === "error" && !check.suppressed).length,
suppressed: checks.filter((check) => check.suppressed).length,
repairable: checks.filter((check) => check.fixAction).length,
},
};
+9 -7
View File
@@ -373,7 +373,8 @@ function registerRepositoryIpc({
});
register("git-validator:preview-repair", async ({ fullName, check }) => {
const repository = await resolveRepository({ fullName });
return gitValidator.previewRepair(repository, check);
const currentCheck = await gitValidator.resolveRepairCheck(repository, check);
return gitValidator.previewRepair(repository, currentCheck);
});
register("git-validator:export", async ({ fullName, format = "json" }) => {
const repository = await resolveRepository({ fullName });
@@ -390,18 +391,19 @@ function registerRepositoryIpc({
"add-editorconfig",
"protect-default-branch",
]);
if (!allowed.has(check?.fixAction))
const currentCheck = await gitValidator.resolveRepairCheck(repository, check);
if (!allowed.has(currentCheck.fixAction))
throw new Error("Unsupported Git Validator repair request.");
const result = await gitValidator.repair(repository, check);
const result = await gitValidator.repair(repository, currentCheck);
await audit.append("git-validator.repair", {
repository: repository.fullName,
checkId: check.id,
action: check.fixAction,
checkId: currentCheck.id,
action: currentCheck.fixAction,
});
await diagnostics.info("git-validator.repair.completed", {
repository: repository.fullName,
checkId: check.id,
action: check.fixAction,
checkId: currentCheck.id,
action: currentCheck.fixAction,
});
return result;
});
+10 -3
View File
@@ -461,13 +461,15 @@ function createMockDeploymentBridge(context) {
},
async gitValidatorScan(fullName) {
await wait(260);
const policy = state.gitValidatorPolicy || { id: "standard", label: "Standard", requiredScore: 70 };
const activeWarnings = 3;
return {
repository: fullName,
checkedAt: iso(),
score: 78,
grade: "Good",
policy: state.gitValidatorPolicy || { id: "standard", label: "Standard", requiredScore: 70 },
ready: true,
policy,
ready: 78 >= policy.requiredScore && (policy.id === "minimal" || activeWarnings === 0),
commitSha: "8cbaf303aa3bb9b4023a7c89aa13fb70ce612847",
trend: { newlyFound: ["working-tree"], resolved: ["editorconfig"], regressions: [], suppressions: [] },
expiredSuppressions: [],
@@ -572,7 +574,12 @@ function createMockDeploymentBridge(context) {
};
},
async gitValidatorSetPolicy(_fullName, policy) {
state.gitValidatorPolicy = { id: policy.id, label: policy.id[0].toUpperCase() + policy.id.slice(1) };
const requiredScores = { minimal: 55, standard: 70, strict: 82, production: 90 };
state.gitValidatorPolicy = {
id: policy.id,
label: policy.id[0].toUpperCase() + policy.id.slice(1),
requiredScore: requiredScores[policy.id] || 70,
};
return clone(state.gitValidatorPolicy);
},
async gitValidatorSuppress(_fullName, suppression) {
+17 -3
View File
@@ -937,6 +937,21 @@ select:focus-visible {
min-height: 0;
overflow: hidden;
}
.repo-content > .tab-page,
.repo-content > .validator-page {
height: 100%;
min-height: 0;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
.repo-content > .validator-empty,
.repo-content > .empty-state {
max-height: 100%;
overflow-y: auto;
overscroll-behavior: contain;
}
.changes-layout {
height: 100%;
min-height: 0;
@@ -1286,7 +1301,7 @@ html[data-theme="light"] .diff-line.remove {
padding: 18px;
display: grid;
gap: 14px;
overflow: auto;
align-content: start;
}
.validator-empty {
min-height: 360px;
@@ -2572,9 +2587,8 @@ kbd {
font: 11px var(--font-mono);
}
.tab-page {
min-height: 100%;
min-height: 0;
padding: 18px 19px 42px;
overflow: auto;
}
.git-tools-grid {
display: grid;