@mergesignal/shared 0.4.2 → 0.5.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.
Files changed (193) hide show
  1. package/dist/actionsStepSummary.d.ts +1 -22
  2. package/dist/actionsStepSummary.d.ts.map +1 -1
  3. package/dist/actionsStepSummary.js +19 -716
  4. package/dist/actionsStepSummary.test.js +34 -329
  5. package/dist/assessmentLabels.d.ts +6 -0
  6. package/dist/assessmentLabels.d.ts.map +1 -0
  7. package/dist/assessmentLabels.js +33 -0
  8. package/dist/assessmentProjection.d.ts +12 -0
  9. package/dist/assessmentProjection.d.ts.map +1 -0
  10. package/dist/assessmentProjection.js +100 -0
  11. package/dist/assessmentSchema.d.ts +155 -0
  12. package/dist/assessmentSchema.d.ts.map +1 -0
  13. package/dist/assessmentSchema.js +110 -0
  14. package/dist/cardObservationCatalog.d.ts +2 -0
  15. package/dist/cardObservationCatalog.d.ts.map +1 -1
  16. package/dist/cardObservationCatalog.js +47 -1
  17. package/dist/engineWireRegression.test.js +24 -4
  18. package/dist/fixtures/assessmentFixtures.d.ts +13 -0
  19. package/dist/fixtures/assessmentFixtures.d.ts.map +1 -0
  20. package/dist/fixtures/assessmentFixtures.js +164 -0
  21. package/dist/formatCardExposureDisplay.d.ts +0 -4
  22. package/dist/formatCardExposureDisplay.d.ts.map +1 -1
  23. package/dist/formatCardExposureDisplay.js +0 -15
  24. package/dist/formatInsight.d.ts +3 -2
  25. package/dist/formatInsight.d.ts.map +1 -1
  26. package/dist/formatInsight.js +26 -1
  27. package/dist/index.d.ts +7 -11
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +7 -11
  30. package/dist/narrativeParity.test.js +6 -37
  31. package/dist/presentGitHubPrComment.d.ts +1 -3
  32. package/dist/presentGitHubPrComment.d.ts.map +1 -1
  33. package/dist/presentGitHubPrComment.js +0 -17
  34. package/dist/presentation/compose/narrativeChannels.d.ts +17 -0
  35. package/dist/presentation/compose/narrativeChannels.d.ts.map +1 -0
  36. package/dist/presentation/compose/narrativeChannels.js +45 -0
  37. package/dist/presentation/compose/narrativeChannels.test.d.ts +2 -0
  38. package/dist/presentation/compose/narrativeChannels.test.d.ts.map +1 -0
  39. package/dist/presentation/compose/narrativeChannels.test.js +42 -0
  40. package/dist/presentation/compose/narrativeCompose.d.ts +1 -0
  41. package/dist/presentation/compose/narrativeCompose.d.ts.map +1 -1
  42. package/dist/presentation/compose/narrativeCompose.js +5 -7
  43. package/dist/presentation/dto/assessmentPresentationFields.d.ts +13 -0
  44. package/dist/presentation/dto/assessmentPresentationFields.d.ts.map +1 -0
  45. package/dist/presentation/dto/dashboardCardPresentation.d.ts +30 -0
  46. package/dist/presentation/dto/dashboardCardPresentation.d.ts.map +1 -0
  47. package/dist/presentation/dto/dashboardCardPresentation.js +1 -0
  48. package/dist/presentation/dto/githubAndCliPresentation.d.ts +4 -3
  49. package/dist/presentation/dto/githubAndCliPresentation.d.ts.map +1 -1
  50. package/dist/presentation/dto/scanDetailsPresentation.d.ts +2 -1
  51. package/dist/presentation/dto/scanDetailsPresentation.d.ts.map +1 -1
  52. package/dist/presentation/dto/types.d.ts +0 -9
  53. package/dist/presentation/dto/types.d.ts.map +1 -1
  54. package/dist/presentation/dto/types.js +1 -22
  55. package/dist/presentation/fixtures/dashboardCardGolden.test.d.ts +2 -0
  56. package/dist/presentation/fixtures/dashboardCardGolden.test.d.ts.map +1 -0
  57. package/dist/presentation/fixtures/dashboardCardGolden.test.js +38 -0
  58. package/dist/presentation/fixtures/presentationPersonaFixtures.d.ts.map +1 -1
  59. package/dist/presentation/fixtures/presentationPersonaFixtures.js +31 -24
  60. package/dist/presentation/fixtures/scanResultFixtures.d.ts.map +1 -1
  61. package/dist/presentation/fixtures/scanResultFixtures.js +14 -3
  62. package/dist/presentation/index.d.ts +6 -6
  63. package/dist/presentation/index.d.ts.map +1 -1
  64. package/dist/presentation/index.js +2 -4
  65. package/dist/presentation/orchestration/buildScanCardPresentation.d.ts +2 -2
  66. package/dist/presentation/orchestration/buildScanCardPresentation.d.ts.map +1 -1
  67. package/dist/presentation/orchestration/buildScanCardPresentation.js +13 -9
  68. package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts +1 -1
  69. package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts.map +1 -1
  70. package/dist/presentation/orchestration/buildScanPresentationBundle.js +12 -10
  71. package/dist/presentation/orchestration/scanPresentationBundle.d.ts +8 -3
  72. package/dist/presentation/orchestration/scanPresentationBundle.d.ts.map +1 -1
  73. package/dist/presentation/presentation.test.js +16 -18
  74. package/dist/presentation/presentationPersonas.test.js +20 -19
  75. package/dist/presentation/presenters/presentCliScanSummary.d.ts.map +1 -1
  76. package/dist/presentation/presenters/presentCliScanSummary.js +4 -2
  77. package/dist/presentation/presenters/presentDashboardCard.d.ts +5 -0
  78. package/dist/presentation/presenters/presentDashboardCard.d.ts.map +1 -0
  79. package/dist/presentation/presenters/presentDashboardCard.js +119 -0
  80. package/dist/presentation/presenters/presentGitHubCheckRun.d.ts.map +1 -1
  81. package/dist/presentation/presenters/presentGitHubCheckRun.js +4 -2
  82. package/dist/presentation/presenters/presentGitHubPrComment.d.ts.map +1 -1
  83. package/dist/presentation/presenters/presentGitHubPrComment.js +15 -21
  84. package/dist/presentation/presenters/presentScanDetails.d.ts.map +1 -1
  85. package/dist/presentation/presenters/presentScanDetails.js +53 -127
  86. package/dist/presentation/profile/buildProfileFromAssessment.d.ts +5 -0
  87. package/dist/presentation/profile/buildProfileFromAssessment.d.ts.map +1 -0
  88. package/dist/presentation/profile/buildProfileFromAssessment.js +58 -0
  89. package/dist/presentation/projectAssessmentFields.d.ts +4 -0
  90. package/dist/presentation/projectAssessmentFields.d.ts.map +1 -0
  91. package/dist/presentation/projectAssessmentFields.js +13 -0
  92. package/dist/presentation/surfaceParity.test.d.ts +2 -0
  93. package/dist/presentation/surfaceParity.test.d.ts.map +1 -0
  94. package/dist/presentation/surfaceParity.test.js +74 -0
  95. package/dist/productMessaging.d.ts +4 -4
  96. package/dist/productMessaging.d.ts.map +1 -1
  97. package/dist/productMessaging.js +4 -4
  98. package/dist/productMessaging.test.js +2 -2
  99. package/dist/repoIntelligenceSchema.d.ts +2 -2
  100. package/dist/resolvePipelineStatus.d.ts +15 -0
  101. package/dist/resolvePipelineStatus.d.ts.map +1 -0
  102. package/dist/resolvePipelineStatus.js +37 -0
  103. package/dist/scanCardPresentationState.d.ts +4 -0
  104. package/dist/scanCardPresentationState.d.ts.map +1 -0
  105. package/dist/scanCardPresentationState.js +4 -0
  106. package/dist/{scanDetailViewModel.d.ts → scanDetailViewModelTypes.d.ts} +60 -32
  107. package/dist/scanDetailViewModelTypes.d.ts.map +1 -0
  108. package/dist/scanDetailViewModelTypes.js +4 -0
  109. package/dist/scanResultSchema.d.ts +75 -2
  110. package/dist/scanResultSchema.d.ts.map +1 -1
  111. package/dist/scanResultSchema.js +4 -2
  112. package/dist/scanResultSchema.test.js +16 -0
  113. package/dist/trustedScanGuards.test.js +7 -0
  114. package/dist/types.d.ts +3 -0
  115. package/dist/types.d.ts.map +1 -1
  116. package/package.json +1 -1
  117. package/dist/collectNarrativeWhyBullets.d.ts +0 -12
  118. package/dist/collectNarrativeWhyBullets.d.ts.map +0 -1
  119. package/dist/collectNarrativeWhyBullets.js +0 -104
  120. package/dist/deriveCardDisplaySummary.d.ts +0 -16
  121. package/dist/deriveCardDisplaySummary.d.ts.map +0 -1
  122. package/dist/deriveCardDisplaySummary.js +0 -56
  123. package/dist/deriveCardDisplaySummary.test.d.ts +0 -2
  124. package/dist/deriveCardDisplaySummary.test.d.ts.map +0 -1
  125. package/dist/deriveCardDisplaySummary.test.js +0 -89
  126. package/dist/deriveCardOperationalObservations.d.ts +0 -19
  127. package/dist/deriveCardOperationalObservations.d.ts.map +0 -1
  128. package/dist/deriveCardOperationalObservations.js +0 -180
  129. package/dist/deriveCardOperationalObservations.test.d.ts +0 -2
  130. package/dist/deriveCardOperationalObservations.test.d.ts.map +0 -1
  131. package/dist/deriveCardOperationalObservations.test.js +0 -268
  132. package/dist/deriveRiskScoreSummary.d.ts +0 -33
  133. package/dist/deriveRiskScoreSummary.d.ts.map +0 -1
  134. package/dist/deriveRiskScoreSummary.js +0 -90
  135. package/dist/deriveRiskScoreSummary.test.d.ts +0 -2
  136. package/dist/deriveRiskScoreSummary.test.d.ts.map +0 -1
  137. package/dist/deriveRiskScoreSummary.test.js +0 -47
  138. package/dist/deriveScanDetailRecommendations.d.ts +0 -63
  139. package/dist/deriveScanDetailRecommendations.d.ts.map +0 -1
  140. package/dist/deriveScanDetailRecommendations.js +0 -725
  141. package/dist/deriveScanDetailRecommendations.test.d.ts +0 -2
  142. package/dist/deriveScanDetailRecommendations.test.d.ts.map +0 -1
  143. package/dist/deriveScanDetailRecommendations.test.js +0 -181
  144. package/dist/deriveScanSummaryText.d.ts +0 -7
  145. package/dist/deriveScanSummaryText.d.ts.map +0 -1
  146. package/dist/deriveScanSummaryText.js +0 -24
  147. package/dist/deriveScanSummaryText.test.d.ts +0 -2
  148. package/dist/deriveScanSummaryText.test.d.ts.map +0 -1
  149. package/dist/deriveScanSummaryText.test.js +0 -77
  150. package/dist/formatCardEvidenceCounts.d.ts +0 -7
  151. package/dist/formatCardEvidenceCounts.d.ts.map +0 -1
  152. package/dist/formatCardEvidenceCounts.js +0 -19
  153. package/dist/prCheckRunPresentation.d.ts +0 -68
  154. package/dist/prCheckRunPresentation.d.ts.map +0 -1
  155. package/dist/prCheckRunPresentation.js +0 -319
  156. package/dist/prCheckRunPresentation.test.d.ts +0 -2
  157. package/dist/prCheckRunPresentation.test.d.ts.map +0 -1
  158. package/dist/prCheckRunPresentation.test.js +0 -278
  159. package/dist/presentation/dto/scanCardPresentation.d.ts +0 -27
  160. package/dist/presentation/dto/scanCardPresentation.d.ts.map +0 -1
  161. package/dist/presentation/intent/derivePresentationInterpretation.d.ts +0 -4
  162. package/dist/presentation/intent/derivePresentationInterpretation.d.ts.map +0 -1
  163. package/dist/presentation/intent/derivePresentationInterpretation.js +0 -202
  164. package/dist/presentation/intent/formatPresentationCopy.d.ts +0 -7
  165. package/dist/presentation/intent/formatPresentationCopy.d.ts.map +0 -1
  166. package/dist/presentation/intent/formatPresentationCopy.js +0 -153
  167. package/dist/presentation/intent/presentationIntent.test.d.ts +0 -2
  168. package/dist/presentation/intent/presentationIntent.test.d.ts.map +0 -1
  169. package/dist/presentation/intent/presentationIntent.test.js +0 -29
  170. package/dist/presentation/intent/verificationFocusLabels.d.ts +0 -2
  171. package/dist/presentation/intent/verificationFocusLabels.d.ts.map +0 -1
  172. package/dist/presentation/intent/verificationFocusLabels.js +0 -45
  173. package/dist/presentation/presenters/presentPipelineScanCard.d.ts +0 -3
  174. package/dist/presentation/presenters/presentPipelineScanCard.d.ts.map +0 -1
  175. package/dist/presentation/presenters/presentPipelineScanCard.js +0 -23
  176. package/dist/presentation/presenters/presentScanCard.d.ts +0 -7
  177. package/dist/presentation/presenters/presentScanCard.d.ts.map +0 -1
  178. package/dist/presentation/presenters/presentScanCard.js +0 -44
  179. package/dist/presentation/profile/derivePresentationProfile.d.ts +0 -12
  180. package/dist/presentation/profile/derivePresentationProfile.d.ts.map +0 -1
  181. package/dist/presentation/profile/derivePresentationProfile.js +0 -85
  182. package/dist/scanCardSummary.d.ts +0 -59
  183. package/dist/scanCardSummary.d.ts.map +0 -1
  184. package/dist/scanCardSummary.js +0 -146
  185. package/dist/scanCardSummary.test.d.ts +0 -2
  186. package/dist/scanCardSummary.test.d.ts.map +0 -1
  187. package/dist/scanCardSummary.test.js +0 -234
  188. package/dist/scanDetailViewModel.d.ts.map +0 -1
  189. package/dist/scanDetailViewModel.js +0 -636
  190. package/dist/scanDetailViewModel.test.d.ts +0 -2
  191. package/dist/scanDetailViewModel.test.d.ts.map +0 -1
  192. package/dist/scanDetailViewModel.test.js +0 -530
  193. /package/dist/presentation/dto/{scanCardPresentation.js → assessmentPresentationFields.js} +0 -0
@@ -1,202 +0,0 @@
1
- import { formatCardAreaLabels } from "../../formatCardAreaLabels.js";
2
- import { mergeVerificationFocusLabels } from "./verificationFocusLabels.js";
3
- const TOOLING_CLASSES = new Set([
4
- "tooling",
5
- "test",
6
- "lint",
7
- "format",
8
- "build",
9
- "ci",
10
- ]);
11
- const RUNTIME_IMPACT_RANK = {
12
- confirmed: 3,
13
- possible: 2,
14
- unknown: 1,
15
- none: 0,
16
- };
17
- const EVIDENCE_RANK = {
18
- high: 3,
19
- medium: 2,
20
- low: 1,
21
- };
22
- function isRuntimeEligible(row) {
23
- if (row.suppressRuntimeNarrative)
24
- return false;
25
- if (row.runtimeImpact === "confirmed" || row.runtimeImpact === "possible") {
26
- return true;
27
- }
28
- if (row.dependencyClass === "runtime")
29
- return true;
30
- if (row.usagePathCount > 0)
31
- return true;
32
- return false;
33
- }
34
- function isToolingOriented(row) {
35
- if (row.suppressRuntimeNarrative)
36
- return true;
37
- if (row.dependencyClass && TOOLING_CLASSES.has(row.dependencyClass)) {
38
- return true;
39
- }
40
- return false;
41
- }
42
- function compareRuntimePackages(a, b, order) {
43
- const impactA = RUNTIME_IMPACT_RANK[a.runtimeImpact ?? "none"] ?? 0;
44
- const impactB = RUNTIME_IMPACT_RANK[b.runtimeImpact ?? "none"] ?? 0;
45
- if (impactB !== impactA)
46
- return impactB - impactA;
47
- const evA = EVIDENCE_RANK[a.evidenceStrength ?? "low"] ?? 0;
48
- const evB = EVIDENCE_RANK[b.evidenceStrength ?? "low"] ?? 0;
49
- if (evB !== evA)
50
- return evB - evA;
51
- return order.indexOf(a.packageName) - order.indexOf(b.packageName);
52
- }
53
- function pickAnchorPackage(rows, changedOrder) {
54
- if (rows.length === 0)
55
- return null;
56
- const sorted = [...rows].sort((a, b) => compareRuntimePackages(a, b, changedOrder));
57
- return sorted[0]?.packageName ?? null;
58
- }
59
- function pickToolingAnchor(rows, changedOrder) {
60
- if (rows.length === 0)
61
- return null;
62
- const sorted = [...rows].sort((a, b) => changedOrder.indexOf(a.packageName) - changedOrder.indexOf(b.packageName));
63
- return sorted[0]?.packageName ?? null;
64
- }
65
- function isToolingPatchSet(rows, facts) {
66
- if (rows.length === 0)
67
- return false;
68
- const narrow = !facts.blastRadius || facts.blastRadius.level === "narrow";
69
- if (!narrow)
70
- return false;
71
- return rows.every((row) => row.suppressRuntimeNarrative &&
72
- (row.expectedImpact === "typecheck" ||
73
- row.expectedImpact === "build_time"));
74
- }
75
- function runtimeSurfaceLabelFromFacts(facts, anchorRow) {
76
- const area = facts.affectedAreas[0];
77
- if (area) {
78
- const formatted = formatCardAreaLabels([area.label], 1);
79
- return formatted[0] ?? area.label;
80
- }
81
- if (anchorRow?.packageRole === "http_framework") {
82
- return "API request handling";
83
- }
84
- if (anchorRow?.packageRole === "auth") {
85
- return "authentication flows";
86
- }
87
- if (anchorRow?.packageRole === "queue") {
88
- return "background job processing";
89
- }
90
- return "application code";
91
- }
92
- function collectVerificationLabels(rows) {
93
- return mergeVerificationFocusLabels(rows.map((r) => r.verificationFocus));
94
- }
95
- function showLimitedEvidence(rows) {
96
- return rows.some((r) => r.evidenceStrength === "low");
97
- }
98
- function dominantExpectedImpact(rows) {
99
- for (const row of rows) {
100
- if (row.expectedImpact && row.expectedImpact !== "unknown") {
101
- return row.expectedImpact;
102
- }
103
- }
104
- return null;
105
- }
106
- function emptyInterpretation(intent) {
107
- return {
108
- intent,
109
- anchorPackage: null,
110
- suppressRuntimeNarrative: intent.startsWith("tooling"),
111
- allowRuntimeNarrative: intent.includes("runtime"),
112
- showLimitedEvidence: false,
113
- expectedImpactKey: null,
114
- verificationLabels: [],
115
- runtimeSurfaceLabel: null,
116
- runtimePackages: [],
117
- };
118
- }
119
- export function derivePresentationInterpretation(facts) {
120
- const changedOrder = facts.changedPackages.all;
121
- const semantics = facts.changedPackageSemantics.length > 0
122
- ? facts.changedPackageSemantics
123
- : facts.packageSemantics && facts.changedPackages.primary
124
- ? [
125
- {
126
- packageName: facts.changedPackages.primary,
127
- dependencyClass: facts.packageSemantics.dependencyClass,
128
- packageRole: facts.packageSemantics.packageRole,
129
- runtimeImpact: facts.packageSemantics.runtimeImpact,
130
- expectedImpact: facts.packageSemantics.expectedImpact,
131
- suppressRuntimeNarrative: facts.packageSemantics.suppressRuntimeNarrative,
132
- evidenceStrength: facts.packageSemantics.evidenceStrength,
133
- verificationFocus: facts.packageSemantics.verificationFocus,
134
- usagePathCount: 0,
135
- usageAreaCount: 0,
136
- },
137
- ]
138
- : [];
139
- const tier1Ok = facts.availability.tiersPresent.tier1 &&
140
- facts.availability.repoIntelligenceParse === "ok";
141
- if (!tier1Ok) {
142
- return emptyInterpretation("limited_context");
143
- }
144
- if (!facts.changedPackages.primary) {
145
- return emptyInterpretation("no_changed_packages");
146
- }
147
- const runtimeEligible = semantics.filter(isRuntimeEligible);
148
- if (runtimeEligible.length > 0) {
149
- const anchorPackage = pickAnchorPackage(runtimeEligible, changedOrder);
150
- const anchorRow = runtimeEligible.find((r) => r.packageName === anchorPackage);
151
- const runtimeSurfaceLabel = runtimeSurfaceLabelFromFacts(facts, anchorRow);
152
- const verificationLabels = collectVerificationLabels(runtimeEligible);
153
- let intent = "runtime_upgrade";
154
- if (runtimeEligible.length > 1) {
155
- intent = "multi_runtime_upgrade";
156
- }
157
- else if (runtimeEligible.some((r) => r.packageRole === "auth")) {
158
- intent = "auth_runtime_upgrade";
159
- }
160
- else if (runtimeEligible.some((r) => r.packageRole === "queue")) {
161
- intent = "queue_runtime_upgrade";
162
- }
163
- return {
164
- intent,
165
- anchorPackage,
166
- suppressRuntimeNarrative: false,
167
- allowRuntimeNarrative: true,
168
- showLimitedEvidence: showLimitedEvidence(runtimeEligible),
169
- expectedImpactKey: dominantExpectedImpact(runtimeEligible),
170
- verificationLabels,
171
- runtimeSurfaceLabel,
172
- runtimePackages: runtimeEligible.map((r) => r.packageName),
173
- };
174
- }
175
- const toolingOnly = semantics.length > 0 && semantics.every(isToolingOriented);
176
- if (toolingOnly) {
177
- const anchorPackage = pickToolingAnchor(semantics, changedOrder);
178
- const isPatch = isToolingPatchSet(semantics, facts);
179
- const intent = isPatch
180
- ? "tooling_patch"
181
- : "tooling_upgrade";
182
- const anchorRow = semantics.find((r) => r.packageName === anchorPackage);
183
- return {
184
- intent,
185
- anchorPackage,
186
- suppressRuntimeNarrative: true,
187
- allowRuntimeNarrative: false,
188
- showLimitedEvidence: showLimitedEvidence(semantics),
189
- expectedImpactKey: anchorRow?.expectedImpact ?? null,
190
- verificationLabels: collectVerificationLabels(semantics),
191
- runtimeSurfaceLabel: null,
192
- runtimePackages: [],
193
- };
194
- }
195
- return {
196
- ...emptyInterpretation("unknown_upgrade"),
197
- anchorPackage: facts.changedPackages.primary,
198
- verificationLabels: collectVerificationLabels(semantics),
199
- showLimitedEvidence: showLimitedEvidence(semantics),
200
- expectedImpactKey: dominantExpectedImpact(semantics),
201
- };
202
- }
@@ -1,7 +0,0 @@
1
- import type { ScanNarrativeFacts } from "../../scanNarrativeFacts.js";
2
- import type { PresentationStatus } from "../dto/types.js";
3
- import type { PresentationInterpretation } from "./presentationIntent.js";
4
- export declare function formatPresentationHeadline(interpretation: PresentationInterpretation, facts: ScanNarrativeFacts, status: PresentationStatus | undefined): string;
5
- export declare function formatPresentationKeyPoints(interpretation: PresentationInterpretation, facts: ScanNarrativeFacts, status: PresentationStatus | undefined, max: number): string[];
6
- export declare function formatPresentationVerification(interpretation: PresentationInterpretation, status: PresentationStatus | undefined, max: number): string[];
7
- //# sourceMappingURL=formatPresentationCopy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"formatPresentationCopy.d.ts","sourceRoot":"","sources":["../../../src/presentation/intent/formatPresentationCopy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAM1D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAa1E,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,0BAA0B,EAC1C,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,kBAAkB,GAAG,SAAS,GACrC,MAAM,CAmDR;AA0BD,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,0BAA0B,EAC1C,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,GAAG,EAAE,MAAM,GACV,MAAM,EAAE,CAmEV;AAuBD,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,0BAA0B,EAC1C,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,GAAG,EAAE,MAAM,GACV,MAAM,EAAE,CAmBV"}
@@ -1,153 +0,0 @@
1
- import { scanSurfaceCopy } from "../../scanSurfaceCopy.js";
2
- import { applyPostureVocabularyGuardHeadline, applyPostureVocabularyGuardLines, } from "./applyPostureVocabularyGuard.js";
3
- import { formatPackageDisplayName } from "./packageDisplayName.js";
4
- function anchorSemantics(facts, interpretation) {
5
- const name = interpretation.anchorPackage;
6
- if (!name)
7
- return null;
8
- return (facts.changedPackageSemantics.find((r) => r.packageName === name) ?? null);
9
- }
10
- export function formatPresentationHeadline(interpretation, facts, status) {
11
- const anchor = interpretation.anchorPackage ?? facts.changedPackages.primary;
12
- const row = anchorSemantics(facts, interpretation);
13
- const pkgDisplay = formatPackageDisplayName(anchor ?? "dependency", row?.packageRole);
14
- const copy = scanSurfaceCopy.presentation;
15
- let headline;
16
- switch (interpretation.intent) {
17
- case "limited_context":
18
- headline = copy.limitedContextHeadline;
19
- break;
20
- case "no_changed_packages":
21
- headline = copy.noChangedPackagesHeadline;
22
- break;
23
- case "tooling_patch":
24
- headline = copy.toolingPatchHeadline.replace("{package}", pkgDisplay);
25
- break;
26
- case "tooling_upgrade":
27
- headline = copy.toolingUpgradeHeadline.replace("{package}", pkgDisplay);
28
- break;
29
- case "multi_runtime_upgrade":
30
- headline = copy.multiRuntimeHeadline;
31
- break;
32
- case "auth_runtime_upgrade":
33
- case "queue_runtime_upgrade":
34
- case "runtime_upgrade": {
35
- const surface = interpretation.runtimeSurfaceLabel ?? "application code";
36
- headline = copy.runtimeUpgradeHeadline
37
- .replace("{package}", pkgDisplay)
38
- .replace("{surface}", surface);
39
- break;
40
- }
41
- case "unknown_upgrade":
42
- if (status === "safe") {
43
- headline = copy.safeNeutralHeadline.replace("{package}", pkgDisplay);
44
- }
45
- else {
46
- headline = copy.defaultUpgradeHeadline.replace("{package}", pkgDisplay);
47
- }
48
- break;
49
- default:
50
- headline = copy.safeNeutralHeadline.replace("{package}", pkgDisplay);
51
- }
52
- return applyPostureVocabularyGuardHeadline(headline, status, interpretation.anchorPackage);
53
- }
54
- function formatExpectedImpactKeyPoint(interpretation) {
55
- if (interpretation.intent !== "tooling_patch" &&
56
- interpretation.intent !== "tooling_upgrade") {
57
- return null;
58
- }
59
- const key = interpretation.expectedImpactKey;
60
- let workflows = "build and typecheck workflows";
61
- if (key === "test_time")
62
- workflows = "test workflows";
63
- else if (key === "development_only")
64
- workflows = "development workflows";
65
- else if (key === "build_time")
66
- workflows = "build workflows";
67
- return scanSurfaceCopy.presentation.expectedImpactLimitedKeyPoint.replace("{workflows}", workflows);
68
- }
69
- function formatLimitedEvidenceKeyPoint() {
70
- return scanSurfaceCopy.presentation.limitedEvidenceKeyPoint;
71
- }
72
- export function formatPresentationKeyPoints(interpretation, facts, status, max) {
73
- const points = [];
74
- if (interpretation.intent === "limited_context") {
75
- points.push(scanSurfaceCopy.presentation.limitedContextKeyPoint);
76
- if (facts.changedPackages.primary) {
77
- points.push(scanSurfaceCopy.presentation.changedPackageKeyPoint.replace("{package}", facts.changedPackages.primary));
78
- }
79
- return applyPostureVocabularyGuardLines(points, status).slice(0, max);
80
- }
81
- if (interpretation.showLimitedEvidence) {
82
- points.push(formatLimitedEvidenceKeyPoint());
83
- }
84
- if (interpretation.suppressRuntimeNarrative) {
85
- points.push(scanSurfaceCopy.presentation.noRuntimePathsKeyPoint);
86
- const impact = formatExpectedImpactKeyPoint(interpretation);
87
- if (impact)
88
- points.push(impact);
89
- }
90
- else if (interpretation.allowRuntimeNarrative) {
91
- const usage = facts.packageUsage.find((u) => u.packageName === interpretation.anchorPackage);
92
- const paths = [...(usage?.paths ?? []), ...(usage?.criticalPaths ?? [])];
93
- if (paths.length > 0) {
94
- points.push(scanSurfaceCopy.presentation.usedInRuntimePathsKeyPoint.replace("{count}", String(paths.length)));
95
- }
96
- else {
97
- points.push(scanSurfaceCopy.presentation.runtimeUsageKeyPoint);
98
- }
99
- if (facts.affectedAreas.length > 0) {
100
- const labels = facts.affectedAreas
101
- .slice(0, 2)
102
- .map((a) => a.label)
103
- .join(", ");
104
- points.push(scanSurfaceCopy.presentation.affectedAreasKeyPoint.replace("{areas}", labels));
105
- }
106
- const blast = facts.blastRadius;
107
- if (blast?.level === "wide") {
108
- points.push(scanSurfaceCopy.presentation.blastRadiusWideKeyPoint);
109
- }
110
- else if (blast?.level === "moderate") {
111
- points.push(scanSurfaceCopy.presentation.blastRadiusLevelKeyPoint.replace("{level}", "Moderate"));
112
- }
113
- }
114
- return applyPostureVocabularyGuardLines(points, status).slice(0, max);
115
- }
116
- const AUTH_VERIFICATION = [
117
- "routes",
118
- "middleware/hooks",
119
- "auth flow",
120
- "serialization",
121
- "error handling",
122
- ];
123
- const QUEUE_VERIFICATION = [
124
- "workers",
125
- "queue",
126
- "serialization",
127
- "error handling",
128
- ];
129
- const RUNTIME_DEFAULT_VERIFICATION = [
130
- "routes",
131
- "middleware/hooks",
132
- "error handling",
133
- ];
134
- export function formatPresentationVerification(interpretation, status, max) {
135
- let actions = [];
136
- if (interpretation.verificationLabels.length > 0) {
137
- actions = [...interpretation.verificationLabels];
138
- }
139
- else if (interpretation.intent === "auth_runtime_upgrade") {
140
- actions = [...AUTH_VERIFICATION];
141
- }
142
- else if (interpretation.intent === "queue_runtime_upgrade") {
143
- actions = [...QUEUE_VERIFICATION];
144
- }
145
- else if (interpretation.allowRuntimeNarrative) {
146
- actions = [...RUNTIME_DEFAULT_VERIFICATION];
147
- }
148
- else if (interpretation.intent === "tooling_patch" ||
149
- interpretation.intent === "tooling_upgrade") {
150
- actions = ["CI", "typecheck", "build"];
151
- }
152
- return applyPostureVocabularyGuardLines(actions, status).slice(0, max);
153
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=presentationIntent.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"presentationIntent.test.d.ts","sourceRoot":"","sources":["../../../src/presentation/intent/presentationIntent.test.ts"],"names":[],"mappings":""}
@@ -1,29 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { deriveScanNarrative } from "../../deriveScanNarrative.js";
3
- import { scanResultMixedTypescriptFastify, scanResultTypescriptPatch, scanResultFastifyRuntime, } from "../fixtures/presentationPersonaFixtures.js";
4
- import { derivePresentationInterpretation } from "./derivePresentationInterpretation.js";
5
- describe("derivePresentationInterpretation", () => {
6
- it("typescript patch: tooling_patch intent from engine semantics", () => {
7
- const facts = deriveScanNarrative(scanResultTypescriptPatch);
8
- const interp = derivePresentationInterpretation(facts);
9
- // Engine: suppressRuntimeNarrative=true, expectedImpact=typecheck, dependencyClass=tooling
10
- expect(interp.intent).toBe("tooling_patch");
11
- expect(interp.anchorPackage).toBe("typescript");
12
- expect(interp.suppressRuntimeNarrative).toBe(true);
13
- });
14
- it("fastify: runtime_upgrade from runtimeImpact=confirmed", () => {
15
- const facts = deriveScanNarrative(scanResultFastifyRuntime);
16
- const interp = derivePresentationInterpretation(facts);
17
- expect(interp.intent).toBe("runtime_upgrade");
18
- expect(interp.anchorPackage).toBe("fastify");
19
- expect(interp.allowRuntimeNarrative).toBe(true);
20
- });
21
- it("mixed typescript+fastify: runtime dominates tooling (anchor fastify)", () => {
22
- const facts = deriveScanNarrative(scanResultMixedTypescriptFastify);
23
- const interp = derivePresentationInterpretation(facts);
24
- expect(interp.intent).toBe("runtime_upgrade");
25
- expect(interp.anchorPackage).toBe("fastify");
26
- expect(interp.runtimePackages).toContain("fastify");
27
- expect(interp.runtimePackages).not.toContain("typescript");
28
- });
29
- });
@@ -1,2 +0,0 @@
1
- export declare function mergeVerificationFocusLabels(focusLists: string[][], max?: number): string[];
2
- //# sourceMappingURL=verificationFocusLabels.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verificationFocusLabels.d.ts","sourceRoot":"","sources":["../../../src/presentation/intent/verificationFocusLabels.ts"],"names":[],"mappings":"AA2BA,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAAE,EAAE,EACtB,GAAG,SAAI,GACN,MAAM,EAAE,CAeV"}
@@ -1,45 +0,0 @@
1
- const FOCUS_LABELS = {
2
- ci: "CI",
3
- typecheck: "typecheck",
4
- build: "build",
5
- routes: "routes",
6
- middleware: "middleware/hooks",
7
- hooks: "middleware/hooks",
8
- auth_flow: "auth flow",
9
- auth: "auth flow",
10
- serialization: "serialization",
11
- error_handling: "error handling",
12
- handlers: "handlers",
13
- plugins: "plugins",
14
- session: "session",
15
- workers: "workers",
16
- queue: "queue",
17
- test_suite: "test suite",
18
- lint: "lint",
19
- format: "format",
20
- };
21
- function labelVerificationFocus(focus) {
22
- const key = focus.trim().toLowerCase();
23
- if (!key)
24
- return "";
25
- return FOCUS_LABELS[key] ?? focus.replace(/_/g, " ");
26
- }
27
- export function mergeVerificationFocusLabels(focusLists, max = 6) {
28
- const seen = new Set();
29
- const out = [];
30
- for (const list of focusLists) {
31
- for (const f of list) {
32
- const label = labelVerificationFocus(f);
33
- if (!label)
34
- continue;
35
- const norm = label.toLowerCase();
36
- if (seen.has(norm))
37
- continue;
38
- seen.add(norm);
39
- out.push(label);
40
- if (out.length >= max)
41
- return out;
42
- }
43
- }
44
- return out;
45
- }
@@ -1,3 +0,0 @@
1
- import type { ScanCardPresentation } from "../dto/scanCardPresentation.js";
2
- export declare function presentPipelineScanCard(pipelineStatus: "queued" | "running" | "failed"): ScanCardPresentation;
3
- //# sourceMappingURL=presentPipelineScanCard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"presentPipelineScanCard.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentPipelineScanCard.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAC9C,oBAAoB,CAqBtB"}
@@ -1,23 +0,0 @@
1
- import { scanSurfaceCopy } from "../../scanSurfaceCopy.js";
2
- import { normalizeGeneratedText, } from "../../normalizeGeneratedText.js";
3
- export function presentPipelineScanCard(pipelineStatus) {
4
- const isRunning = pipelineStatus === "queued" || pipelineStatus === "running";
5
- const headline = isRunning
6
- ? scanSurfaceCopy.pipeline.scanRunning
7
- : scanSurfaceCopy.pipeline.analysisIncomplete;
8
- return {
9
- pipeline: {
10
- status: pipelineStatus,
11
- headline: normalizeGeneratedText(headline),
12
- subheadline: isRunning
13
- ? scanSurfaceCopy.pipeline.scanIncomplete
14
- : undefined,
15
- },
16
- headline: normalizeGeneratedText(headline),
17
- changedPackages: [],
18
- keyPoints: [],
19
- affectedAreas: [],
20
- verificationActions: [],
21
- evidence: [],
22
- };
23
- }
@@ -1,7 +0,0 @@
1
- import type { ScanCardPresentation } from "../dto/scanCardPresentation.js";
2
- import type { ScanPresentationBundle } from "../orchestration/scanPresentationBundle.js";
3
- export type PresentScanCardContext = {
4
- includeFindingCounts?: boolean;
5
- };
6
- export declare function presentScanCard(bundle: ScanPresentationBundle, ctx?: PresentScanCardContext): ScanCardPresentation;
7
- //# sourceMappingURL=presentScanCard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"presentScanCard.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentScanCard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAgB3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEzF,MAAM,MAAM,sBAAsB,GAAG;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAsBF,wBAAgB,eAAe,CAC7B,MAAM,EAAE,sBAAsB,EAC9B,GAAG,GAAE,sBAA2B,GAC/B,oBAAoB,CA0BtB"}
@@ -1,44 +0,0 @@
1
- import { aggregateFindingCounts } from "../dto/types.js";
2
- import { composeAffectedAreaLabels, composeEvidenceRows, composeHeadline, composeKeyPoints, composeSubheadline, composeSupportingContext, composeVerificationActions, evidenceContextFromProfile, } from "../compose/narrativeCompose.js";
3
- import { normalizeGeneratedText, normalizeGeneratedTextNullable, } from "../../normalizeGeneratedText.js";
4
- import { scanSurfaceCopy } from "../../scanSurfaceCopy.js";
5
- function normalizeCard(p) {
6
- return {
7
- ...p,
8
- headline: normalizeGeneratedText(p.headline),
9
- subheadline: normalizeGeneratedTextNullable(p.subheadline) ?? undefined,
10
- keyPoints: p.keyPoints.map((k) => normalizeGeneratedText(k)),
11
- affectedAreas: p.affectedAreas.map((a) => normalizeGeneratedText(a)),
12
- verificationActions: p.verificationActions.map((v) => normalizeGeneratedText(v)),
13
- evidence: p.evidence.map((e) => ({
14
- label: normalizeGeneratedText(e.label),
15
- value: normalizeGeneratedText(e.value),
16
- })),
17
- supportingContext: p.supportingContext?.map((s) => normalizeGeneratedText(s)),
18
- };
19
- }
20
- export function presentScanCard(bundle, ctx = {}) {
21
- const { facts, profile, result } = bundle;
22
- const presentation = {
23
- status: profile.status,
24
- density: profile.density,
25
- confidence: profile.confidence,
26
- evidenceContext: evidenceContextFromProfile(bundle),
27
- headline: composeHeadline(bundle),
28
- subheadline: composeSubheadline(bundle) ?? undefined,
29
- changedPackages: facts.changedPackages.all,
30
- primaryPackage: facts.changedPackages.primary ?? undefined,
31
- keyPoints: composeKeyPoints(bundle, 3),
32
- affectedAreas: composeAffectedAreaLabels(bundle, 2),
33
- verificationActions: composeVerificationActions(bundle, 2),
34
- evidence: composeEvidenceRows(bundle, 3),
35
- supportingContext: composeSupportingContext(bundle),
36
- riskIndex: facts.riskIndex,
37
- findingCounts: ctx.includeFindingCounts
38
- ? aggregateFindingCounts(result.findings)
39
- : null,
40
- actionLabel: scanSurfaceCopy.presentation.actionLabelReview,
41
- presentationIntent: profile.interpretation.intent,
42
- };
43
- return normalizeCard(presentation);
44
- }
@@ -1,12 +0,0 @@
1
- import type { ScanNarrativeFacts } from "../../scanNarrativeFacts.js";
2
- import type { PipelineStatus } from "../dto/types.js";
3
- import type { PresentationProfile } from "./presentationProfile.js";
4
- type DerivePresentationProfileContext = {
5
- pipelineStatus: PipelineStatus;
6
- decision?: string | null;
7
- totalScore?: number | null;
8
- };
9
- /** INTERNAL - only called from buildScanPresentationBundle */
10
- export declare function derivePresentationProfile(facts: ScanNarrativeFacts, ctx: DerivePresentationProfileContext): PresentationProfile | null;
11
- export {};
12
- //# sourceMappingURL=derivePresentationProfile.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"derivePresentationProfile.d.ts","sourceRoot":"","sources":["../../../src/presentation/profile/derivePresentationProfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAKtE,OAAO,KAAK,EAAE,cAAc,EAAsB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,KAAK,gCAAgC,GAAG;IACtC,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAwFF,8DAA8D;AAC9D,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,kBAAkB,EACzB,GAAG,EAAE,gCAAgC,GACpC,mBAAmB,GAAG,IAAI,CAwB5B"}
@@ -1,85 +0,0 @@
1
- import { mergePostureFromDecision } from "../../riskVocabulary.js";
2
- import { scanSurfaceCopy } from "../../scanSurfaceCopy.js";
3
- import { derivePresentationInterpretation } from "../intent/derivePresentationInterpretation.js";
4
- function statusFromScore(totalScore) {
5
- if (totalScore == null || !Number.isFinite(totalScore))
6
- return "needs_review";
7
- if (totalScore <= 30)
8
- return "safe";
9
- if (totalScore <= 60)
10
- return "needs_review";
11
- return "risky";
12
- }
13
- function resolveStatus(facts, ctx) {
14
- const fromFacts = facts.mergePosture;
15
- if (fromFacts)
16
- return fromFacts;
17
- const fromDecision = mergePostureFromDecision(ctx.decision ?? undefined);
18
- if (fromDecision)
19
- return fromDecision;
20
- return statusFromScore(ctx.totalScore ?? facts.riskIndex);
21
- }
22
- function hasStrongPrIntelligence(facts) {
23
- return (facts.availability.tiersPresent.tier1 &&
24
- facts.availability.repoIntelligenceParse === "ok");
25
- }
26
- function hasHighSeverityFindings(facts) {
27
- return facts.reviewerGuidance.some((g) => g.kind === "finding" &&
28
- (g.priority === "critical" || g.priority === "high"));
29
- }
30
- function deriveDensity(facts, priority, interpretation) {
31
- if (priority === "limited") {
32
- return hasHighSeverityFindings(facts) ? "standard" : "minimal";
33
- }
34
- if (interpretation.allowRuntimeNarrative) {
35
- const wideOrModerate = facts.blastRadius?.level === "wide" ||
36
- facts.blastRadius?.level === "moderate";
37
- const hasAreas = facts.affectedAreas.length > 0;
38
- const hasPaths = facts.packageUsage.some((u) => u.paths.length > 0 || u.criticalPaths.length > 0);
39
- if (wideOrModerate || hasAreas || hasPaths) {
40
- return "rich";
41
- }
42
- }
43
- if (interpretation.suppressRuntimeNarrative) {
44
- const narrow = !facts.blastRadius || facts.blastRadius.level === "narrow";
45
- if (narrow && facts.affectedAreas.length === 0) {
46
- return "minimal";
47
- }
48
- }
49
- return "standard";
50
- }
51
- function deriveConfidence(facts, priority) {
52
- if (priority === "limited")
53
- return "low";
54
- const decisionConf = facts.confidence.decision;
55
- if (decisionConf === "high" || decisionConf === "medium")
56
- return "high";
57
- const sparseUsage = facts.packageUsage.length === 0 ||
58
- facts.packageUsage.every((u) => u.paths.length === 0 && u.criticalPaths.length === 0);
59
- if (sparseUsage)
60
- return "medium";
61
- return "high";
62
- }
63
- /** INTERNAL - only called from buildScanPresentationBundle */
64
- export function derivePresentationProfile(facts, ctx) {
65
- if (ctx.pipelineStatus !== "done")
66
- return null;
67
- const interpretation = derivePresentationInterpretation(facts);
68
- const priority = hasStrongPrIntelligence(facts)
69
- ? "pr_intelligence"
70
- : "limited";
71
- const status = resolveStatus(facts, ctx);
72
- const density = deriveDensity(facts, priority, interpretation);
73
- const confidence = deriveConfidence(facts, priority);
74
- const degradedMessage = priority === "limited"
75
- ? scanSurfaceCopy.presentation.limitedContextMessage
76
- : undefined;
77
- return {
78
- status,
79
- density,
80
- confidence,
81
- priority,
82
- degradedMessage,
83
- interpretation,
84
- };
85
- }