@mergesignal/shared 0.2.7 → 0.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/dist/actionsStepSummary.d.ts.map +1 -1
- package/dist/actionsStepSummary.js +2 -29
- package/dist/collectNarrativeWhyBullets.d.ts +12 -0
- package/dist/collectNarrativeWhyBullets.d.ts.map +1 -0
- package/dist/collectNarrativeWhyBullets.js +104 -0
- package/dist/deriveScanNarrative.d.ts +0 -3
- package/dist/deriveScanNarrative.d.ts.map +1 -1
- package/dist/deriveScanNarrative.js +177 -63
- package/dist/deriveScanNarrative.test.js +90 -6
- package/dist/engineWireRegression.test.d.ts +2 -0
- package/dist/engineWireRegression.test.d.ts.map +1 -0
- package/dist/engineWireRegression.test.js +57 -0
- package/dist/fixtures/legacyEngineRepoIntelligence.d.ts +28 -0
- package/dist/fixtures/legacyEngineRepoIntelligence.d.ts.map +1 -0
- package/dist/fixtures/legacyEngineRepoIntelligence.js +28 -0
- package/dist/fixtures/repoIntelligenceFixtures.d.ts +2 -2
- package/dist/fixtures/repoIntelligenceFixtures.d.ts.map +1 -1
- package/dist/fixtures/repoIntelligenceFixtures.js +59 -3
- package/dist/fixtures/repoIntelligenceTestHelpers.d.ts +5 -0
- package/dist/fixtures/repoIntelligenceTestHelpers.d.ts.map +1 -0
- package/dist/fixtures/repoIntelligenceTestHelpers.js +28 -0
- package/dist/formatInsight.d.ts +2 -2
- package/dist/formatInsight.d.ts.map +1 -1
- package/dist/formatInsight.js +2 -7
- package/dist/formatInsight.test.js +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/narrativeParity.test.d.ts +2 -0
- package/dist/narrativeParity.test.d.ts.map +1 -0
- package/dist/narrativeParity.test.js +65 -0
- package/dist/narrativePresentation.d.ts +50 -0
- package/dist/narrativePresentation.d.ts.map +1 -0
- package/dist/narrativePresentation.js +180 -0
- package/dist/narrativePresentation.test.d.ts +2 -0
- package/dist/narrativePresentation.test.d.ts.map +1 -0
- package/dist/narrativePresentation.test.js +54 -0
- package/dist/normalizeGeneratedText.d.ts +8 -0
- package/dist/normalizeGeneratedText.d.ts.map +1 -0
- package/dist/normalizeGeneratedText.js +31 -0
- package/dist/normalizeGeneratedText.test.d.ts +2 -0
- package/dist/normalizeGeneratedText.test.d.ts.map +1 -0
- package/dist/normalizeGeneratedText.test.js +18 -0
- package/dist/prCheckRunPresentation.d.ts +4 -3
- package/dist/prCheckRunPresentation.d.ts.map +1 -1
- package/dist/prCheckRunPresentation.js +56 -51
- package/dist/prCheckRunPresentation.test.js +2 -2
- package/dist/presentGitHubPrComment.d.ts +9 -0
- package/dist/presentGitHubPrComment.d.ts.map +1 -0
- package/dist/presentGitHubPrComment.js +80 -0
- package/dist/presentScanCardSummary.d.ts.map +1 -1
- package/dist/presentScanCardSummary.js +69 -64
- package/dist/repoIntelligenceMappers.d.ts +20 -0
- package/dist/repoIntelligenceMappers.d.ts.map +1 -0
- package/dist/repoIntelligenceMappers.js +60 -0
- package/dist/repoIntelligenceSchema.contract.test.d.ts +2 -0
- package/dist/repoIntelligenceSchema.contract.test.d.ts.map +1 -0
- package/dist/repoIntelligenceSchema.contract.test.js +19 -0
- package/dist/repoIntelligenceSchema.d.ts +52 -83
- package/dist/repoIntelligenceSchema.d.ts.map +1 -1
- package/dist/repoIntelligenceSchema.js +99 -141
- package/dist/repoIntelligenceValidation.d.ts +18 -0
- package/dist/repoIntelligenceValidation.d.ts.map +1 -0
- package/dist/repoIntelligenceValidation.js +76 -0
- package/dist/repoIntelligenceValidation.persist.test.d.ts +2 -0
- package/dist/repoIntelligenceValidation.persist.test.d.ts.map +1 -0
- package/dist/repoIntelligenceValidation.persist.test.js +44 -0
- package/dist/riskVocabulary.js +1 -1
- package/dist/scanCardSummary.d.ts +9 -1
- package/dist/scanCardSummary.d.ts.map +1 -1
- package/dist/scanCardSummary.js +1 -1
- package/dist/scanCardSummary.test.js +12 -8
- package/dist/scanDetailViewModel.d.ts +9 -1
- package/dist/scanDetailViewModel.d.ts.map +1 -1
- package/dist/scanDetailViewModel.js +164 -37
- package/dist/scanDetailViewModel.test.js +28 -1
- package/dist/scanNarrativeFacts.d.ts +23 -8
- package/dist/scanNarrativeFacts.d.ts.map +1 -1
- package/dist/scanNarrativeFacts.js +7 -0
- package/dist/scanSurfaceCopy.d.ts +26 -26
- package/dist/scanSurfaceCopy.d.ts.map +1 -1
- package/dist/scanSurfaceCopy.js +26 -26
- package/dist/types.d.ts +15 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,35 +1,11 @@
|
|
|
1
|
-
import { phraseForFamily, } from "./cardObservationCatalog.js";
|
|
2
|
-
import { aggregateFindingCounts, deriveRiskIndexBand, } from "./scanCardSummary.js";
|
|
1
|
+
import { isCatalogPhrase, phraseForFamily, } from "./cardObservationCatalog.js";
|
|
2
|
+
import { aggregateFindingCounts, deriveRiskIndexBand, SCAN_CARD_SCANNING_SUMMARY, } from "./scanCardSummary.js";
|
|
3
3
|
import { deriveCardExposureDisplay, } from "./formatCardExposureDisplay.js";
|
|
4
4
|
import { formatCardAreaLabels } from "./formatCardAreaLabels.js";
|
|
5
|
+
import { composeContextLineFromFacts, composeVerificationPrompt, formatBlastRadiusDetailLine, formatChangedPackagesShort, formatFrameworksSummary, formatUsageSummaryLine, labelBlastRadiusLevel, labelReachabilityKind, labelRuntimeSurface, } from "./narrativePresentation.js";
|
|
6
|
+
import { normalizeGeneratedText, normalizeGeneratedTextNullable, } from "./normalizeGeneratedText.js";
|
|
5
7
|
import { MERGE_POSTURE_LABEL } from "./riskVocabulary.js";
|
|
6
8
|
import { scanSurfaceCopy } from "./scanSurfaceCopy.js";
|
|
7
|
-
function formatChangedPackagesDisplay(facts) {
|
|
8
|
-
const { primary, others } = facts.changedPackages;
|
|
9
|
-
if (!primary)
|
|
10
|
-
return null;
|
|
11
|
-
if (others.length === 0)
|
|
12
|
-
return primary;
|
|
13
|
-
return `${primary} +${others.length}`;
|
|
14
|
-
}
|
|
15
|
-
function labelRuntimeSurface(facts) {
|
|
16
|
-
const rs = facts.runtimeSurface;
|
|
17
|
-
if (!rs)
|
|
18
|
-
return null;
|
|
19
|
-
return scanSurfaceCopy.narrativeCard.runtimeSurface[rs.kind];
|
|
20
|
-
}
|
|
21
|
-
function labelReachability(facts) {
|
|
22
|
-
const r = facts.reachability;
|
|
23
|
-
if (!r)
|
|
24
|
-
return null;
|
|
25
|
-
return scanSurfaceCopy.narrativeCard.reachability[r.kind];
|
|
26
|
-
}
|
|
27
|
-
function labelBlastRadius(facts) {
|
|
28
|
-
const br = facts.blastRadius;
|
|
29
|
-
if (!br)
|
|
30
|
-
return null;
|
|
31
|
-
return scanSurfaceCopy.narrativeCard.blastRadius[br.level];
|
|
32
|
-
}
|
|
33
9
|
function formatAffectedAreaLabels(facts) {
|
|
34
10
|
const ordered = [];
|
|
35
11
|
for (const area of facts.affectedAreas) {
|
|
@@ -62,7 +38,7 @@ function selectSecondaryLines(facts, exclude) {
|
|
|
62
38
|
}
|
|
63
39
|
return lines;
|
|
64
40
|
}
|
|
65
|
-
function repositoryContextPhrases(facts) {
|
|
41
|
+
function repositoryContextPhrases(facts, max) {
|
|
66
42
|
const phrases = [];
|
|
67
43
|
const seen = new Set();
|
|
68
44
|
for (const ctx of facts.repositoryContext) {
|
|
@@ -71,32 +47,13 @@ function repositoryContextPhrases(facts) {
|
|
|
71
47
|
continue;
|
|
72
48
|
seen.add(phrase);
|
|
73
49
|
phrases.push(phrase);
|
|
74
|
-
if (phrases.length >=
|
|
50
|
+
if (phrases.length >= max)
|
|
75
51
|
break;
|
|
76
52
|
}
|
|
77
53
|
return phrases;
|
|
78
54
|
}
|
|
79
|
-
function
|
|
80
|
-
const
|
|
81
|
-
const runtime = labelRuntimeSurface(facts);
|
|
82
|
-
const reach = labelReachability(facts);
|
|
83
|
-
const blast = labelBlastRadius(facts);
|
|
84
|
-
if (runtime)
|
|
85
|
-
parts.push(runtime);
|
|
86
|
-
if (reach)
|
|
87
|
-
parts.push(reach);
|
|
88
|
-
if (blast)
|
|
89
|
-
parts.push(blast);
|
|
90
|
-
const areas = formatAffectedAreaLabels(facts);
|
|
91
|
-
if (areas.length > 0) {
|
|
92
|
-
parts.push(areas.join(scanSurfaceCopy.narrativeCard.areasSeparator));
|
|
93
|
-
}
|
|
94
|
-
if (parts.length === 0)
|
|
95
|
-
return null;
|
|
96
|
-
return parts.join(scanSurfaceCopy.narrativeCard.contextSeparator);
|
|
97
|
-
}
|
|
98
|
-
function buildLegacyObservations(facts, primaryInsight) {
|
|
99
|
-
const repoPhrases = repositoryContextPhrases(facts);
|
|
55
|
+
function buildLegacyObservations(facts, primaryInsight, repoPhraseCap) {
|
|
56
|
+
const repoPhrases = repositoryContextPhrases(facts, repoPhraseCap);
|
|
100
57
|
const secondary = selectSecondaryLines(facts, primaryInsight);
|
|
101
58
|
if (primaryInsight) {
|
|
102
59
|
return {
|
|
@@ -110,10 +67,34 @@ function buildLegacyObservations(facts, primaryInsight) {
|
|
|
110
67
|
return { operationalObservations: [], supportingLine: null };
|
|
111
68
|
}
|
|
112
69
|
return {
|
|
113
|
-
operationalObservations: repoPhrases.slice(0,
|
|
70
|
+
operationalObservations: repoPhrases.slice(0, repoPhraseCap),
|
|
114
71
|
supportingLine: repoPhrases.length === 1 ? (secondary[0] ?? null) : null,
|
|
115
72
|
};
|
|
116
73
|
}
|
|
74
|
+
function normalizeCardSummary(summary) {
|
|
75
|
+
return {
|
|
76
|
+
...summary,
|
|
77
|
+
headline: normalizeGeneratedText(summary.headline),
|
|
78
|
+
summaryLine: normalizeGeneratedTextNullable(summary.summaryLine),
|
|
79
|
+
supportingLine: normalizeGeneratedTextNullable(summary.supportingLine),
|
|
80
|
+
changedPackagesDisplay: normalizeGeneratedTextNullable(summary.changedPackagesDisplay),
|
|
81
|
+
runtimeSurfaceLabel: normalizeGeneratedTextNullable(summary.runtimeSurfaceLabel),
|
|
82
|
+
reachabilityLabel: normalizeGeneratedTextNullable(summary.reachabilityLabel),
|
|
83
|
+
blastRadiusLabel: normalizeGeneratedTextNullable(summary.blastRadiusLabel),
|
|
84
|
+
primaryInsight: normalizeGeneratedTextNullable(summary.primaryInsight),
|
|
85
|
+
structuralOnlyDisclaimer: normalizeGeneratedTextNullable(summary.structuralOnlyDisclaimer),
|
|
86
|
+
usageSummary: normalizeGeneratedTextNullable(summary.usageSummary),
|
|
87
|
+
verificationLine: normalizeGeneratedTextNullable(summary.verificationLine),
|
|
88
|
+
blastRadiusDetail: normalizeGeneratedTextNullable(summary.blastRadiusDetail),
|
|
89
|
+
frameworksSummary: normalizeGeneratedTextNullable(summary.frameworksSummary),
|
|
90
|
+
affectedAreas: summary.affectedAreas.map((a) => normalizeGeneratedText(a)),
|
|
91
|
+
topAffectedAreas: summary.topAffectedAreas.map((a) => normalizeGeneratedText(a)),
|
|
92
|
+
operationalObservations: summary.operationalObservations.map((p) => {
|
|
93
|
+
const normalized = normalizeGeneratedText(p);
|
|
94
|
+
return isCatalogPhrase(normalized) ? normalized : p;
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
117
98
|
/**
|
|
118
99
|
* Dashboard card presentation DTO from consumer-agnostic facts.
|
|
119
100
|
*/
|
|
@@ -129,23 +110,27 @@ export function presentScanCardSummary(facts, options = {}) {
|
|
|
129
110
|
affectedAreas: [],
|
|
130
111
|
primaryInsight: null,
|
|
131
112
|
structuralOnlyDisclaimer: null,
|
|
113
|
+
usageSummary: null,
|
|
114
|
+
verificationLine: null,
|
|
115
|
+
blastRadiusDetail: null,
|
|
116
|
+
frameworksSummary: null,
|
|
132
117
|
};
|
|
133
118
|
if (pipelineStatus === "queued" || pipelineStatus === "running") {
|
|
134
|
-
return {
|
|
119
|
+
return normalizeCardSummary({
|
|
135
120
|
mergePosture: null,
|
|
136
121
|
riskIndex: null,
|
|
137
122
|
riskIndexBand: null,
|
|
138
123
|
headline: scanSurfaceCopy.pipeline.scanRunning,
|
|
139
|
-
summaryLine:
|
|
124
|
+
summaryLine: SCAN_CARD_SCANNING_SUMMARY,
|
|
140
125
|
findingCounts: null,
|
|
141
126
|
topAffectedAreas: [],
|
|
142
127
|
operationalObservations: [],
|
|
143
128
|
supportingLine: null,
|
|
144
129
|
...emptyPresentationFields,
|
|
145
|
-
};
|
|
130
|
+
});
|
|
146
131
|
}
|
|
147
132
|
if (pipelineStatus === "failed") {
|
|
148
|
-
return {
|
|
133
|
+
return normalizeCardSummary({
|
|
149
134
|
mergePosture: null,
|
|
150
135
|
riskIndex: null,
|
|
151
136
|
riskIndexBand: null,
|
|
@@ -156,7 +141,7 @@ export function presentScanCardSummary(facts, options = {}) {
|
|
|
156
141
|
operationalObservations: [],
|
|
157
142
|
supportingLine: null,
|
|
158
143
|
...emptyPresentationFields,
|
|
159
|
-
};
|
|
144
|
+
});
|
|
160
145
|
}
|
|
161
146
|
const posture = facts.mergePosture;
|
|
162
147
|
const riskIndex = facts.riskIndex;
|
|
@@ -167,12 +152,17 @@ export function presentScanCardSummary(facts, options = {}) {
|
|
|
167
152
|
const findingCounts = options.findings
|
|
168
153
|
? aggregateFindingCounts(options.findings)
|
|
169
154
|
: null;
|
|
170
|
-
const
|
|
155
|
+
const prIntelligence = facts.availability.mode === "pr_intelligence" ||
|
|
156
|
+
facts.availability.tiersPresent.tier1;
|
|
157
|
+
const changedPackagesDisplay = formatChangedPackagesShort(facts, 2);
|
|
171
158
|
const runtimeSurfaceLabel = labelRuntimeSurface(facts);
|
|
172
|
-
const reachabilityLabel =
|
|
173
|
-
const blastRadiusLabel =
|
|
159
|
+
const reachabilityLabel = labelReachabilityKind(facts);
|
|
160
|
+
const blastRadiusLabel = labelBlastRadiusLevel(facts);
|
|
174
161
|
const affectedAreas = formatAffectedAreaLabels(facts);
|
|
175
|
-
const contextLine =
|
|
162
|
+
const contextLine = composeContextLineFromFacts(facts, {
|
|
163
|
+
includePathSample: prIntelligence,
|
|
164
|
+
maxAreas: 2,
|
|
165
|
+
});
|
|
176
166
|
const structuralOnlyDisclaimer = facts.availability.mode === "graph_fallback" &&
|
|
177
167
|
!facts.availability.tiersPresent.tier1
|
|
178
168
|
? scanSurfaceCopy.narrativeCard.structuralOnlyDisclaimer
|
|
@@ -180,8 +170,19 @@ export function presentScanCardSummary(facts, options = {}) {
|
|
|
180
170
|
const insightMessage = selectPrimaryInsight(facts);
|
|
181
171
|
const primaryInsight = insightMessage ??
|
|
182
172
|
(facts.availability.mode !== "graph_fallback" ? contextLine : null);
|
|
183
|
-
const
|
|
184
|
-
|
|
173
|
+
const usageSummary = prIntelligence ? formatUsageSummaryLine(facts, 1) : null;
|
|
174
|
+
const verificationLine = prIntelligence
|
|
175
|
+
? composeVerificationPrompt(facts)
|
|
176
|
+
: null;
|
|
177
|
+
const blastRadiusDetail = prIntelligence
|
|
178
|
+
? formatBlastRadiusDetailLine(facts, 1)
|
|
179
|
+
: null;
|
|
180
|
+
const frameworksSummary = prIntelligence
|
|
181
|
+
? formatFrameworksSummary(facts, 2)
|
|
182
|
+
: null;
|
|
183
|
+
const repoPhraseCap = prIntelligence ? 0 : 3;
|
|
184
|
+
const { operationalObservations, supportingLine } = buildLegacyObservations(facts, primaryInsight, repoPhraseCap);
|
|
185
|
+
return normalizeCardSummary({
|
|
185
186
|
mergePosture: posture,
|
|
186
187
|
riskIndex,
|
|
187
188
|
riskIndexBand,
|
|
@@ -200,7 +201,11 @@ export function presentScanCardSummary(facts, options = {}) {
|
|
|
200
201
|
affectedAreas,
|
|
201
202
|
primaryInsight,
|
|
202
203
|
structuralOnlyDisclaimer,
|
|
203
|
-
|
|
204
|
+
usageSummary,
|
|
205
|
+
verificationLine,
|
|
206
|
+
blastRadiusDetail,
|
|
207
|
+
frameworksSummary,
|
|
208
|
+
});
|
|
204
209
|
}
|
|
205
210
|
export function exposureFromFacts(facts) {
|
|
206
211
|
return deriveCardExposureDisplay(facts.riskIndex) ?? null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BlastRadiusLevel, ReachabilityKind, RuntimeSurfaceKind } from "./scanNarrativeFacts.js";
|
|
2
|
+
/** Engine-internal blast radius vocabulary → canonical wire. */
|
|
3
|
+
export type EngineBlastRadiusLevel = "small" | "moderate" | "large";
|
|
4
|
+
/** Engine-internal reachability spread buckets. */
|
|
5
|
+
export type EngineReachabilityBucket = "very_low" | "low" | "moderate" | "high";
|
|
6
|
+
/** Engine-internal runtime surface labels. */
|
|
7
|
+
export type EngineRuntimeSurface = "runtime" | "test" | "build" | "dev" | "ci";
|
|
8
|
+
export declare function mapBlastRadiusLevel(level: EngineBlastRadiusLevel): BlastRadiusLevel;
|
|
9
|
+
export declare function mapRuntimeSurfaceKind(surface: EngineRuntimeSurface): RuntimeSurfaceKind;
|
|
10
|
+
/**
|
|
11
|
+
* Maps engine reachability spread + runtime classification to narrative reachability kind.
|
|
12
|
+
* Documented in repoIntelligenceSchema.ts header.
|
|
13
|
+
*/
|
|
14
|
+
export declare function mapReachabilityKind(input: {
|
|
15
|
+
bucket: EngineReachabilityBucket;
|
|
16
|
+
reachesRuntime: boolean;
|
|
17
|
+
dominantSurface: EngineRuntimeSurface;
|
|
18
|
+
}): ReachabilityKind;
|
|
19
|
+
export declare function areaSlugToLabel(slug: string): string;
|
|
20
|
+
//# sourceMappingURL=repoIntelligenceMappers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoIntelligenceMappers.d.ts","sourceRoot":"","sources":["../src/repoIntelligenceMappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AAEjC,gEAAgE;AAChE,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEpE,mDAAmD;AACnD,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC;AAEhF,8CAA8C;AAC9C,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;AAE/E,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,sBAAsB,GAC5B,gBAAgB,CAalB;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,oBAAoB,GAC5B,kBAAkB,CAapB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,wBAAwB,CAAC;IACjC,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,oBAAoB,CAAC;CACvC,GAAG,gBAAgB,CAwBnB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKpD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export function mapBlastRadiusLevel(level) {
|
|
2
|
+
switch (level) {
|
|
3
|
+
case "small":
|
|
4
|
+
return "narrow";
|
|
5
|
+
case "moderate":
|
|
6
|
+
return "moderate";
|
|
7
|
+
case "large":
|
|
8
|
+
return "wide";
|
|
9
|
+
default: {
|
|
10
|
+
const x = level;
|
|
11
|
+
return x;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function mapRuntimeSurfaceKind(surface) {
|
|
16
|
+
switch (surface) {
|
|
17
|
+
case "runtime":
|
|
18
|
+
return "runtime";
|
|
19
|
+
case "test":
|
|
20
|
+
return "test";
|
|
21
|
+
case "build":
|
|
22
|
+
case "dev":
|
|
23
|
+
case "ci":
|
|
24
|
+
return "build";
|
|
25
|
+
default:
|
|
26
|
+
return "unknown";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Maps engine reachability spread + runtime classification to narrative reachability kind.
|
|
31
|
+
* Documented in repoIntelligenceSchema.ts header.
|
|
32
|
+
*/
|
|
33
|
+
export function mapReachabilityKind(input) {
|
|
34
|
+
const { bucket, reachesRuntime, dominantSurface } = input;
|
|
35
|
+
if (dominantSurface === "test" && !reachesRuntime) {
|
|
36
|
+
return "test_only";
|
|
37
|
+
}
|
|
38
|
+
if ((dominantSurface === "build" ||
|
|
39
|
+
dominantSurface === "dev" ||
|
|
40
|
+
dominantSurface === "ci") &&
|
|
41
|
+
!reachesRuntime) {
|
|
42
|
+
return "build_only";
|
|
43
|
+
}
|
|
44
|
+
if (reachesRuntime) {
|
|
45
|
+
return "on_runtime_paths";
|
|
46
|
+
}
|
|
47
|
+
if (bucket === "very_low" || bucket === "low") {
|
|
48
|
+
return "unreachable";
|
|
49
|
+
}
|
|
50
|
+
if (bucket === "moderate" || bucket === "high") {
|
|
51
|
+
return "on_runtime_paths";
|
|
52
|
+
}
|
|
53
|
+
return "unknown";
|
|
54
|
+
}
|
|
55
|
+
export function areaSlugToLabel(slug) {
|
|
56
|
+
return slug
|
|
57
|
+
.split("_")
|
|
58
|
+
.map((w) => (w ? w[0].toUpperCase() + w.slice(1) : w))
|
|
59
|
+
.join(" ");
|
|
60
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoIntelligenceSchema.contract.test.d.ts","sourceRoot":"","sources":["../src/repoIntelligenceSchema.contract.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { fixtureRepoIntelligenceFastify, fixtureRepoIntelligenceMultiPackage, } from "./fixtures/repoIntelligenceFixtures.js";
|
|
3
|
+
import { legacyEngineRepoIntelligenceJwt } from "./fixtures/legacyEngineRepoIntelligence.js";
|
|
4
|
+
import { safeParseRepoIntelligence, validateRepoIntelligenceWire, } from "./repoIntelligenceSchema.js";
|
|
5
|
+
describe("repoIntelligenceWireSchema contract", () => {
|
|
6
|
+
it("accepts canonical consumer fixtures", () => {
|
|
7
|
+
expect(() => validateRepoIntelligenceWire(fixtureRepoIntelligenceFastify)).not.toThrow();
|
|
8
|
+
expect(() => validateRepoIntelligenceWire(fixtureRepoIntelligenceMultiPackage)).not.toThrow();
|
|
9
|
+
});
|
|
10
|
+
it("rejects legacy engine wire (name, large blast, object frameworks, file hotspots)", () => {
|
|
11
|
+
const r = safeParseRepoIntelligence(legacyEngineRepoIntelligenceJwt);
|
|
12
|
+
expect(r.ok).toBe(false);
|
|
13
|
+
if (r.ok)
|
|
14
|
+
return;
|
|
15
|
+
expect(r.issueCount).toBeGreaterThan(0);
|
|
16
|
+
const joined = r.issues.join(" ");
|
|
17
|
+
expect(joined.length).toBeGreaterThan(0);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -1,106 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical `ScanResult.repoIntelligence` wire contract (Wave 1 + Wave 2).
|
|
3
|
+
*
|
|
4
|
+
* Bump {@link REPO_INTELLIGENCE_ABI} when this schema changes incompatibly.
|
|
5
|
+
* Engine maps internal signals to this shape at emit time; consumers must use
|
|
6
|
+
* {@link safeParseRepoIntelligence} and honor `analysisPreparation.repoIntelligenceValidation`.
|
|
7
|
+
*/
|
|
1
8
|
import { z } from "zod";
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}, z.core.$loose>]>;
|
|
11
|
-
declare const looseReachabilitySchema: z.ZodUnion<readonly [z.ZodEnum<{
|
|
12
|
-
unknown: "unknown";
|
|
13
|
-
on_runtime_paths: "on_runtime_paths";
|
|
14
|
-
build_only: "build_only";
|
|
15
|
-
test_only: "test_only";
|
|
16
|
-
unreachable: "unreachable";
|
|
17
|
-
}>, z.ZodString, z.ZodObject<{
|
|
18
|
-
kind: z.ZodString;
|
|
19
|
-
}, z.core.$loose>]>;
|
|
20
|
-
export declare const repoIntelligenceSchema: z.ZodObject<{
|
|
21
|
-
packages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
22
|
-
runtimeSurface: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
9
|
+
import type { ScanResult } from "./types.js";
|
|
10
|
+
import type { BlastRadiusLevel } from "./scanNarrativeFacts.js";
|
|
11
|
+
/** Bump when wire schema changes incompatibly. */
|
|
12
|
+
export declare const REPO_INTELLIGENCE_ABI: "1";
|
|
13
|
+
/** Strict canonical wire schema — single source of truth. */
|
|
14
|
+
export declare const repoIntelligenceWireSchema: z.ZodObject<{
|
|
15
|
+
packages: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
16
|
+
runtimeSurface: z.ZodEnum<{
|
|
23
17
|
unknown: "unknown";
|
|
24
18
|
runtime: "runtime";
|
|
25
19
|
build: "build";
|
|
26
20
|
test: "test";
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
}, z.core.$loose>]>>;
|
|
30
|
-
reachability: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
21
|
+
}>;
|
|
22
|
+
reachability: z.ZodEnum<{
|
|
31
23
|
unknown: "unknown";
|
|
32
24
|
on_runtime_paths: "on_runtime_paths";
|
|
33
25
|
build_only: "build_only";
|
|
34
26
|
test_only: "test_only";
|
|
35
27
|
unreachable: "unreachable";
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
packageName: z.ZodOptional<z.ZodString>;
|
|
41
|
-
package: z.ZodOptional<z.ZodString>;
|
|
42
|
-
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
28
|
+
}>;
|
|
29
|
+
usage: z.ZodObject<{
|
|
30
|
+
packageName: z.ZodString;
|
|
31
|
+
files: z.ZodArray<z.ZodString>;
|
|
43
32
|
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
44
33
|
criticalPaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
45
34
|
areas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
46
|
-
}, z.core.$
|
|
47
|
-
usage: z.ZodOptional<z.ZodObject<{
|
|
48
|
-
packageName: z.ZodOptional<z.ZodString>;
|
|
49
|
-
package: z.ZodOptional<z.ZodString>;
|
|
50
|
-
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
51
|
-
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
52
|
-
criticalPaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
53
|
-
areas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
54
|
-
}, z.core.$loose>>;
|
|
35
|
+
}, z.core.$strip>;
|
|
55
36
|
areas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
56
|
-
|
|
57
|
-
packageName: z.ZodOptional<z.ZodString>;
|
|
58
|
-
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
59
|
-
depth: z.ZodOptional<z.ZodNumber>;
|
|
60
|
-
}, z.core.$loose>>>;
|
|
61
|
-
}, z.core.$loose>>>;
|
|
37
|
+
}, z.core.$strip>>;
|
|
62
38
|
packageUsage: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
63
|
-
packageName: z.
|
|
64
|
-
|
|
65
|
-
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
39
|
+
packageName: z.ZodString;
|
|
40
|
+
files: z.ZodArray<z.ZodString>;
|
|
66
41
|
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
67
42
|
criticalPaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
68
43
|
areas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
69
|
-
}, z.core.$
|
|
44
|
+
}, z.core.$strip>>>;
|
|
70
45
|
blastRadius: z.ZodOptional<z.ZodObject<{
|
|
71
|
-
level: z.
|
|
46
|
+
level: z.ZodEnum<{
|
|
72
47
|
moderate: "moderate";
|
|
73
48
|
narrow: "narrow";
|
|
74
49
|
wide: "wide";
|
|
75
|
-
}
|
|
50
|
+
}>;
|
|
76
51
|
factors: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
77
52
|
changedPackageCount: z.ZodOptional<z.ZodNumber>;
|
|
78
|
-
}, z.core.$
|
|
79
|
-
runtimeSurface: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
80
|
-
unknown: "unknown";
|
|
81
|
-
runtime: "runtime";
|
|
82
|
-
build: "build";
|
|
83
|
-
test: "test";
|
|
84
|
-
}>, z.ZodString, z.ZodObject<{
|
|
85
|
-
kind: z.ZodString;
|
|
86
|
-
}, z.core.$loose>]>>;
|
|
87
|
-
reachability: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
88
|
-
unknown: "unknown";
|
|
89
|
-
on_runtime_paths: "on_runtime_paths";
|
|
90
|
-
build_only: "build_only";
|
|
91
|
-
test_only: "test_only";
|
|
92
|
-
unreachable: "unreachable";
|
|
93
|
-
}>, z.ZodString, z.ZodObject<{
|
|
94
|
-
kind: z.ZodString;
|
|
95
|
-
}, z.core.$loose>]>>;
|
|
53
|
+
}, z.core.$strip>>;
|
|
96
54
|
applicationAreas: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
97
55
|
id: z.ZodString;
|
|
98
56
|
label: z.ZodString;
|
|
99
|
-
}, z.core.$
|
|
57
|
+
}, z.core.$strip>>>;
|
|
100
58
|
affectedAreas: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
101
59
|
id: z.ZodString;
|
|
102
60
|
label: z.ZodString;
|
|
103
|
-
}, z.core.$
|
|
61
|
+
}, z.core.$strip>>>;
|
|
104
62
|
hotspots: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
105
63
|
packageName: z.ZodString;
|
|
106
64
|
source: z.ZodOptional<z.ZodEnum<{
|
|
@@ -108,16 +66,27 @@ export declare const repoIntelligenceSchema: z.ZodObject<{
|
|
|
108
66
|
graph: "graph";
|
|
109
67
|
}>>;
|
|
110
68
|
depth: z.ZodOptional<z.ZodNumber>;
|
|
111
|
-
paths: z.
|
|
112
|
-
}, z.core.$
|
|
69
|
+
paths: z.ZodArray<z.ZodString>;
|
|
70
|
+
}, z.core.$strip>>>;
|
|
113
71
|
frameworks: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
114
|
-
}, z.core.$
|
|
115
|
-
export type RepoIntelligence = z.infer<typeof
|
|
116
|
-
export
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
export
|
|
72
|
+
}, z.core.$strip>;
|
|
73
|
+
export type RepoIntelligence = z.infer<typeof repoIntelligenceWireSchema>;
|
|
74
|
+
export type ParseRepoIntelligenceSuccess = {
|
|
75
|
+
ok: true;
|
|
76
|
+
value: RepoIntelligence;
|
|
77
|
+
};
|
|
78
|
+
export type ParseRepoIntelligenceFailure = {
|
|
79
|
+
ok: false;
|
|
80
|
+
issues: string[];
|
|
81
|
+
issueCount: number;
|
|
82
|
+
packageCount: number;
|
|
83
|
+
};
|
|
84
|
+
export type ParseRepoIntelligenceResult = ParseRepoIntelligenceSuccess | ParseRepoIntelligenceFailure;
|
|
85
|
+
export declare function countRepoIntelligencePackages(raw: unknown): number;
|
|
86
|
+
export declare function safeParseRepoIntelligence(raw: unknown): ParseRepoIntelligenceResult;
|
|
87
|
+
/** Throws when wire block is present but invalid (CI / tests only). */
|
|
88
|
+
export declare function validateRepoIntelligenceWire(raw: unknown): RepoIntelligence;
|
|
89
|
+
/** CI helper — fails test when engine output includes invalid repoIntelligence. */
|
|
90
|
+
export declare function assertEngineOutputRepoIntelligenceValid(scan: ScanResult): void;
|
|
121
91
|
export declare function readBlastLevel(level: BlastRadiusLevel | undefined): BlastRadiusLevel | null;
|
|
122
|
-
export {};
|
|
123
92
|
//# sourceMappingURL=repoIntelligenceSchema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repoIntelligenceSchema.d.ts","sourceRoot":"","sources":["../src/repoIntelligenceSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"repoIntelligenceSchema.d.ts","sourceRoot":"","sources":["../src/repoIntelligenceSchema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,kDAAkD;AAClD,eAAO,MAAM,qBAAqB,EAAG,GAAY,CAAC;AA+ClD,6DAA6D;AAC7D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQrC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE1E,MAAM,MAAM,4BAA4B,GAAG;IACzC,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACnC,4BAA4B,GAC5B,4BAA4B,CAAC;AAQjC,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAUlE;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,GACX,2BAA2B,CAyC7B;AAED,uEAAuE;AACvE,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAM3E;AAED,mFAAmF;AACnF,wBAAgB,uCAAuC,CACrD,IAAI,EAAE,UAAU,GACf,IAAI,CAGN;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,gBAAgB,GAAG,SAAS,GAClC,gBAAgB,GAAG,IAAI,CAKzB"}
|