@shapeshift-labs/frontier-swarm-codex 0.5.119 → 0.5.121

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 (197) hide show
  1. package/README.md +8 -0
  2. package/dist/apply.d.ts.map +1 -1
  3. package/dist/apply.js +152 -17
  4. package/dist/apply.js.map +1 -1
  5. package/dist/artifact-store.d.ts.map +1 -1
  6. package/dist/artifact-store.js +20 -6
  7. package/dist/artifact-store.js.map +1 -1
  8. package/dist/cli-args.d.ts +1 -1
  9. package/dist/cli-args.d.ts.map +1 -1
  10. package/dist/cli-args.js +15 -2
  11. package/dist/cli-args.js.map +1 -1
  12. package/dist/cli-help.d.ts.map +1 -1
  13. package/dist/cli-help.js +6 -0
  14. package/dist/cli-help.js.map +1 -1
  15. package/dist/cli-run-events-args.d.ts +5 -0
  16. package/dist/cli-run-events-args.d.ts.map +1 -0
  17. package/dist/cli-run-events-args.js +19 -0
  18. package/dist/cli-run-events-args.js.map +1 -0
  19. package/dist/cli.js +20 -1
  20. package/dist/cli.js.map +1 -1
  21. package/dist/codex-events.d.ts +3 -0
  22. package/dist/codex-events.d.ts.map +1 -1
  23. package/dist/codex-events.js +38 -0
  24. package/dist/codex-events.js.map +1 -1
  25. package/dist/codex-executor.d.ts.map +1 -1
  26. package/dist/codex-executor.js +67 -4
  27. package/dist/codex-executor.js.map +1 -1
  28. package/dist/codex-run-metadata.d.ts +1 -0
  29. package/dist/codex-run-metadata.d.ts.map +1 -1
  30. package/dist/codex-run-metadata.js +1 -0
  31. package/dist/codex-run-metadata.js.map +1 -1
  32. package/dist/codex-run-swarm.d.ts.map +1 -1
  33. package/dist/codex-run-swarm.js +69 -5
  34. package/dist/codex-run-swarm.js.map +1 -1
  35. package/dist/codex-run-timeline.d.ts +10 -0
  36. package/dist/codex-run-timeline.d.ts.map +1 -0
  37. package/dist/codex-run-timeline.js +31 -0
  38. package/dist/codex-run-timeline.js.map +1 -0
  39. package/dist/codex-run.d.ts.map +1 -1
  40. package/dist/codex-run.js +74 -6
  41. package/dist/codex-run.js.map +1 -1
  42. package/dist/collect-bundle-reasons.d.ts.map +1 -1
  43. package/dist/collect-bundle-reasons.js +7 -0
  44. package/dist/collect-bundle-reasons.js.map +1 -1
  45. package/dist/collect-bundles.d.ts +2 -0
  46. package/dist/collect-bundles.d.ts.map +1 -1
  47. package/dist/collect-bundles.js +52 -3
  48. package/dist/collect-bundles.js.map +1 -1
  49. package/dist/collect-dashboard-quality.d.ts.map +1 -1
  50. package/dist/collect-dashboard-quality.js +12 -3
  51. package/dist/collect-dashboard-quality.js.map +1 -1
  52. package/dist/collect-dashboard.d.ts.map +1 -1
  53. package/dist/collect-dashboard.js +54 -1
  54. package/dist/collect-dashboard.js.map +1 -1
  55. package/dist/collect-evidence.d.ts.map +1 -1
  56. package/dist/collect-evidence.js +49 -7
  57. package/dist/collect-evidence.js.map +1 -1
  58. package/dist/collect-finalize.d.ts.map +1 -1
  59. package/dist/collect-finalize.js +5 -1
  60. package/dist/collect-finalize.js.map +1 -1
  61. package/dist/collect-landed.d.ts.map +1 -1
  62. package/dist/collect-landed.js +4 -1
  63. package/dist/collect-landed.js.map +1 -1
  64. package/dist/collect-pids.d.ts.map +1 -1
  65. package/dist/collect-pids.js +9 -2
  66. package/dist/collect-pids.js.map +1 -1
  67. package/dist/collect-research-outcomes.d.ts +6 -0
  68. package/dist/collect-research-outcomes.d.ts.map +1 -0
  69. package/dist/collect-research-outcomes.js +79 -0
  70. package/dist/collect-research-outcomes.js.map +1 -0
  71. package/dist/collect-run-graph.d.ts +7 -0
  72. package/dist/collect-run-graph.d.ts.map +1 -0
  73. package/dist/collect-run-graph.js +1246 -0
  74. package/dist/collect-run-graph.js.map +1 -0
  75. package/dist/collect-semantic-admission.d.ts +18 -0
  76. package/dist/collect-semantic-admission.d.ts.map +1 -0
  77. package/dist/collect-semantic-admission.js +500 -0
  78. package/dist/collect-semantic-admission.js.map +1 -0
  79. package/dist/collect-setup.d.ts.map +1 -1
  80. package/dist/collect-setup.js +2 -0
  81. package/dist/collect-setup.js.map +1 -1
  82. package/dist/collect-terminal-state.d.ts.map +1 -1
  83. package/dist/collect-terminal-state.js +38 -1
  84. package/dist/collect-terminal-state.js.map +1 -1
  85. package/dist/collect-workspace-only.d.ts +1 -0
  86. package/dist/collect-workspace-only.d.ts.map +1 -1
  87. package/dist/collect-workspace-only.js +123 -21
  88. package/dist/collect-workspace-only.js.map +1 -1
  89. package/dist/collect.d.ts.map +1 -1
  90. package/dist/collect.js +57 -10
  91. package/dist/collect.js.map +1 -1
  92. package/dist/common.d.ts.map +1 -1
  93. package/dist/common.js +1 -0
  94. package/dist/common.js.map +1 -1
  95. package/dist/dashboard-ui-health.d.ts.map +1 -1
  96. package/dist/dashboard-ui-health.js +2 -0
  97. package/dist/dashboard-ui-health.js.map +1 -1
  98. package/dist/dashboard-ui-jobs.js +3 -0
  99. package/dist/dashboard-ui-jobs.js.map +1 -1
  100. package/dist/dashboard-ui-semantic.d.ts +6 -2
  101. package/dist/dashboard-ui-semantic.d.ts.map +1 -1
  102. package/dist/dashboard-ui-semantic.js +245 -53
  103. package/dist/dashboard-ui-semantic.js.map +1 -1
  104. package/dist/dashboard-ui.js +3 -2
  105. package/dist/dashboard-ui.js.map +1 -1
  106. package/dist/dashboard.d.ts.map +1 -1
  107. package/dist/dashboard.js +48 -0
  108. package/dist/dashboard.js.map +1 -1
  109. package/dist/index.d.ts +4 -0
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +2 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/query-matchers.d.ts.map +1 -1
  114. package/dist/query-matchers.js +4 -1
  115. package/dist/query-matchers.js.map +1 -1
  116. package/dist/query-semantic-edit.d.ts +41 -0
  117. package/dist/query-semantic-edit.d.ts.map +1 -1
  118. package/dist/query-semantic-edit.js +468 -0
  119. package/dist/query-semantic-edit.js.map +1 -1
  120. package/dist/query-summaries.d.ts +2 -0
  121. package/dist/query-summaries.d.ts.map +1 -1
  122. package/dist/query-summaries.js +4 -2
  123. package/dist/query-summaries.js.map +1 -1
  124. package/dist/query-types.d.ts +3 -0
  125. package/dist/query-types.d.ts.map +1 -1
  126. package/dist/query.d.ts +5 -0
  127. package/dist/query.d.ts.map +1 -1
  128. package/dist/query.js +7 -1
  129. package/dist/query.js.map +1 -1
  130. package/dist/run-events.d.ts +54 -0
  131. package/dist/run-events.d.ts.map +1 -0
  132. package/dist/run-events.js +196 -0
  133. package/dist/run-events.js.map +1 -0
  134. package/dist/run-graph-live.d.ts +46 -0
  135. package/dist/run-graph-live.d.ts.map +1 -0
  136. package/dist/run-graph-live.js +799 -0
  137. package/dist/run-graph-live.js.map +1 -0
  138. package/dist/run-graph-utils.d.ts +8 -0
  139. package/dist/run-graph-utils.d.ts.map +1 -0
  140. package/dist/run-graph-utils.js +44 -0
  141. package/dist/run-graph-utils.js.map +1 -0
  142. package/dist/score.js +1 -1
  143. package/dist/score.js.map +1 -1
  144. package/dist/semantic-import-quality-helpers.d.ts +55 -0
  145. package/dist/semantic-import-quality-helpers.d.ts.map +1 -0
  146. package/dist/semantic-import-quality-helpers.js +146 -0
  147. package/dist/semantic-import-quality-helpers.js.map +1 -0
  148. package/dist/semantic-import-quality.d.ts.map +1 -1
  149. package/dist/semantic-import-quality.js +519 -115
  150. package/dist/semantic-import-quality.js.map +1 -1
  151. package/dist/semantic-import-select.d.ts +2 -0
  152. package/dist/semantic-import-select.d.ts.map +1 -1
  153. package/dist/semantic-import-select.js +2 -0
  154. package/dist/semantic-import-select.js.map +1 -1
  155. package/dist/semantic-import-sidecar.d.ts +2 -0
  156. package/dist/semantic-import-sidecar.d.ts.map +1 -1
  157. package/dist/semantic-import-sidecar.js +196 -0
  158. package/dist/semantic-import-sidecar.js.map +1 -1
  159. package/dist/semantic-import.d.ts +6 -2
  160. package/dist/semantic-import.d.ts.map +1 -1
  161. package/dist/semantic-import.js +213 -8
  162. package/dist/semantic-import.js.map +1 -1
  163. package/dist/semantic-merge-admission.d.ts +59 -0
  164. package/dist/semantic-merge-admission.d.ts.map +1 -0
  165. package/dist/semantic-merge-admission.js +399 -0
  166. package/dist/semantic-merge-admission.js.map +1 -0
  167. package/dist/types-apply-lease.d.ts +26 -0
  168. package/dist/types-apply-lease.d.ts.map +1 -0
  169. package/dist/types-apply-lease.js +2 -0
  170. package/dist/types-apply-lease.js.map +1 -0
  171. package/dist/types-collection-quality.d.ts +6 -0
  172. package/dist/types-collection-quality.d.ts.map +1 -1
  173. package/dist/types-collection.d.ts +6 -1
  174. package/dist/types-collection.d.ts.map +1 -1
  175. package/dist/types-dashboard-metrics.d.ts +68 -1
  176. package/dist/types-dashboard-metrics.d.ts.map +1 -1
  177. package/dist/types-dashboard.d.ts +14 -0
  178. package/dist/types-dashboard.d.ts.map +1 -1
  179. package/dist/types-evidence.d.ts +15 -0
  180. package/dist/types-evidence.d.ts.map +1 -1
  181. package/dist/types-run-graph.d.ts +74 -0
  182. package/dist/types-run-graph.d.ts.map +1 -0
  183. package/dist/types-run-graph.js +2 -0
  184. package/dist/types-run-graph.js.map +1 -0
  185. package/dist/types-run.d.ts +22 -0
  186. package/dist/types-run.d.ts.map +1 -1
  187. package/dist/types-semantic-quality.d.ts +118 -0
  188. package/dist/types-semantic-quality.d.ts.map +1 -0
  189. package/dist/types-semantic-quality.js +2 -0
  190. package/dist/types-semantic-quality.js.map +1 -0
  191. package/dist/types-semantic.d.ts +98 -47
  192. package/dist/types-semantic.d.ts.map +1 -1
  193. package/dist/types-workspace.d.ts +3 -0
  194. package/dist/types-workspace.d.ts.map +1 -1
  195. package/dist/types.d.ts +2 -0
  196. package/dist/types.d.ts.map +1 -1
  197. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
- import { nonNegativeNumber, readStringArray, uniqueStrings } from './common.js';
1
+ import { isObject, nonNegativeNumber, numberRecord, readStringArray, uniqueStrings } from './common.js';
2
2
  import { semanticImportFactSummary } from './semantic-import-facts.js';
3
3
  import { semanticImportUniversalAstLayerSummary } from './semantic-import-layers.js';
4
4
  import { semanticImportParadigmSemanticsSummary } from './semantic-import-paradigm.js';
@@ -8,6 +8,7 @@ import { summarizeSemanticEditScript } from './semantic-edit-script.js';
8
8
  import { summarizeSemanticEditProjection, emptySemanticEditProjectionSummary } from './semantic-edit-projection.js';
9
9
  import { emptySemanticEditReplaySummary, summarizeSemanticEditReplay } from './semantic-edit-replay.js';
10
10
  import { classifySemanticEditScriptAdmission } from './semantic-edit-admission.js';
11
+ import { semanticImportCandidateCount, semanticImportExpected, semanticImportExpectedMissingReasonCodes, semanticImportExpectedSatisfied, semanticImportNativeCompileSummary, semanticImportSliceAdmissionSummary, semanticImportSourceProjectionSummary, semanticLineageExpectedForBeforeSourceDiff, semanticSelectionSummary } from './semantic-import-quality-helpers.js';
11
12
  export function summarizeCodexSemanticImportQuality(summary, expected = false) {
12
13
  const total = nonNegativeNumber(summary?.total);
13
14
  const candidates = semanticImportCandidateCount(summary);
@@ -15,9 +16,16 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
15
16
  const eligible = nonNegativeNumber(summary?.eligible);
16
17
  const imported = nonNegativeNumber(summary?.imported);
17
18
  const errors = nonNegativeNumber(summary?.errors);
19
+ const lossCount = nonNegativeNumber(summary?.lossCount);
20
+ const lossesBySeverity = numberRecord(summary?.lossesBySeverity);
21
+ const semanticErrorLosses = nonNegativeNumber(lossesBySeverity.error);
22
+ const semanticWarningLosses = nonNegativeNumber(lossesBySeverity.warning);
18
23
  const symbols = nonNegativeNumber(summary?.semanticIndex?.symbols);
19
24
  const ownershipRegions = nonNegativeNumber(summary?.semanticSidecars?.ownershipRegions);
20
25
  const patchHints = nonNegativeNumber(summary?.semanticSidecars?.patchHints);
26
+ const semanticReadiness = numberRecord(summary?.readiness);
27
+ const sourceProjections = semanticImportSourceProjectionSummary(summary);
28
+ const nativeCompiles = semanticImportNativeCompileSummary(summary);
21
29
  const semanticFacts = semanticImportFactSummary(summary);
22
30
  const dependencyRelations = nonNegativeNumber(summary?.dependencies?.total);
23
31
  const dependencyPredicates = Array.isArray(summary?.dependencies?.predicates)
@@ -35,11 +43,14 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
35
43
  const universalAstLayerNames = universalAstLayerSummary.names;
36
44
  const proofSpec = semanticImportProofSpecSummary(summary);
37
45
  const paradigmSemantics = semanticImportParadigmSemanticsSummary(summary);
46
+ const semanticSliceAdmissions = semanticImportSliceAdmissionSummary(summary);
38
47
  const semanticLineage = semanticImportLineageSummary(summary);
39
48
  const semanticEditScript = summarizeSemanticEditScript(summary) ?? summarizeSemanticEditScript({ semanticEditScripts: summary?.semanticEditScripts });
40
49
  const semanticEditProjection = summarizeSemanticEditProjection(summary) ?? emptySemanticEditProjectionSummary();
41
50
  const semanticEditReplay = summarizeSemanticEditReplay(summary) ?? emptySemanticEditReplaySummary();
42
- const semanticEditAdmission = classifySemanticEditScriptAdmission(semanticEditScript);
51
+ const semanticMergeAdmission = summarizeSemanticMergeAdmissionQuality(summary);
52
+ const jsTsSafeMergeApply = summarizeJsTsSafeMergeApplyQuality(summary);
53
+ const semanticEditAdmission = semanticEditAdmissionWithSafeMerge(classifySemanticEditScriptAdmission(semanticEditScript), semanticMergeAdmission, jsTsSafeMergeApply);
43
54
  const semanticLineageExpected = semanticLineageExpectedForBeforeSourceDiff(summary, semanticLineage.beforeSymbols);
44
55
  const selection = semanticSelectionSummary(summary);
45
56
  const present = !!summary;
@@ -78,6 +89,20 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
78
89
  warnings.push('semantic import imported no files');
79
90
  if (present && errors > 0)
80
91
  warnings.push('semantic import has errors');
92
+ if (present && semanticErrorLosses > 0)
93
+ warnings.push('semantic import has error losses');
94
+ if (present && semanticReadiness.blocked > 0)
95
+ warnings.push('semantic import readiness is blocked');
96
+ if (present && semanticReadiness['needs-review'] > 0)
97
+ warnings.push('semantic import readiness needs review');
98
+ if (present && sourceProjections.blocked > 0)
99
+ warnings.push('semantic source projection is blocked');
100
+ if (present && sourceProjections.stubs > 0)
101
+ warnings.push('semantic source projection uses stubs');
102
+ if (present && nativeCompiles.blocked > 0)
103
+ warnings.push('semantic native compile is blocked');
104
+ if (present && nativeCompiles.targetStubs > 0)
105
+ warnings.push('semantic native compile emitted target stubs');
81
106
  if (present && selected === 0 && selection.includeFiltered > 0)
82
107
  warnings.push('semantic import include filters selected no files');
83
108
  if (present && selected === 0 && selection.unsupportedLanguage > 0)
@@ -96,6 +121,8 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
96
121
  warnings.push('semantic import has failed proof obligations');
97
122
  if (present && proofSpec.stale > 0)
98
123
  warnings.push('semantic import has stale proof obligations');
124
+ if (present && semanticSliceAdmissions.rejected > 0)
125
+ warnings.push('semantic slice admission rejected candidates');
99
126
  if (present && symbols > 0 && semanticLineageExpected && semanticLineage.inferredEvents === 0) {
100
127
  warnings.push('semantic import has symbols but no inferred semantic lineage for expected before-source diff');
101
128
  }
@@ -126,6 +153,26 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
126
153
  warnings.push('semantic edit replay is blocked');
127
154
  if (present && semanticEditReplay.needsPort > 0)
128
155
  warnings.push('semantic edit replay needs port');
156
+ if (present && semanticMergeAdmission.noOp > 0)
157
+ warnings.push('semantic merge admission is no-op');
158
+ if (present && semanticMergeAdmission.stale > 0)
159
+ warnings.push('semantic merge admission is stale');
160
+ if (present && semanticMergeAdmission.conflicts > 0)
161
+ warnings.push('semantic merge admission has conflicts');
162
+ if (present && semanticMergeAdmission.reviewRequired > 0)
163
+ warnings.push('semantic merge admission needs review');
164
+ if (present && semanticMergeAdmission.blocked > 0)
165
+ warnings.push('semantic merge admission is blocked');
166
+ if (present && jsTsSafeMergeApply.noOp > 0)
167
+ warnings.push('semantic safe-merge apply is no-op');
168
+ if (present && jsTsSafeMergeApply.stale > 0)
169
+ warnings.push('semantic safe-merge apply is stale');
170
+ if (present && jsTsSafeMergeApply.conflicts > 0)
171
+ warnings.push('semantic safe-merge apply has conflicts');
172
+ if (present && jsTsSafeMergeApply.needsReview > 0)
173
+ warnings.push('semantic safe-merge apply needs review');
174
+ if (present && jsTsSafeMergeApply.blocked > 0)
175
+ warnings.push('semantic safe-merge apply is blocked');
129
176
  return {
130
177
  expected: effectiveExpected,
131
178
  expectedSatisfied,
@@ -138,9 +185,27 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
138
185
  eligible,
139
186
  imported,
140
187
  errors,
188
+ lossCount,
189
+ lossesBySeverity,
190
+ semanticErrorLosses,
191
+ semanticWarningLosses,
141
192
  symbols,
142
193
  ownershipRegions,
143
194
  patchHints,
195
+ semanticReadiness,
196
+ sourceProjectionTotal: sourceProjections.total,
197
+ sourceProjectionPreserved: sourceProjections.preserved,
198
+ sourceProjectionStubs: sourceProjections.stubs,
199
+ sourceProjectionReady: sourceProjections.ready,
200
+ sourceProjectionNeedsReview: sourceProjections.needsReview,
201
+ sourceProjectionBlocked: sourceProjections.blocked,
202
+ nativeCompileTotal: nativeCompiles.total,
203
+ nativeCompileEmitted: nativeCompiles.emitted,
204
+ nativeCompilePreserved: nativeCompiles.preserved,
205
+ nativeCompileTargetStubs: nativeCompiles.targetStubs,
206
+ nativeCompileReady: nativeCompiles.ready,
207
+ nativeCompileNeedsReview: nativeCompiles.needsReview,
208
+ nativeCompileBlocked: nativeCompiles.blocked,
144
209
  semanticFacts: semanticFacts.total,
145
210
  semanticFactPredicates: semanticFacts.predicates,
146
211
  semanticFactSummary: semanticFacts.byPredicate,
@@ -156,6 +221,10 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
156
221
  paradigmSemanticsRecords: paradigmSemantics.total,
157
222
  paradigmSemanticsGroups: paradigmSemantics.groups.length,
158
223
  paradigmSemanticsLoweringRecords: paradigmSemantics.loweringRecords,
224
+ semanticSliceAdmissionTotal: semanticSliceAdmissions.total,
225
+ semanticSliceAdmissionAdmitted: semanticSliceAdmissions.admitted,
226
+ semanticSliceAdmissionPrioritized: semanticSliceAdmissions.prioritized,
227
+ semanticSliceAdmissionRejected: semanticSliceAdmissions.rejected,
159
228
  semanticLineageEvents: semanticLineage.inferredEvents,
160
229
  semanticLineageMoved: semanticLineage.moved,
161
230
  semanticLineageRenamed: semanticLineage.renamed,
@@ -169,121 +238,11 @@ export function summarizeCodexSemanticImportQuality(summary, expected = false) {
169
238
  semanticEditProjection,
170
239
  semanticEditReplay,
171
240
  semanticEditAdmission,
241
+ semanticMergeAdmission,
242
+ jsTsSafeMergeApply,
172
243
  warnings: uniqueStrings(warnings)
173
244
  };
174
245
  }
175
- function semanticImportCandidateCount(summary) {
176
- const record = summaryRecord(summary);
177
- return nonNegativeNumber(record?.selection?.candidates ?? record?.total);
178
- }
179
- function semanticImportExpected(summary, fallback) {
180
- if (fallback)
181
- return true;
182
- const record = summaryRecord(summary);
183
- if (!record)
184
- return false;
185
- return record.semanticImportExpected === true ||
186
- record.expected === true ||
187
- record.quality?.expected === true ||
188
- record.admission?.expected === true;
189
- }
190
- function semanticImportExpectedSatisfied(summary, input) {
191
- if (!input.expected)
192
- return true;
193
- const explicit = semanticImportExplicitExpectedSatisfied(summary);
194
- if (explicit !== undefined)
195
- return explicit && input.reasonCodes.length === 0;
196
- return input.present &&
197
- !input.empty &&
198
- input.imported > 0 &&
199
- input.symbols > 0 &&
200
- input.ownershipRegions > 0 &&
201
- input.patchHints > 0 &&
202
- input.reasonCodes.length === 0;
203
- }
204
- function semanticImportExpectedMissingReasonCodes(summary, input) {
205
- const record = summaryRecord(summary);
206
- const explicitCodes = uniqueStrings([
207
- ...readStringArray(record?.semanticImportExpectedMissingReasonCodes),
208
- ...readStringArray(record?.quality?.expectedMissingReasonCodes),
209
- ...readStringArray(record?.admission?.expectedMissingReasonCodes)
210
- ]);
211
- if (!input.expected)
212
- return explicitCodes;
213
- const inferredCodes = [];
214
- if (!input.present)
215
- inferredCodes.push('expected-semantic-import-missing');
216
- if (input.present && input.selected === 0)
217
- inferredCodes.push('expected-semantic-import-missing');
218
- if (input.present && input.selected > 0 && input.imported === 0)
219
- inferredCodes.push('missing-imports');
220
- if (input.present && input.imported > 0 && input.symbols === 0) {
221
- inferredCodes.push('expected-semantic-import-empty', 'empty-semantic-index');
222
- }
223
- if (input.present && input.imported > 0 && input.ownershipRegions === 0)
224
- inferredCodes.push('missing-ownership-regions');
225
- if (input.present && input.imported > 0 && input.patchHints === 0)
226
- inferredCodes.push('missing-patch-hints');
227
- if (input.empty && !inferredCodes.includes('expected-semantic-import-empty')) {
228
- inferredCodes.push('expected-semantic-import-empty');
229
- }
230
- return uniqueStrings([...explicitCodes, ...inferredCodes]);
231
- }
232
- function semanticImportExplicitExpectedSatisfied(summary) {
233
- const record = summaryRecord(summary);
234
- const candidates = [
235
- record?.semanticImportExpectedSatisfied,
236
- record?.quality?.expectedSatisfied,
237
- record?.admission?.expectedSatisfied
238
- ];
239
- for (const value of candidates) {
240
- if (typeof value === 'boolean')
241
- return value;
242
- }
243
- return undefined;
244
- }
245
- function semanticLineageExpectedForBeforeSourceDiff(summary, beforeSymbols) {
246
- if (beforeSymbols > 0)
247
- return true;
248
- const record = summaryRecord(summary);
249
- if (!record)
250
- return false;
251
- const quality = record.quality;
252
- const admission = record.admission;
253
- const lineage = record.semanticLineage;
254
- const inference = record.semanticLineageInference;
255
- const lineageInference = record.lineageInference;
256
- return [
257
- record.semanticLineageExpected,
258
- record.semanticLineageInferenceExpected,
259
- record.beforeSourceDiffExpected,
260
- record.beforeSourceExpected,
261
- quality?.semanticLineageExpected,
262
- quality?.beforeSourceDiffExpected,
263
- admission?.semanticLineageExpected,
264
- admission?.beforeSourceDiffExpected,
265
- lineage?.expected,
266
- lineage?.beforeSourceDiffExpected,
267
- inference?.expected,
268
- inference?.beforeSourceDiffExpected,
269
- lineageInference?.expected,
270
- lineageInference?.beforeSourceDiffExpected
271
- ].some((value) => value === true);
272
- }
273
- function summaryRecord(summary) {
274
- return summary && typeof summary === 'object' && !Array.isArray(summary)
275
- ? summary
276
- : undefined;
277
- }
278
- function semanticSelectionSummary(summary) {
279
- const selection = summary && typeof summary === 'object'
280
- ? summary.selection
281
- : undefined;
282
- return {
283
- includeFiltered: nonNegativeNumber(selection?.includeFiltered),
284
- unsupportedLanguage: nonNegativeNumber(selection?.unsupportedLanguage)
285
- };
286
- }
287
246
  export function semanticImportSummaryFromBundle(bundle) {
288
247
  const metadata = bundle.metadata;
289
248
  return richerSemanticImportSummary(bundle.semanticImport, metadata?.semanticImport);
@@ -311,7 +270,9 @@ function semanticImportSummaryRichness(summary) {
311
270
  semanticImportUniversalAstLayerSummary(summary).total,
312
271
  semanticImportProofSpecSummary(summary).total,
313
272
  semanticImportParadigmSemanticsSummary(summary).total,
314
- semanticImportLineageSummary(summary).inferredEvents
273
+ semanticImportLineageSummary(summary).inferredEvents,
274
+ summarizeSemanticMergeAdmissionQuality(summary).total,
275
+ summarizeJsTsSafeMergeApplyQuality(summary).total
315
276
  ];
316
277
  return values.reduce((sum, value) => sum + nonNegativeNumber(value), 0);
317
278
  }
@@ -322,4 +283,447 @@ export function semanticImportEnabled(input) {
322
283
  return false;
323
284
  return input.enabled !== false;
324
285
  }
286
+ function semanticEditAdmissionWithSafeMerge(editAdmission, semanticMergeAdmission, jsTsSafeMergeApply) {
287
+ if (editAdmission.status === 'conflict' || editAdmission.status === 'stale' || editAdmission.status === 'blocked' || editAdmission.status === 'review-required') {
288
+ return editAdmission;
289
+ }
290
+ if (jsTsSafeMergeApply.conflicts > 0 || semanticMergeAdmission.conflicts > 0) {
291
+ return safeMergeAdmissionDecision('conflict', `semantic safe-merge conflict signals: ${jsTsSafeMergeApply.conflicts + semanticMergeAdmission.conflicts}`);
292
+ }
293
+ if (jsTsSafeMergeApply.stale > 0 || semanticMergeAdmission.stale > 0) {
294
+ return safeMergeAdmissionDecision('stale', `semantic safe-merge stale signals: ${jsTsSafeMergeApply.stale + semanticMergeAdmission.stale}`);
295
+ }
296
+ if (jsTsSafeMergeApply.blocked > 0 || semanticMergeAdmission.blocked > 0) {
297
+ return safeMergeAdmissionDecision('blocked', `semantic safe-merge blocked signals: ${jsTsSafeMergeApply.blocked + semanticMergeAdmission.blocked}`);
298
+ }
299
+ if (jsTsSafeMergeApply.needsReview > 0 || semanticMergeAdmission.reviewRequired > 0 || semanticMergeAdmission.safeWithLosses > 0) {
300
+ return safeMergeAdmissionDecision('review-required', 'semantic safe-merge needs review');
301
+ }
302
+ if (safeMergeApplyClean(jsTsSafeMergeApply)) {
303
+ return {
304
+ status: 'auto-merge-candidate',
305
+ autoMergeCandidate: true,
306
+ cleanEligible: true,
307
+ reasons: ['semantic safe-merge apply accepted clean']
308
+ };
309
+ }
310
+ if (semanticMergeAdmissionClean(semanticMergeAdmission)) {
311
+ return {
312
+ status: 'auto-merge-candidate',
313
+ autoMergeCandidate: true,
314
+ cleanEligible: true,
315
+ reasons: ['semantic merge admission is safe']
316
+ };
317
+ }
318
+ return editAdmission;
319
+ }
320
+ function safeMergeAdmissionDecision(status, reason) {
321
+ return {
322
+ status,
323
+ autoMergeCandidate: false,
324
+ cleanEligible: false,
325
+ reasons: [reason]
326
+ };
327
+ }
328
+ function safeMergeApplyClean(summary) {
329
+ return summary.total > 0 &&
330
+ summary.acceptedClean + summary.alreadyApplied > 0 &&
331
+ summary.noOp + summary.stale + summary.conflicts + summary.needsReview + summary.blocked === 0;
332
+ }
333
+ function semanticMergeAdmissionClean(summary) {
334
+ return summary.total > 0 &&
335
+ summary.autoMergeable + summary.safe > 0 &&
336
+ summary.safeWithLosses + summary.noOp + summary.stale + summary.conflicts + summary.reviewRequired + summary.blocked === 0;
337
+ }
338
+ function summarizeSemanticMergeAdmissionQuality(value) {
339
+ const direct = directSafeMergeValues(value, ['semanticMergeAdmissions', 'semanticMergeAdmission', 'semanticMergeAdmissionSummary']);
340
+ if (direct.length > 0)
341
+ return mergeSemanticMergeAdmissionSummaries(direct.map(normalizeSemanticMergeAdmissionRecord));
342
+ const records = isObject(value) && Array.isArray(value.records) ? value.records.filter(isObject) : [];
343
+ return mergeSemanticMergeAdmissionSummaries(records.flatMap((record) => {
344
+ const sidecar = isObject(record.semanticSidecar) ? record.semanticSidecar : {};
345
+ const mergeCandidate = isObject(record.mergeCandidate) ? record.mergeCandidate : {};
346
+ return directSafeMergeValues({
347
+ semanticMergeAdmission: record.semanticMergeAdmission,
348
+ semanticMergeAdmissions: record.semanticMergeAdmissions,
349
+ semanticMergeAdmissionSummary: record.semanticMergeAdmissionSummary,
350
+ sidecarSemanticMergeAdmission: sidecar.semanticMergeAdmission,
351
+ sidecarSemanticMergeAdmissions: sidecar.semanticMergeAdmissions,
352
+ mergeCandidateAdmission: mergeCandidate.semanticMergeAdmission ?? mergeCandidate.mergeAdmission ?? mergeCandidate.admission
353
+ }, [
354
+ 'semanticMergeAdmission',
355
+ 'semanticMergeAdmissions',
356
+ 'semanticMergeAdmissionSummary',
357
+ 'sidecarSemanticMergeAdmission',
358
+ 'sidecarSemanticMergeAdmissions',
359
+ 'mergeCandidateAdmission'
360
+ ]).map(normalizeSemanticMergeAdmissionRecord);
361
+ }));
362
+ }
363
+ function summarizeJsTsSafeMergeApplyQuality(value) {
364
+ const direct = directSafeMergeValues(value, ['jsTsSafeMergeApply', 'jsTsSafeMergeApplies', 'safeMergeApply', 'safeMergeApplies']);
365
+ if (direct.length > 0)
366
+ return mergeJsTsSafeMergeApplySummaries(direct.map(normalizeJsTsSafeMergeApplyRecord));
367
+ const records = isObject(value) && Array.isArray(value.records) ? value.records.filter(isObject) : [];
368
+ return mergeJsTsSafeMergeApplySummaries(records.flatMap((record) => {
369
+ const sidecar = isObject(record.semanticSidecar) ? record.semanticSidecar : {};
370
+ return directSafeMergeValues({
371
+ jsTsSafeMergeApply: record.jsTsSafeMergeApply,
372
+ jsTsSafeMergeApplies: record.jsTsSafeMergeApplies,
373
+ safeMergeApply: record.safeMergeApply,
374
+ safeMergeApplies: record.safeMergeApplies,
375
+ sidecarJsTsSafeMergeApply: sidecar.jsTsSafeMergeApply,
376
+ sidecarSafeMergeApply: sidecar.safeMergeApply
377
+ }, [
378
+ 'jsTsSafeMergeApply',
379
+ 'jsTsSafeMergeApplies',
380
+ 'safeMergeApply',
381
+ 'safeMergeApplies',
382
+ 'sidecarJsTsSafeMergeApply',
383
+ 'sidecarSafeMergeApply'
384
+ ]).map(normalizeJsTsSafeMergeApplyRecord);
385
+ }));
386
+ }
387
+ function normalizeSemanticMergeAdmissionRecord(value) {
388
+ const record = isObject(value) ? value : {};
389
+ const summary = isObject(record.summary) ? record.summary : record;
390
+ const byClassification = mergeNumberRecords(numberRecord(summary.byClassification), numberRecord(summary.classificationCounts));
391
+ const byDecision = mergeNumberRecords(numberRecord(summary.byDecision), numberRecord(summary.decisionCounts));
392
+ const classification = stringValue(summary.classification ?? record.classification);
393
+ const decision = stringValue(summary.decision ?? record.decision ?? summary.status ?? record.status);
394
+ if (classification)
395
+ addSignalCount(byClassification, classification);
396
+ if (decision)
397
+ addSignalCount(byDecision, decision);
398
+ if (Object.keys(byClassification).length === 0) {
399
+ for (const entry of readStringArray(summary.classifications))
400
+ addSignalCount(byClassification, entry);
401
+ }
402
+ if (Object.keys(byDecision).length === 0) {
403
+ for (const entry of readStringArray(summary.decisions))
404
+ addSignalCount(byDecision, entry);
405
+ }
406
+ const safe = Math.max(nonNegativeNumber(summary.safe), signalCount(byClassification, 'safe'));
407
+ const safeWithLosses = Math.max(nonNegativeNumber(summary.safeWithLosses), signalCount(byClassification, 'safe-with-losses'));
408
+ const reviewRequired = Math.max(nonNegativeNumber(summary.reviewRequired), nonNegativeNumber(summary.needsReview), signalCount(byClassification, 'review-required', 'needs-review', 'review', 'human-review'), signalCount(byDecision, 'review-required', 'needs-review', 'review', 'human-review'));
409
+ const autoMergeable = Math.max(nonNegativeNumber(summary.autoMergeable), record.autoMergeable === true ? 1 : 0, signalCount(byDecision, 'auto-mergeable', 'auto-merge-candidate'), safe);
410
+ const noOp = Math.max(nonNegativeNumber(summary.noOp), signalCount(byDecision, 'no-op', 'noop', 'no-change'));
411
+ const stale = Math.max(nonNegativeNumber(summary.stale), signalCount(byDecision, 'stale', 'rerun-semantic-import'));
412
+ const blocked = Math.max(nonNegativeNumber(summary.blocked), signalCount(byClassification, 'blocked', 'blocked-evidence'), signalCount(byDecision, 'blocked', 'blocked-evidence', 'block'));
413
+ const conflicts = Math.max(nonNegativeNumber(summary.conflicts), signalCount(byDecision, 'conflict', 'conflicts', 'conflict-blocked'));
414
+ const total = nonNegativeNumber(summary.total) ||
415
+ sumRecord(byClassification) ||
416
+ sumRecord(byDecision) ||
417
+ (classification || decision || record.kind === 'frontier.lang.semanticMergeAdmission' ? 1 : 0);
418
+ return {
419
+ total,
420
+ classifications: positiveRecordKeys(byClassification),
421
+ byClassification,
422
+ decisions: positiveRecordKeys(byDecision),
423
+ byDecision,
424
+ noOp,
425
+ stale,
426
+ needsReview: Math.max(nonNegativeNumber(summary.needsReview), reviewRequired),
427
+ blocked,
428
+ conflicts,
429
+ conflictReasonCodes: uniqueStrings([...readStringArray(summary.conflictReasonCodes), ...readStringArray(record.conflictReasonCodes)]),
430
+ conflictKeys: uniqueStrings([...readStringArray(summary.conflictKeys), ...readStringArray(record.conflictKeys)]),
431
+ evidenceIds: uniqueStrings([...readStringArray(summary.evidenceIds), ...readStringArray(record.evidenceIds), ...objectIds(record.evidence)]),
432
+ autoApplyable: Math.max(nonNegativeNumber(summary.autoApplyable), autoMergeable),
433
+ autoApplyCandidates: Math.max(nonNegativeNumber(summary.autoApplyCandidates), autoMergeable),
434
+ empty: total === 0,
435
+ safe,
436
+ safeWithLosses,
437
+ reviewRequired,
438
+ autoMergeable,
439
+ reasonCodes: uniqueStrings([...readStringArray(summary.reasonCodes), ...readStringArray(record.reasonCodes), ...readStringArray(record.reasons)]),
440
+ conflictKeyKinds: uniqueStrings([...readStringArray(summary.conflictKeyKinds), ...readStringArray(record.conflictKeyKinds)]),
441
+ candidateIds: uniqueStrings([...readStringArray(summary.candidateIds), ...stringArray(record.candidateId)])
442
+ };
443
+ }
444
+ function normalizeJsTsSafeMergeApplyRecord(value) {
445
+ const record = isObject(value) ? value : {};
446
+ const summary = isObject(record.summary) ? record.summary : record;
447
+ const admission = isObject(record.admission) ? record.admission : {};
448
+ const byClassification = mergeNumberRecords(numberRecord(summary.byClassification), numberRecord(summary.classificationCounts));
449
+ const byDecision = mergeNumberRecords(numberRecord(summary.byDecision), numberRecord(summary.decisionCounts));
450
+ const byStatus = mergeNumberRecords(numberRecord(summary.byStatus), numberRecord(summary.statusCounts));
451
+ const byAction = mergeNumberRecords(numberRecord(summary.byAction), numberRecord(summary.actionCounts));
452
+ const classification = stringValue(summary.classification ?? record.classification);
453
+ const decision = stringValue(summary.decision ?? record.decision ?? summary.decision ?? admission.decision);
454
+ const status = stringValue(summary.status ?? record.status ?? admission.status);
455
+ const action = stringValue(summary.action ?? record.action ?? admission.action);
456
+ if (classification)
457
+ addSignalCount(byClassification, classification);
458
+ if (decision)
459
+ addSignalCount(byDecision, decision);
460
+ if (status)
461
+ addSignalCount(byStatus, status);
462
+ if (action)
463
+ addSignalCount(byAction, action);
464
+ if (Object.keys(byClassification).length === 0) {
465
+ for (const entry of readStringArray(summary.classifications))
466
+ addSignalCount(byClassification, entry);
467
+ }
468
+ if (Object.keys(byDecision).length === 0) {
469
+ for (const entry of readStringArray(summary.decisions))
470
+ addSignalCount(byDecision, entry);
471
+ }
472
+ if (Object.keys(byStatus).length === 0) {
473
+ for (const entry of readStringArray(summary.statuses))
474
+ addSignalCount(byStatus, entry);
475
+ }
476
+ if (Object.keys(byAction).length === 0) {
477
+ for (const entry of readStringArray(summary.actions))
478
+ addSignalCount(byAction, entry);
479
+ }
480
+ const acceptedClean = Math.max(nonNegativeNumber(summary.acceptedClean), signalCount(byStatus, 'accepted-clean'), signalCount(byClassification, 'accepted-clean'));
481
+ const alreadyApplied = Math.max(nonNegativeNumber(summary.alreadyApplied), signalCount(byStatus, 'already-applied'), signalCount(byClassification, 'already-applied'));
482
+ const noOp = Math.max(nonNegativeNumber(summary.noOp), signalCount(byStatus, 'no-op', 'noop', 'no-change'), signalCount(byClassification, 'no-op', 'noop', 'no-change'), signalCount(byDecision, 'no-op', 'noop', 'no-change'));
483
+ const stale = Math.max(nonNegativeNumber(summary.stale), signalCount(byStatus, 'stale'), signalCount(byClassification, 'stale'), signalCount(byDecision, 'stale', 'rerun-semantic-import'));
484
+ const needsReview = Math.max(nonNegativeNumber(summary.needsReview), signalCount(byStatus, 'needs-review', 'review-required', 'review', 'human-review'), signalCount(byClassification, 'needs-review', 'review-required', 'review', 'human-review'), signalCount(byDecision, 'needs-review', 'review-required', 'review', 'human-review'));
485
+ const blocked = Math.max(nonNegativeNumber(summary.blocked), signalCount(byStatus, 'blocked', 'blocked-evidence'), signalCount(byClassification, 'blocked', 'blocked-evidence'), signalCount(byDecision, 'blocked', 'blocked-evidence', 'block'));
486
+ const conflicts = Math.max(nonNegativeNumber(summary.conflicts), signalCount(byStatus, 'conflict', 'conflicts', 'conflict-blocked'), signalCount(byClassification, 'conflict', 'conflicts', 'conflict-blocked'));
487
+ const applied = Math.max(nonNegativeNumber(summary.applied), signalCount(byAction, 'apply'), acceptedClean);
488
+ const skipped = Math.max(nonNegativeNumber(summary.skipped), signalCount(byAction, 'skip'), alreadyApplied + noOp);
489
+ const total = nonNegativeNumber(summary.total) ||
490
+ sumRecord(byStatus) ||
491
+ sumRecord(byClassification) ||
492
+ sumRecord(byDecision) ||
493
+ (classification || decision || status || action ? 1 : 0);
494
+ return {
495
+ total,
496
+ classifications: positiveRecordKeys(byClassification),
497
+ byClassification,
498
+ decisions: positiveRecordKeys(byDecision),
499
+ byDecision,
500
+ noOp,
501
+ stale,
502
+ needsReview,
503
+ blocked,
504
+ conflicts,
505
+ conflictReasonCodes: uniqueStrings([...readStringArray(summary.conflictReasonCodes), ...readStringArray(record.conflictReasonCodes)]),
506
+ conflictKeys: uniqueStrings([...readStringArray(summary.conflictKeys), ...readStringArray(record.conflictKeys)]),
507
+ evidenceIds: uniqueStrings([...readStringArray(summary.evidenceIds), ...readStringArray(record.evidenceIds), ...objectIds(record.evidence)]),
508
+ autoApplyable: Math.max(nonNegativeNumber(summary.autoApplyable), acceptedClean + alreadyApplied),
509
+ autoApplyCandidates: Math.max(nonNegativeNumber(summary.autoApplyCandidates), acceptedClean + alreadyApplied),
510
+ empty: total === 0,
511
+ acceptedClean,
512
+ alreadyApplied,
513
+ applied,
514
+ skipped,
515
+ scripts: nonNegativeNumber(summary.scripts) || readStringArray(summary.scriptIds).length,
516
+ projections: nonNegativeNumber(summary.projections) || readStringArray(summary.projectionIds).length,
517
+ replays: nonNegativeNumber(summary.replays) || readStringArray(summary.replayIds).length,
518
+ statuses: positiveRecordKeys(byStatus),
519
+ byStatus,
520
+ actions: positiveRecordKeys(byAction),
521
+ byAction,
522
+ reasonCodes: uniqueStrings([...readStringArray(summary.reasonCodes), ...readStringArray(record.reasonCodes), ...readStringArray(admission.reasonCodes)]),
523
+ sourcePaths: uniqueStrings([...readStringArray(summary.sourcePaths), ...readStringArray(record.sourcePaths), ...stringArray(record.sourcePath)]),
524
+ scriptIds: uniqueStrings([...readStringArray(summary.scriptIds), ...stringArray(record.scriptId)]),
525
+ projectionIds: uniqueStrings([...readStringArray(summary.projectionIds), ...stringArray(record.projectionId)]),
526
+ replayIds: uniqueStrings([...readStringArray(summary.replayIds), ...stringArray(record.replayId)])
527
+ };
528
+ }
529
+ function mergeSemanticMergeAdmissionSummaries(entries) {
530
+ const merged = emptySemanticMergeAdmissionSummary();
531
+ for (const entry of entries) {
532
+ if (entry.empty && entry.total === 0)
533
+ continue;
534
+ addBaseSafeMergeSummary(merged, entry);
535
+ for (const key of ['safe', 'safeWithLosses', 'reviewRequired', 'autoMergeable'])
536
+ merged[key] += nonNegativeNumber(entry[key]);
537
+ merged.reasonCodes = uniqueStrings([...merged.reasonCodes, ...entry.reasonCodes]);
538
+ merged.conflictKeyKinds = uniqueStrings([...merged.conflictKeyKinds, ...entry.conflictKeyKinds]);
539
+ merged.candidateIds = uniqueStrings([...merged.candidateIds, ...entry.candidateIds]);
540
+ }
541
+ merged.empty = merged.total === 0;
542
+ return merged;
543
+ }
544
+ function mergeJsTsSafeMergeApplySummaries(entries) {
545
+ const merged = emptyJsTsSafeMergeApplySummary();
546
+ for (const entry of entries) {
547
+ if (entry.empty && entry.total === 0)
548
+ continue;
549
+ addBaseSafeMergeSummary(merged, entry);
550
+ for (const key of ['acceptedClean', 'alreadyApplied', 'applied', 'skipped', 'scripts', 'projections', 'replays']) {
551
+ merged[key] += nonNegativeNumber(entry[key]);
552
+ }
553
+ mergeIntoNumberRecord(merged.byStatus, entry.byStatus);
554
+ mergeIntoNumberRecord(merged.byAction, entry.byAction);
555
+ merged.statuses = positiveRecordKeys(merged.byStatus);
556
+ merged.actions = positiveRecordKeys(merged.byAction);
557
+ merged.reasonCodes = uniqueStrings([...merged.reasonCodes, ...entry.reasonCodes]);
558
+ merged.sourcePaths = uniqueStrings([...merged.sourcePaths, ...entry.sourcePaths]);
559
+ merged.scriptIds = uniqueStrings([...merged.scriptIds, ...entry.scriptIds]);
560
+ merged.projectionIds = uniqueStrings([...merged.projectionIds, ...entry.projectionIds]);
561
+ merged.replayIds = uniqueStrings([...merged.replayIds, ...entry.replayIds]);
562
+ }
563
+ merged.empty = merged.total === 0;
564
+ return merged;
565
+ }
566
+ function addBaseSafeMergeSummary(target, source) {
567
+ for (const key of ['total', 'noOp', 'stale', 'needsReview', 'blocked', 'conflicts', 'autoApplyable', 'autoApplyCandidates']) {
568
+ target[key] += nonNegativeNumber(source[key]);
569
+ }
570
+ mergeIntoNumberRecord(target.byClassification, source.byClassification);
571
+ mergeIntoNumberRecord(target.byDecision, source.byDecision);
572
+ target.classifications = positiveRecordKeys(target.byClassification);
573
+ target.decisions = positiveRecordKeys(target.byDecision);
574
+ target.conflictReasonCodes = uniqueStrings([...target.conflictReasonCodes, ...source.conflictReasonCodes]);
575
+ target.conflictKeys = uniqueStrings([...target.conflictKeys, ...source.conflictKeys]);
576
+ target.evidenceIds = uniqueStrings([...target.evidenceIds, ...source.evidenceIds]);
577
+ }
578
+ function emptySemanticMergeAdmissionSummary() {
579
+ return {
580
+ total: 0,
581
+ classifications: [],
582
+ byClassification: {},
583
+ decisions: [],
584
+ byDecision: {},
585
+ noOp: 0,
586
+ stale: 0,
587
+ needsReview: 0,
588
+ blocked: 0,
589
+ conflicts: 0,
590
+ conflictReasonCodes: [],
591
+ conflictKeys: [],
592
+ evidenceIds: [],
593
+ autoApplyable: 0,
594
+ autoApplyCandidates: 0,
595
+ empty: true,
596
+ safe: 0,
597
+ safeWithLosses: 0,
598
+ reviewRequired: 0,
599
+ autoMergeable: 0,
600
+ reasonCodes: [],
601
+ conflictKeyKinds: [],
602
+ candidateIds: []
603
+ };
604
+ }
605
+ function emptyJsTsSafeMergeApplySummary() {
606
+ return {
607
+ total: 0,
608
+ classifications: [],
609
+ byClassification: {},
610
+ decisions: [],
611
+ byDecision: {},
612
+ noOp: 0,
613
+ stale: 0,
614
+ needsReview: 0,
615
+ blocked: 0,
616
+ conflicts: 0,
617
+ conflictReasonCodes: [],
618
+ conflictKeys: [],
619
+ evidenceIds: [],
620
+ autoApplyable: 0,
621
+ autoApplyCandidates: 0,
622
+ empty: true,
623
+ acceptedClean: 0,
624
+ alreadyApplied: 0,
625
+ applied: 0,
626
+ skipped: 0,
627
+ scripts: 0,
628
+ projections: 0,
629
+ replays: 0,
630
+ statuses: [],
631
+ byStatus: {},
632
+ actions: [],
633
+ byAction: {},
634
+ reasonCodes: [],
635
+ sourcePaths: [],
636
+ scriptIds: [],
637
+ projectionIds: [],
638
+ replayIds: []
639
+ };
640
+ }
641
+ function directSafeMergeValues(value, keys) {
642
+ if (Array.isArray(value))
643
+ return value;
644
+ if (!isObject(value))
645
+ return [];
646
+ const out = [];
647
+ for (const key of keys) {
648
+ const entry = value[key];
649
+ if (Array.isArray(entry))
650
+ out.push(...entry);
651
+ else if (entry !== undefined)
652
+ out.push(entry);
653
+ }
654
+ return out;
655
+ }
656
+ function addSignalCount(record, key) {
657
+ const normalized = normalizeSafeMergeSignal(key);
658
+ if (!normalized)
659
+ return;
660
+ record[normalized] = (record[normalized] ?? 0) + 1;
661
+ }
662
+ function signalCount(record, ...keys) {
663
+ const aliases = new Set(keys.map(normalizeSafeMergeSignal));
664
+ let count = 0;
665
+ for (const [key, value] of Object.entries(record)) {
666
+ if (aliases.has(normalizeSafeMergeSignal(key)))
667
+ count += nonNegativeNumber(value);
668
+ }
669
+ return count;
670
+ }
671
+ function normalizeSafeMergeSignal(value) {
672
+ const normalized = value.trim().replace(/_/g, '-').toLowerCase();
673
+ const compact = normalized.replace(/-/g, '');
674
+ if (compact === 'safewithlosses')
675
+ return 'safe-with-losses';
676
+ if (compact === 'acceptedclean')
677
+ return 'accepted-clean';
678
+ if (compact === 'alreadyapplied')
679
+ return 'already-applied';
680
+ if (compact === 'noop' || compact === 'nochange' || compact === 'nooperation' || compact === 'unchanged')
681
+ return 'no-op';
682
+ if (compact === 'needsreview')
683
+ return 'needs-review';
684
+ if (compact === 'reviewrequired')
685
+ return 'review-required';
686
+ if (compact === 'humanreview')
687
+ return 'human-review';
688
+ if (compact === 'blockedevidence')
689
+ return 'blocked-evidence';
690
+ if (compact === 'conflictblocked')
691
+ return 'conflict-blocked';
692
+ if (compact === 'automergeable')
693
+ return 'auto-mergeable';
694
+ if (compact === 'automergecandidate')
695
+ return 'auto-merge-candidate';
696
+ return normalized;
697
+ }
698
+ function mergeNumberRecords(...records) {
699
+ const out = {};
700
+ for (const record of records)
701
+ mergeIntoNumberRecord(out, record);
702
+ return out;
703
+ }
704
+ function mergeIntoNumberRecord(target, source) {
705
+ for (const [key, value] of Object.entries(source)) {
706
+ const normalized = normalizeSafeMergeSignal(key);
707
+ if (!normalized)
708
+ continue;
709
+ target[normalized] = (target[normalized] ?? 0) + nonNegativeNumber(value);
710
+ }
711
+ }
712
+ function sumRecord(record) {
713
+ return Object.values(record).reduce((sum, value) => sum + nonNegativeNumber(value), 0);
714
+ }
715
+ function positiveRecordKeys(record) {
716
+ return Object.keys(record).filter((key) => nonNegativeNumber(record[key]) > 0).sort();
717
+ }
718
+ function stringValue(value) {
719
+ return typeof value === 'string' && value.trim() ? value : undefined;
720
+ }
721
+ function stringArray(value) {
722
+ return typeof value === 'string' && value.trim() ? [value] : [];
723
+ }
724
+ function objectIds(value) {
725
+ return Array.isArray(value)
726
+ ? value.flatMap((entry) => isObject(entry) ? stringArray(entry.id) : stringArray(entry))
727
+ : [];
728
+ }
325
729
  //# sourceMappingURL=semantic-import-quality.js.map