@mergesignal/shared 0.3.0 → 0.4.1

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 (112) hide show
  1. package/dist/deriveScanNarrative.d.ts.map +1 -1
  2. package/dist/deriveScanNarrative.js +20 -3
  3. package/dist/deriveScanNarrative.test.js +6 -3
  4. package/dist/engineWireRegression.test.js +2 -2
  5. package/dist/fixtures/repoIntelligenceFixtures.d.ts.map +1 -1
  6. package/dist/fixtures/repoIntelligenceFixtures.js +13 -0
  7. package/dist/index.d.ts +3 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +3 -2
  10. package/dist/narrativeParity.test.js +19 -18
  11. package/dist/narrativePresentation.d.ts.map +1 -1
  12. package/dist/narrativePresentation.js +6 -3
  13. package/dist/presentGitHubPrComment.d.ts +3 -4
  14. package/dist/presentGitHubPrComment.d.ts.map +1 -1
  15. package/dist/presentGitHubPrComment.js +15 -61
  16. package/dist/presentation/compose/narrativeCompose.d.ts +16 -0
  17. package/dist/presentation/compose/narrativeCompose.d.ts.map +1 -0
  18. package/dist/presentation/compose/narrativeCompose.js +167 -0
  19. package/dist/presentation/dto/githubAndCliPresentation.d.ts +53 -0
  20. package/dist/presentation/dto/githubAndCliPresentation.d.ts.map +1 -0
  21. package/dist/presentation/dto/githubAndCliPresentation.js +1 -0
  22. package/dist/presentation/dto/scanCardPresentation.d.ts +25 -0
  23. package/dist/presentation/dto/scanCardPresentation.d.ts.map +1 -0
  24. package/dist/presentation/dto/scanCardPresentation.js +1 -0
  25. package/dist/presentation/dto/scanDetailsPresentation.d.ts +111 -0
  26. package/dist/presentation/dto/scanDetailsPresentation.d.ts.map +1 -0
  27. package/dist/presentation/dto/scanDetailsPresentation.js +1 -0
  28. package/dist/presentation/dto/types.d.ts +24 -0
  29. package/dist/presentation/dto/types.d.ts.map +1 -0
  30. package/dist/presentation/dto/types.js +22 -0
  31. package/dist/presentation/fixtures/scanResultFixtures.d.ts +5 -0
  32. package/dist/presentation/fixtures/scanResultFixtures.d.ts.map +1 -0
  33. package/dist/presentation/fixtures/scanResultFixtures.js +83 -0
  34. package/dist/presentation/index.d.ts +25 -0
  35. package/dist/presentation/index.d.ts.map +1 -0
  36. package/dist/presentation/index.js +13 -0
  37. package/dist/presentation/orchestration/buildScanCardPresentation.d.ts +11 -0
  38. package/dist/presentation/orchestration/buildScanCardPresentation.d.ts.map +1 -0
  39. package/dist/presentation/orchestration/buildScanCardPresentation.js +44 -0
  40. package/dist/presentation/orchestration/buildScanDetailsPresentation.d.ts +14 -0
  41. package/dist/presentation/orchestration/buildScanDetailsPresentation.d.ts.map +1 -0
  42. package/dist/presentation/orchestration/buildScanDetailsPresentation.js +19 -0
  43. package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts +15 -0
  44. package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts.map +1 -0
  45. package/dist/presentation/orchestration/buildScanPresentationBundle.js +23 -0
  46. package/dist/presentation/orchestration/scanPresentationBundle.d.ts +15 -0
  47. package/dist/presentation/orchestration/scanPresentationBundle.d.ts.map +1 -0
  48. package/dist/presentation/orchestration/scanPresentationBundle.js +1 -0
  49. package/dist/presentation/presentation.test.d.ts +2 -0
  50. package/dist/presentation/presentation.test.d.ts.map +1 -0
  51. package/dist/presentation/presentation.test.js +95 -0
  52. package/dist/presentation/presenters/presentCliScanSummary.d.ts +6 -0
  53. package/dist/presentation/presenters/presentCliScanSummary.d.ts.map +1 -0
  54. package/dist/presentation/presenters/presentCliScanSummary.js +30 -0
  55. package/dist/presentation/presenters/presentGitHubCheckRun.d.ts +8 -0
  56. package/dist/presentation/presenters/presentGitHubCheckRun.d.ts.map +1 -0
  57. package/dist/presentation/presenters/presentGitHubCheckRun.js +32 -0
  58. package/dist/presentation/presenters/presentGitHubPrComment.d.ts +4 -0
  59. package/dist/presentation/presenters/presentGitHubPrComment.d.ts.map +1 -0
  60. package/dist/presentation/presenters/presentGitHubPrComment.js +40 -0
  61. package/dist/presentation/presenters/presentPipelineScanCard.d.ts +3 -0
  62. package/dist/presentation/presenters/presentPipelineScanCard.d.ts.map +1 -0
  63. package/dist/presentation/presenters/presentPipelineScanCard.js +23 -0
  64. package/dist/presentation/presenters/presentScanCard.d.ts +7 -0
  65. package/dist/presentation/presenters/presentScanCard.d.ts.map +1 -0
  66. package/dist/presentation/presenters/presentScanCard.js +43 -0
  67. package/dist/presentation/presenters/presentScanDetails.d.ts +9 -0
  68. package/dist/presentation/presenters/presentScanDetails.d.ts.map +1 -0
  69. package/dist/presentation/presenters/presentScanDetails.js +177 -0
  70. package/dist/presentation/profile/derivePresentationProfile.d.ts +12 -0
  71. package/dist/presentation/profile/derivePresentationProfile.d.ts.map +1 -0
  72. package/dist/presentation/profile/derivePresentationProfile.js +94 -0
  73. package/dist/presentation/profile/presentationProfile.d.ts +9 -0
  74. package/dist/presentation/profile/presentationProfile.d.ts.map +1 -0
  75. package/dist/presentation/profile/presentationProfile.js +1 -0
  76. package/dist/presentation/render/renderCliScanSummaryText.d.ts +3 -0
  77. package/dist/presentation/render/renderCliScanSummaryText.d.ts.map +1 -0
  78. package/dist/presentation/render/renderCliScanSummaryText.js +30 -0
  79. package/dist/presentation/render/renderGitHubCheckRunMarkdown.d.ts +3 -0
  80. package/dist/presentation/render/renderGitHubCheckRunMarkdown.d.ts.map +1 -0
  81. package/dist/presentation/render/renderGitHubCheckRunMarkdown.js +23 -0
  82. package/dist/presentation/render/renderGitHubPrCommentMarkdown.d.ts +3 -0
  83. package/dist/presentation/render/renderGitHubPrCommentMarkdown.d.ts.map +1 -0
  84. package/dist/presentation/render/renderGitHubPrCommentMarkdown.js +24 -0
  85. package/dist/repoIntelligenceMappers.d.ts.map +1 -1
  86. package/dist/repoIntelligenceMappers.js +8 -1
  87. package/dist/repoIntelligenceSchema.d.ts +75 -1
  88. package/dist/repoIntelligenceSchema.d.ts.map +1 -1
  89. package/dist/repoIntelligenceSchema.js +74 -1
  90. package/dist/repoIntelligenceSemantics.d.ts +29 -0
  91. package/dist/repoIntelligenceSemantics.d.ts.map +1 -0
  92. package/dist/repoIntelligenceSemantics.js +146 -0
  93. package/dist/repoIntelligenceSemantics.test.d.ts +2 -0
  94. package/dist/repoIntelligenceSemantics.test.d.ts.map +1 -0
  95. package/dist/repoIntelligenceSemantics.test.js +63 -0
  96. package/dist/scanCardSummary.d.ts +4 -35
  97. package/dist/scanCardSummary.d.ts.map +1 -1
  98. package/dist/scanCardSummary.js +12 -63
  99. package/dist/scanCardSummary.test.js +56 -75
  100. package/dist/scanDetailViewModel.d.ts +1 -0
  101. package/dist/scanDetailViewModel.d.ts.map +1 -1
  102. package/dist/scanDetailViewModel.js +1 -1
  103. package/dist/scanNarrativeFacts.d.ts +7 -0
  104. package/dist/scanNarrativeFacts.d.ts.map +1 -1
  105. package/dist/scanNarrativeFacts.js +1 -0
  106. package/dist/scanSurfaceCopy.d.ts +25 -0
  107. package/dist/scanSurfaceCopy.d.ts.map +1 -1
  108. package/dist/scanSurfaceCopy.js +25 -0
  109. package/package.json +1 -1
  110. package/dist/presentScanCardSummary.d.ts +0 -16
  111. package/dist/presentScanCardSummary.d.ts.map +0 -1
  112. package/dist/presentScanCardSummary.js +0 -212
@@ -1,21 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { isCatalogPhrase } from "./cardObservationCatalog.js";
2
+ import { scanSurfaceCopy } from "./scanSurfaceCopy.js";
3
3
  import { aggregateFindingCounts, deriveRiskIndexBand, deriveScanCardSummary, deriveScanCardSummaryFromDenormalized, isPipelineCardSummary, isPipelinePlaceholderCopy, resolvePipelineStatus, resolvePrScanCardSummary, staleScanSubline, } from "./scanCardSummary.js";
4
- const pipelinePresentationDefaults = {
5
- narrativeMode: "denormalized",
6
- codeIntelligenceAvailable: false,
7
- changedPackagesDisplay: null,
8
- runtimeSurfaceLabel: null,
9
- reachabilityLabel: null,
10
- blastRadiusLabel: null,
11
- affectedAreas: [],
12
- primaryInsight: null,
13
- structuralOnlyDisclaimer: null,
14
- usageSummary: null,
15
- verificationLine: null,
16
- blastRadiusDetail: null,
17
- frameworksSummary: null,
18
- };
19
4
  const baseResult = {
20
5
  totalScore: 10,
21
6
  layerScores: {
@@ -27,6 +12,22 @@ const baseResult = {
27
12
  findings: [],
28
13
  generatedAt: "2026-01-01T00:00:00.000Z",
29
14
  };
15
+ function pipelineCard(overrides = {}) {
16
+ return {
17
+ pipeline: {
18
+ status: "queued",
19
+ headline: scanSurfaceCopy.pipeline.scanRunning,
20
+ subheadline: scanSurfaceCopy.pipeline.scanIncomplete,
21
+ },
22
+ headline: scanSurfaceCopy.pipeline.scanRunning,
23
+ changedPackages: [],
24
+ keyPoints: [],
25
+ affectedAreas: [],
26
+ verificationActions: [],
27
+ evidence: [],
28
+ ...overrides,
29
+ };
30
+ }
30
31
  describe("deriveRiskIndexBand", () => {
31
32
  it("maps score thresholds", () => {
32
33
  expect(deriveRiskIndexBand(0)).toBe("low");
@@ -67,18 +68,19 @@ describe("aggregateFindingCounts", () => {
67
68
  describe("deriveScanCardSummary", () => {
68
69
  it("returns scanning copy for queued/running", () => {
69
70
  const queued = deriveScanCardSummary(null, "queued");
70
- expect(queued.headline).toBe("Scan in progress");
71
- expect(queued.summaryLine).toBe("Waiting for results...");
72
- expect(queued.mergePosture).toBeNull();
71
+ expect(queued.headline).toBe(scanSurfaceCopy.pipeline.scanRunning);
72
+ expect(queued.pipeline?.status).toBe("queued");
73
+ expect(queued.status).toBeUndefined();
73
74
  const running = deriveScanCardSummary(null, "running");
74
- expect(running.headline).toBe("Scan in progress");
75
+ expect(running.headline).toBe(scanSurfaceCopy.pipeline.scanRunning);
76
+ expect(running.pipeline?.status).toBe("running");
75
77
  });
76
78
  it("returns failed copy", () => {
77
79
  const failed = deriveScanCardSummary(null, "failed");
78
- expect(failed.headline).toBe("Analysis could not be completed");
79
- expect(failed.mergePosture).toBeNull();
80
+ expect(failed.headline).toBe(scanSurfaceCopy.pipeline.analysisIncomplete);
81
+ expect(failed.pipeline?.status).toBe("failed");
80
82
  });
81
- it("derives posture headline and risk index for done scans", () => {
83
+ it("derives posture and risk index for done scans", () => {
82
84
  const r = {
83
85
  ...baseResult,
84
86
  totalScore: 72,
@@ -99,14 +101,11 @@ describe("deriveScanCardSummary", () => {
99
101
  },
100
102
  };
101
103
  const summary = deriveScanCardSummary(r, "done");
102
- expect(summary.mergePosture).toBe("risky");
103
- expect(summary.headline).toBe("Risky");
104
+ expect(summary.status).toBe("risky");
105
+ expect(summary.headline).toBe(scanSurfaceCopy.presentation.limitedContextHeadline);
104
106
  expect(summary.riskIndex).toBe(72);
105
- expect(summary.riskIndexBand).toBe("high");
106
- expect(summary.summaryLine).toBeNull();
107
- expect(summary.operationalObservations).toContain("Large upgrade blast radius");
108
107
  });
109
- it("keeps quiet safe cards posture-only without observations", () => {
108
+ it("keeps quiet safe cards minimal without extra key points beyond defaults", () => {
110
109
  const r = {
111
110
  ...baseResult,
112
111
  totalScore: 12,
@@ -117,10 +116,10 @@ describe("deriveScanCardSummary", () => {
117
116
  },
118
117
  };
119
118
  const summary = deriveScanCardSummary(r, "done");
120
- expect(summary.summaryLine).toBeNull();
121
- expect(summary.operationalObservations).toEqual([]);
119
+ expect(summary.status).toBe("safe");
120
+ expect(summary.keyPoints.length).toBeGreaterThan(0);
122
121
  });
123
- it("surfaces catalog observations from explain signals", () => {
122
+ it("surfaces catalog key points from explain signals", () => {
124
123
  const r = {
125
124
  ...baseResult,
126
125
  decision: {
@@ -147,11 +146,7 @@ describe("deriveScanCardSummary", () => {
147
146
  },
148
147
  };
149
148
  const summary = deriveScanCardSummary(r, "done");
150
- expect(summary.topAffectedAreas).toHaveLength(2);
151
- expect(summary.operationalObservations.length).toBeGreaterThan(0);
152
- for (const phrase of summary.operationalObservations) {
153
- expect(isCatalogPhrase(phrase)).toBe(true);
154
- }
149
+ expect(summary.keyPoints.length).toBeGreaterThan(0);
155
150
  });
156
151
  it("exports stale subline constant", () => {
157
152
  expect(staleScanSubline()).toBe("Based on earlier commit");
@@ -183,32 +178,21 @@ describe("resolvePipelineStatus", () => {
183
178
  });
184
179
  describe("isPipelineCardSummary", () => {
185
180
  it("detects scanning placeholder summaries", () => {
186
- expect(isPipelineCardSummary({
187
- mergePosture: null,
188
- riskIndex: null,
189
- riskIndexBand: null,
190
- headline: "Scan in progress",
191
- summaryLine: "Waiting for results...",
192
- findingCounts: null,
193
- topAffectedAreas: [],
194
- operationalObservations: [],
195
- supportingLine: null,
196
- ...pipelinePresentationDefaults,
197
- })).toBe(true);
198
- });
199
- it("detects hybrid completed posture with pipeline summary line", () => {
200
- expect(isPipelineCardSummary({
201
- mergePosture: "risky",
202
- riskIndex: 72,
203
- riskIndexBand: "high",
204
- headline: "Risky",
205
- summaryLine: "Waiting for results...",
206
- findingCounts: null,
207
- topAffectedAreas: [],
208
- operationalObservations: [],
209
- supportingLine: null,
210
- ...pipelinePresentationDefaults,
211
- })).toBe(true);
181
+ expect(isPipelineCardSummary(pipelineCard({
182
+ pipeline: {
183
+ status: "queued",
184
+ headline: scanSurfaceCopy.pipeline.scanRunning,
185
+ subheadline: scanSurfaceCopy.pipeline.scanIncomplete,
186
+ },
187
+ }))).toBe(true);
188
+ });
189
+ it("detects failed pipeline summaries", () => {
190
+ expect(isPipelineCardSummary(pipelineCard({
191
+ pipeline: {
192
+ status: "failed",
193
+ headline: scanSurfaceCopy.pipeline.analysisIncomplete,
194
+ },
195
+ }))).toBe(true);
212
196
  });
213
197
  });
214
198
  describe("isPipelinePlaceholderCopy", () => {
@@ -218,23 +202,21 @@ describe("isPipelinePlaceholderCopy", () => {
218
202
  });
219
203
  });
220
204
  describe("deriveScanCardSummaryFromDenormalized", () => {
221
- it("builds risky summary from denormalized columns without generic narration", () => {
205
+ it("builds risky summary from denormalized columns", () => {
222
206
  const summary = deriveScanCardSummaryFromDenormalized("risky", 72, "Auth boundary change", "done");
223
- expect(summary.mergePosture).toBe("risky");
224
- expect(summary.headline).toBe("Risky");
207
+ expect(summary.status).toBe("risky");
225
208
  expect(summary.riskIndex).toBe(72);
226
- expect(summary.summaryLine).toBeNull();
227
- expect(summary.operationalObservations).toEqual([]);
209
+ expect(summary.pipeline).toBeUndefined();
228
210
  });
229
211
  it("does not inject pipeline placeholder summaryText", () => {
230
212
  const summary = deriveScanCardSummaryFromDenormalized("risky", 72, "Waiting for results...", "done");
231
- expect(summary.mergePosture).toBe("risky");
232
- expect(summary.summaryLine).not.toBe("Waiting for results...");
213
+ expect(summary.status).toBe("risky");
214
+ expect(summary.pipeline).toBeUndefined();
233
215
  });
234
216
  it("does not inject raw generic summaryText on quiet safe cards", () => {
235
217
  const summary = deriveScanCardSummaryFromDenormalized("safe", 12, "No high-confidence merge risks from this PR dependency change", "done");
236
- expect(summary.mergePosture).toBe("safe");
237
- expect(summary.summaryLine).toBeNull();
218
+ expect(summary.status).toBe("safe");
219
+ expect(summary.pipeline).toBeUndefined();
238
220
  });
239
221
  });
240
222
  describe("resolvePrScanCardSummary", () => {
@@ -246,8 +228,7 @@ describe("resolvePrScanCardSummary", () => {
246
228
  summaryText: "Waiting for results...",
247
229
  result: null,
248
230
  });
249
- expect(summary.mergePosture).toBe("risky");
250
- expect(summary.headline).toBe("Risky");
251
- expect(summary.summaryLine).not.toBe("Waiting for results...");
231
+ expect(summary.status).toBe("risky");
232
+ expect(summary.pipeline).toBeUndefined();
252
233
  });
253
234
  });
@@ -122,6 +122,7 @@ export declare function deriveVerdictLine(posture: MergePosture | null, totalSco
122
122
  export declare function deriveAct2Themes(result: ScanResult): string[];
123
123
  export declare function deriveOperationalImpact(result: ScanResult, verifyLabels?: Set<string>): ScanDetailOperationalImpact;
124
124
  export declare function presentScanDetailNarrativeContext(facts: ScanNarrativeFacts): ScanDetailNarrativeContext;
125
+ export declare function deriveVerdictLineFromFacts(facts: ScanNarrativeFacts, result: ScanResult): string;
125
126
  /** Scan detail presentation from shared narrative facts. */
126
127
  export declare function presentScanDetailViewModel(facts: ScanNarrativeFacts, result: ScanResult, options: DeriveScanDetailOptions): ScanDetailViewModel;
127
128
  export declare function deriveScanDetailViewModel(result: ScanResult | null | undefined, options: DeriveScanDetailOptions): ScanDetailViewModel | null;
@@ -1 +1 @@
1
- {"version":3,"file":"scanDetailViewModel.d.ts","sourceRoot":"","sources":["../src/scanDetailViewModel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanDetailViewModel.d.ts","sourceRoot":"","sources":["../src/scanDetailViewModel.ts"],"names":[],"mappings":"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"}
@@ -552,7 +552,7 @@ function deriveBecauseThemesFromFacts(facts) {
552
552
  }
553
553
  return themes.slice(0, ACT2_MAX_THEMES);
554
554
  }
555
- function deriveVerdictLineFromFacts(facts, result) {
555
+ export function deriveVerdictLineFromFacts(facts, result) {
556
556
  const topGuidance = facts.reviewerGuidance.find((g) => (g.scope === "changed" || g.kind === "insight") && g.message.trim());
557
557
  if (topGuidance) {
558
558
  return truncateWithEllipsis(topGuidance.message.trim(), VERDICT_LINE_MAX_CHARS);
@@ -47,6 +47,13 @@ export type ScanNarrativeFacts = {
47
47
  frameworks: string[];
48
48
  };
49
49
  } | null;
50
+ /** From sanitized repoIntelligence primary package semantics (ABI 2). */
51
+ packageSemantics: {
52
+ runtimeImpact: "none" | "possible" | "confirmed" | "unknown" | null;
53
+ expectedImpact: "runtime" | "build_time" | "typecheck" | "test_time" | "development_only" | "unknown" | null;
54
+ suppressRuntimeNarrative: boolean;
55
+ verificationFocus: string[];
56
+ } | null;
50
57
  blastRadius: {
51
58
  level: BlastRadiusLevel;
52
59
  changedPackageCount?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"scanNarrativeFacts.d.ts","sourceRoot":"","sources":["../src/scanNarrativeFacts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanNarrativeFacts.d.ts","sourceRoot":"","sources":["../src/scanNarrativeFacts.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ export const EMPTY_SCAN_NARRATIVE_FACTS = {
10
10
  frameworks: [],
11
11
  runtimeSurface: null,
12
12
  reachability: null,
13
+ packageSemantics: null,
13
14
  blastRadius: null,
14
15
  affectedAreas: [],
15
16
  hotspots: [],
@@ -288,6 +288,31 @@ export declare const scanSurfaceCopy: {
288
288
  readonly areasSeparator: " | ";
289
289
  readonly contextSeparator: " | ";
290
290
  };
291
+ /** Shared presentation layer copy (composeHeadline, key points, verification). */
292
+ readonly presentation: {
293
+ readonly limitedContextHeadline: "Dependency upgrade with limited scan context";
294
+ readonly limitedContextMessage: "PR-specific scan context was limited";
295
+ readonly limitedContextKeyPoint: "PR-specific intelligence was limited for this scan";
296
+ readonly noChangedPackagesHeadline: "Dependency scan complete";
297
+ readonly multiRuntimeHeadline: "Multiple runtime dependency upgrades need review";
298
+ readonly buildOnlyHeadline: "{package} patch upgrade with limited application impact";
299
+ readonly runtimeHeadline: "{package} upgrade affects {surface}";
300
+ readonly defaultUpgradeHeadline: "{package} dependency upgrade needs review";
301
+ readonly changedPackageKeyPoint: "Changed package: {package}";
302
+ readonly usedInPathsSingle: "Used across application code ({path})";
303
+ readonly usedInPathsMultiple: "Used across {count} code paths";
304
+ readonly noRuntimePathsKeyPoint: "No runtime usage paths detected";
305
+ readonly blastRadiusWideKeyPoint: "Blast radius is wide";
306
+ readonly blastRadiusLevelKeyPoint: "Blast radius is {level}";
307
+ readonly noAffectedAreasKeyPoint: "No affected application areas identified";
308
+ readonly affectedAreasKeyPoint: "Affected areas: {areas}";
309
+ readonly verifyCiTypecheck: "Confirm CI/typecheck passes";
310
+ readonly verifyAuthFlow: "Run authenticated API request flow";
311
+ readonly verifyErrorResponses: "Check error responses and status codes";
312
+ readonly graphDepthContext: "Repository graph max depth: {depth}";
313
+ readonly graphSizeContext: "Repository graph: {nodes} nodes, {edges} edges";
314
+ readonly actionLabelReview: "Review scan";
315
+ };
291
316
  readonly cli: {
292
317
  readonly stderrAnalysisIncomplete: "Analysis could not be completed.";
293
318
  readonly stderrOutputNotVerified: "These results could not be verified.";
@@ -1 +1 @@
1
- {"version":3,"file":"scanSurfaceCopy.d.ts","sourceRoot":"","sources":["../src/scanSurfaceCopy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;QAgBxB,8EAA8E;;QAG9E,6DAA6D;;;;QAO7D,qDAAqD;;;;;QASrD,mEAAmE;;;;QAOnE,yFAAyF;;QAGzF,mFAAmF;;QAGnF,4EAA4E;;QAE5E,8FAA8F;;QAE9F,+DAA+D;;;QAI/D,6EAA6E;;;;;QAK7E,2CAA2C;;;QAK3C,2EAA2E;;QAE3E,4EAA4E;;;QAI5E,sEAAsE;;;IAGxE,2EAA2E;;;;;;;;;;;;;;QAiBzE,oEAAoE;;;IAGtE,wEAAwE;;;;;;QAOtE,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkCzC,yDAAyD;;YAGzD,mDAAmD;;YAGnD,8BAA8B;;YAE9B,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CtD,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsI/C,uFAAuF;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BvF,sEAAsE;;;;;CAO9D,CAAC;AAEX,iEAAiE;AACjE,wBAAgB,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D"}
1
+ {"version":3,"file":"scanSurfaceCopy.d.ts","sourceRoot":"","sources":["../src/scanSurfaceCopy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;QAgBxB,8EAA8E;;QAG9E,6DAA6D;;;;QAO7D,qDAAqD;;;;;QASrD,mEAAmE;;;;QAOnE,yFAAyF;;QAGzF,mFAAmF;;QAGnF,4EAA4E;;QAE5E,8FAA8F;;QAE9F,+DAA+D;;;QAI/D,6EAA6E;;;;;QAK7E,2CAA2C;;;QAK3C,2EAA2E;;QAE3E,4EAA4E;;;QAI5E,sEAAsE;;;IAGxE,2EAA2E;;;;;;;;;;;;;;QAiBzE,oEAAoE;;;IAGtE,wEAAwE;;;;;;QAOtE,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkCzC,yDAAyD;;YAGzD,mDAAmD;;YAGnD,8BAA8B;;YAE9B,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CtD,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsI/C,uFAAuF;;;;;;;;;;;;;;;;;;;;;;;;IAwBvF,kFAAkF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+BlF,sEAAsE;;;;;CAO9D,CAAC;AAEX,iEAAiE;AACjE,wBAAgB,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D"}
@@ -291,6 +291,31 @@ export const scanSurfaceCopy = {
291
291
  areasSeparator: " | ",
292
292
  contextSeparator: " | ",
293
293
  },
294
+ /** Shared presentation layer copy (composeHeadline, key points, verification). */
295
+ presentation: {
296
+ limitedContextHeadline: "Dependency upgrade with limited scan context",
297
+ limitedContextMessage: "PR-specific scan context was limited",
298
+ limitedContextKeyPoint: "PR-specific intelligence was limited for this scan",
299
+ noChangedPackagesHeadline: "Dependency scan complete",
300
+ multiRuntimeHeadline: "Multiple runtime dependency upgrades need review",
301
+ buildOnlyHeadline: "{package} patch upgrade with limited application impact",
302
+ runtimeHeadline: "{package} upgrade affects {surface}",
303
+ defaultUpgradeHeadline: "{package} dependency upgrade needs review",
304
+ changedPackageKeyPoint: "Changed package: {package}",
305
+ usedInPathsSingle: "Used across application code ({path})",
306
+ usedInPathsMultiple: "Used across {count} code paths",
307
+ noRuntimePathsKeyPoint: "No runtime usage paths detected",
308
+ blastRadiusWideKeyPoint: "Blast radius is wide",
309
+ blastRadiusLevelKeyPoint: "Blast radius is {level}",
310
+ noAffectedAreasKeyPoint: "No affected application areas identified",
311
+ affectedAreasKeyPoint: "Affected areas: {areas}",
312
+ verifyCiTypecheck: "Confirm CI/typecheck passes",
313
+ verifyAuthFlow: "Run authenticated API request flow",
314
+ verifyErrorResponses: "Check error responses and status codes",
315
+ graphDepthContext: "Repository graph max depth: {depth}",
316
+ graphSizeContext: "Repository graph: {nodes} nodes, {edges} edges",
317
+ actionLabelReview: "Review scan",
318
+ },
294
319
  cli: {
295
320
  stderrAnalysisIncomplete: "Analysis could not be completed.",
296
321
  stderrOutputNotVerified: "These results could not be verified.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mergesignal/shared",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "MergeSignal shared scan contract, presentation policy, and trusted validation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,16 +0,0 @@
1
- import { type ScanCardSummary, type ScanPipelineStatus } from "./scanCardSummary.js";
2
- import type { ScanNarrativeFacts } from "./scanNarrativeFacts.js";
3
- import { type CardExposureDisplay } from "./formatCardExposureDisplay.js";
4
- import { type MergePosture } from "./riskVocabulary.js";
5
- import type { ScanResult } from "./types.js";
6
- export type PresentScanCardSummaryOptions = {
7
- pipelineStatus?: ScanPipelineStatus;
8
- findings?: ScanResult["findings"];
9
- };
10
- /**
11
- * Dashboard card presentation DTO from consumer-agnostic facts.
12
- */
13
- export declare function presentScanCardSummary(facts: ScanNarrativeFacts, options?: PresentScanCardSummaryOptions): ScanCardSummary;
14
- export type { CardExposureDisplay, MergePosture };
15
- export declare function exposureFromFacts(facts: ScanNarrativeFacts): CardExposureDisplay | null;
16
- //# sourceMappingURL=presentScanCardSummary.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"presentScanCardSummary.d.ts","sourceRoot":"","sources":["../src/presentScanCardSummary.ts"],"names":[],"mappings":"AAKA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,gCAAgC,CAAC;AAkBxC,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;CACnC,CAAC;AA2HF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,6BAAkC,GAC1C,eAAe,CA8HjB;AAED,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,CAAC;AAElD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,kBAAkB,GACxB,mBAAmB,GAAG,IAAI,CAE5B"}
@@ -1,212 +0,0 @@
1
- import { isCatalogPhrase, phraseForFamily, } from "./cardObservationCatalog.js";
2
- import { aggregateFindingCounts, deriveRiskIndexBand, SCAN_CARD_SCANNING_SUMMARY, } from "./scanCardSummary.js";
3
- import { deriveCardExposureDisplay, } from "./formatCardExposureDisplay.js";
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";
7
- import { MERGE_POSTURE_LABEL } from "./riskVocabulary.js";
8
- import { scanSurfaceCopy } from "./scanSurfaceCopy.js";
9
- function formatAffectedAreaLabels(facts) {
10
- const ordered = [];
11
- for (const area of facts.affectedAreas) {
12
- const formatted = formatCardAreaLabels([area.label], 1);
13
- if (formatted[0])
14
- ordered.push(formatted[0]);
15
- if (ordered.length >= 2)
16
- break;
17
- }
18
- return ordered;
19
- }
20
- function selectPrimaryInsight(facts) {
21
- const changedGuidance = facts.reviewerGuidance.find((g) => g.scope === "changed" && g.message.trim());
22
- if (changedGuidance)
23
- return changedGuidance.message.trim();
24
- const insight = facts.reviewerGuidance.find((g) => g.kind === "insight" && g.message.trim());
25
- if (insight)
26
- return insight.message.trim();
27
- return null;
28
- }
29
- function selectSecondaryLines(facts, exclude) {
30
- const lines = [];
31
- for (const g of facts.reviewerGuidance) {
32
- const msg = g.message.trim();
33
- if (!msg || msg === exclude)
34
- continue;
35
- lines.push(msg);
36
- if (lines.length >= 2)
37
- break;
38
- }
39
- return lines;
40
- }
41
- function repositoryContextPhrases(facts, max) {
42
- const phrases = [];
43
- const seen = new Set();
44
- for (const ctx of facts.repositoryContext) {
45
- const phrase = phraseForFamily(ctx.family);
46
- if (seen.has(phrase))
47
- continue;
48
- seen.add(phrase);
49
- phrases.push(phrase);
50
- if (phrases.length >= max)
51
- break;
52
- }
53
- return phrases;
54
- }
55
- function buildLegacyObservations(facts, primaryInsight, repoPhraseCap) {
56
- const repoPhrases = repositoryContextPhrases(facts, repoPhraseCap);
57
- const secondary = selectSecondaryLines(facts, primaryInsight);
58
- if (primaryInsight) {
59
- return {
60
- operationalObservations: repoPhrases.slice(0, 1),
61
- supportingLine: repoPhrases[0] && repoPhrases[0] !== primaryInsight
62
- ? repoPhrases[0]
63
- : (secondary[0] ?? null),
64
- };
65
- }
66
- if (repoPhrases.length === 0) {
67
- return { operationalObservations: [], supportingLine: null };
68
- }
69
- return {
70
- operationalObservations: repoPhrases.slice(0, repoPhraseCap),
71
- supportingLine: repoPhrases.length === 1 ? (secondary[0] ?? null) : null,
72
- };
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
- }
98
- /**
99
- * Dashboard card presentation DTO from consumer-agnostic facts.
100
- */
101
- export function presentScanCardSummary(facts, options = {}) {
102
- const pipelineStatus = options.pipelineStatus ?? "done";
103
- const emptyPresentationFields = {
104
- narrativeMode: facts.availability.mode,
105
- codeIntelligenceAvailable: facts.availability.codeIntelligenceAvailable,
106
- changedPackagesDisplay: null,
107
- runtimeSurfaceLabel: null,
108
- reachabilityLabel: null,
109
- blastRadiusLabel: null,
110
- affectedAreas: [],
111
- primaryInsight: null,
112
- structuralOnlyDisclaimer: null,
113
- usageSummary: null,
114
- verificationLine: null,
115
- blastRadiusDetail: null,
116
- frameworksSummary: null,
117
- };
118
- if (pipelineStatus === "queued" || pipelineStatus === "running") {
119
- return normalizeCardSummary({
120
- mergePosture: null,
121
- riskIndex: null,
122
- riskIndexBand: null,
123
- headline: scanSurfaceCopy.pipeline.scanRunning,
124
- summaryLine: SCAN_CARD_SCANNING_SUMMARY,
125
- findingCounts: null,
126
- topAffectedAreas: [],
127
- operationalObservations: [],
128
- supportingLine: null,
129
- ...emptyPresentationFields,
130
- });
131
- }
132
- if (pipelineStatus === "failed") {
133
- return normalizeCardSummary({
134
- mergePosture: null,
135
- riskIndex: null,
136
- riskIndexBand: null,
137
- headline: scanSurfaceCopy.pipeline.analysisIncomplete,
138
- summaryLine: null,
139
- findingCounts: null,
140
- topAffectedAreas: [],
141
- operationalObservations: [],
142
- supportingLine: null,
143
- ...emptyPresentationFields,
144
- });
145
- }
146
- const posture = facts.mergePosture;
147
- const riskIndex = facts.riskIndex;
148
- const riskIndexBand = deriveRiskIndexBand(riskIndex);
149
- const headline = posture
150
- ? MERGE_POSTURE_LABEL[posture]
151
- : scanSurfaceCopy.checkRun.mergePostureUnavailable;
152
- const findingCounts = options.findings
153
- ? aggregateFindingCounts(options.findings)
154
- : null;
155
- const prIntelligence = facts.availability.mode === "pr_intelligence" ||
156
- facts.availability.tiersPresent.tier1;
157
- const changedPackagesDisplay = formatChangedPackagesShort(facts, 2);
158
- const runtimeSurfaceLabel = labelRuntimeSurface(facts);
159
- const reachabilityLabel = labelReachabilityKind(facts);
160
- const blastRadiusLabel = labelBlastRadiusLevel(facts);
161
- const affectedAreas = formatAffectedAreaLabels(facts);
162
- const contextLine = composeContextLineFromFacts(facts, {
163
- includePathSample: prIntelligence,
164
- maxAreas: 2,
165
- });
166
- const structuralOnlyDisclaimer = facts.availability.mode === "graph_fallback" &&
167
- !facts.availability.tiersPresent.tier1
168
- ? scanSurfaceCopy.narrativeCard.structuralOnlyDisclaimer
169
- : null;
170
- const insightMessage = selectPrimaryInsight(facts);
171
- const primaryInsight = insightMessage ??
172
- (facts.availability.mode !== "graph_fallback" ? contextLine : null);
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({
186
- mergePosture: posture,
187
- riskIndex,
188
- riskIndexBand,
189
- headline,
190
- summaryLine: null,
191
- findingCounts,
192
- topAffectedAreas: affectedAreas,
193
- operationalObservations,
194
- supportingLine,
195
- narrativeMode: facts.availability.mode,
196
- codeIntelligenceAvailable: facts.availability.codeIntelligenceAvailable,
197
- changedPackagesDisplay,
198
- runtimeSurfaceLabel,
199
- reachabilityLabel,
200
- blastRadiusLabel,
201
- affectedAreas,
202
- primaryInsight,
203
- structuralOnlyDisclaimer,
204
- usageSummary,
205
- verificationLine,
206
- blastRadiusDetail,
207
- frameworksSummary,
208
- });
209
- }
210
- export function exposureFromFacts(facts) {
211
- return deriveCardExposureDisplay(facts.riskIndex) ?? null;
212
- }