@decantr/verifier 2.1.0 → 2.3.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/README.md +3 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +35 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/schema/decantr-ci-report.v1.json +104 -0
package/README.md
CHANGED
|
@@ -18,8 +18,9 @@ npm install @decantr/verifier
|
|
|
18
18
|
- `critiqueFile()` for file-level review against compiled review-pack contracts
|
|
19
19
|
- `createContractAssertions()` for explicit route, shell, accessibility, context, and design-token assertions derived from Essence/context
|
|
20
20
|
- `createEvidenceBundle()` for privacy-redacted local evidence artifacts used by AI repair loops and CI
|
|
21
|
-
- schema-backed report types for project audits, Project Health, Evidence Bundles, Workspace Health, file critiques, and showcase verification
|
|
21
|
+
- schema-backed report types for project audits, Project Health, Decantr CI reports, Evidence Bundles, Workspace Health, file critiques, and showcase verification
|
|
22
22
|
- `ProjectHealthReport`, `ProjectHealthFinding`, and `ProjectHealthRemediation` types for the CLI's end-user health surface
|
|
23
|
+
- interaction findings now include scanned file counts, file line ranges, and expected signal evidence where available, so CLI health/check output can point agents at source-grounded remediation
|
|
23
24
|
- published verifier report schemas are exercised by AJV-backed round-trip tests against real audit, critique, and shortlist-report outputs
|
|
24
25
|
- project audits include runtime evidence when a built `dist/` output is present:
|
|
25
26
|
- root document
|
|
@@ -55,6 +56,7 @@ function isBlocking(report: ProjectHealthReport) {
|
|
|
55
56
|
- `@decantr/verifier/schema/verification-report.common.v1.json`
|
|
56
57
|
- `@decantr/verifier/schema/project-audit-report.v1.json`
|
|
57
58
|
- `@decantr/verifier/schema/project-health-report.v1.json`
|
|
59
|
+
- `@decantr/verifier/schema/decantr-ci-report.v1.json`
|
|
58
60
|
- `@decantr/verifier/schema/evidence-bundle.v1.json`
|
|
59
61
|
- `@decantr/verifier/schema/workspace-health-report.v1.json`
|
|
60
62
|
- `@decantr/verifier/schema/file-critique-report.v1.json`
|
package/dist/index.d.ts
CHANGED
|
@@ -97,6 +97,13 @@ declare const INTERACTION_SIGNALS: Record<string, InteractionRequirement>;
|
|
|
97
97
|
interface InteractionMissingFinding {
|
|
98
98
|
interaction: string;
|
|
99
99
|
suggestion: string;
|
|
100
|
+
scannedFiles?: number;
|
|
101
|
+
scannedLocations?: Array<{
|
|
102
|
+
file: string;
|
|
103
|
+
startLine: number;
|
|
104
|
+
endLine: number;
|
|
105
|
+
}>;
|
|
106
|
+
expectedSignals?: string[];
|
|
100
107
|
}
|
|
101
108
|
/**
|
|
102
109
|
* Scan a source-tree map (file path → file contents) for evidence of each
|
|
@@ -119,6 +126,7 @@ declare const VERIFICATION_SCHEMA_URLS: {
|
|
|
119
126
|
readonly common: "https://decantr.ai/schemas/verification-report.common.v1.json";
|
|
120
127
|
readonly projectAudit: "https://decantr.ai/schemas/project-audit-report.v1.json";
|
|
121
128
|
readonly projectHealth: "https://decantr.ai/schemas/project-health-report.v1.json";
|
|
129
|
+
readonly decantrCi: "https://decantr.ai/schemas/decantr-ci-report.v1.json";
|
|
122
130
|
readonly evidenceBundle: "https://decantr.ai/schemas/evidence-bundle.v1.json";
|
|
123
131
|
readonly workspaceHealth: "https://decantr.ai/schemas/workspace-health-report.v1.json";
|
|
124
132
|
readonly fileCritique: "https://decantr.ai/schemas/file-critique-report.v1.json";
|
package/dist/index.js
CHANGED
|
@@ -653,7 +653,7 @@ var INTERACTION_SIGNALS = {
|
|
|
653
653
|
},
|
|
654
654
|
"click-connect": {
|
|
655
655
|
interaction: "click-connect",
|
|
656
|
-
signals: [/onClick.*?port|connect/i, /connections?\s*[
|
|
656
|
+
signals: [/onClick.*?port|connect/i, /connections?\s*[:[=]/i],
|
|
657
657
|
suggestion: "Implement a two-click state machine: first click selects a port, second click on another port creates a connection. Store connections in component state."
|
|
658
658
|
},
|
|
659
659
|
"inline-edit": {
|
|
@@ -697,9 +697,11 @@ var INTERACTION_SIGNALS = {
|
|
|
697
697
|
suggestion: "Implement focus trap inside modal/dialog \u2014 listen for Tab key, cycle focus within the dialog, restore focus on close."
|
|
698
698
|
}
|
|
699
699
|
};
|
|
700
|
+
function sourceLineCount(source) {
|
|
701
|
+
return Math.max(1, source.replace(/\r?\n$/, "").split(/\r?\n/).length);
|
|
702
|
+
}
|
|
700
703
|
function verifyInteractionsInSource(interactions, sources) {
|
|
701
704
|
if (interactions.length === 0 || sources.size === 0) return [];
|
|
702
|
-
const combined = Array.from(sources.values()).join("\n\n");
|
|
703
705
|
const unique = Array.from(new Set(interactions));
|
|
704
706
|
const missing = [];
|
|
705
707
|
for (const interaction of unique) {
|
|
@@ -707,16 +709,30 @@ function verifyInteractionsInSource(interactions, sources) {
|
|
|
707
709
|
if (!requirement) {
|
|
708
710
|
continue;
|
|
709
711
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
712
|
+
let matched = false;
|
|
713
|
+
for (const source of sources.values()) {
|
|
714
|
+
matched = requirement.signals.some((signal) => {
|
|
715
|
+
if (typeof signal === "string") {
|
|
716
|
+
return source.includes(signal);
|
|
717
|
+
}
|
|
718
|
+
signal.lastIndex = 0;
|
|
719
|
+
return signal.test(source);
|
|
720
|
+
});
|
|
721
|
+
if (matched) break;
|
|
722
|
+
}
|
|
716
723
|
if (!matched) {
|
|
717
724
|
missing.push({
|
|
718
725
|
interaction,
|
|
719
|
-
suggestion: requirement.suggestion
|
|
726
|
+
suggestion: requirement.suggestion,
|
|
727
|
+
scannedFiles: sources.size,
|
|
728
|
+
scannedLocations: [...sources.entries()].slice(0, 8).map(([file, source]) => ({
|
|
729
|
+
file,
|
|
730
|
+
startLine: 1,
|
|
731
|
+
endLine: sourceLineCount(source)
|
|
732
|
+
})),
|
|
733
|
+
expectedSignals: requirement.signals.map(
|
|
734
|
+
(signal) => typeof signal === "string" ? signal : String(signal)
|
|
735
|
+
)
|
|
720
736
|
});
|
|
721
737
|
}
|
|
722
738
|
}
|
|
@@ -731,6 +747,7 @@ var VERIFICATION_SCHEMA_URLS = {
|
|
|
731
747
|
common: "https://decantr.ai/schemas/verification-report.common.v1.json",
|
|
732
748
|
projectAudit: "https://decantr.ai/schemas/project-audit-report.v1.json",
|
|
733
749
|
projectHealth: "https://decantr.ai/schemas/project-health-report.v1.json",
|
|
750
|
+
decantrCi: "https://decantr.ai/schemas/decantr-ci-report.v1.json",
|
|
734
751
|
evidenceBundle: "https://decantr.ai/schemas/evidence-bundle.v1.json",
|
|
735
752
|
workspaceHealth: "https://decantr.ai/schemas/workspace-health-report.v1.json",
|
|
736
753
|
fileCritique: "https://decantr.ai/schemas/file-critique-report.v1.json",
|
|
@@ -1689,6 +1706,11 @@ function buildRegistryContext(projectRoot) {
|
|
|
1689
1706
|
}
|
|
1690
1707
|
} catch {
|
|
1691
1708
|
}
|
|
1709
|
+
for (const id of ["content-section", "footer", "form-basic", "hero", "nav-header"]) {
|
|
1710
|
+
if (!patternRegistry.has(id)) {
|
|
1711
|
+
patternRegistry.set(id, { id, source: "bundled" });
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1692
1714
|
return { themeRegistry, patternRegistry };
|
|
1693
1715
|
}
|
|
1694
1716
|
function guardViolationToFinding(violation) {
|
|
@@ -2862,7 +2884,10 @@ function appendSourceAuditFindings(findings, sourceAudit, essence, reviewPack) {
|
|
|
2862
2884
|
})
|
|
2863
2885
|
);
|
|
2864
2886
|
}
|
|
2865
|
-
if (topology.hasAuthFeature && topology.primaryRoutes.length > 0 && sourceAudit.protectedSurfaceSignals.count > 0 && sourceAudit.authGuardSignals.count > 0 && !sourceAuditBucketsOverlap(sourceAudit.protectedSurfaceSignals, sourceAudit.authGuardSignals) && !sourceAuditBucketsOverlap(
|
|
2887
|
+
if (topology.hasAuthFeature && topology.primaryRoutes.length > 0 && sourceAudit.protectedSurfaceSignals.count > 0 && sourceAudit.authGuardSignals.count > 0 && !sourceAuditBucketsOverlap(sourceAudit.protectedSurfaceSignals, sourceAudit.authGuardSignals) && !sourceAuditBucketsOverlap(
|
|
2888
|
+
sourceAudit.protectedSurfaceSignals,
|
|
2889
|
+
sourceAudit.authSessionSignals
|
|
2890
|
+
) && !sourceAuditProtectedSurfacesCoveredByGuardedNextLayouts(
|
|
2866
2891
|
sourceAudit.protectedSurfaceSignals,
|
|
2867
2892
|
sourceAudit.authGuardSignals,
|
|
2868
2893
|
topology
|