@eduardbar/drift 1.3.0 → 1.4.0
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/.gga +50 -0
- package/.github/actions/drift-review/README.md +60 -0
- package/.github/actions/drift-review/action.yml +131 -0
- package/.github/actions/drift-scan/README.md +28 -32
- package/.github/actions/drift-scan/action.yml +78 -14
- package/.github/workflows/review-pr.yml +34 -41
- package/AGENTS.md +75 -251
- package/CHANGELOG.md +28 -0
- package/README.md +148 -41
- package/dist/benchmark.d.ts +1 -1
- package/dist/benchmark.js +71 -52
- package/dist/cli.js +243 -8
- package/dist/config.js +16 -2
- package/dist/diff.js +42 -50
- package/dist/doctor.d.ts +5 -0
- package/dist/doctor.js +133 -0
- package/dist/format.d.ts +17 -0
- package/dist/format.js +45 -0
- package/dist/guard-types.d.ts +57 -0
- package/dist/guard-types.js +2 -0
- package/dist/guard.d.ts +14 -0
- package/dist/guard.js +239 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +4 -1
- package/dist/init.d.ts +15 -0
- package/dist/init.js +273 -0
- package/dist/map-cycles.d.ts +2 -0
- package/dist/map-cycles.js +34 -0
- package/dist/map-svg.d.ts +19 -0
- package/dist/map-svg.js +97 -0
- package/dist/map.js +78 -138
- package/dist/metrics.js +70 -55
- package/dist/output-metadata.d.ts +13 -0
- package/dist/output-metadata.js +17 -0
- package/dist/plugins-capabilities.d.ts +4 -0
- package/dist/plugins-capabilities.js +21 -0
- package/dist/plugins-messages.d.ts +10 -0
- package/dist/plugins-messages.js +16 -0
- package/dist/plugins-rules.d.ts +9 -0
- package/dist/plugins-rules.js +137 -0
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +45 -142
- package/dist/reporter-constants.d.ts +16 -0
- package/dist/reporter-constants.js +39 -0
- package/dist/reporter.d.ts +3 -3
- package/dist/reporter.js +35 -55
- package/dist/review.d.ts +2 -1
- package/dist/review.js +2 -1
- package/dist/rules/phase3-configurable.js +23 -15
- package/dist/saas/constants.d.ts +15 -0
- package/dist/saas/constants.js +48 -0
- package/dist/saas/dashboard.d.ts +8 -0
- package/dist/saas/dashboard.js +132 -0
- package/dist/saas/errors.d.ts +19 -0
- package/dist/saas/errors.js +37 -0
- package/dist/saas/helpers.d.ts +21 -0
- package/dist/saas/helpers.js +110 -0
- package/dist/saas/ingest.d.ts +3 -0
- package/dist/saas/ingest.js +249 -0
- package/dist/saas/organization.d.ts +5 -0
- package/dist/saas/organization.js +82 -0
- package/dist/saas/plan-change.d.ts +10 -0
- package/dist/saas/plan-change.js +15 -0
- package/dist/saas/store.d.ts +21 -0
- package/dist/saas/store.js +159 -0
- package/dist/saas/types.d.ts +191 -0
- package/dist/saas/types.js +2 -0
- package/dist/saas.d.ts +8 -218
- package/dist/saas.js +7 -761
- package/dist/sarif.d.ts +74 -0
- package/dist/sarif.js +122 -0
- package/dist/trust-advanced.d.ts +14 -0
- package/dist/trust-advanced.js +65 -0
- package/dist/trust-kpi-fs.d.ts +3 -0
- package/dist/trust-kpi-fs.js +141 -0
- package/dist/trust-kpi-parse.d.ts +7 -0
- package/dist/trust-kpi-parse.js +186 -0
- package/dist/trust-kpi-types.d.ts +16 -0
- package/dist/trust-kpi-types.js +2 -0
- package/dist/trust-kpi.d.ts +1 -3
- package/dist/trust-kpi.js +6 -266
- package/dist/trust-policy.d.ts +32 -0
- package/dist/trust-policy.js +160 -0
- package/dist/trust-render.d.ts +9 -0
- package/dist/trust-render.js +54 -0
- package/dist/trust-scoring.d.ts +9 -0
- package/dist/trust-scoring.js +208 -0
- package/dist/trust.d.ts +4 -32
- package/dist/trust.js +29 -432
- package/dist/types/app.d.ts +30 -0
- package/dist/types/app.js +2 -0
- package/dist/types/config.d.ts +25 -0
- package/dist/types/config.js +2 -0
- package/dist/types/core.d.ts +100 -0
- package/dist/types/core.js +2 -0
- package/dist/types/diff.d.ts +55 -0
- package/dist/types/diff.js +2 -0
- package/dist/types/plugin.d.ts +41 -0
- package/dist/types/plugin.js +2 -0
- package/dist/types/trust.d.ts +120 -0
- package/dist/types/trust.js +2 -0
- package/dist/types.d.ts +8 -365
- package/docs/release-notes-draft.md +40 -0
- package/docs/rules-catalog.md +49 -0
- package/docs/trust-core-release-checklist.md +37 -5
- package/package.json +3 -2
- package/packages/vscode-drift/src/code-actions.ts +1 -1
- package/schemas/drift-ai-output.v1.json +162 -0
- package/schemas/drift-report.v1.json +151 -0
- package/schemas/drift-trust.v1.json +131 -0
- package/scripts/smoke-repo.mjs +394 -0
- package/src/benchmark.ts +75 -53
- package/src/cli.ts +285 -13
- package/src/config.ts +19 -2
- package/src/diff.ts +57 -48
- package/src/doctor.ts +173 -0
- package/src/format.ts +81 -0
- package/src/guard-types.ts +64 -0
- package/src/guard.ts +324 -0
- package/src/index.ts +35 -0
- package/src/init.ts +298 -0
- package/src/map-cycles.ts +38 -0
- package/src/map-svg.ts +124 -0
- package/src/map.ts +111 -142
- package/src/metrics.ts +78 -59
- package/src/output-metadata.ts +30 -0
- package/src/plugins-capabilities.ts +36 -0
- package/src/plugins-messages.ts +35 -0
- package/src/plugins-rules.ts +296 -0
- package/src/plugins.ts +76 -283
- package/src/reporter-constants.ts +46 -0
- package/src/reporter.ts +64 -65
- package/src/review.ts +4 -2
- package/src/rules/phase3-configurable.ts +39 -26
- package/src/saas/constants.ts +56 -0
- package/src/saas/dashboard.ts +172 -0
- package/src/saas/errors.ts +45 -0
- package/src/saas/helpers.ts +140 -0
- package/src/saas/ingest.ts +278 -0
- package/src/saas/organization.ts +99 -0
- package/src/saas/plan-change.ts +19 -0
- package/src/saas/store.ts +172 -0
- package/src/saas/types.ts +216 -0
- package/src/saas.ts +49 -1031
- package/src/sarif.ts +232 -0
- package/src/trust-advanced.ts +99 -0
- package/src/trust-kpi-fs.ts +169 -0
- package/src/trust-kpi-parse.ts +219 -0
- package/src/trust-kpi-types.ts +19 -0
- package/src/trust-kpi.ts +8 -316
- package/src/trust-policy.ts +246 -0
- package/src/trust-render.ts +61 -0
- package/src/trust-scoring.ts +231 -0
- package/src/trust.ts +62 -576
- package/src/types/app.ts +30 -0
- package/src/types/config.ts +27 -0
- package/src/types/core.ts +105 -0
- package/src/types/diff.ts +61 -0
- package/src/types/plugin.ts +46 -0
- package/src/types/trust.ts +134 -0
- package/src/types.ts +78 -409
- package/tests/cli-sarif.test.ts +92 -0
- package/tests/format.test.ts +157 -0
- package/tests/new-features.test.ts +10 -2
- package/tests/phase1-init-doctor-guard.test.ts +199 -0
- package/tests/sarif.test.ts +160 -0
- package/tests/trust-kpi.test.ts +31 -4
- package/tests/trust.test.ts +18 -0
package/dist/format.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const UNIFIED_FORMAT_VALUES = ['console', 'json', 'markdown', 'ai', 'sarif'];
|
|
2
|
+
function assertSupportedFormatValue(command, format) {
|
|
3
|
+
if (UNIFIED_FORMAT_VALUES.includes(format))
|
|
4
|
+
return;
|
|
5
|
+
throw new Error(`Invalid --format '${format}' for '${command}'. Allowed values: ${UNIFIED_FORMAT_VALUES.join(', ')}.`);
|
|
6
|
+
}
|
|
7
|
+
function throwUnsupportedFormat(command, selected, supported) {
|
|
8
|
+
throw new Error(`Format '${selected}' is not supported for '${command}'. Supported formats: ${supported.join(', ')}.`);
|
|
9
|
+
}
|
|
10
|
+
function normalizeLegacyFormatSelection(command, selectedLegacyFormats) {
|
|
11
|
+
if (selectedLegacyFormats.length === 0)
|
|
12
|
+
return undefined;
|
|
13
|
+
const uniqueFormats = [...new Set(selectedLegacyFormats)];
|
|
14
|
+
if (uniqueFormats.length > 1) {
|
|
15
|
+
throw new Error(`Conflicting legacy format flags for '${command}': ${uniqueFormats.join(' vs ')}. Use a single format option.`);
|
|
16
|
+
}
|
|
17
|
+
return uniqueFormats[0];
|
|
18
|
+
}
|
|
19
|
+
export function resolveOutputFormat(options) {
|
|
20
|
+
const { command, format, supported, onWarning } = options;
|
|
21
|
+
const legacyAliases = options.legacyAliases ?? [];
|
|
22
|
+
for (const alias of legacyAliases) {
|
|
23
|
+
if (!alias.used)
|
|
24
|
+
continue;
|
|
25
|
+
onWarning?.(`Warning: --${alias.flag} is deprecated for '${command}'. Use --format ${alias.mapsTo} instead.`);
|
|
26
|
+
}
|
|
27
|
+
const selectedLegacyFormat = normalizeLegacyFormatSelection(command, legacyAliases.filter((alias) => alias.used).map((alias) => alias.mapsTo));
|
|
28
|
+
const selectedFormat = format?.trim();
|
|
29
|
+
if (selectedFormat) {
|
|
30
|
+
assertSupportedFormatValue(command, selectedFormat);
|
|
31
|
+
if (selectedLegacyFormat && selectedLegacyFormat !== selectedFormat) {
|
|
32
|
+
throw new Error(`Conflicting format flags for '${command}': --format ${selectedFormat} and legacy alias for ${selectedLegacyFormat}.`);
|
|
33
|
+
}
|
|
34
|
+
if (!supported.includes(selectedFormat)) {
|
|
35
|
+
throwUnsupportedFormat(command, selectedFormat, supported);
|
|
36
|
+
}
|
|
37
|
+
return selectedFormat;
|
|
38
|
+
}
|
|
39
|
+
const resolvedFromLegacy = selectedLegacyFormat ?? 'console';
|
|
40
|
+
if (!supported.includes(resolvedFromLegacy)) {
|
|
41
|
+
throwUnsupportedFormat(command, resolvedFromLegacy, supported);
|
|
42
|
+
}
|
|
43
|
+
return resolvedFromLegacy;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { DriftAnalysisOptions, DriftDiff, DriftIssue, DriftReport } from './types.js';
|
|
2
|
+
export type IssueSeverity = DriftIssue['severity'];
|
|
3
|
+
export interface GuardBaseline {
|
|
4
|
+
score?: number;
|
|
5
|
+
totalIssues?: number;
|
|
6
|
+
errors?: number;
|
|
7
|
+
warnings?: number;
|
|
8
|
+
infos?: number;
|
|
9
|
+
bySeverity?: Partial<Record<IssueSeverity, number>>;
|
|
10
|
+
summary?: {
|
|
11
|
+
errors?: number;
|
|
12
|
+
warnings?: number;
|
|
13
|
+
infos?: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface GuardThresholds {
|
|
17
|
+
error?: number;
|
|
18
|
+
warning?: number;
|
|
19
|
+
info?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface GuardOptions {
|
|
22
|
+
baseRef?: string;
|
|
23
|
+
baselinePath?: string;
|
|
24
|
+
baseline?: GuardBaseline;
|
|
25
|
+
budget?: number;
|
|
26
|
+
bySeverity?: GuardThresholds;
|
|
27
|
+
analysis?: DriftAnalysisOptions;
|
|
28
|
+
}
|
|
29
|
+
export interface GuardMetrics {
|
|
30
|
+
scoreDelta: number;
|
|
31
|
+
totalIssuesDelta: number;
|
|
32
|
+
severityDelta: Record<IssueSeverity, number>;
|
|
33
|
+
}
|
|
34
|
+
export interface GuardCheck {
|
|
35
|
+
id: string;
|
|
36
|
+
passed: boolean;
|
|
37
|
+
actual: number;
|
|
38
|
+
limit: number;
|
|
39
|
+
message: string;
|
|
40
|
+
}
|
|
41
|
+
export interface GuardEvaluation {
|
|
42
|
+
passed: boolean;
|
|
43
|
+
checks: GuardCheck[];
|
|
44
|
+
}
|
|
45
|
+
export interface GuardResult {
|
|
46
|
+
scannedAt: string;
|
|
47
|
+
projectPath: string;
|
|
48
|
+
mode: 'diff' | 'baseline';
|
|
49
|
+
passed: boolean;
|
|
50
|
+
baseRef?: string;
|
|
51
|
+
baselinePath?: string;
|
|
52
|
+
metrics: GuardMetrics;
|
|
53
|
+
checks: GuardCheck[];
|
|
54
|
+
current: DriftReport;
|
|
55
|
+
diff?: DriftDiff;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=guard-types.d.ts.map
|
package/dist/guard.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GuardEvaluation, GuardMetrics, GuardOptions, GuardResult, GuardThresholds } from './guard-types.js';
|
|
2
|
+
interface GuardEvalInput {
|
|
3
|
+
metrics: GuardMetrics;
|
|
4
|
+
budget?: number;
|
|
5
|
+
bySeverity?: GuardThresholds;
|
|
6
|
+
enforceNoRegression: {
|
|
7
|
+
score: boolean;
|
|
8
|
+
totalIssues: boolean;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare function evaluateGuard(input: GuardEvalInput): GuardEvaluation;
|
|
12
|
+
export declare function runGuard(targetPath: string, options?: GuardOptions): Promise<GuardResult>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=guard.d.ts.map
|
package/dist/guard.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { relative, resolve } from 'node:path';
|
|
3
|
+
import { analyzeProject } from './analyzer.js';
|
|
4
|
+
import { loadConfig } from './config.js';
|
|
5
|
+
import { computeDiff } from './diff.js';
|
|
6
|
+
import { cleanupTempDir, extractFilesAtRef } from './git.js';
|
|
7
|
+
import { buildReport } from './reporter.js';
|
|
8
|
+
function parseNumber(value) {
|
|
9
|
+
return typeof value === 'number' && !Number.isNaN(value) ? value : undefined;
|
|
10
|
+
}
|
|
11
|
+
function normalizeBaseline(baseline) {
|
|
12
|
+
const bySeverityFromRoot = baseline.bySeverity;
|
|
13
|
+
const bySeverity = {
|
|
14
|
+
error: parseNumber(bySeverityFromRoot?.error) ?? parseNumber(baseline.errors) ?? parseNumber(baseline.summary?.errors),
|
|
15
|
+
warning: parseNumber(bySeverityFromRoot?.warning) ?? parseNumber(baseline.warnings) ?? parseNumber(baseline.summary?.warnings),
|
|
16
|
+
info: parseNumber(bySeverityFromRoot?.info) ?? parseNumber(baseline.infos) ?? parseNumber(baseline.summary?.infos),
|
|
17
|
+
};
|
|
18
|
+
const normalized = {
|
|
19
|
+
score: parseNumber(baseline.score),
|
|
20
|
+
totalIssues: parseNumber(baseline.totalIssues),
|
|
21
|
+
bySeverity,
|
|
22
|
+
};
|
|
23
|
+
const hasAnyAnchor = normalized.score !== undefined ||
|
|
24
|
+
normalized.totalIssues !== undefined ||
|
|
25
|
+
normalized.bySeverity.error !== undefined ||
|
|
26
|
+
normalized.bySeverity.warning !== undefined ||
|
|
27
|
+
normalized.bySeverity.info !== undefined;
|
|
28
|
+
if (!hasAnyAnchor) {
|
|
29
|
+
throw new Error('Invalid guard baseline: expected score, totalIssues, or severity counters (error/warning/info).');
|
|
30
|
+
}
|
|
31
|
+
return normalized;
|
|
32
|
+
}
|
|
33
|
+
function readBaselineFromFile(projectPath, baselinePath) {
|
|
34
|
+
const resolvedBaselinePath = resolve(projectPath, baselinePath ?? 'drift-baseline.json');
|
|
35
|
+
if (!existsSync(resolvedBaselinePath))
|
|
36
|
+
return undefined;
|
|
37
|
+
const raw = JSON.parse(readFileSync(resolvedBaselinePath, 'utf8'));
|
|
38
|
+
return {
|
|
39
|
+
baseline: normalizeBaseline(raw),
|
|
40
|
+
path: resolvedBaselinePath,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function remapBaseReportPaths(baseReport, tempDir, projectPath) {
|
|
44
|
+
return {
|
|
45
|
+
...baseReport,
|
|
46
|
+
files: baseReport.files.map((file) => ({
|
|
47
|
+
...file,
|
|
48
|
+
path: resolve(projectPath, relative(tempDir, file.path)),
|
|
49
|
+
})),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function countSeverityDeltaFromDiff(diff) {
|
|
53
|
+
const severityDelta = {
|
|
54
|
+
error: 0,
|
|
55
|
+
warning: 0,
|
|
56
|
+
info: 0,
|
|
57
|
+
};
|
|
58
|
+
for (const file of diff.files) {
|
|
59
|
+
for (const issue of file.newIssues) {
|
|
60
|
+
severityDelta[issue.severity] += 1;
|
|
61
|
+
}
|
|
62
|
+
for (const issue of file.resolvedIssues) {
|
|
63
|
+
severityDelta[issue.severity] -= 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return severityDelta;
|
|
67
|
+
}
|
|
68
|
+
function buildMetricsFromDiff(diff) {
|
|
69
|
+
return {
|
|
70
|
+
scoreDelta: diff.totalDelta,
|
|
71
|
+
totalIssuesDelta: diff.newIssuesCount - diff.resolvedIssuesCount,
|
|
72
|
+
severityDelta: countSeverityDeltaFromDiff(diff),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function buildMetricsFromBaseline(current, baseline) {
|
|
76
|
+
return {
|
|
77
|
+
scoreDelta: current.totalScore - (baseline.score ?? current.totalScore),
|
|
78
|
+
totalIssuesDelta: current.totalIssues - (baseline.totalIssues ?? current.totalIssues),
|
|
79
|
+
severityDelta: {
|
|
80
|
+
error: current.summary.errors - (baseline.bySeverity.error ?? current.summary.errors),
|
|
81
|
+
warning: current.summary.warnings - (baseline.bySeverity.warning ?? current.summary.warnings),
|
|
82
|
+
info: current.summary.infos - (baseline.bySeverity.info ?? current.summary.infos),
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function addCheck(checks, input) {
|
|
87
|
+
checks.push({
|
|
88
|
+
id: input.id,
|
|
89
|
+
passed: input.actual <= input.limit,
|
|
90
|
+
actual: input.actual,
|
|
91
|
+
limit: input.limit,
|
|
92
|
+
message: input.message,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
export function evaluateGuard(input) {
|
|
96
|
+
const checks = [];
|
|
97
|
+
if (input.enforceNoRegression.score) {
|
|
98
|
+
addCheck(checks, {
|
|
99
|
+
id: 'no-regression-score',
|
|
100
|
+
actual: input.metrics.scoreDelta,
|
|
101
|
+
limit: 0,
|
|
102
|
+
message: 'Score delta must be <= 0.',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (input.enforceNoRegression.totalIssues) {
|
|
106
|
+
addCheck(checks, {
|
|
107
|
+
id: 'no-regression-total-issues',
|
|
108
|
+
actual: input.metrics.totalIssuesDelta,
|
|
109
|
+
limit: 0,
|
|
110
|
+
message: 'Total issues delta must be <= 0.',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (typeof input.budget === 'number' && !Number.isNaN(input.budget)) {
|
|
114
|
+
addCheck(checks, {
|
|
115
|
+
id: 'budget-total-delta',
|
|
116
|
+
actual: input.metrics.scoreDelta,
|
|
117
|
+
limit: input.budget,
|
|
118
|
+
message: `Score delta must be <= budget (${input.budget}).`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const severityThresholds = input.bySeverity;
|
|
122
|
+
if (severityThresholds) {
|
|
123
|
+
const severities = ['error', 'warning', 'info'];
|
|
124
|
+
for (const severity of severities) {
|
|
125
|
+
const threshold = severityThresholds[severity];
|
|
126
|
+
if (typeof threshold !== 'number' || Number.isNaN(threshold))
|
|
127
|
+
continue;
|
|
128
|
+
addCheck(checks, {
|
|
129
|
+
id: `severity-${severity}`,
|
|
130
|
+
actual: input.metrics.severityDelta[severity],
|
|
131
|
+
limit: threshold,
|
|
132
|
+
message: `${severity} delta must be <= ${threshold}.`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
passed: checks.every((check) => check.passed),
|
|
138
|
+
checks,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
export async function runGuard(targetPath, options = {}) {
|
|
142
|
+
const runtimeState = await initializeGuardRuntime(targetPath, options);
|
|
143
|
+
const { projectPath, config, currentReport } = runtimeState;
|
|
144
|
+
let tempDir;
|
|
145
|
+
try {
|
|
146
|
+
if (options.baseRef) {
|
|
147
|
+
tempDir = extractFilesAtRef(projectPath, options.baseRef);
|
|
148
|
+
return createDiffGuardResult({
|
|
149
|
+
projectPath,
|
|
150
|
+
currentReport,
|
|
151
|
+
options,
|
|
152
|
+
tempDir,
|
|
153
|
+
config,
|
|
154
|
+
baseRef: options.baseRef,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const inlineBaseline = options.baseline ? normalizeBaseline(options.baseline) : undefined;
|
|
158
|
+
const fileBaseline = inlineBaseline ? undefined : readBaselineFromFile(projectPath, options.baselinePath);
|
|
159
|
+
const baseline = inlineBaseline ?? fileBaseline?.baseline;
|
|
160
|
+
const baselinePath = fileBaseline?.path;
|
|
161
|
+
if (!baseline) {
|
|
162
|
+
throw new Error('Guard requires a comparison point: provide baseRef or a baseline (inline or file).');
|
|
163
|
+
}
|
|
164
|
+
return createBaselineGuardResult({
|
|
165
|
+
projectPath,
|
|
166
|
+
currentReport,
|
|
167
|
+
options,
|
|
168
|
+
baseline,
|
|
169
|
+
baselinePath,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
if (tempDir)
|
|
174
|
+
cleanupTempDir(tempDir);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async function initializeGuardRuntime(targetPath, options) {
|
|
178
|
+
const projectPath = resolve(targetPath);
|
|
179
|
+
const config = await loadConfig(projectPath);
|
|
180
|
+
const currentFiles = analyzeProject(projectPath, config, options.analysis);
|
|
181
|
+
const currentReport = buildReport(projectPath, currentFiles);
|
|
182
|
+
return {
|
|
183
|
+
projectPath,
|
|
184
|
+
config,
|
|
185
|
+
currentReport,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function createDiffGuardResult(input) {
|
|
189
|
+
const { projectPath, currentReport, options, tempDir, config, baseRef } = input;
|
|
190
|
+
const baseFiles = analyzeProject(tempDir, config, options.analysis);
|
|
191
|
+
const baseReport = buildReport(tempDir, baseFiles);
|
|
192
|
+
const remappedBase = remapBaseReportPaths(baseReport, tempDir, projectPath);
|
|
193
|
+
const diff = computeDiff(remappedBase, currentReport, baseRef);
|
|
194
|
+
const metrics = buildMetricsFromDiff(diff);
|
|
195
|
+
const evaluation = evaluateGuard({
|
|
196
|
+
metrics,
|
|
197
|
+
budget: options.budget,
|
|
198
|
+
bySeverity: options.bySeverity,
|
|
199
|
+
enforceNoRegression: {
|
|
200
|
+
score: true,
|
|
201
|
+
totalIssues: true,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
return {
|
|
205
|
+
scannedAt: new Date().toISOString(),
|
|
206
|
+
projectPath,
|
|
207
|
+
mode: 'diff',
|
|
208
|
+
passed: evaluation.passed,
|
|
209
|
+
baseRef,
|
|
210
|
+
metrics,
|
|
211
|
+
checks: evaluation.checks,
|
|
212
|
+
current: currentReport,
|
|
213
|
+
diff,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function createBaselineGuardResult(input) {
|
|
217
|
+
const { projectPath, currentReport, options, baseline, baselinePath } = input;
|
|
218
|
+
const metrics = buildMetricsFromBaseline(currentReport, baseline);
|
|
219
|
+
const evaluation = evaluateGuard({
|
|
220
|
+
metrics,
|
|
221
|
+
budget: options.budget,
|
|
222
|
+
bySeverity: options.bySeverity,
|
|
223
|
+
enforceNoRegression: {
|
|
224
|
+
score: baseline.score !== undefined,
|
|
225
|
+
totalIssues: baseline.totalIssues !== undefined,
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
scannedAt: new Date().toISOString(),
|
|
230
|
+
projectPath,
|
|
231
|
+
mode: 'baseline',
|
|
232
|
+
passed: evaluation.passed,
|
|
233
|
+
baselinePath,
|
|
234
|
+
metrics,
|
|
235
|
+
checks: evaluation.checks,
|
|
236
|
+
current: currentReport,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=guard.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
export { analyzeProject, analyzeFile, RULE_WEIGHTS } from './analyzer.js';
|
|
2
2
|
export { buildReport, formatMarkdown } from './reporter.js';
|
|
3
3
|
export { computeDiff } from './diff.js';
|
|
4
|
+
export { runGuard, evaluateGuard } from './guard.js';
|
|
5
|
+
export type { GuardBaseline, GuardThresholds, GuardOptions, GuardMetrics, GuardCheck, GuardEvaluation, GuardResult, } from './guard-types.js';
|
|
4
6
|
export { generateReview, formatReviewMarkdown } from './review.js';
|
|
5
|
-
export {
|
|
7
|
+
export { runDoctor } from './doctor.js';
|
|
8
|
+
export type { DoctorOptions } from './doctor.js';
|
|
9
|
+
export { buildTrustReport, formatTrustConsole, formatTrustMarkdown, formatTrustJson, resolveTrustGatePolicy, evaluateTrustGate, shouldFailByMaxRisk, shouldFailTrustGate, normalizeMergeRiskLevel, MERGE_RISK_ORDER, } from './trust.js';
|
|
10
|
+
export type { TrustGateOptions, TrustGatePolicyResolutionOptions, TrustGatePolicyResolutionStep, TrustGateEvaluation, } from './trust.js';
|
|
6
11
|
export { computeTrustKpis, computeTrustKpisFromReports, formatTrustKpiConsole, formatTrustKpiJson, } from './trust-kpi.js';
|
|
12
|
+
export { toSarif, diffToSarif } from './sarif.js';
|
|
13
|
+
export type { SarifLevel, DriftSarifRule, DriftSarifResult, DriftSarifRun, DriftSarifLog, } from './sarif.js';
|
|
7
14
|
export { generateArchitectureMap, generateArchitectureSvg } from './map.js';
|
|
8
|
-
export type { DriftReport, FileReport, DriftIssue, DriftDiff, FileDiff, DriftConfig, RepoQualityScore, MaintenanceRiskMetrics, DriftTrustReport, TrustReason, TrustFixPriority, TrustDiffContext, TrustKpiReport, TrustKpiDiagnostic, TrustDiffTrendSummary, TrustScoreStats, MergeRiskLevel, DriftPlugin, DriftPluginRule, } from './types.js';
|
|
15
|
+
export type { DriftReport, FileReport, DriftIssue, DriftDiff, FileDiff, DriftConfig, RepoQualityScore, MaintenanceRiskMetrics, DriftTrustReport, TrustReason, TrustFixPriority, TrustDiffContext, TrustKpiReport, TrustKpiDiagnostic, TrustDiffTrendSummary, TrustScoreStats, MergeRiskLevel, DriftPlugin, DriftPluginRule, TrustGatePolicyConfig, TrustAdvancedContext, } from './types.js';
|
|
9
16
|
export { loadHistory, saveSnapshot } from './snapshot.js';
|
|
10
17
|
export type { SnapshotEntry, SnapshotHistory } from './snapshot.js';
|
|
11
18
|
export { DEFAULT_SAAS_POLICY, defaultSaasStorePath, resolveSaasPolicy, SaasActorRequiredError, SaasPermissionError, getRequiredRoleForOperation, assertSaasPermission, getSaasEffectiveLimits, getOrganizationEffectiveLimits, changeOrganizationPlan, listOrganizationPlanChanges, getOrganizationUsageSnapshot, ingestSnapshotFromReport, listSaasSnapshots, getSaasSummary, generateSaasDashboardHtml, } from './saas.js';
|
|
12
|
-
export type { SaasRole, SaasPlan, SaasPolicy, SaasPolicyOverrides, SaasStore, SaasSummary, SaasSnapshot, SaasQueryOptions, IngestOptions, SaasPlanChange, SaasOperation, SaasPermissionContext, SaasPermissionResult, SaasEffectiveLimits, SaasOrganizationUsageSnapshot, ChangeOrganizationPlanOptions, SaasUsageQueryOptions, SaasPlanChangeQueryOptions, } from './saas.js';
|
|
19
|
+
export type { SaasUser, SaasOrganization, SaasWorkspace, SaasRepo, SaasMembership, SaasRole, SaasPlan, SaasPolicy, SaasPolicyOverrides, SaasStore, SaasSummary, SaasSnapshot, SaasQueryOptions, IngestOptions, SaasPlanChange, SaasOperation, SaasPermissionContext, SaasPermissionResult, SaasEffectiveLimits, SaasOrganizationUsageSnapshot, ChangeOrganizationPlanOptions, SaasUsageQueryOptions, SaasPlanChangeQueryOptions, } from './saas.js';
|
|
13
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export { analyzeProject, analyzeFile, RULE_WEIGHTS } from './analyzer.js';
|
|
2
2
|
export { buildReport, formatMarkdown } from './reporter.js';
|
|
3
3
|
export { computeDiff } from './diff.js';
|
|
4
|
+
export { runGuard, evaluateGuard } from './guard.js';
|
|
4
5
|
export { generateReview, formatReviewMarkdown } from './review.js';
|
|
5
|
-
export {
|
|
6
|
+
export { runDoctor } from './doctor.js';
|
|
7
|
+
export { buildTrustReport, formatTrustConsole, formatTrustMarkdown, formatTrustJson, resolveTrustGatePolicy, evaluateTrustGate, shouldFailByMaxRisk, shouldFailTrustGate, normalizeMergeRiskLevel, MERGE_RISK_ORDER, } from './trust.js';
|
|
6
8
|
export { computeTrustKpis, computeTrustKpisFromReports, formatTrustKpiConsole, formatTrustKpiJson, } from './trust-kpi.js';
|
|
9
|
+
export { toSarif, diffToSarif } from './sarif.js';
|
|
7
10
|
export { generateArchitectureMap, generateArchitectureSvg } from './map.js';
|
|
8
11
|
export { loadHistory, saveSnapshot } from './snapshot.js';
|
|
9
12
|
export { DEFAULT_SAAS_POLICY, defaultSaasStorePath, resolveSaasPolicy, SaasActorRequiredError, SaasPermissionError, getRequiredRoleForOperation, assertSaasPermission, getSaasEffectiveLimits, getOrganizationEffectiveLimits, changeOrganizationPlan, listOrganizationPlanChanges, getOrganizationUsageSnapshot, ingestSnapshotFromReport, listSaasSnapshots, getSaasSummary, generateSaasDashboardHtml, } from './saas.js';
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface InitOptions {
|
|
2
|
+
preset?: string;
|
|
3
|
+
ci?: boolean;
|
|
4
|
+
baseline?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const INIT_PRESETS: readonly ["node-backend", "react-app", "hexagonal", "monorepo"];
|
|
7
|
+
/**
|
|
8
|
+
* Initialize drift configuration with optional presets and scaffolding.
|
|
9
|
+
*
|
|
10
|
+
* @param projectRoot - Absolute path to project root
|
|
11
|
+
* @param options - Init options from CLI
|
|
12
|
+
*/
|
|
13
|
+
export declare function runInit(projectRoot: string, options: InitOptions): Promise<void>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=init.d.ts.map
|