rea-agents 2.0.0 → 2.2.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 (273) hide show
  1. package/README.md +103 -38
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/AndroidApplicationService.js +17 -0
  4. package/dist/application/AppleApplicationService.js +17 -0
  5. package/dist/application/ArtifactExtraction.js +1 -1
  6. package/dist/application/ArtifactInventory/classify.js +42 -0
  7. package/dist/application/ArtifactInventory/hash.js +43 -0
  8. package/dist/application/ArtifactInventory/reader.js +41 -0
  9. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  10. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  11. package/dist/application/ArtifactInventory/types.js +10 -0
  12. package/dist/application/ArtifactInventory.js +9 -351
  13. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  14. package/dist/application/BinarySession.js +47 -270
  15. package/dist/application/BinarySessionExecution.js +28 -0
  16. package/dist/application/BinarySessionOpen.js +39 -0
  17. package/dist/application/BinarySessionRecords.js +149 -0
  18. package/dist/application/BinarySessionStatus.js +75 -0
  19. package/dist/application/CapabilityInventory.js +24 -2
  20. package/dist/application/ClientRegistrationStatus.js +11 -4
  21. package/dist/application/CrossVersionInventory.js +8 -2
  22. package/dist/application/CrossVersionInvestigation.js +1 -23
  23. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  24. package/dist/application/DirectAnalysis.js +47 -44
  25. package/dist/application/Doctor.js +156 -238
  26. package/dist/application/DoctorDiagnostics.js +180 -0
  27. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  28. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  29. package/dist/application/EnhancedToolPagination.js +22 -0
  30. package/dist/application/EnhancedToolTypes.js +4 -0
  31. package/dist/application/EnhancedTools.js +20 -37
  32. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  33. package/dist/application/InventoryProjectionEvidence.js +41 -0
  34. package/dist/application/InvestigationProviders.js +12 -0
  35. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  36. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  37. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  38. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  39. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  40. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  41. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  42. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  43. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  44. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  45. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  46. package/dist/application/JavaScriptJsonModules.js +39 -0
  47. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  48. package/dist/application/JavaScriptReplayPermission.js +16 -0
  49. package/dist/application/JavaScriptReplayService.js +182 -156
  50. package/dist/application/LinuxHopper.js +10 -0
  51. package/dist/application/MacHopper.js +22 -11
  52. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  53. package/dist/application/PermissionAuthority.js +106 -63
  54. package/dist/application/ProcessCaptureCapability.js +1 -1
  55. package/dist/application/ProcessCapturePermission.js +13 -0
  56. package/dist/application/ProcessCli.js +2 -12
  57. package/dist/application/ProcessHarness.js +1 -1
  58. package/dist/application/ProcessPairedExperiment.js +72 -0
  59. package/dist/application/ProjectPermissionStore.js +48 -9
  60. package/dist/application/RealHopperAssertions.js +76 -0
  61. package/dist/application/ReconstructionCoverageService.js +69 -0
  62. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  63. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  64. package/dist/application/Setup.js +148 -260
  65. package/dist/application/SetupClientConfiguration.js +224 -0
  66. package/dist/application/SetupClients.js +24 -2
  67. package/dist/application/SetupPlan.js +124 -12
  68. package/dist/application/SetupSkill.js +54 -36
  69. package/dist/application/SupportedClients.js +1 -0
  70. package/dist/application/Uninstall.js +12 -3
  71. package/dist/application/Upgrade.js +16 -1
  72. package/dist/application/WindowsCapabilities.js +86 -0
  73. package/dist/artifacts/AsarArtifactReader.js +11 -0
  74. package/dist/browser/BrowserProcessStartup.js +88 -0
  75. package/dist/browser/CdpCaptureDocuments.js +12 -8
  76. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  77. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  78. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  79. package/dist/browser/CdpCaptureEventState.js +1 -0
  80. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  81. package/dist/browser/CdpCaptureEvents.js +29 -496
  82. package/dist/browser/CdpObservationSession.js +51 -8
  83. package/dist/browser/CdpPageCapture.js +12 -133
  84. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  85. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  86. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  87. package/dist/browser/PngVisualDiff.js +9 -2
  88. package/dist/catalogIdentity.js +4 -0
  89. package/dist/cli/artifactCommands.js +82 -0
  90. package/dist/cli/coreAnalysisCommands.js +232 -0
  91. package/dist/cli/managedCommands.js +397 -0
  92. package/dist/cli/managedProjectGraphCommand.js +24 -0
  93. package/dist/cli/options.js +9 -0
  94. package/dist/cli/setupCommands.js +113 -0
  95. package/dist/cli/types.js +1 -0
  96. package/dist/cli/utilityCommands.js +122 -0
  97. package/dist/cli.js +10 -768
  98. package/dist/cliApplicationCommands.js +118 -4
  99. package/dist/cliBrowserAdvancedCommands.js +73 -16
  100. package/dist/cliBrowserCommands.js +39 -115
  101. package/dist/cliCommandNames.js +4 -0
  102. package/dist/cliElectronCommands.js +33 -62
  103. package/dist/cliEvidenceCommands.js +13 -2
  104. package/dist/cliInvestigationCommands.js +53 -10
  105. package/dist/cliObservationOptions.js +137 -0
  106. package/dist/cliPolicyCommands.js +80 -46
  107. package/dist/cliSetup.js +306 -0
  108. package/dist/config/environment.js +107 -0
  109. package/dist/config/parseConfig.js +228 -0
  110. package/dist/config/parsers.js +68 -0
  111. package/dist/config/permissions.js +30 -0
  112. package/dist/config/types.js +1 -0
  113. package/dist/config.js +1 -375
  114. package/dist/contracts/applicationToolContracts.js +134 -0
  115. package/dist/contracts/electronToolContracts.js +51 -3
  116. package/dist/contracts/managedToolContracts.js +8 -3
  117. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  118. package/dist/contracts/providerSelection.js +2 -0
  119. package/dist/contracts/sessionStatusContract.js +26 -0
  120. package/dist/contracts/toolContractTypes.js +12 -1
  121. package/dist/contracts/toolContracts.js +5 -12
  122. package/dist/contracts/toolEffects.js +14 -0
  123. package/dist/contracts/toolOutputSchemaGroups.js +274 -0
  124. package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
  125. package/dist/contracts/toolOutputSchemas.js +2 -550
  126. package/dist/domain/analysisErrorPresentation.js +234 -0
  127. package/dist/domain/analysisErrorProjection.js +284 -0
  128. package/dist/domain/androidApplication.js +206 -0
  129. package/dist/domain/appleApplication.js +221 -0
  130. package/dist/domain/artifactComparison.js +34 -15
  131. package/dist/domain/binaryTarget.js +87 -37
  132. package/dist/domain/boundedCartesianProjection.js +15 -0
  133. package/dist/domain/browserObservation.js +1 -285
  134. package/dist/domain/browserObservationSchemas.js +286 -0
  135. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  136. package/dist/domain/errors.js +4 -486
  137. package/dist/domain/functionComparison.js +4 -165
  138. package/dist/domain/functionComparisonDimensions.js +164 -0
  139. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  140. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  141. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  142. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  143. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  144. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  145. package/dist/domain/javascriptSemanticIr.js +30 -0
  146. package/dist/domain/javascriptSemanticProjection.js +366 -0
  147. package/dist/domain/javascriptSemanticState.js +40 -0
  148. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  149. package/dist/domain/javascriptSemanticValues.js +352 -0
  150. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  151. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  152. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  153. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  154. package/dist/domain/knownPageCoverage.js +21 -0
  155. package/dist/domain/managedApplicationGraph.js +14 -364
  156. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  157. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  158. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  159. package/dist/domain/managedArtifact.js +16 -8
  160. package/dist/domain/managedMemberComparison.js +37 -391
  161. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  162. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  163. package/dist/domain/managedNativeVerification.js +27 -389
  164. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  165. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  166. package/dist/domain/managedReconstruction.js +82 -69
  167. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  168. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  169. package/dist/domain/permissionPolicy.js +2 -0
  170. package/dist/domain/processComparison.js +19 -0
  171. package/dist/domain/processPairedExperiment.js +128 -0
  172. package/dist/domain/reconstructionCoverage.js +387 -0
  173. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  174. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  175. package/dist/domain/replayMachine.js +316 -0
  176. package/dist/domain/replayMachineRuntime.js +215 -0
  177. package/dist/domain/runtimeCharacterization.js +85 -0
  178. package/dist/domain/runtimeIdentification.js +210 -0
  179. package/dist/domain/webBundleAnalyzer.js +3 -409
  180. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  181. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  182. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  183. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  184. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  185. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  186. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  187. package/dist/dotnet/ManagedMemberRows.js +120 -0
  188. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  189. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  190. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  191. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  192. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  193. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  194. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  195. package/dist/dotnet/ManagedPeReader.js +59 -28
  196. package/dist/evaluation/CodexAgentEval.js +132 -0
  197. package/dist/generatedPackageMetadata.js +2 -2
  198. package/dist/ghidra/GhidraClient.js +76 -91
  199. package/dist/ghidra/GhidraClientStartup.js +29 -0
  200. package/dist/ghidra/GhidraClientWire.js +34 -0
  201. package/dist/ghidra/GhidraDefaults.js +1 -1
  202. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  203. package/dist/ghidra/GhidraInstallation.js +20 -15
  204. package/dist/ghidra/GhidraLauncher.js +93 -29
  205. package/dist/ghidra/GhidraProvider.js +61 -161
  206. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  207. package/dist/ghidra/GhidraSessionValues.js +2 -0
  208. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  209. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  210. package/dist/ghidra/GhidraTransport.js +71 -0
  211. package/dist/identity.js +4 -2
  212. package/dist/main/messages.js +5 -0
  213. package/dist/main/reload.js +49 -0
  214. package/dist/main/shutdown.js +25 -0
  215. package/dist/main/startup.js +14 -0
  216. package/dist/main/state.js +26 -0
  217. package/dist/main/transport.js +61 -0
  218. package/dist/main/types.js +1 -0
  219. package/dist/main.js +35 -146
  220. package/dist/process/PrivateRuntimeRoot.js +3 -2
  221. package/dist/process/ProcessOwnership.js +35 -0
  222. package/dist/process/ProviderProcess.js +2 -0
  223. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  224. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  225. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  226. package/dist/replay/ReplayOutcome.js +95 -0
  227. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  228. package/dist/server/ProcessCaptureElicitation.js +157 -0
  229. package/dist/server/createServer.js +124 -56
  230. package/dist/server/javascriptApplicationResult.js +85 -0
  231. package/dist/server/registerApplicationTools/characterization.js +57 -0
  232. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  233. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  234. package/dist/server/registerApplicationTools/coverage.js +84 -0
  235. package/dist/server/registerApplicationTools/helpers.js +42 -0
  236. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  237. package/dist/server/registerApplicationTools/types.js +1 -0
  238. package/dist/server/registerApplicationTools.js +10 -112
  239. package/dist/server/registerBrowserTools.js +59 -83
  240. package/dist/server/registerElectronTools.js +48 -49
  241. package/dist/server/registerEnhancedTools.js +34 -42
  242. package/dist/server/registerEvidenceResources.js +56 -0
  243. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  244. package/dist/server/registerInvestigationTools/types.js +1 -0
  245. package/dist/server/registerInvestigationTools.js +83 -116
  246. package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
  247. package/dist/server/registerManagedTools.js +18 -1
  248. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  249. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  250. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  251. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  252. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  253. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  254. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  255. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  256. package/dist/server/registerManagedWorkflowTools.js +10 -274
  257. package/dist/server/registerOfficialTools.js +73 -59
  258. package/dist/server/registerSessionRecordTools.js +137 -0
  259. package/dist/server/registerSessionStatusTool.js +97 -26
  260. package/dist/server/registerSessionTools.js +60 -164
  261. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  262. package/dist/server/toolRegistrationOptions.js +101 -3
  263. package/dist/server/toolResult.js +15 -4
  264. package/package.json +11 -11
  265. package/skills/reverse-engineer-anything/SKILL.md +76 -0
  266. package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
  267. package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
  268. package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
  269. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
  270. package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
  271. package/scripts/prepare-node-pty.mjs +0 -35
  272. package/scripts/rebuild-native.mjs +0 -22
  273. package/skills/rea-analysis/SKILL.md +0 -222
@@ -1,17 +1,9 @@
1
- import { diffLines } from "diff";
2
- import { parseFunctionEvidence, } from "./functionDossierEvidence.js";
3
- import { commentProjection, combineCoverage, functionMatch, identityProjection, isAutoName, normalizeCfg, project, referenceKindProjection, referenceProjection, sorted, stringAndNameProjection, } from "./functionComparisonNormalization.js";
1
+ import { parseFunctionEvidence } from "./functionDossierEvidence.js";
2
+ import { functionMatch } from "./functionComparisonNormalization.js";
4
3
  import { functionComparisonResultSchema, } from "./functionComparisonSchemas.js";
5
- import { canonicalJson, dimensionResult, overallStatus, summarize, unresolvedDimension as buildUnresolvedDimension, } from "./functionComparisonResults.js";
4
+ import { overallStatus, summarize, canonicalJson, } from "./functionComparisonResults.js";
5
+ import { compareDimensions } from "./functionComparisonDimensions.js";
6
6
  export { functionComparisonInputSchema, functionComparisonResultSchema, } from "./functionComparisonSchemas.js";
7
- const unresolvedDimension = (...[dimension, status, links, leftCount, rightCount, limitations]) => buildUnresolvedDimension({
8
- dimension,
9
- status,
10
- links,
11
- leftCount,
12
- rightCount,
13
- limitations,
14
- });
15
7
  /** Compare two explicit function Evidence page sets without fuzzy matching. */
16
8
  export const compareFunctions = (leftInput, rightInput, offset, limit) => {
17
9
  const left = parseFunctionEvidence(leftInput);
@@ -52,156 +44,3 @@ export const compareFunctions = (leftInput, rightInput, offset, limit) => {
52
44
  ].sort((a, b) => a.localeCompare(b)),
53
45
  });
54
46
  };
55
- const compareDimensions = (left, right, links, providersDiffer) => [
56
- compareIdentity(left, right, links, providersDiffer),
57
- compareText("pseudocode", left.pseudocode.text, right.pseudocode.text, left.pseudocode.complete, right.pseudocode.complete, links, providersDiffer),
58
- compareText("assembly", left.collections.assembly.items.join("\n"), right.collections.assembly.items.join("\n"), left.collections.assembly.complete, right.collections.assembly.complete, links, providersDiffer, left.collections.assembly.truncated || right.collections.assembly.truncated, "Assembly is opaque provider text; relocation normalization is unavailable."),
59
- compareComments(left, right, links, providersDiffer),
60
- compareCalls(left, right, links, providersDiffer),
61
- compareReferences(left, right, links, providersDiffer),
62
- compareStringsAndNames(left, right, links, providersDiffer),
63
- compareCfg(left, right, links, providersDiffer),
64
- ];
65
- const compareText = (...[dimension, left, right, leftComplete, rightComplete, links, providersDiffer, explicitTruncation, limitation,]) => {
66
- const truncated = explicitTruncation ?? (!leftComplete || !rightComplete);
67
- if (!leftComplete || !rightComplete || providersDiffer)
68
- return unresolvedDimension(dimension, truncated ? "truncated" : "unknown", links, left.length, right.length, [
69
- ...(limitation === undefined ? [] : [limitation]),
70
- ...(providersDiffer
71
- ? ["Exact text comparison requires one provider identity."]
72
- : []),
73
- ]);
74
- const changes = diffLines(left, right, {
75
- timeout: 100,
76
- maxEditLength: 10_000,
77
- });
78
- if (changes === undefined)
79
- return unresolvedDimension(dimension, "unknown", links, left.length, right.length, ["Bounded line diff exceeded its time or edit-distance limit."]);
80
- const delta = changes.reduce((summary, change) => ({
81
- added_lines: summary.added_lines + (change.added ? (change.count ?? 0) : 0),
82
- removed_lines: summary.removed_lines + (change.removed ? (change.count ?? 0) : 0),
83
- hunks: summary.hunks + (change.added || change.removed ? 1 : 0),
84
- }), { added_lines: 0, removed_lines: 0, hunks: 0 });
85
- return dimensionResult({
86
- dimension,
87
- status: delta.hunks === 0 ? "unchanged" : "changed",
88
- left,
89
- right,
90
- links,
91
- providersDiffer,
92
- leftCount: [...left].length,
93
- rightCount: [...right].length,
94
- textDelta: delta,
95
- limitations: limitation === undefined ? [] : [limitation],
96
- });
97
- };
98
- const compareCollections = (...[dimension, left, right, leftCoverage, rightCoverage, links, providersDiffer,]) => {
99
- if (!leftCoverage.complete || !rightCoverage.complete)
100
- return unresolvedDimension(dimension, leftCoverage.truncated || rightCoverage.truncated
101
- ? "truncated"
102
- : "unknown", links, left.length, right.length, []);
103
- return compareValues(dimension, sorted(left), sorted(right), links, true, true, providersDiffer);
104
- };
105
- const compareComments = (left, right, links, providersDiffer) => {
106
- const leftValues = commentProjection(left);
107
- const rightValues = commentProjection(right);
108
- if (leftValues === null || rightValues === null)
109
- return unresolvedDimension("comments", "unknown", links, left.collections.comments.items.length, right.collections.comments.items.length, ["Comment locations could not be normalized relative to the function."]);
110
- return compareCollections("comments", leftValues, rightValues, left.collections.comments, right.collections.comments, links, providersDiffer);
111
- };
112
- const compareStringsAndNames = (left, right, links, providersDiffer) => {
113
- const leftValues = stringAndNameProjection(left);
114
- const rightValues = stringAndNameProjection(right);
115
- if (leftValues === null || rightValues === null)
116
- return unresolvedDimension("strings_names", "unknown", links, null, null, [
117
- "Reference source locations could not be normalized to function offsets.",
118
- ]);
119
- return compareCollections("strings_names", leftValues, rightValues, combineCoverage(left.collections.referenced_strings, left.collections.referenced_names), combineCoverage(right.collections.referenced_strings, right.collections.referenced_names), links, providersDiffer);
120
- };
121
- const compareReferences = (left, right, links, providersDiffer) => {
122
- const leftCoverage = combineCoverage(left.collections.incoming_references, left.collections.outgoing_references);
123
- const rightCoverage = combineCoverage(right.collections.incoming_references, right.collections.outgoing_references);
124
- if (!leftCoverage.complete || !rightCoverage.complete)
125
- return unresolvedDimension("references", leftCoverage.truncated || rightCoverage.truncated
126
- ? "truncated"
127
- : "unknown", links, leftCoverage.items.length, rightCoverage.items.length, []);
128
- const leftProjection = referenceProjection(left);
129
- const rightProjection = referenceProjection(right);
130
- if (leftProjection.length === 0 && rightProjection.length === 0)
131
- return compareValues("references", leftProjection, rightProjection, links, true, true, providersDiffer);
132
- if (canonicalJson(leftProjection) !== canonicalJson(rightProjection))
133
- return dimensionResult({
134
- dimension: "references",
135
- status: "changed",
136
- left: leftProjection,
137
- right: rightProjection,
138
- links,
139
- providersDiffer,
140
- leftCount: leftProjection.length,
141
- rightCount: rightProjection.length,
142
- textDelta: null,
143
- limitations: [
144
- "Reference endpoints differ independently of provider reference-kind metadata.",
145
- ],
146
- });
147
- const leftKinds = referenceKindProjection(left);
148
- const rightKinds = referenceKindProjection(right);
149
- if (leftKinds !== null && rightKinds !== null)
150
- return compareValues("references", leftKinds, rightKinds, links, true, true, providersDiffer);
151
- return unresolvedDimension("references", "unknown", links, leftProjection.length, rightProjection.length, [
152
- "At least one provider did not expose reference kinds, so equal endpoints do not prove equal edge semantics.",
153
- ]);
154
- };
155
- const compareIdentity = (left, right, links, providersDiffer) => {
156
- if (isAutoName(left.procedure.name) || isAutoName(right.procedure.name))
157
- return unresolvedDimension("identity", "unknown", links, null, null, [
158
- "Address-derived function names are not stable cross-version identity.",
159
- ]);
160
- return compareValues("identity", identityProjection(left), identityProjection(right), links, true, true, providersDiffer);
161
- };
162
- const compareCalls = (left, right, links, providersDiffer) => {
163
- const leftValues = callProjection(left);
164
- const rightValues = callProjection(right);
165
- if ([...leftValues, ...rightValues].some(({ name }) => isAutoName(name)))
166
- return unresolvedDimension("calls", "unknown", links, leftValues.length, rightValues.length, ["Address-derived callee or caller names cannot be matched safely."]);
167
- return compareCollections("calls", leftValues, rightValues, combineCoverage(left.collections.callers, left.collections.callees), combineCoverage(right.collections.callers, right.collections.callees), links, providersDiffer);
168
- };
169
- const callProjection = (snapshot) => [
170
- ...project(snapshot.collections.callers, ({ name }) => ({
171
- direction: "in",
172
- name,
173
- })),
174
- ...project(snapshot.collections.callees, ({ name }) => ({
175
- direction: "out",
176
- name,
177
- })),
178
- ];
179
- const compareCfg = (left, right, links, providersDiffer) => {
180
- const leftBlocks = left.collections.basic_blocks;
181
- const rightBlocks = right.collections.basic_blocks;
182
- if (!leftBlocks.complete || !rightBlocks.complete)
183
- return unresolvedDimension("cfg", leftBlocks.truncated || rightBlocks.truncated ? "truncated" : "unknown", links, leftBlocks.items.length, rightBlocks.items.length, []);
184
- const leftGraph = normalizeCfg(leftBlocks.items);
185
- const rightGraph = normalizeCfg(rightBlocks.items);
186
- if (leftGraph === null || rightGraph === null)
187
- return unresolvedDimension("cfg", "unknown", links, leftBlocks.items.length, rightBlocks.items.length, ["CFG addresses could not be normalized to local block indices."]);
188
- return compareValues("cfg", leftGraph, rightGraph, links, true, true, providersDiffer);
189
- };
190
- const compareValues = (...[dimension, left, right, links, leftComplete, rightComplete, providersDiffer,]) => {
191
- if (!leftComplete || !rightComplete)
192
- return unresolvedDimension(dimension, "unknown", links, null, null, []);
193
- const leftJson = canonicalJson(left);
194
- const rightJson = canonicalJson(right);
195
- return dimensionResult({
196
- dimension,
197
- status: leftJson === rightJson ? "unchanged" : "changed",
198
- left,
199
- right,
200
- links,
201
- providersDiffer,
202
- leftCount: Array.isArray(left) ? left.length : null,
203
- rightCount: Array.isArray(right) ? right.length : null,
204
- textDelta: null,
205
- limitations: [],
206
- });
207
- };
@@ -0,0 +1,164 @@
1
+ import { diffLines } from "diff";
2
+ import { commentProjection, combineCoverage, identityProjection, isAutoName, normalizeCfg, project, referenceKindProjection, referenceProjection, sorted, stringAndNameProjection, } from "./functionComparisonNormalization.js";
3
+ import { canonicalJson, dimensionResult, unresolvedDimension as buildUnresolvedDimension, } from "./functionComparisonResults.js";
4
+ const unresolvedDimension = (...[dimension, status, links, leftCount, rightCount, limitations]) => buildUnresolvedDimension({
5
+ dimension,
6
+ status,
7
+ links,
8
+ leftCount,
9
+ rightCount,
10
+ limitations,
11
+ });
12
+ export const compareDimensions = (left, right, links, providersDiffer) => [
13
+ compareIdentity(left, right, links, providersDiffer),
14
+ compareText("pseudocode", left.pseudocode.text, right.pseudocode.text, left.pseudocode.complete, right.pseudocode.complete, links, providersDiffer),
15
+ compareText("assembly", left.collections.assembly.items.join("\n"), right.collections.assembly.items.join("\n"), left.collections.assembly.complete, right.collections.assembly.complete, links, providersDiffer, left.collections.assembly.truncated || right.collections.assembly.truncated, "Assembly is opaque provider text; relocation normalization is unavailable."),
16
+ compareComments(left, right, links, providersDiffer),
17
+ compareCalls(left, right, links, providersDiffer),
18
+ compareReferences(left, right, links, providersDiffer),
19
+ compareStringsAndNames(left, right, links, providersDiffer),
20
+ compareCfg(left, right, links, providersDiffer),
21
+ ];
22
+ const compareText = (...[dimension, left, right, leftComplete, rightComplete, links, providersDiffer, explicitTruncation, limitation,]) => {
23
+ const truncated = explicitTruncation ?? (!leftComplete || !rightComplete);
24
+ if (!leftComplete || !rightComplete || providersDiffer)
25
+ return unresolvedDimension(dimension, truncated ? "truncated" : "unknown", links, left.length, right.length, [
26
+ ...(limitation === undefined ? [] : [limitation]),
27
+ ...(providersDiffer
28
+ ? ["Exact text comparison requires one provider identity."]
29
+ : []),
30
+ ]);
31
+ const changes = diffLines(left, right, {
32
+ timeout: 100,
33
+ maxEditLength: 10_000,
34
+ });
35
+ if (changes === undefined)
36
+ return unresolvedDimension(dimension, "unknown", links, left.length, right.length, ["Bounded line diff exceeded its time or edit-distance limit."]);
37
+ const delta = changes.reduce((summary, change) => ({
38
+ added_lines: summary.added_lines + (change.added ? (change.count ?? 0) : 0),
39
+ removed_lines: summary.removed_lines + (change.removed ? (change.count ?? 0) : 0),
40
+ hunks: summary.hunks + (change.added || change.removed ? 1 : 0),
41
+ }), { added_lines: 0, removed_lines: 0, hunks: 0 });
42
+ return dimensionResult({
43
+ dimension,
44
+ status: delta.hunks === 0 ? "unchanged" : "changed",
45
+ left,
46
+ right,
47
+ links,
48
+ providersDiffer,
49
+ leftCount: [...left].length,
50
+ rightCount: [...right].length,
51
+ textDelta: delta,
52
+ limitations: limitation === undefined ? [] : [limitation],
53
+ });
54
+ };
55
+ const compareCollections = (...[dimension, left, right, leftCoverage, rightCoverage, links, providersDiffer,]) => {
56
+ if (!leftCoverage.complete || !rightCoverage.complete)
57
+ return unresolvedDimension(dimension, leftCoverage.truncated || rightCoverage.truncated
58
+ ? "truncated"
59
+ : "unknown", links, left.length, right.length, []);
60
+ return compareValues(dimension, sorted(left), sorted(right), links, true, true, providersDiffer);
61
+ };
62
+ const compareComments = (left, right, links, providersDiffer) => {
63
+ const leftValues = commentProjection(left);
64
+ const rightValues = commentProjection(right);
65
+ if (leftValues === null || rightValues === null)
66
+ return unresolvedDimension("comments", "unknown", links, left.collections.comments.items.length, right.collections.comments.items.length, ["Comment locations could not be normalized relative to the function."]);
67
+ return compareCollections("comments", leftValues, rightValues, left.collections.comments, right.collections.comments, links, providersDiffer);
68
+ };
69
+ const compareStringsAndNames = (left, right, links, providersDiffer) => {
70
+ const leftValues = stringAndNameProjection(left);
71
+ const rightValues = stringAndNameProjection(right);
72
+ if (leftValues === null || rightValues === null)
73
+ return unresolvedDimension("strings_names", "unknown", links, null, null, [
74
+ "Reference source locations could not be normalized to function offsets.",
75
+ ]);
76
+ return compareCollections("strings_names", leftValues, rightValues, combineCoverage(left.collections.referenced_strings, left.collections.referenced_names), combineCoverage(right.collections.referenced_strings, right.collections.referenced_names), links, providersDiffer);
77
+ };
78
+ const compareReferences = (left, right, links, providersDiffer) => {
79
+ const leftCoverage = combineCoverage(left.collections.incoming_references, left.collections.outgoing_references);
80
+ const rightCoverage = combineCoverage(right.collections.incoming_references, right.collections.outgoing_references);
81
+ if (!leftCoverage.complete || !rightCoverage.complete)
82
+ return unresolvedDimension("references", leftCoverage.truncated || rightCoverage.truncated
83
+ ? "truncated"
84
+ : "unknown", links, leftCoverage.items.length, rightCoverage.items.length, []);
85
+ const leftProjection = referenceProjection(left);
86
+ const rightProjection = referenceProjection(right);
87
+ if (leftProjection.length === 0 && rightProjection.length === 0)
88
+ return compareValues("references", leftProjection, rightProjection, links, true, true, providersDiffer);
89
+ if (canonicalJson(leftProjection) !== canonicalJson(rightProjection))
90
+ return dimensionResult({
91
+ dimension: "references",
92
+ status: "changed",
93
+ left: leftProjection,
94
+ right: rightProjection,
95
+ links,
96
+ providersDiffer,
97
+ leftCount: leftProjection.length,
98
+ rightCount: rightProjection.length,
99
+ textDelta: null,
100
+ limitations: [
101
+ "Reference endpoints differ independently of provider reference-kind metadata.",
102
+ ],
103
+ });
104
+ const leftKinds = referenceKindProjection(left);
105
+ const rightKinds = referenceKindProjection(right);
106
+ if (leftKinds !== null && rightKinds !== null)
107
+ return compareValues("references", leftKinds, rightKinds, links, true, true, providersDiffer);
108
+ return unresolvedDimension("references", "unknown", links, leftProjection.length, rightProjection.length, [
109
+ "At least one provider did not expose reference kinds, so equal endpoints do not prove equal edge semantics.",
110
+ ]);
111
+ };
112
+ const compareIdentity = (left, right, links, providersDiffer) => {
113
+ if (isAutoName(left.procedure.name) || isAutoName(right.procedure.name))
114
+ return unresolvedDimension("identity", "unknown", links, null, null, [
115
+ "Address-derived function names are not stable cross-version identity.",
116
+ ]);
117
+ return compareValues("identity", identityProjection(left), identityProjection(right), links, true, true, providersDiffer);
118
+ };
119
+ const compareCalls = (left, right, links, providersDiffer) => {
120
+ const leftValues = callProjection(left);
121
+ const rightValues = callProjection(right);
122
+ if ([...leftValues, ...rightValues].some(({ name }) => isAutoName(name)))
123
+ return unresolvedDimension("calls", "unknown", links, leftValues.length, rightValues.length, ["Address-derived callee or caller names cannot be matched safely."]);
124
+ return compareCollections("calls", leftValues, rightValues, combineCoverage(left.collections.callers, left.collections.callees), combineCoverage(right.collections.callers, right.collections.callees), links, providersDiffer);
125
+ };
126
+ const callProjection = (snapshot) => [
127
+ ...project(snapshot.collections.callers, ({ name }) => ({
128
+ direction: "in",
129
+ name,
130
+ })),
131
+ ...project(snapshot.collections.callees, ({ name }) => ({
132
+ direction: "out",
133
+ name,
134
+ })),
135
+ ];
136
+ const compareCfg = (left, right, links, providersDiffer) => {
137
+ const leftBlocks = left.collections.basic_blocks;
138
+ const rightBlocks = right.collections.basic_blocks;
139
+ if (!leftBlocks.complete || !rightBlocks.complete)
140
+ return unresolvedDimension("cfg", leftBlocks.truncated || rightBlocks.truncated ? "truncated" : "unknown", links, leftBlocks.items.length, rightBlocks.items.length, []);
141
+ const leftGraph = normalizeCfg(leftBlocks.items);
142
+ const rightGraph = normalizeCfg(rightBlocks.items);
143
+ if (leftGraph === null || rightGraph === null)
144
+ return unresolvedDimension("cfg", "unknown", links, leftBlocks.items.length, rightBlocks.items.length, ["CFG addresses could not be normalized to local block indices."]);
145
+ return compareValues("cfg", leftGraph, rightGraph, links, true, true, providersDiffer);
146
+ };
147
+ const compareValues = (...[dimension, left, right, links, leftComplete, rightComplete, providersDiffer,]) => {
148
+ if (!leftComplete || !rightComplete)
149
+ return unresolvedDimension(dimension, "unknown", links, null, null, []);
150
+ const leftJson = canonicalJson(left);
151
+ const rightJson = canonicalJson(right);
152
+ return dimensionResult({
153
+ dimension,
154
+ status: leftJson === rightJson ? "unchanged" : "changed",
155
+ left,
156
+ right,
157
+ links,
158
+ providersDiffer,
159
+ leftCount: Array.isArray(left) ? left.length : null,
160
+ rightCount: Array.isArray(right) ? right.length : null,
161
+ textDelta: null,
162
+ limitations: [],
163
+ });
164
+ };
@@ -145,20 +145,32 @@ const relationshipSignature = (node, side, context) => {
145
145
  const signatures = graph.edges.flatMap((edge) => {
146
146
  if (edge.source_node_id === node.node_id)
147
147
  return [
148
- edgeSignature("out", edge.relation, edge.target_node_id, paired, nodeById),
148
+ edgeSignature({
149
+ direction: "out",
150
+ relation: edge.relation,
151
+ neighborId: edge.target_node_id,
152
+ paired,
153
+ nodeById,
154
+ }),
149
155
  ];
150
156
  if (edge.target_node_id === node.node_id)
151
157
  return [
152
- edgeSignature("in", edge.relation, edge.source_node_id, paired, nodeById),
158
+ edgeSignature({
159
+ direction: "in",
160
+ relation: edge.relation,
161
+ neighborId: edge.source_node_id,
162
+ paired,
163
+ nodeById,
164
+ }),
153
165
  ];
154
166
  return [];
155
167
  });
156
168
  return canonical(signatures.sort(compareCodePoints));
157
169
  };
158
- const edgeSignature = (direction, relation, neighborId, paired, nodeById) => {
159
- const mapped = paired.get(neighborId);
160
- const neighbor = nodeById.get(neighborId);
161
- return `${direction}\0${relation}\0${mapped ?? `unmatched:${neighbor?.kind ?? "unknown"}`}`;
170
+ const edgeSignature = (context) => {
171
+ const mapped = context.paired.get(context.neighborId);
172
+ const neighbor = context.nodeById.get(context.neighborId);
173
+ return `${context.direction}\0${context.relation}\0${mapped ?? `unmatched:${neighbor?.kind ?? "unknown"}`}`;
162
174
  };
163
175
  const itemEvidenceLinks = (left, right, context) => [
164
176
  ...new Set([
@@ -23,7 +23,7 @@ export const matchJavaScriptApplicationVersions = (leftNodes, rightNodes) => {
23
23
  const rightCandidates = new Map();
24
24
  const pairs = [];
25
25
  for (const tier of matchTiers())
26
- applyTier(left, right, pairs, leftCandidates, rightCandidates, tier);
26
+ applyTier({ left, right, pairs, leftCandidates, rightCandidates, tier });
27
27
  const remainingLeft = sortedNodes(left.values());
28
28
  const remainingRight = sortedNodes(right.values());
29
29
  const leftIds = new Set(remainingLeft.map(({ node_id: id }) => id));
@@ -36,24 +36,24 @@ export const matchJavaScriptApplicationVersions = (leftNodes, rightNodes) => {
36
36
  candidatesForRight: filteredCandidates(rightCandidates, leftIds),
37
37
  };
38
38
  };
39
- const applyTier = (left, right, pairs, leftCandidates, rightCandidates, tier) => {
40
- const leftByKey = nodesByKey(left.values(), tier.key);
41
- const rightByKey = nodesByKey(right.values(), tier.key);
39
+ const applyTier = (context) => {
40
+ const leftByKey = nodesByKey(context.left.values(), context.tier.key);
41
+ const rightByKey = nodesByKey(context.right.values(), context.tier.key);
42
42
  for (const key of [...leftByKey.keys()].sort(compareCodePoints)) {
43
43
  const leftGroup = leftByKey.get(key) ?? [];
44
44
  const rightGroup = rightByKey.get(key) ?? [];
45
45
  if (rightGroup.length === 0)
46
46
  continue;
47
- recordCandidates(leftGroup, rightGroup, leftCandidates, rightCandidates);
47
+ recordCandidates(leftGroup, rightGroup, context.leftCandidates, context.rightCandidates);
48
48
  if (leftGroup.length !== 1 || rightGroup.length !== 1)
49
49
  continue;
50
50
  const leftNode = leftGroup[0];
51
51
  const rightNode = rightGroup[0];
52
52
  if (leftNode === undefined || rightNode === undefined)
53
53
  continue;
54
- pairs.push({ left: leftNode, right: rightNode, ...tier });
55
- left.delete(leftNode.node_id);
56
- right.delete(rightNode.node_id);
54
+ context.pairs.push({ left: leftNode, right: rightNode, ...context.tier });
55
+ context.left.delete(leftNode.node_id);
56
+ context.right.delete(rightNode.node_id);
57
57
  }
58
58
  };
59
59
  const nodesByKey = (nodes, keyFor) => {
@@ -0,0 +1,97 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
4
+ export const javascriptExportInstrumentationInputSchema = z.strictObject({
5
+ artifact_path: z.string().min(1).max(4_096),
6
+ artifact_sha256: digestSchema,
7
+ selection: z.strictObject({
8
+ byte_start: z.number().int().min(0),
9
+ byte_end: z.number().int().min(1),
10
+ selected_sha256: digestSchema,
11
+ export_name: z.string().regex(/^[A-Za-z_$][A-Za-z0-9_$]{0,199}$/u),
12
+ }),
13
+ });
14
+ export const javascriptExportTransformationManifestSchema = z.strictObject({
15
+ schema_version: z.literal(1),
16
+ kind: z.literal("commonjs-factory-export-v1"),
17
+ artifact_path: z.string().min(1).max(4_096),
18
+ original_sha256: digestSchema,
19
+ original_byte_length: z.number().int().min(0),
20
+ instrumented_sha256: digestSchema,
21
+ instrumented_byte_length: z.number().int().min(0),
22
+ selected_range: z.strictObject({
23
+ byte_start: z.number().int().min(0),
24
+ byte_end: z.number().int().min(1),
25
+ selected_sha256: digestSchema,
26
+ }),
27
+ inserted_ranges: z
28
+ .array(z.strictObject({
29
+ byte_start: z.number().int().min(0),
30
+ byte_end: z.number().int().min(1),
31
+ inserted_sha256: digestSchema,
32
+ purpose: z.enum(["factory-prefix", "export-binding", "factory-suffix"]),
33
+ }))
34
+ .length(3),
35
+ output_format: z.literal("commonjs-factory"),
36
+ source_map: z.literal(null),
37
+ });
38
+ /** Instrument one exact UTF-8 expression range without mutating source bytes. */
39
+ export const instrumentJavaScriptExport = (source, rawInput) => {
40
+ const input = javascriptExportInstrumentationInputSchema.parse(rawInput);
41
+ if (sha256(source) !== input.artifact_sha256)
42
+ throw new TypeError("JavaScript instrumentation artifact digest mismatch");
43
+ const { byte_start: start, byte_end: end } = input.selection;
44
+ if (end <= start || end > source.byteLength)
45
+ throw new TypeError("JavaScript instrumentation selection is out of bounds");
46
+ const selected = source.slice(start, end);
47
+ if (sha256(selected) !== input.selection.selected_sha256)
48
+ throw new TypeError("JavaScript instrumentation selection digest mismatch");
49
+ decodeUtf8(source);
50
+ decodeUtf8(selected);
51
+ const prefix = encode("function(module, exports, require) {\n");
52
+ const binding = encode(`\nmodule.exports[${JSON.stringify(input.selection.export_name)}] = (${decodeUtf8(selected)});\n`);
53
+ const suffix = encode("}\n");
54
+ const bytes = concatenate([prefix, source, binding, suffix]);
55
+ const bindingStart = prefix.byteLength + source.byteLength;
56
+ const suffixStart = bindingStart + binding.byteLength;
57
+ const manifest = javascriptExportTransformationManifestSchema.parse({
58
+ schema_version: 1,
59
+ kind: "commonjs-factory-export-v1",
60
+ artifact_path: input.artifact_path,
61
+ original_sha256: input.artifact_sha256,
62
+ original_byte_length: source.byteLength,
63
+ instrumented_sha256: sha256(bytes),
64
+ instrumented_byte_length: bytes.byteLength,
65
+ selected_range: {
66
+ byte_start: start,
67
+ byte_end: end,
68
+ selected_sha256: input.selection.selected_sha256,
69
+ },
70
+ inserted_ranges: [
71
+ range(0, prefix, "factory-prefix"),
72
+ range(bindingStart, binding, "export-binding"),
73
+ range(suffixStart, suffix, "factory-suffix"),
74
+ ],
75
+ output_format: "commonjs-factory",
76
+ source_map: null,
77
+ });
78
+ return { bytes, manifest };
79
+ };
80
+ const range = (start, bytes, purpose) => ({
81
+ byte_start: start,
82
+ byte_end: start + bytes.byteLength,
83
+ inserted_sha256: sha256(bytes),
84
+ purpose,
85
+ });
86
+ const encode = (value) => new TextEncoder().encode(value);
87
+ const decodeUtf8 = (value) => new TextDecoder("utf-8", { fatal: true }).decode(value);
88
+ const concatenate = (values) => {
89
+ const output = new Uint8Array(values.reduce((total, value) => total + value.byteLength, 0));
90
+ let offset = 0;
91
+ for (const value of values) {
92
+ output.set(value, offset);
93
+ offset += value.byteLength;
94
+ }
95
+ return output;
96
+ };
97
+ const sha256 = (value) => createHash("sha256").update(value).digest("hex");
@@ -18,11 +18,23 @@ export const traverseApplicationFeature = (graph, seedNodeIds, direction, limits
18
18
  const depth = depths.get(current) ?? 0;
19
19
  for (const entry of adjacency.get(current) ?? []) {
20
20
  if (depth >= limits.max_depth) {
21
- recordOmission(entry, current, omittedNodes, omittedEdges, frontier);
21
+ recordOmission({
22
+ entry,
23
+ current,
24
+ omittedNodes,
25
+ omittedEdges,
26
+ frontier,
27
+ });
22
28
  continue;
23
29
  }
24
30
  if (!visited.has(entry.nextNodeId) && visited.size >= limits.max_nodes) {
25
- recordOmission(entry, current, omittedNodes, omittedEdges, frontier);
31
+ recordOmission({
32
+ entry,
33
+ current,
34
+ omittedNodes,
35
+ omittedEdges,
36
+ frontier,
37
+ });
26
38
  continue;
27
39
  }
28
40
  if (!retainedEdges.has(entry.edge.edge_id) &&
@@ -80,9 +92,9 @@ const buildAdjacency = (edges, direction) => {
80
92
  const addAdjacency = (adjacency, nodeId, entry) => {
81
93
  adjacency.set(nodeId, [...(adjacency.get(nodeId) ?? []), entry]);
82
94
  };
83
- const recordOmission = (entry, current, omittedNodes, omittedEdges, frontier) => {
84
- omittedNodes.add(entry.nextNodeId);
85
- omittedEdges.add(entry.edge.edge_id);
86
- frontier.add(current);
87
- frontier.add(entry.nextNodeId);
95
+ const recordOmission = (context) => {
96
+ context.omittedNodes.add(context.entry.nextNodeId);
97
+ context.omittedEdges.add(context.entry.edge.edge_id);
98
+ context.frontier.add(context.current);
99
+ context.frontier.add(context.entry.nextNodeId);
88
100
  };
@@ -61,7 +61,8 @@ const candidatesForLayer = (layer) => {
61
61
  const candidateCategory = (node) => {
62
62
  if (node.kind === "electron-renderer")
63
63
  return "renderer";
64
- if (node.kind === "javascript-asset" || node.kind === "javascript-module")
64
+ if (node.kind === "javascript-asset" ||
65
+ (node.kind === "javascript-module" && !isStaticSourceModule(node)))
65
66
  return "javascript";
66
67
  if (node.kind === "worker")
67
68
  return "worker";
@@ -69,6 +70,7 @@ const candidateCategory = (node) => {
69
70
  return "service-worker";
70
71
  return null;
71
72
  };
73
+ const isStaticSourceModule = (node) => node.observations.some(({ properties }) => properties.semantic_role === "source-module");
72
74
  const indexStaticPaths = (graph) => {
73
75
  const nodes = new Map(graph.nodes.map((candidate) => [candidate.node_id, candidate]));
74
76
  const relatedBySource = new Map();