rea-agents 1.6.0 → 2.0.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 (238) hide show
  1. package/README.md +157 -66
  2. package/bridge/ghidra/ReaGhidraBridge.java +2075 -0
  3. package/bridge/hopper_bridge.py +13 -3
  4. package/dist/application/AbortablePromise.js +25 -0
  5. package/dist/application/AnalysisProvider.js +3 -0
  6. package/dist/application/AnalysisProviderEvaluation.js +60 -0
  7. package/dist/application/AnalysisProviderRegistry.js +228 -0
  8. package/dist/application/AnalysisSnapshotCache.js +41 -21
  9. package/dist/application/AnalysisSnapshotFiles.js +5 -6
  10. package/dist/application/BinarySession.js +218 -101
  11. package/dist/application/CapabilityInventory.js +18 -0
  12. package/dist/application/CompositeProvider.js +20 -8
  13. package/dist/application/CrossVersionInvestigation.js +10 -6
  14. package/dist/application/DirectAnalysis.js +49 -35
  15. package/dist/application/Doctor.js +110 -8
  16. package/dist/application/ElectronBoundaryAnalysis.js +96 -0
  17. package/dist/application/ElectronBoundaryGraph.js +9 -0
  18. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  19. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  20. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  21. package/dist/application/ElectronBoundaryGraphWindows.js +199 -0
  22. package/dist/application/EnhancedTools.js +39 -14
  23. package/dist/application/InvestigationProviders.js +41 -0
  24. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  25. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  26. package/dist/application/JavaScriptApplicationService.js +74 -0
  27. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  28. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  29. package/dist/application/JavaScriptArtifactAnalysis.js +305 -0
  30. package/dist/application/JavaScriptArtifactAnalysisTypes.js +1 -0
  31. package/dist/application/JavaScriptArtifactFiles.js +231 -0
  32. package/dist/application/JavaScriptArtifactGraphAccumulator.js +54 -0
  33. package/dist/application/JavaScriptArtifactGraphBuilder.js +144 -0
  34. package/dist/application/JavaScriptArtifactGraphContext.js +205 -0
  35. package/dist/application/JavaScriptArtifactGraphDocuments.js +108 -0
  36. package/dist/application/JavaScriptArtifactGraphEvidence.js +99 -0
  37. package/dist/application/JavaScriptArtifactGraphFindings.js +271 -0
  38. package/dist/application/JavaScriptArtifactGraphStructure.js +409 -0
  39. package/dist/application/JavaScriptArtifactReconstruction.js +77 -0
  40. package/dist/application/JavaScriptArtifactReconstructionInput.js +18 -0
  41. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  42. package/dist/application/JavaScriptReplayService.js +266 -0
  43. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  44. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  45. package/dist/application/MacHopper.js +20 -4
  46. package/dist/application/ManagedApplicationGraphService.js +55 -0
  47. package/dist/application/ManagedMemberComparisonService.js +122 -0
  48. package/dist/application/ManagedNativeVerificationService.js +39 -0
  49. package/dist/application/ManagedReconstructionService.js +58 -0
  50. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  51. package/dist/application/PermissionAuthority.js +1 -1
  52. package/dist/application/ProcessCaptureLifecycle.js +1 -1
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProcessSampling.js +16 -12
  55. package/dist/application/ProjectPermissionStore.js +1 -0
  56. package/dist/application/SessionProviderRouter.js +219 -0
  57. package/dist/application/Setup.js +84 -60
  58. package/dist/application/SetupClients.js +1 -1
  59. package/dist/application/SetupPlan.js +9 -2
  60. package/dist/application/SupportedClients.js +40 -16
  61. package/dist/application/Upgrade.js +1 -1
  62. package/dist/application/runtime.js +11 -6
  63. package/dist/artifacts/AsarArtifactReader.js +23 -3
  64. package/dist/browser/CdpBrowserProvider.js +4 -2
  65. package/dist/browser/CdpCaptureEvents.js +49 -0
  66. package/dist/browser/CdpElectronInspection.js +106 -162
  67. package/dist/browser/CdpElectronProvider.js +9 -3
  68. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  69. package/dist/browser/CdpElectronScripts.js +94 -0
  70. package/dist/browser/CdpElectronWorkers.js +56 -0
  71. package/dist/browser/CdpEndpoint.js +14 -1
  72. package/dist/browser/CdpPageCapture.js +8 -4
  73. package/dist/catalogIdentity.js +6 -42
  74. package/dist/cli.js +446 -34
  75. package/dist/cliApplicationCommands.js +62 -0
  76. package/dist/cliBrowserAdvancedCommands.js +5 -4
  77. package/dist/cliBrowserCommands.js +5 -4
  78. package/dist/cliCommandNames.js +56 -0
  79. package/dist/cliElectronCommands.js +106 -3
  80. package/dist/cliEvidenceCommands.js +4 -3
  81. package/dist/cliInvestigationCommands.js +2 -1
  82. package/dist/cliJsonInput.js +54 -0
  83. package/dist/cliPolicyCommands.js +2 -1
  84. package/dist/cliProcessCommands.js +3 -2
  85. package/dist/config.js +101 -2
  86. package/dist/contracts/applicationToolContracts.js +91 -0
  87. package/dist/contracts/artifactToolContracts.js +5 -9
  88. package/dist/contracts/browserToolContracts.js +14 -62
  89. package/dist/contracts/electronToolContracts.js +45 -19
  90. package/dist/contracts/enhancedInputs.js +2 -2
  91. package/dist/contracts/errorSchemas.js +1 -0
  92. package/dist/contracts/investigationExamples.js +0 -6
  93. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  94. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  95. package/dist/contracts/managedToolContracts.js +153 -0
  96. package/dist/contracts/managedWorkflowExamples.js +346 -0
  97. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  98. package/dist/contracts/nativeToolContracts.js +2 -6
  99. package/dist/contracts/promptContracts.js +18 -2
  100. package/dist/contracts/providerSelection.js +28 -0
  101. package/dist/contracts/sessionLifecycleInputs.js +2 -0
  102. package/dist/contracts/toolContractExamples.js +10 -25
  103. package/dist/contracts/toolContracts.js +69 -65
  104. package/dist/contracts/toolEffects.js +160 -0
  105. package/dist/contracts/toolOutputSchemas.js +152 -42
  106. package/dist/doctorRuntime.js +47 -0
  107. package/dist/domain/analysisProfile.js +78 -0
  108. package/dist/domain/analysisSnapshot.js +92 -46
  109. package/dist/domain/artifactComparison.js +3 -4
  110. package/dist/domain/artifactGraph.js +1 -0
  111. package/dist/domain/binaryTarget.js +4 -29
  112. package/dist/domain/browserObservation.js +3 -0
  113. package/dist/domain/bundleComparison.js +4 -4
  114. package/dist/domain/electronObservation.js +13 -0
  115. package/dist/domain/electronStaticAnalysis.js +9 -0
  116. package/dist/domain/electronStaticAnalysisBrowser.js +194 -0
  117. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  118. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  119. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  120. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  121. package/dist/domain/errors.js +148 -7
  122. package/dist/domain/evidence.js +44 -5
  123. package/dist/domain/evidenceBundle.js +9 -7
  124. package/dist/domain/functionComparison.js +9 -3
  125. package/dist/domain/functionComparisonNormalization.js +37 -0
  126. package/dist/domain/functionComparisonSchemas.js +3 -8
  127. package/dist/domain/functionDossierEvidence.js +4 -1
  128. package/dist/domain/hopperValues.js +66 -9
  129. package/dist/domain/inputIssueProjection.js +52 -0
  130. package/dist/domain/investigationWorkspace.js +2 -1
  131. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  132. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  133. package/dist/domain/javascriptApplicationEvidenceSchemas.js +379 -0
  134. package/dist/domain/javascriptApplicationGraph.js +282 -0
  135. package/dist/domain/javascriptApplicationGraphSchemas.js +139 -0
  136. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  137. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  138. package/dist/domain/javascriptApplicationVersionItems.js +221 -0
  139. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  140. package/dist/domain/javascriptAstFingerprint.js +143 -0
  141. package/dist/domain/javascriptFeatureSeed.js +140 -0
  142. package/dist/domain/javascriptFeatureTrace.js +232 -0
  143. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  144. package/dist/domain/javascriptFeatureTraversal.js +88 -0
  145. package/dist/domain/javascriptNativeHandoff.js +85 -0
  146. package/dist/domain/javascriptReplay.js +361 -0
  147. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  148. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  149. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  150. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  151. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  152. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  153. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  154. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  155. package/dist/domain/javascriptRuntimeStaticCandidates.js +191 -0
  156. package/dist/domain/javascriptStaticAnalysis.js +346 -0
  157. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  158. package/dist/domain/javascriptStaticAnalysisHelpers.js +274 -0
  159. package/dist/domain/javascriptStaticAnalysisState.js +23 -0
  160. package/dist/domain/javascriptStaticAnalysisTypes.js +1 -0
  161. package/dist/domain/managedApplicationGraph.js +556 -0
  162. package/dist/domain/managedArtifact.js +444 -0
  163. package/dist/domain/managedMemberComparison.js +565 -0
  164. package/dist/domain/managedNativeVerification.js +408 -0
  165. package/dist/domain/managedReconstruction.js +183 -0
  166. package/dist/domain/managedRuntimeCorrelation.js +175 -0
  167. package/dist/domain/reconstructionVerificationSchemas.js +1 -3
  168. package/dist/dotnet/ManagedArtifactInspector.js +318 -0
  169. package/dist/dotnet/ManagedMemberInspector.js +887 -0
  170. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +368 -0
  172. package/dist/dotnet/ManagedMetadataLayout.js +322 -0
  173. package/dist/dotnet/ManagedNativeBoundaryInspector.js +391 -0
  174. package/dist/dotnet/ManagedPeReader.js +157 -0
  175. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  176. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  177. package/dist/generatedPackageMetadata.js +2 -2
  178. package/dist/ghidra/GhidraAnalysisProfile.js +37 -0
  179. package/dist/ghidra/GhidraClient.js +400 -0
  180. package/dist/ghidra/GhidraClientTypes.js +1 -0
  181. package/dist/ghidra/GhidraDefaults.js +20 -0
  182. package/dist/ghidra/GhidraDiagnostics.js +43 -0
  183. package/dist/ghidra/GhidraDoctor.js +59 -0
  184. package/dist/ghidra/GhidraFunctionValues.js +264 -0
  185. package/dist/ghidra/GhidraInstallation.js +239 -0
  186. package/dist/ghidra/GhidraInventoryValues.js +217 -0
  187. package/dist/ghidra/GhidraLauncher.js +139 -0
  188. package/dist/ghidra/GhidraProvider.js +366 -0
  189. package/dist/ghidra/GhidraRequestQueue.js +98 -0
  190. package/dist/ghidra/GhidraResponseBuffer.js +31 -0
  191. package/dist/ghidra/GhidraResponseRouter.js +24 -0
  192. package/dist/ghidra/GhidraSessionError.js +39 -0
  193. package/dist/ghidra/GhidraSessionValues.js +62 -0
  194. package/dist/ghidra/GhidraSocketConnection.js +46 -0
  195. package/dist/ghidra/protocol.js +69 -0
  196. package/dist/hopper/BridgeLauncher.js +19 -54
  197. package/dist/hopper/HopperAnalysisProfile.js +106 -0
  198. package/dist/hopper/HopperClient.js +154 -162
  199. package/dist/hopper/HopperProvider.js +99 -7
  200. package/dist/hopper/HopperSessionValues.js +27 -0
  201. package/dist/hopper/HopperSocketConnection.js +31 -0
  202. package/dist/main.js +14 -0
  203. package/dist/native/NativeMacOSProvider.js +3 -1
  204. package/dist/process/PendingOperations.js +59 -0
  205. package/dist/process/PrivateRuntimeRoot.js +33 -0
  206. package/dist/process/ProviderDeadline.js +95 -0
  207. package/dist/process/ProviderProcess.js +275 -0
  208. package/dist/replay/JavaScriptReplayWorker.js +286 -0
  209. package/dist/replay/LinuxJavaScriptReplayRunner.js +434 -0
  210. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  211. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  212. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  213. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  214. package/dist/server/createServer.js +53 -0
  215. package/dist/server/promptCompletion.js +9 -3
  216. package/dist/server/registerApplicationTools.js +115 -0
  217. package/dist/server/registerArtifactComparisonTool.js +16 -9
  218. package/dist/server/registerBrowserTools.js +33 -8
  219. package/dist/server/registerBundleComparisonTool.js +17 -20
  220. package/dist/server/registerElectronTools.js +45 -3
  221. package/dist/server/registerEnhancedTools.js +67 -19
  222. package/dist/server/registerEvidenceTools.js +5 -1
  223. package/dist/server/registerFunctionComparisonTool.js +14 -7
  224. package/dist/server/registerInvestigationTools.js +21 -17
  225. package/dist/server/registerManagedTools.js +6 -0
  226. package/dist/server/registerManagedWorkflowTools.js +277 -0
  227. package/dist/server/registerOfficialTools.js +11 -8
  228. package/dist/server/registerProcessComparisonTool.js +25 -47
  229. package/dist/server/registerSessionStatusTool.js +7 -7
  230. package/dist/server/registerSessionTools.js +57 -87
  231. package/dist/server/sessionEvidence.js +14 -19
  232. package/dist/server/toolInputValidation.js +77 -0
  233. package/dist/server/toolRegistrationOptions.js +79 -2
  234. package/dist/server/toolResult.js +25 -17
  235. package/package.json +17 -7
  236. package/scripts/rea.mjs +36 -2
  237. package/skills/rea-analysis/SKILL.md +59 -3
  238. /package/dist/{application → process}/ProcessOwnership.js +0 -0
@@ -0,0 +1,556 @@
1
+ import { createHash } from "node:crypto";
2
+ import { basename } from "node:path";
3
+ import canonicalize from "canonicalize";
4
+ import { z } from "zod";
5
+ import { evidenceSchema, parseEvidence } from "./evidence.js";
6
+ import { createJavaScriptApplicationEdge, createJavaScriptApplicationGraph, createJavaScriptApplicationNode, javascriptApplicationGraphSchema, } from "./javascriptApplicationGraph.js";
7
+ import { managedArtifactInspectionSchema, managedMemberInspectionSchema, managedNativeBoundaryInspectionSchema, } from "./managedArtifact.js";
8
+ const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
9
+ const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
10
+ const boundedTextSchema = z.string().min(1).max(4_096);
11
+ const managedApplicationGraphLimitsSchema = z.strictObject({
12
+ max_types: z.number().int().min(0).max(100_000).default(5_000),
13
+ max_methods: z.number().int().min(0).max(100_000).default(10_000),
14
+ max_fields: z.number().int().min(0).max(100_000).default(5_000),
15
+ max_pinvoke_imports: z.number().int().min(0).max(100_000).default(5_000),
16
+ max_native_implementations: z
17
+ .number()
18
+ .int()
19
+ .min(0)
20
+ .max(100_000)
21
+ .default(5_000),
22
+ });
23
+ /** Authenticated managed Evidence records projected into the application graph. */
24
+ export const projectManagedApplicationGraphInputSchema = z
25
+ .strictObject({
26
+ managed_artifact: evidenceSchema.optional(),
27
+ managed_members: evidenceSchema.optional(),
28
+ managed_native_boundaries: evidenceSchema.optional(),
29
+ limits: managedApplicationGraphLimitsSchema.default({
30
+ max_types: 5_000,
31
+ max_methods: 10_000,
32
+ max_fields: 5_000,
33
+ max_pinvoke_imports: 5_000,
34
+ max_native_implementations: 5_000,
35
+ }),
36
+ })
37
+ .superRefine((input, context) => {
38
+ if (input.managed_artifact === undefined &&
39
+ input.managed_members === undefined &&
40
+ input.managed_native_boundaries === undefined)
41
+ context.addIssue({
42
+ code: "custom",
43
+ message: "At least one managed artifact, member, or native-boundary Evidence record is required",
44
+ });
45
+ });
46
+ /** Managed-code projection result containing a validated application graph. */
47
+ export const managedApplicationGraphResultSchema = z.strictObject({
48
+ schema_version: z.literal(1),
49
+ projection_id: z.string().regex(/^magp_[a-f0-9]{64}$/u),
50
+ root_artifact_sha256: digestSchema,
51
+ source_evidence: z.strictObject({
52
+ managed_artifact_evidence_id: evidenceIdSchema.nullable(),
53
+ managed_members_evidence_id: evidenceIdSchema.nullable(),
54
+ managed_native_boundaries_evidence_id: evidenceIdSchema.nullable(),
55
+ }),
56
+ summary: z.strictObject({
57
+ graph_nodes: z.number().int().min(0),
58
+ graph_edges: z.number().int().min(0),
59
+ assemblies: z.number().int().min(0),
60
+ modules: z.number().int().min(0),
61
+ types: z.number().int().min(0),
62
+ methods: z.number().int().min(0),
63
+ fields: z.number().int().min(0),
64
+ pinvoke_imports: z.number().int().min(0),
65
+ native_implementations: z.number().int().min(0),
66
+ }),
67
+ graph: javascriptApplicationGraphSchema,
68
+ coverage: z.strictObject({
69
+ status: z.enum(["complete-within-inputs", "partial", "truncated"]),
70
+ omitted_types: z.number().int().min(0),
71
+ omitted_methods: z.number().int().min(0),
72
+ omitted_fields: z.number().int().min(0),
73
+ omitted_pinvoke_imports: z.number().int().min(0),
74
+ omitted_native_implementations: z.number().int().min(0),
75
+ }),
76
+ evidence_links: z.array(evidenceIdSchema).min(1).max(3),
77
+ limitations: z.array(boundedTextSchema).max(1_000),
78
+ });
79
+ const sha256 = (value) => {
80
+ const serialized = canonicalize(value);
81
+ if (serialized === undefined)
82
+ throw new TypeError("Managed application graph canonicalization failed");
83
+ return createHash("sha256").update(serialized).digest("hex");
84
+ };
85
+ /** Project authenticated managed Evidence records into the application graph. */
86
+ export const projectManagedApplicationGraph = (input) => {
87
+ const parsed = parseManagedInputs(input);
88
+ const artifactIdentity = chooseArtifact(parsed);
89
+ assertSameArtifact(parsed, artifactIdentity.sha256);
90
+ const evidenceLinks = [
91
+ parsed.artifact?.evidence.evidence_id,
92
+ parsed.members?.evidence.evidence_id,
93
+ parsed.boundaries?.evidence.evidence_id,
94
+ ].filter((id) => id !== undefined);
95
+ const state = {
96
+ nodes: [],
97
+ edges: [],
98
+ artifactSha256: artifactIdentity.sha256,
99
+ artifactPath: artifactIdentity.path,
100
+ evidenceLinks,
101
+ typeNodes: new Map(),
102
+ methodNodes: new Map(),
103
+ fieldNodes: new Map(),
104
+ };
105
+ const artifactNode = addArtifactNode(state);
106
+ addArtifactIdentityNodes(state, artifactNode, parsed);
107
+ const memberCounts = addMemberNodes(state, artifactNode, parsed, input.limits);
108
+ const boundaryCounts = addBoundaryNodes(state, artifactNode, parsed, input.limits);
109
+ const omissions = omittedCounts(parsed, input.limits);
110
+ const limitations = projectionLimitations(parsed, omissions);
111
+ const graph = createJavaScriptApplicationGraph({
112
+ schema: "JavaScriptApplicationGraph",
113
+ schema_version: 1,
114
+ root_node_ids: [artifactNode.node_id],
115
+ nodes: state.nodes,
116
+ edges: state.edges,
117
+ coverage: graphCoverage(omissions),
118
+ limitations,
119
+ });
120
+ const withoutId = {
121
+ schema_version: 1,
122
+ root_artifact_sha256: state.artifactSha256,
123
+ source_evidence: {
124
+ managed_artifact_evidence_id: parsed.artifact?.evidence.evidence_id ?? null,
125
+ managed_members_evidence_id: parsed.members?.evidence.evidence_id ?? null,
126
+ managed_native_boundaries_evidence_id: parsed.boundaries?.evidence.evidence_id ?? null,
127
+ },
128
+ summary: {
129
+ graph_nodes: graph.nodes.length,
130
+ graph_edges: graph.edges.length,
131
+ assemblies: parsed.artifact?.result.assembly === null ? 0 : 1,
132
+ modules: parsed.artifact?.result.module === null ? 0 : 1,
133
+ ...memberCounts,
134
+ ...boundaryCounts,
135
+ },
136
+ graph,
137
+ coverage: resultCoverage(omissions),
138
+ evidence_links: evidenceLinks,
139
+ limitations,
140
+ };
141
+ return managedApplicationGraphResultSchema.parse({
142
+ ...withoutId,
143
+ projection_id: `magp_${sha256(withoutId)}`,
144
+ });
145
+ };
146
+ const parseManagedInputs = (input) => ({
147
+ artifact: input.managed_artifact === undefined
148
+ ? null
149
+ : parseManagedEvidence(input.managed_artifact, "inspect_managed_artifact", managedArtifactInspectionSchema),
150
+ members: input.managed_members === undefined
151
+ ? null
152
+ : parseManagedEvidence(input.managed_members, "inspect_managed_members", managedMemberInspectionSchema),
153
+ boundaries: input.managed_native_boundaries === undefined
154
+ ? null
155
+ : parseManagedEvidence(input.managed_native_boundaries, "inspect_managed_native_boundaries", managedNativeBoundaryInspectionSchema),
156
+ });
157
+ const parseManagedEvidence = (rawEvidence, operation, schema) => {
158
+ const evidence = parseEvidence(rawEvidence);
159
+ if (evidence.operation !== operation)
160
+ throw new TypeError(`Evidence operation is not ${operation}`);
161
+ return { evidence, result: schema.parse(evidence.normalized_result) };
162
+ };
163
+ const chooseArtifact = (parsed) => {
164
+ const result = parsed.artifact?.result ??
165
+ parsed.members?.result ??
166
+ parsed.boundaries?.result;
167
+ if (result === undefined)
168
+ throw new TypeError("Managed graph projection requires managed Evidence");
169
+ return { sha256: result.artifact.sha256, path: result.artifact.path };
170
+ };
171
+ const assertSameArtifact = (parsed, sha256Value) => {
172
+ for (const result of [
173
+ parsed.artifact?.result,
174
+ parsed.members?.result,
175
+ parsed.boundaries?.result,
176
+ ])
177
+ if (result !== undefined && result.artifact.sha256 !== sha256Value)
178
+ throw new TypeError("Managed graph projection inputs must describe the same artifact SHA-256");
179
+ };
180
+ const addArtifactNode = (state) => {
181
+ const node = createJavaScriptApplicationNode({
182
+ kind: "artifact",
183
+ identity: {
184
+ strategy: "content-digest",
185
+ stability: "global-exact",
186
+ sha256: state.artifactSha256,
187
+ },
188
+ observations: [
189
+ {
190
+ label: basename(state.artifactPath),
191
+ properties: {
192
+ format: "pe",
193
+ source: "managed-application-graph",
194
+ },
195
+ evidence: managedEvidence(state, "project-managed-artifact"),
196
+ },
197
+ ],
198
+ });
199
+ state.nodes.push(node);
200
+ return node;
201
+ };
202
+ const addArtifactIdentityNodes = (state, artifactNode, parsed) => {
203
+ const artifact = parsed.artifact?.result;
204
+ if (artifact?.assembly !== undefined && artifact.assembly !== null) {
205
+ const assembly = createJavaScriptApplicationNode({
206
+ kind: "managed-assembly",
207
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-assembly", artifact.assembly.token),
208
+ observations: [
209
+ {
210
+ label: artifact.assembly.name,
211
+ properties: {
212
+ name: artifact.assembly.name,
213
+ version: artifact.assembly.version,
214
+ culture: artifact.assembly.culture,
215
+ public_key_kind: artifact.assembly.public_key.kind,
216
+ },
217
+ evidence: managedEvidence(state, "inspect_managed_artifact"),
218
+ },
219
+ ],
220
+ });
221
+ state.nodes.push(assembly);
222
+ addContainsEdge(state, artifactNode, assembly, "declares-managed-assembly");
223
+ }
224
+ const module = artifact?.module ??
225
+ parsed.members?.result.module ??
226
+ parsed.boundaries?.result.module;
227
+ if (module !== undefined && module !== null) {
228
+ const moduleNode = createJavaScriptApplicationNode({
229
+ kind: "managed-module",
230
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-module", module.mvid ?? module.token),
231
+ observations: [
232
+ {
233
+ label: module.name,
234
+ properties: {
235
+ name: module.name,
236
+ mvid: module.mvid,
237
+ generation: module.generation,
238
+ token: module.token,
239
+ },
240
+ evidence: managedEvidence(state, "inspect_managed_artifact"),
241
+ },
242
+ ],
243
+ });
244
+ state.nodes.push(moduleNode);
245
+ addContainsEdge(state, artifactNode, moduleNode, "declares-managed-module");
246
+ }
247
+ };
248
+ const addMemberNodes = (state, artifactNode, parsed, limits) => {
249
+ const members = parsed.members?.result;
250
+ if (members === undefined)
251
+ return { types: 0, methods: 0, fields: 0 };
252
+ const types = members.types.items.slice(0, limits.max_types);
253
+ const methods = members.methods.items.slice(0, limits.max_methods);
254
+ const fields = members.fields.items.slice(0, limits.max_fields);
255
+ for (const type of types) {
256
+ const node = typeNode(state, type);
257
+ state.nodes.push(node);
258
+ state.typeNodes.set(type.token, node);
259
+ addContainsEdge(state, artifactNode, node, "declares-managed-type");
260
+ }
261
+ for (const method of methods) {
262
+ const node = methodNode(state, method);
263
+ state.nodes.push(node);
264
+ state.methodNodes.set(method.token, node);
265
+ const owner = method.declaring_type_token === null
266
+ ? artifactNode
267
+ : (state.typeNodes.get(method.declaring_type_token) ?? artifactNode);
268
+ addContainsEdge(state, owner, node, "declares-managed-method");
269
+ }
270
+ for (const field of fields) {
271
+ const node = fieldNode(state, field);
272
+ state.nodes.push(node);
273
+ state.fieldNodes.set(field.token, node);
274
+ const owner = field.declaring_type_token === null
275
+ ? artifactNode
276
+ : (state.typeNodes.get(field.declaring_type_token) ?? artifactNode);
277
+ addContainsEdge(state, owner, node, "declares-managed-field");
278
+ }
279
+ return {
280
+ types: types.length,
281
+ methods: methods.length,
282
+ fields: fields.length,
283
+ };
284
+ };
285
+ const typeNode = (state, type) => createJavaScriptApplicationNode({
286
+ kind: "managed-type",
287
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-type-token", type.token),
288
+ observations: [
289
+ {
290
+ label: type.full_name,
291
+ properties: {
292
+ token: type.token,
293
+ namespace: type.namespace,
294
+ name: type.name,
295
+ full_name: type.full_name,
296
+ flags: type.flags,
297
+ extends_token: type.extends_token,
298
+ },
299
+ evidence: managedEvidence(state, "inspect_managed_members"),
300
+ },
301
+ ],
302
+ });
303
+ const methodNode = (state, method) => createJavaScriptApplicationNode({
304
+ kind: "managed-method",
305
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-method-token", method.token),
306
+ observations: [
307
+ {
308
+ label: method.declaring_type === null
309
+ ? method.name
310
+ : `${method.declaring_type}.${method.name}`,
311
+ properties: {
312
+ token: method.token,
313
+ declaring_type_token: method.declaring_type_token,
314
+ declaring_type: method.declaring_type,
315
+ name: method.name,
316
+ rva: method.rva,
317
+ signature_sha256: method.signature.raw_sha256,
318
+ signature_status: method.signature.parse_status,
319
+ body_status: method.body.status,
320
+ normalized_il_sha256: method.body.normalized_il_sha256,
321
+ il_size: method.body.il_size,
322
+ },
323
+ evidence: managedEvidence(state, "inspect_managed_members"),
324
+ },
325
+ ],
326
+ });
327
+ const fieldNode = (state, field) => createJavaScriptApplicationNode({
328
+ kind: "managed-field",
329
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-field-token", field.token),
330
+ observations: [
331
+ {
332
+ label: field.declaring_type === null
333
+ ? field.name
334
+ : `${field.declaring_type}.${field.name}`,
335
+ properties: {
336
+ token: field.token,
337
+ declaring_type_token: field.declaring_type_token,
338
+ declaring_type: field.declaring_type,
339
+ name: field.name,
340
+ flags: field.flags,
341
+ signature_sha256: field.signature.raw_sha256,
342
+ signature_status: field.signature.parse_status,
343
+ },
344
+ evidence: managedEvidence(state, "inspect_managed_members"),
345
+ },
346
+ ],
347
+ });
348
+ const addBoundaryNodes = (state, artifactNode, parsed, limits) => {
349
+ const boundaries = parsed.boundaries?.result;
350
+ if (boundaries === undefined)
351
+ return { pinvoke_imports: 0, native_implementations: 0 };
352
+ const pinvokes = boundaries.pinvoke_imports.items.slice(0, limits.max_pinvoke_imports);
353
+ const implementations = boundaries.native_implementations.items.slice(0, limits.max_native_implementations);
354
+ for (const pinvoke of pinvokes) {
355
+ const node = pinvokeNode(state, pinvoke);
356
+ state.nodes.push(node);
357
+ const owner = pinvoke.member_token === null
358
+ ? artifactNode
359
+ : (state.methodNodes.get(pinvoke.member_token) ?? artifactNode);
360
+ state.edges.push(createJavaScriptApplicationEdge({
361
+ source_node_id: owner.node_id,
362
+ target_node_id: node.node_id,
363
+ relation: "imports",
364
+ properties: {
365
+ kind: "managed-pinvoke",
366
+ import_name: pinvoke.import_name,
367
+ import_scope_name: pinvoke.import_scope_name,
368
+ },
369
+ evidence: managedEvidence(state, "inspect_managed_native_boundaries"),
370
+ }));
371
+ }
372
+ for (const implementation of implementations) {
373
+ const node = nativeImplementationNode(state, implementation);
374
+ state.nodes.push(node);
375
+ const owner = state.methodNodes.get(implementation.token) ?? artifactNode;
376
+ addContainsEdge(state, owner, node, "declares-managed-native-implementation");
377
+ }
378
+ return {
379
+ pinvoke_imports: pinvokes.length,
380
+ native_implementations: implementations.length,
381
+ };
382
+ };
383
+ const pinvokeNode = (state, pinvoke) => createJavaScriptApplicationNode({
384
+ kind: "managed-pinvoke-import",
385
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-pinvoke-token", pinvoke.token),
386
+ observations: [
387
+ {
388
+ label: pinvoke.import_name,
389
+ properties: {
390
+ token: pinvoke.token,
391
+ member_token: pinvoke.member_token,
392
+ member_name: pinvoke.member_name,
393
+ import_name: pinvoke.import_name,
394
+ import_scope_name: pinvoke.import_scope_name,
395
+ char_set: pinvoke.char_set,
396
+ call_convention: pinvoke.call_convention,
397
+ verification: pinvoke.verification,
398
+ },
399
+ evidence: managedEvidence(state, "inspect_managed_native_boundaries"),
400
+ },
401
+ ],
402
+ });
403
+ const nativeImplementationNode = (state, implementation) => createJavaScriptApplicationNode({
404
+ kind: "managed-native-implementation",
405
+ identity: artifactLocalIdentity(state.artifactSha256, "managed-native-implementation-token", implementation.token),
406
+ observations: [
407
+ {
408
+ label: implementation.name,
409
+ properties: {
410
+ token: implementation.token,
411
+ name: implementation.name,
412
+ rva: implementation.rva,
413
+ code_type: implementation.code_type,
414
+ managed_kind: implementation.managed_kind,
415
+ pinvoke_declared: implementation.pinvoke_declared,
416
+ boundary_kind: implementation.boundary_kind,
417
+ body_interpretation: implementation.body_interpretation,
418
+ },
419
+ evidence: managedEvidence(state, "inspect_managed_native_boundaries"),
420
+ },
421
+ ],
422
+ });
423
+ const addContainsEdge = (state, source, target, kind) => {
424
+ state.edges.push(createJavaScriptApplicationEdge({
425
+ source_node_id: source.node_id,
426
+ target_node_id: target.node_id,
427
+ relation: "contains",
428
+ properties: { kind },
429
+ evidence: managedEvidence(state, "project-managed-contains"),
430
+ }));
431
+ };
432
+ const artifactLocalIdentity = (artifactSha256, namespace, key) => ({
433
+ strategy: "artifact-local-key",
434
+ stability: "artifact-version",
435
+ artifact_sha256: artifactSha256,
436
+ namespace,
437
+ key,
438
+ });
439
+ const managedEvidence = (state, operation) => ({
440
+ authority: "managed-static-analysis",
441
+ state: "observed",
442
+ confidence: "exact",
443
+ artifact: {
444
+ available: true,
445
+ artifact_id: `art_${state.artifactSha256}`,
446
+ sha256: state.artifactSha256,
447
+ },
448
+ location: {
449
+ available: true,
450
+ value: {
451
+ kind: "artifact-path",
452
+ path: graphArtifactPath(state.artifactPath),
453
+ },
454
+ },
455
+ extractor: {
456
+ name: "rea-dotnet-static",
457
+ version: "1",
458
+ operation,
459
+ executable_sha256: null,
460
+ },
461
+ coverage: completeCoverage(),
462
+ limitations: [],
463
+ evidence_ids: state.evidenceLinks,
464
+ });
465
+ const graphArtifactPath = (path) => {
466
+ const name = basename(path).replaceAll(/[^A-Za-z0-9._-]/gu, "_");
467
+ return `managed/${name.length === 0 ? "artifact.pe" : name}`;
468
+ };
469
+ const completeCoverage = () => ({
470
+ status: "complete",
471
+ truncated: false,
472
+ omitted_count: 0,
473
+ limits: [],
474
+ });
475
+ const graphCoverage = (omissions) => {
476
+ const omitted = totalOmitted(omissions);
477
+ return {
478
+ status: omitted === 0 ? "complete" : "partial",
479
+ truncated: omitted > 0,
480
+ omitted_count: omitted,
481
+ limits: [
482
+ { name: "max_types", value: omissions.limits.max_types, unit: "items" },
483
+ {
484
+ name: "max_methods",
485
+ value: omissions.limits.max_methods,
486
+ unit: "items",
487
+ },
488
+ { name: "max_fields", value: omissions.limits.max_fields, unit: "items" },
489
+ {
490
+ name: "max_pinvoke_imports",
491
+ value: omissions.limits.max_pinvoke_imports,
492
+ unit: "items",
493
+ },
494
+ {
495
+ name: "max_native_implementations",
496
+ value: omissions.limits.max_native_implementations,
497
+ unit: "items",
498
+ },
499
+ ],
500
+ };
501
+ };
502
+ const resultCoverage = (omissions) => {
503
+ const omitted = totalOmitted(omissions);
504
+ return {
505
+ status: omitted > 0
506
+ ? "truncated"
507
+ : omissions.partialInput
508
+ ? "partial"
509
+ : "complete-within-inputs",
510
+ omitted_types: omissions.types,
511
+ omitted_methods: omissions.methods,
512
+ omitted_fields: omissions.fields,
513
+ omitted_pinvoke_imports: omissions.pinvokeImports,
514
+ omitted_native_implementations: omissions.nativeImplementations,
515
+ };
516
+ };
517
+ const omittedCounts = (parsed, limits) => ({
518
+ limits,
519
+ partialInput: (parsed.members !== null &&
520
+ parsed.members.result.coverage.state !== "complete") ||
521
+ (parsed.boundaries !== null &&
522
+ parsed.boundaries.result.coverage.state !== "complete") ||
523
+ (parsed.artifact !== null &&
524
+ parsed.artifact.result.coverage.state !== "complete"),
525
+ types: Math.max(0, (parsed.members?.result.types.items.length ?? 0) - limits.max_types),
526
+ methods: Math.max(0, (parsed.members?.result.methods.items.length ?? 0) - limits.max_methods),
527
+ fields: Math.max(0, (parsed.members?.result.fields.items.length ?? 0) - limits.max_fields),
528
+ pinvokeImports: Math.max(0, (parsed.boundaries?.result.pinvoke_imports.items.length ?? 0) -
529
+ limits.max_pinvoke_imports),
530
+ nativeImplementations: Math.max(0, (parsed.boundaries?.result.native_implementations.items.length ?? 0) -
531
+ limits.max_native_implementations),
532
+ });
533
+ const totalOmitted = (omissions) => omissions.types +
534
+ omissions.methods +
535
+ omissions.fields +
536
+ omissions.pinvokeImports +
537
+ omissions.nativeImplementations;
538
+ const projectionLimitations = (parsed, omissions) => [
539
+ "Managed graph projection preserves static metadata observations only; it does not execute managed code, load assemblies, or map managed tokens to native addresses.",
540
+ ...(parsed.members === null
541
+ ? [
542
+ "Managed member Evidence was not supplied; type, method, and field nodes are absent.",
543
+ ]
544
+ : []),
545
+ ...(parsed.boundaries === null
546
+ ? [
547
+ "Managed native-boundary Evidence was not supplied; P/Invoke and native-implementation nodes are absent.",
548
+ ]
549
+ : []),
550
+ ...(omissions.partialInput
551
+ ? ["At least one supplied managed Evidence record has partial coverage."]
552
+ : []),
553
+ ...(totalOmitted(omissions) > 0
554
+ ? ["Projection output was truncated by managed application graph limits."]
555
+ : []),
556
+ ];