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
@@ -0,0 +1,307 @@
1
+ import { parse } from "@babel/parser";
2
+ import * as t from "@babel/types";
3
+ import { calleeName, endpointArgument, location, locationFields, objectString, objectValue, propertyName, resolveSpecifier, sanitizeCandidate, stringArgument, } from "./webBundleAnalyzerAst.js";
4
+ export const analyzeScript = (script, input, accumulator) => {
5
+ let file;
6
+ try {
7
+ file = parse(script.source.artifact.text, {
8
+ sourceType: "unambiguous",
9
+ errorRecovery: true,
10
+ plugins: ["jsx", "typescript"],
11
+ });
12
+ }
13
+ catch {
14
+ accumulator.parseFailures += 1;
15
+ return;
16
+ }
17
+ accumulator.parsedScripts += 1;
18
+ detectVendorFingerprints(script, accumulator, input.analysis_limits.max_findings);
19
+ t.traverseFast(file, (node) => {
20
+ accumulator.visitedNodes += 1;
21
+ if (accumulator.visitedNodes > input.analysis_limits.max_ast_nodes) {
22
+ accumulator.astLimitReached = true;
23
+ return t.traverseFast.stop;
24
+ }
25
+ inspectNode(script, node, accumulator, input.analysis_limits.max_findings);
26
+ return undefined;
27
+ });
28
+ };
29
+ const inspectNode = (script, node, accumulator, maximumFindings) => {
30
+ if ((t.isImportDeclaration(node) || t.isExportAllDeclaration(node)) &&
31
+ node.source !== undefined)
32
+ addEdge({
33
+ script,
34
+ specifier: node.source.value,
35
+ kind: "static_import",
36
+ node,
37
+ accumulator,
38
+ maximumFindings,
39
+ });
40
+ else if (t.isExportNamedDeclaration(node) && node.source != null)
41
+ addEdge({
42
+ script,
43
+ specifier: node.source.value,
44
+ kind: "static_import",
45
+ node,
46
+ accumulator,
47
+ maximumFindings,
48
+ });
49
+ else if (t.isImportExpression(node) && t.isStringLiteral(node.source))
50
+ addEdge({
51
+ script,
52
+ specifier: node.source.value,
53
+ kind: "dynamic_import",
54
+ node,
55
+ accumulator,
56
+ maximumFindings,
57
+ });
58
+ if (t.isObjectProperty(node))
59
+ inspectRouteProperty(script, node, accumulator, maximumFindings);
60
+ if (t.isCallExpression(node) || t.isNewExpression(node))
61
+ inspectCall(script, node, accumulator, maximumFindings);
62
+ };
63
+ const inspectCall = (script, node, accumulator, maximumFindings) => {
64
+ const name = calleeName(node.callee);
65
+ const first = stringArgument(node.arguments[0]);
66
+ if ((name === "require" || name.endsWith(".require")) && first !== undefined)
67
+ addEdge({
68
+ script,
69
+ specifier: first,
70
+ kind: "require",
71
+ node,
72
+ accumulator,
73
+ maximumFindings,
74
+ });
75
+ if ((name === "importScripts" || name.endsWith(".importScripts")) &&
76
+ first !== undefined)
77
+ addEdge({
78
+ script,
79
+ specifier: first,
80
+ kind: "worker_import",
81
+ node,
82
+ accumulator,
83
+ maximumFindings,
84
+ });
85
+ if (routeCallNames.some((candidate) => name === candidate || name.endsWith(`.${candidate}`))) {
86
+ if (first !== undefined)
87
+ addFinding({
88
+ collection: accumulator.routes,
89
+ script,
90
+ rawValue: first,
91
+ mechanism: `call:${name}`,
92
+ node,
93
+ accumulator,
94
+ maximumFindings,
95
+ });
96
+ addRouteFrameworkInference({
97
+ script,
98
+ name,
99
+ node,
100
+ accumulator,
101
+ maximumFindings,
102
+ });
103
+ }
104
+ const endpoint = endpointArgument(name, node.arguments);
105
+ if (endpoint !== undefined)
106
+ addFinding({
107
+ collection: accumulator.endpoints,
108
+ script,
109
+ rawValue: endpoint,
110
+ mechanism: `call:${name}`,
111
+ node,
112
+ accumulator,
113
+ maximumFindings,
114
+ });
115
+ if (name.endsWith("modelContext.registerTool") ||
116
+ name === "modelContext.registerTool")
117
+ addWebMcpDeclaration(script, node, accumulator, maximumFindings);
118
+ };
119
+ const inspectRouteProperty = (script, node, accumulator, maximumFindings) => {
120
+ const key = propertyName(node.key);
121
+ if ((key === "path" || key === "route") && t.isStringLiteral(node.value))
122
+ addFinding({
123
+ collection: accumulator.routes,
124
+ script,
125
+ rawValue: node.value.value,
126
+ mechanism: `property:${key}`,
127
+ node,
128
+ accumulator,
129
+ maximumFindings,
130
+ });
131
+ };
132
+ const addEdge = (context) => {
133
+ const bounded = context.specifier.slice(0, 4_096);
134
+ const key = `edge\0${context.script.script_key}\0${context.kind}\0${bounded}`;
135
+ addBounded(context.accumulator, key, context.maximumFindings, () => context.accumulator.edges.push({
136
+ from_script_key: context.script.script_key,
137
+ kind: context.kind,
138
+ specifier: bounded,
139
+ resolved_url: resolveSpecifier(bounded, context.script.url),
140
+ location: location(context.script.script_key, context.node),
141
+ }));
142
+ };
143
+ const addFinding = (context) => {
144
+ const value = sanitizeCandidate(context.rawValue);
145
+ const key = `finding\0${context.mechanism}\0${context.script.script_key}\0${value}`;
146
+ addBounded(context.accumulator, key, context.maximumFindings, () => context.collection.push({
147
+ value,
148
+ mechanism: context.mechanism,
149
+ location: location(context.script.script_key, context.node),
150
+ }));
151
+ };
152
+ const addWebMcpDeclaration = (script, node, accumulator, maximumFindings) => {
153
+ const declaration = node.arguments[0];
154
+ if (!t.isObjectExpression(declaration))
155
+ return;
156
+ const name = objectString(declaration, "name");
157
+ const description = objectString(declaration, "description");
158
+ const schema = objectValue(declaration, "inputSchema") ??
159
+ objectValue(declaration, "input_schema");
160
+ const declaredProperties = t.isObjectExpression(schema)
161
+ ? objectValue(schema, "properties")
162
+ : undefined;
163
+ const propertyObject = t.isObjectExpression(declaredProperties)
164
+ ? declaredProperties
165
+ : schema;
166
+ const schemaPropertyNames = t.isObjectExpression(propertyObject)
167
+ ? propertyObject.properties.flatMap((property) => t.isObjectProperty(property)
168
+ ? [propertyName(property.key)].filter(Boolean)
169
+ : [])
170
+ : [];
171
+ const key = `webmcp\0${script.script_key}\0${name ?? ""}\0${schemaPropertyNames.join("\0")}`;
172
+ addBounded(accumulator, key, maximumFindings, () => accumulator.webMcp.push({
173
+ name: name?.slice(0, 256) ?? null,
174
+ description: description?.slice(0, 2_048) ?? null,
175
+ schema_property_names: [...new Set(schemaPropertyNames)]
176
+ .sort()
177
+ .slice(0, 256),
178
+ trust: "page-declared-untrusted",
179
+ location: location(script.script_key, node),
180
+ }));
181
+ };
182
+ const detectVendorFingerprints = (script, accumulator, maximumFindings) => {
183
+ const text = script.source.artifact.text;
184
+ for (const detector of vendorDetectors) {
185
+ if (!detector.patterns.some((pattern) => text.includes(pattern)))
186
+ continue;
187
+ const key = `vendor\0${script.script_key}\0${detector.value}`;
188
+ addBounded(accumulator, key, maximumFindings, () => accumulator.inferences.push({
189
+ kind: detector.kind,
190
+ value: detector.value,
191
+ confidence: detector.confidence,
192
+ basis: [basis(script, detector.detector)],
193
+ }));
194
+ }
195
+ };
196
+ const addRouteFrameworkInference = (context) => {
197
+ const value = context.name.endsWith("useRoutes") ||
198
+ context.name.endsWith("createBrowserRouter")
199
+ ? "React Router-compatible route API"
200
+ : "Generic route registration API";
201
+ const key = `route-framework\0${context.script.script_key}\0${value}`;
202
+ addBounded(context.accumulator, key, context.maximumFindings, () => context.accumulator.inferences.push({
203
+ kind: "route_framework",
204
+ value,
205
+ confidence: "medium",
206
+ basis: [
207
+ {
208
+ ...basis(context.script, `call:${context.name}`),
209
+ ...locationFields(context.node),
210
+ },
211
+ ],
212
+ }));
213
+ };
214
+ const addBounded = (accumulator, key, maximum, add) => {
215
+ if (accumulator.seen.has(key))
216
+ return;
217
+ const findings = accumulator.edges.length +
218
+ accumulator.routes.length +
219
+ accumulator.endpoints.length +
220
+ accumulator.webMcp.length +
221
+ accumulator.inferences.length;
222
+ if (findings >= maximum) {
223
+ accumulator.droppedFindings += 1;
224
+ return;
225
+ }
226
+ accumulator.seen.add(key);
227
+ add();
228
+ };
229
+ const basis = (script, detector) => ({
230
+ script_key: script.script_key,
231
+ artifact_sha256: script.source.artifact.sha256,
232
+ line: null,
233
+ column: null,
234
+ detector,
235
+ });
236
+ export const emptyAccumulator = () => ({
237
+ edges: [],
238
+ routes: [],
239
+ endpoints: [],
240
+ webMcp: [],
241
+ inferences: [],
242
+ seen: new Set(),
243
+ visitedNodes: 0,
244
+ parsedScripts: 0,
245
+ parseFailures: 0,
246
+ droppedFindings: 0,
247
+ astLimitReached: false,
248
+ });
249
+ export const isIncludedScript = (script) => script.source.included;
250
+ const routeCallNames = [
251
+ "route",
252
+ "addRoute",
253
+ "useRoutes",
254
+ "createBrowserRouter",
255
+ "createHashRouter",
256
+ ];
257
+ const vendorDetectors = [
258
+ {
259
+ value: "webpack",
260
+ detector: "webpack-runtime",
261
+ patterns: ["__webpack_require__"],
262
+ confidence: "high",
263
+ kind: "bundle_runtime",
264
+ },
265
+ {
266
+ value: "Vite",
267
+ detector: "vite-runtime",
268
+ patterns: ["__vite__", "import.meta.hot"],
269
+ confidence: "medium",
270
+ kind: "bundle_runtime",
271
+ },
272
+ {
273
+ value: "React",
274
+ detector: "react-runtime",
275
+ patterns: ["__REACT_DEVTOOLS_GLOBAL_HOOK__", "React.createElement"],
276
+ confidence: "medium",
277
+ kind: "vendor_fingerprint",
278
+ },
279
+ {
280
+ value: "Vue",
281
+ detector: "vue-runtime",
282
+ patterns: ["__VUE__", "createApp("],
283
+ confidence: "medium",
284
+ kind: "vendor_fingerprint",
285
+ },
286
+ {
287
+ value: "Next.js",
288
+ detector: "next-runtime",
289
+ patterns: ["__NEXT_DATA__", "/_next/"],
290
+ confidence: "high",
291
+ kind: "vendor_fingerprint",
292
+ },
293
+ {
294
+ value: "Angular",
295
+ detector: "angular-runtime",
296
+ patterns: ["ɵɵdefineComponent"],
297
+ confidence: "high",
298
+ kind: "vendor_fingerprint",
299
+ },
300
+ {
301
+ value: "Svelte",
302
+ detector: "svelte-runtime",
303
+ patterns: ["svelte/internal"],
304
+ confidence: "medium",
305
+ kind: "vendor_fingerprint",
306
+ },
307
+ ];
@@ -0,0 +1,120 @@
1
+ import { webBundleAnalysisSchema, } from "./webBundleAnalysis.js";
2
+ export const buildWebBundleAnalysis = (inspection, sourceScripts, sourceMaps, accumulator) => {
3
+ const unavailable = inspection.scripts.items
4
+ .filter((script) => !script.source.included)
5
+ .map(({ script_key }) => script_key);
6
+ const sourceMapIncomplete = sourceMaps.status === "partial" || sourceMaps.status === "unavailable";
7
+ const partial = accumulator.parseFailures > 0 ||
8
+ unavailable.length > 0 ||
9
+ sourceMapIncomplete;
10
+ const truncated = accumulator.astLimitReached ||
11
+ accumulator.droppedFindings > 0 ||
12
+ sourceMaps.status === "truncated";
13
+ return webBundleAnalysisSchema.parse({
14
+ schema_version: 1,
15
+ capture: buildCaptureObservation(inspection, sourceScripts),
16
+ observations: {
17
+ chunks: {
18
+ nodes: sourceScripts.map(chunkNode),
19
+ edges: accumulator.edges,
20
+ },
21
+ routes: accumulator.routes,
22
+ endpoints: accumulator.endpoints,
23
+ webmcp_declarations: accumulator.webMcp,
24
+ source_maps: sourceMaps,
25
+ },
26
+ inferences: accumulator.inferences,
27
+ unknowns: buildUnknowns({
28
+ sourceScripts,
29
+ unavailable,
30
+ parseFailures: accumulator.parseFailures,
31
+ sourceMaps,
32
+ }),
33
+ completeness: buildCompleteness({
34
+ truncated,
35
+ partial,
36
+ parsedScripts: accumulator.parsedScripts,
37
+ parseFailures: accumulator.parseFailures,
38
+ visitedNodes: accumulator.visitedNodes,
39
+ droppedFindings: accumulator.droppedFindings,
40
+ }),
41
+ limitations: bundleLimitations(),
42
+ });
43
+ };
44
+ const buildCaptureObservation = (inspection, sourceScripts) => ({
45
+ target_url: inspection.target.url,
46
+ scripts_observed: inspection.scripts.total,
47
+ scripts_analyzed: sourceScripts.length,
48
+ source_artifacts: sourceScripts.map(sourceArtifact),
49
+ });
50
+ const sourceArtifact = (script) => {
51
+ if (!script.source.included)
52
+ throw new TypeError("Filtered source changed");
53
+ const { text: _text, ...artifact } = script.source.artifact;
54
+ return { ...artifact, text_available: true };
55
+ };
56
+ const chunkNode = (script) => {
57
+ if (!script.source.included)
58
+ throw new TypeError("Filtered source changed");
59
+ return {
60
+ script_key: script.script_key,
61
+ url: script.url,
62
+ artifact_sha256: script.source.artifact.sha256,
63
+ bytes: script.source.artifact.bytes,
64
+ };
65
+ };
66
+ const buildUnknowns = (input) => [
67
+ ...(input.unavailable.length === 0
68
+ ? []
69
+ : [
70
+ {
71
+ dimension: "script_source",
72
+ reason: "Source artifact was not captured within approved limits",
73
+ affected_script_keys: input.unavailable,
74
+ },
75
+ ]),
76
+ ...(input.parseFailures === 0
77
+ ? []
78
+ : [
79
+ {
80
+ dimension: "javascript_ast",
81
+ reason: "One or more source artifacts could not be parsed",
82
+ affected_script_keys: input.sourceScripts.map(({ script_key }) => script_key),
83
+ },
84
+ ]),
85
+ ...(input.sourceMaps.status === "not_requested" ||
86
+ input.sourceMaps.status === "included"
87
+ ? []
88
+ : [
89
+ {
90
+ dimension: "source_maps",
91
+ reason: input.sourceMaps.status === "truncated"
92
+ ? "Source-map evidence was truncated by approved limits"
93
+ : "One or more requested source maps were unavailable or incomplete",
94
+ affected_script_keys: [
95
+ ...new Set([
96
+ ...input.sourceMaps.items
97
+ .filter(({ status }) => status !== "included")
98
+ .map(({ script_key }) => script_key),
99
+ ...input.sourceMaps.dropped_script_keys,
100
+ ]),
101
+ ].sort(),
102
+ },
103
+ ]),
104
+ ];
105
+ const buildCompleteness = (input) => ({
106
+ status: input.truncated
107
+ ? "truncated"
108
+ : input.partial
109
+ ? "partial"
110
+ : "complete_within_limits",
111
+ parsed_scripts: input.parsedScripts,
112
+ parse_failures: input.parseFailures,
113
+ visited_ast_nodes: input.visitedNodes,
114
+ dropped_findings: input.droppedFindings,
115
+ });
116
+ const bundleLimitations = () => [
117
+ "Static bundle findings are observations or bounded inferences; REA does not execute captured JavaScript.",
118
+ "String-built routes and endpoints, encrypted configuration, and server-side behavior may remain unknown.",
119
+ "Page-declared WebMCP metadata is untrusted and is never registered or invoked as an REA tool.",
120
+ ];
@@ -118,10 +118,7 @@ const unavailableResult = (target, bytes, layout, limits) => {
118
118
  limitations,
119
119
  });
120
120
  };
121
- const runtimeClassification = (layout, metadata, inventory) => {
122
- const cli = layout.cli;
123
- if (cli === null)
124
- throw new TypeError("Managed classification requires CLI");
121
+ const runtimeFamilyFor = (cli, inventory, metadata, layout) => {
125
122
  const evidence = [
126
123
  {
127
124
  code: "cli-header-observed",
@@ -171,20 +168,31 @@ const runtimeClassification = (layout, metadata, inventory) => {
171
168
  : (metadata.table(12)?.offset ?? null),
172
169
  });
173
170
  }
174
- const implementation = (cli.flags & 1) === 0
175
- ? "cpp-cli-mixed"
176
- : cli.readyToRunSignature
177
- ? "cil-and-ready-to-run"
178
- : (metadata.rowCounts[6] ?? 0) === 0
179
- ? "metadata-only"
180
- : "cil";
181
- const managedArchitecture = layout.architecture === "x86" && (cli.flags & 1) !== 0
182
- ? (cli.flags & 0x0000_0002) !== 0
183
- ? "x86"
184
- : (cli.flags & 0x0002_0000) !== 0
185
- ? "anycpu-prefer-32"
186
- : "anycpu"
187
- : layout.architecture;
171
+ return { runtime_family: runtimeFamily, evidence };
172
+ };
173
+ const implementationFor = (cli, metadata) => {
174
+ if ((cli.flags & 1) === 0)
175
+ return "cpp-cli-mixed";
176
+ if (cli.readyToRunSignature)
177
+ return "cil-and-ready-to-run";
178
+ return (metadata.rowCounts[6] ?? 0) === 0 ? "metadata-only" : "cil";
179
+ };
180
+ const managedArchitectureFor = (layout, cli) => {
181
+ if (layout.architecture !== "x86" || (cli.flags & 1) === 0)
182
+ return layout.architecture;
183
+ if ((cli.flags & 0x0000_0002) !== 0)
184
+ return "x86";
185
+ if ((cli.flags & 0x0002_0000) !== 0)
186
+ return "anycpu-prefer-32";
187
+ return "anycpu";
188
+ };
189
+ const runtimeClassification = ({ layout, metadata, inventory, }) => {
190
+ const cli = layout.cli;
191
+ if (cli === null)
192
+ throw new TypeError("Managed classification requires CLI");
193
+ const { runtime_family: runtimeFamily, evidence } = runtimeFamilyFor(cli, inventory, metadata, layout);
194
+ const implementation = implementationFor(cli, metadata);
195
+ const managedArchitecture = managedArchitectureFor(layout, cli);
188
196
  evidence.push({
189
197
  code: "managed-architecture-derived",
190
198
  detail: `Managed architecture ${managedArchitecture} is derived from PE machine and CLI flags.`,
@@ -197,7 +205,7 @@ const runtimeClassification = (layout, metadata, inventory) => {
197
205
  evidence,
198
206
  };
199
207
  };
200
- const partialMetadataResult = (target, bytes, layout, limits, issue) => ({
208
+ const partialMetadataResult = ({ target, bytes, layout, limits, issue, }) => ({
201
209
  ...base(target, bytes, layout),
202
210
  classification: {
203
211
  status: "malformed",
@@ -247,6 +255,9 @@ const mapResources = (bytes, layout, issues) => {
247
255
  return null;
248
256
  }
249
257
  };
258
+ const inventoryPagesComplete = (inventory) => inventory.references.complete &&
259
+ inventory.resources.complete &&
260
+ inventory.attributes.complete;
250
261
  /** Inspect PE/CLI identity directly from bounded bytes without CLR loading. */
251
262
  export const inspectManagedArtifactBytes = (bytes, target, limits) => {
252
263
  const layout = readManagedPeLayout(bytes);
@@ -254,11 +265,17 @@ export const inspectManagedArtifactBytes = (bytes, target, limits) => {
254
265
  return unavailableResult(target, bytes, layout, limits);
255
266
  const cli = layout.cli;
256
267
  if (cli.metadata.size > limits.maxMetadataBytes)
257
- return managedArtifactInspectionSchema.parse(partialMetadataResult(target, bytes, layout, limits, {
258
- code: "limit-exceeded",
259
- scope: "cli.metadata",
260
- offset: cli.headerOffset + 8,
261
- detail: `CLI metadata size exceeds max_metadata_bytes ${String(limits.maxMetadataBytes)}`,
268
+ return managedArtifactInspectionSchema.parse(partialMetadataResult({
269
+ target,
270
+ bytes,
271
+ layout,
272
+ limits,
273
+ issue: {
274
+ code: "limit-exceeded",
275
+ scope: "cli.metadata",
276
+ offset: cli.headerOffset + 8,
277
+ detail: `CLI metadata size exceeds max_metadata_bytes ${String(limits.maxMetadataBytes)}`,
278
+ },
262
279
  }));
263
280
  let metadata;
264
281
  try {
@@ -268,15 +285,19 @@ export const inspectManagedArtifactBytes = (bytes, target, limits) => {
268
285
  catch (cause) {
269
286
  if (!(cause instanceof ManagedReaderFailure))
270
287
  throw cause;
271
- return managedArtifactInspectionSchema.parse(partialMetadataResult(target, bytes, layout, limits, cause.issue));
288
+ return managedArtifactInspectionSchema.parse(partialMetadataResult({
289
+ target,
290
+ bytes,
291
+ layout,
292
+ limits,
293
+ issue: cause.issue,
294
+ }));
272
295
  }
273
296
  const resourceIssues = [];
274
297
  const resourceDirectory = mapResources(bytes, layout, resourceIssues);
275
298
  const inventory = readManagedMetadataInventory(bytes, metadata, limits, resourceDirectory);
276
299
  const issues = [...resourceIssues, ...inventory.issues];
277
- const pagesComplete = inventory.references.complete &&
278
- inventory.resources.complete &&
279
- inventory.attributes.complete;
300
+ const pagesComplete = inventoryPagesComplete(inventory);
280
301
  const limitations = [
281
302
  ...(pagesComplete
282
303
  ? []
@@ -295,7 +316,7 @@ export const inspectManagedArtifactBytes = (bytes, target, limits) => {
295
316
  classification: {
296
317
  status: "managed",
297
318
  container: "pe",
298
- ...runtimeClassification(layout, metadata, inventory),
319
+ ...runtimeClassification({ layout, metadata, inventory }),
299
320
  },
300
321
  metadata: {
301
322
  status: issues.length === 0 ? "complete" : "partial",