rea-agents 6.3.0 → 6.4.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 (487) hide show
  1. package/README.md +7 -4
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/dist/adb/AdbConfiguration.js +88 -0
  6. package/dist/adb/AdbDeviceOutput.js +186 -0
  7. package/dist/adb/AdbProvider.js +1190 -0
  8. package/dist/adb/AdbShellOutput.js +309 -0
  9. package/dist/android/AndroidTargetSnapshot.js +104 -22
  10. package/dist/android/JadxConfiguration.js +44 -24
  11. package/dist/android/JadxProvider.js +51 -19
  12. package/dist/apktool/ApktoolConfiguration.js +84 -0
  13. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  14. package/dist/apktool/ApktoolProvider.js +506 -0
  15. package/dist/application/AnalysisProvider.js +8 -2
  16. package/dist/application/AppBundleExecutable.js +27 -22
  17. package/dist/application/BinaryTargetResolver.js +22 -2
  18. package/dist/application/CapabilityInventory.js +11 -1
  19. package/dist/application/ClientConfigurationDocument.js +70 -0
  20. package/dist/application/ClientConfigurationFiles.js +91 -0
  21. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  22. package/dist/application/ClientRegistrationStatus.js +66 -31
  23. package/dist/application/DirectAnalysis.js +2 -2
  24. package/dist/application/DirectAnalysisCleanup.js +1 -1
  25. package/dist/application/DirectAnalysisStatus.js +1 -1
  26. package/dist/application/Doctor.js +5 -3
  27. package/dist/application/DoctorDiagnostics.js +1 -1
  28. package/dist/application/EvidenceBundleCommands.js +6 -12
  29. package/dist/application/GeminiClientSettings.js +139 -0
  30. package/dist/application/HermesClientHome.js +115 -0
  31. package/dist/application/HopperDownload.js +39 -0
  32. package/dist/application/InvestigationProviders.js +6 -0
  33. package/dist/application/JsonFiles.js +6 -5
  34. package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
  35. package/dist/application/LinuxHopper.js +4 -12
  36. package/dist/application/MacHopper.js +172 -149
  37. package/dist/application/MipsElfAbiFlags.js +140 -0
  38. package/dist/application/ProviderOperationExecution.js +31 -0
  39. package/dist/application/ReconstructionObligationCandidates.js +9 -3
  40. package/dist/application/ReferenceSourceImport.js +76 -29
  41. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  42. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  43. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  44. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  45. package/dist/application/RegularFileRead.js +93 -7
  46. package/dist/application/Setup.js +54 -6
  47. package/dist/application/SetupClientConfiguration.js +116 -16
  48. package/dist/application/SetupHost.js +102 -24
  49. package/dist/application/SetupPlan.js +5 -8
  50. package/dist/application/SetupSkill.js +58 -39
  51. package/dist/application/SupportedClients.js +290 -65
  52. package/dist/application/Uninstall.js +158 -10
  53. package/dist/application/UpdateMaintenance.js +17 -21
  54. package/dist/application/Utf8JsonInput.js +7 -0
  55. package/dist/application/WebScriptExportService.js +131 -65
  56. package/dist/application/WebSourceLocationService.js +3 -0
  57. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  58. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  59. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  60. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  61. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  62. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  63. package/dist/application/binary/BinarySession.js +2 -1
  64. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  65. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  66. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  67. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  68. package/dist/application/evm/EvmInterfaceService.js +3 -0
  69. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  70. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  71. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  72. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  73. package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
  74. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  75. package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
  76. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  77. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
  78. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  79. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
  80. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  81. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  82. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
  83. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  84. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
  85. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
  86. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  89. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
  90. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
  91. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
  92. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
  93. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
  94. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
  95. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
  96. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  97. package/dist/application/jeb/JebAnalysisService.js +13 -0
  98. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  99. package/dist/application/native/NativeUiActionTrace.js +16 -8
  100. package/dist/application/native/NativeValueTrace.js +23 -6
  101. package/dist/application/process/ProcessCli.js +25 -20
  102. package/dist/artifacts/ArtifactPaths.js +129 -8
  103. package/dist/artifacts/ArtifactProvider.js +20 -15
  104. package/dist/artifacts/ArtifactReader.js +23 -0
  105. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  106. package/dist/artifacts/AsarArtifactReader.js +176 -102
  107. package/dist/artifacts/AsarHeader.js +24 -0
  108. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  109. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  110. package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
  111. package/dist/artifacts/SafeOutputTree.js +245 -70
  112. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  113. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  114. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  115. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  116. package/dist/artifacts/ZipArtifactReader.js +77 -27
  117. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  118. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  119. package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
  120. package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
  121. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
  122. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  123. package/dist/artifacts/inventory/classify.js +75 -32
  124. package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
  125. package/dist/artifacts/inventory/reader.js +13 -5
  126. package/dist/artifacts/inventory/scanCanonical.js +62 -25
  127. package/dist/artifacts/inventory/scanReader.js +38 -11
  128. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
  129. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  130. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  131. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  132. package/dist/browser/CdpBrowserProvider.js +5 -0
  133. package/dist/browser/CdpCaptureDocuments.js +40 -6
  134. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  135. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  136. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  137. package/dist/browser/CdpCaptureEvents.js +4 -9
  138. package/dist/browser/CdpConnection.js +22 -5
  139. package/dist/browser/CdpPageCapture.js +1 -1
  140. package/dist/browser/CdpTargetSession.js +30 -34
  141. package/dist/browser/CdpWebMcpDiscovery.js +32 -10
  142. package/dist/browser/ElectronFileScope.js +99 -9
  143. package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
  144. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  145. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  146. package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
  147. package/dist/browser/PlaywrightScenarioSession.js +127 -54
  148. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  149. package/dist/browser/PngVisualDiff.js +198 -29
  150. package/dist/browser/WebSourceMapFetcher.js +3 -3
  151. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  152. package/dist/browser/assets/PublishWebScripts.js +75 -20
  153. package/dist/browser/assets/WebArtifactReads.js +23 -1
  154. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  155. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  156. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  157. package/dist/browser/history/HarCapture.js +14 -0
  158. package/dist/browser/history/HarCaptureProcess.js +2 -10
  159. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  160. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  161. package/dist/cli/adbCommands.js +337 -0
  162. package/dist/cli/analysisViewCommands.js +39 -1
  163. package/dist/cli/apktoolCommands.js +53 -0
  164. package/dist/cli/artifactCommands.js +8 -11
  165. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  166. package/dist/cli/browserAdvancedCommands.js +65 -36
  167. package/dist/cli/coreBinaryCommands.js +0 -5
  168. package/dist/cli/coreNativeCommands.js +1 -14
  169. package/dist/cli/electronCommands.js +6 -1
  170. package/dist/cli/evmCommands.js +13 -4
  171. package/dist/cli/firmwareCommands.js +7 -2
  172. package/dist/cli/javascriptApplicationAnalysis.js +17 -1
  173. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  174. package/dist/cli/jebCommands.js +99 -0
  175. package/dist/cli/jsonOutput.js +11 -4
  176. package/dist/cli/referenceSourceImportStatus.js +7 -0
  177. package/dist/cli/setupCommands.js +15 -3
  178. package/dist/cli/utilityCommands.js +66 -18
  179. package/dist/cli/webScriptCommands.js +20 -1
  180. package/dist/cli/webSourceLocationCommands.js +21 -9
  181. package/dist/cli.js +6 -0
  182. package/dist/cliBrowserScenarioCommands.js +2 -1
  183. package/dist/cliCommandNames.js +32 -0
  184. package/dist/cliJsonInput.js +2 -2
  185. package/dist/cliObservationOptions.js +3 -0
  186. package/dist/composition/adb.js +3 -0
  187. package/dist/composition/apktool.js +3 -0
  188. package/dist/composition/binaryDiagnostics.js +4 -0
  189. package/dist/composition/directAnalysis.js +12 -4
  190. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  191. package/dist/composition/jeb.js +6 -0
  192. package/dist/config/environment.js +10 -0
  193. package/dist/config/ghidraLanguageOverride.js +9 -0
  194. package/dist/config/mcpInputSchemaProfile.js +27 -0
  195. package/dist/config/parseConfig.js +28 -1
  196. package/dist/contracts/adb/adbToolContracts.js +353 -0
  197. package/dist/contracts/advertisedInputExamples.js +48 -0
  198. package/dist/contracts/analysisDetail.js +10 -0
  199. package/dist/contracts/analysisViewToolContracts.js +17 -2
  200. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  201. package/dist/contracts/artifactToolContracts.js +8 -5
  202. package/dist/contracts/browserToolContracts.js +1 -1
  203. package/dist/contracts/compactInputSchema.js +256 -0
  204. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  205. package/dist/contracts/inputSchemaPresentation.js +10 -10
  206. package/dist/contracts/javascript/electronToolContracts.js +15 -3
  207. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  208. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  209. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  210. package/dist/contracts/officialToolContracts.js +5 -5
  211. package/dist/contracts/sessionToolContracts.js +2 -2
  212. package/dist/contracts/sessionToolSchemas.js +6 -2
  213. package/dist/contracts/toolContractExamples.js +6 -0
  214. package/dist/contracts/toolContractTypes.js +3 -0
  215. package/dist/contracts/toolContracts.js +6 -0
  216. package/dist/contracts/toolEffects.js +167 -0
  217. package/dist/contracts/toolOutputSchemaGroups.js +5 -3
  218. package/dist/contracts/toolSchemaMetadata.js +82 -7
  219. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  220. package/dist/domain/analysisErrorCleanup.js +29 -0
  221. package/dist/domain/analysisErrorPresentation.js +18 -6
  222. package/dist/domain/analysisErrorProjection.js +4 -1
  223. package/dist/domain/analysisSnapshot.js +2 -1
  224. package/dist/domain/analysisView/analysisView.js +52 -2
  225. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  226. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  227. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  228. package/dist/domain/android/androidApplication.js +25 -20
  229. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  230. package/dist/domain/apple/appleApplication.js +40 -23
  231. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  232. package/dist/domain/apple/dyldPaths.js +9 -1
  233. package/dist/domain/apple/dylibResolution.js +2 -2
  234. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  235. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  236. package/dist/domain/artifactComparison.js +35 -7
  237. package/dist/domain/artifactGraph.js +5 -3
  238. package/dist/domain/artifactIdentity.js +30 -2
  239. package/dist/domain/artifactInspection.js +3 -43
  240. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  241. package/dist/domain/artifactInventoryEvidence.js +11 -12
  242. package/dist/domain/artifactPathSyntax.js +1 -1
  243. package/dist/domain/binaryTarget.js +16 -0
  244. package/dist/domain/binaryTargetTypes.js +8 -1
  245. package/dist/domain/browserObservationSchemas.js +8 -4
  246. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  247. package/dist/domain/compactStringIdentity.js +9 -0
  248. package/dist/domain/evidence.js +2 -1
  249. package/dist/domain/evidenceRecordSummary.js +144 -0
  250. package/dist/domain/inputIssueProjection.js +16 -1
  251. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
  252. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
  253. package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
  254. package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
  255. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  256. package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
  257. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
  258. package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
  259. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  260. package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
  261. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
  262. package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
  263. package/dist/domain/javascript/javascriptAstValues.js +32 -0
  264. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  265. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  266. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
  267. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  268. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  269. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
  270. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
  271. package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
  272. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  273. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  274. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  275. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  276. package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
  277. package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
  278. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
  279. package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
  280. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
  281. package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
  282. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  283. package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
  284. package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
  285. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
  286. package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
  287. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
  288. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  289. package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
  290. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  291. package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
  292. package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
  293. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  294. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  295. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
  296. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  297. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  298. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  299. package/dist/domain/jeb/jebAnalysis.js +114 -0
  300. package/dist/domain/jsonShape.js +63 -52
  301. package/dist/domain/jsonValue.js +3 -0
  302. package/dist/domain/managed/managedApplicationGraph.js +37 -0
  303. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  304. package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
  305. package/dist/domain/managed/managedArtifact.js +1 -0
  306. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  307. package/dist/domain/native/nativeAotPe.js +1408 -0
  308. package/dist/domain/native/nativeInstruction.js +21 -0
  309. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  310. package/dist/domain/native/peResources.js +94 -0
  311. package/dist/domain/nativeConvention.js +33 -0
  312. package/dist/domain/process/processCapture.js +91 -1
  313. package/dist/domain/process/processCaptureExample.js +24 -0
  314. package/dist/domain/process/processCaptureValidation.js +79 -0
  315. package/dist/domain/process/processScenario.js +59 -7
  316. package/dist/domain/propertyListKeys.js +3 -1
  317. package/dist/domain/referenceSourceGraph.js +25 -16
  318. package/dist/domain/referenceSourceImportParsing.js +6 -3
  319. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  320. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  321. package/dist/domain/webBundleAnalyzerInspection.js +14 -2
  322. package/dist/domain/webCaptureDiff.js +102 -4
  323. package/dist/domain/webScriptExportError.js +10 -4
  324. package/dist/domain/webScriptExportPlan.js +7 -13
  325. package/dist/domain/zipPackageFormat.js +4 -1
  326. package/dist/domain/zodCollectionSteps.js +24 -0
  327. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  328. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  329. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  330. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  331. package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
  332. package/dist/dotnet/ManagedMemberRows.js +9 -4
  333. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  334. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  335. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  336. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  337. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  338. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  339. package/dist/dotnet/ManagedPeReader.js +41 -25
  340. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  341. package/dist/dotnet/ManagedStaticProvider.js +55 -24
  342. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  343. package/dist/evaluation/CodexAgentEval.js +43 -13
  344. package/dist/evm/EvmoleFailures.js +0 -2
  345. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  346. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  347. package/dist/filesystem/OwnedFileHandle.js +36 -0
  348. package/dist/filesystem/RegularFile.js +33 -1
  349. package/dist/filesystem/StableFileHash.js +46 -0
  350. package/dist/filesystem/readFileHandleChunks.js +26 -0
  351. package/dist/firmware/FirmwareCommand.js +25 -3
  352. package/dist/firmware/FirmwareFiles.js +23 -8
  353. package/dist/firmware/FirmwareProvider.js +156 -32
  354. package/dist/firmware/FirmwarePublication.js +24 -3
  355. package/dist/firmware/FirmwareRelease.js +1 -0
  356. package/dist/generatedPackageMetadata.js +2 -2
  357. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  358. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  359. package/dist/ghidra/GhidraClient.js +76 -4
  360. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  361. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  362. package/dist/ghidra/GhidraInstallation.js +1 -1
  363. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  364. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  365. package/dist/ghidra/GhidraLauncher.js +80 -39
  366. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  367. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  368. package/dist/ghidra/GhidraProvider.js +57 -9
  369. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  370. package/dist/ghidra/GhidraProviderClient.js +282 -21
  371. package/dist/ghidra/GhidraSessionValues.js +9 -2
  372. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  373. package/dist/hopper/HopperClient.js +15 -6
  374. package/dist/hopper/HopperMachOImage.js +2 -0
  375. package/dist/hopper/HopperProvider.js +13 -2
  376. package/dist/ida/IdaOperationRunner.js +8 -2
  377. package/dist/ida/IdaProvider.js +7 -0
  378. package/dist/ida/IdaSessionClient.js +3 -1
  379. package/dist/ida/IdaWorkspace.js +4 -2
  380. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  381. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  382. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  383. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  384. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  385. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  386. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  387. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  388. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  389. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  390. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  391. package/dist/javascript/recovery/WakaruReport.js +12 -7
  392. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  393. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  394. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  395. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  396. package/dist/jeb/JebMcpConnection.js +179 -0
  397. package/dist/jeb/JebMcpEndpoint.js +40 -0
  398. package/dist/jeb/JebProvider.js +299 -0
  399. package/dist/mcpDoctor.js +15 -6
  400. package/dist/native/AppleDispatchCoverage.js +25 -12
  401. package/dist/native/AppleDispatchMetadata.js +14 -7
  402. package/dist/native/AppleMachoFixups.js +71 -15
  403. package/dist/native/AppleMachoSelection.js +23 -3
  404. package/dist/native/NativeMacOSProvider.js +91 -16
  405. package/dist/native/NativeMachoInspection.js +11 -7
  406. package/dist/native/NativeUiHelperRuntime.js +6 -1
  407. package/dist/native/NativeUiObservation.js +4 -3
  408. package/dist/native/pe/PeResourceLayout.js +120 -0
  409. package/dist/native/pe/PeResourceParser.js +286 -0
  410. package/dist/native/pe/PeResourcesProvider.js +63 -0
  411. package/dist/process/BoundedFileBytes.js +30 -7
  412. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  413. package/dist/process/OwnedCommand.js +4 -3
  414. package/dist/process/ProcessOwnership.js +104 -112
  415. package/dist/process/ProcessOwnershipObservation.js +96 -39
  416. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  417. package/dist/process/ProcessRunTokenObservations.js +48 -0
  418. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  419. package/dist/process/ProviderProcess.js +4 -3
  420. package/dist/process/capture/FilesystemSnapshot.js +28 -4
  421. package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
  422. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  423. package/dist/process/capture/ProcessHarness.js +194 -26
  424. package/dist/process/capture/ProcessNormalization.js +3 -1
  425. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  426. package/dist/process/capture/TerminalRenderer.js +24 -7
  427. package/dist/reference/ReferenceSourceReader.js +22 -5
  428. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  429. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  430. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  431. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  432. package/dist/server/EvidenceMcpServer.js +36 -1
  433. package/dist/server/admittedToolOperation.js +9 -0
  434. package/dist/server/contractToolHandler.js +21 -0
  435. package/dist/server/createServer.js +97 -25
  436. package/dist/server/registerAdbTools.js +36 -0
  437. package/dist/server/registerAnalysisViewTool.js +4 -9
  438. package/dist/server/registerAndroidTools.js +3 -12
  439. package/dist/server/registerApktoolTools.js +14 -0
  440. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
  441. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  442. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  443. package/dist/server/registerApplicationTools/coverage.js +3 -2
  444. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  445. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  446. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  447. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  448. package/dist/server/registerArtifactComparisonTool.js +5 -2
  449. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  450. package/dist/server/registerBrowserScenarioTool.js +10 -7
  451. package/dist/server/registerBrowserTools.js +12 -9
  452. package/dist/server/registerBundleComparisonTool.js +16 -2
  453. package/dist/server/registerCloseLifecycleTool.js +32 -3
  454. package/dist/server/registerElectronTools.js +28 -10
  455. package/dist/server/registerEvmTools.js +4 -9
  456. package/dist/server/registerFirmwareTools.js +3 -11
  457. package/dist/server/registerFunctionComparisonTool.js +5 -2
  458. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  459. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  460. package/dist/server/registerJebTools.js +16 -0
  461. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  462. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  463. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  464. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  465. package/dist/server/registerPeResourcesTool.js +9 -0
  466. package/dist/server/registerProcessComparisonTool.js +5 -2
  467. package/dist/server/registerRecordedCrashTools.js +4 -9
  468. package/dist/server/registerSessionRecordTools.js +2 -1
  469. package/dist/server/registerSessionTools.js +49 -18
  470. package/dist/server/registerWebModuleTool.js +4 -9
  471. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  472. package/dist/server/registerWebRuntimeTools.js +6 -5
  473. package/dist/server/registerWebScriptTool.js +6 -3
  474. package/dist/server/registerWebSourceLocationTool.js +4 -9
  475. package/dist/server/toolResult.js +21 -2
  476. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  477. package/install.sh +7 -4
  478. package/licenses/nativeaot-parser-MIT.txt +28 -0
  479. package/native/windows/build/manifest.json +2 -2
  480. package/native/windows/build/rea-windows-x64.node +0 -0
  481. package/package.json +33 -5
  482. package/scripts/rea.mjs +16 -1
  483. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  484. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  485. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  486. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  487. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
@@ -1,9 +1,17 @@
1
- import { inflateSync } from "node:zlib";
1
+ import { constants as zlibConstants, crc32, inflateSync } from "node:zlib";
2
+ import { AnalysisResourceConstraintError, AnalysisUnsupportedTargetError, } from "../domain/analysisErrorCore.js";
2
3
  import { decodeCanonicalBase64 } from "../domain/webScreenshot.js";
4
+ /** Conservative allowance for the simultaneously live PNG comparison buffers. */
5
+ const PNG_COMPARISON_WORKING_MEMORY_BYTES = 256 * 1024 * 1024;
6
+ const PNG_INFLATE_CHUNK_BYTES = zlibConstants.Z_DEFAULT_CHUNK;
3
7
  /** Compare two validated screenshots using deterministic RGBA metrics. */
4
8
  export const comparePngScreenshots = (input) => {
5
- const before = decodePng(input.before);
6
- const after = decodePng(input.after);
9
+ admitEncodedInputPair(input.before, input.after);
10
+ const beforePlan = parsePng(input.before, "before");
11
+ const afterPlan = parsePng(input.after, "after");
12
+ admitPngPair(beforePlan, afterPlan);
13
+ const before = decodePng(beforePlan);
14
+ const after = decodePng(afterPlan);
7
15
  if (before.width !== after.width || before.height !== after.height)
8
16
  return {
9
17
  status: "dimension_mismatch",
@@ -57,7 +65,7 @@ export const comparePngScreenshots = (input) => {
57
65
  changed_ratio: changedPixels / pixels,
58
66
  };
59
67
  };
60
- const decodePng = (artifact) => {
68
+ const parsePng = (artifact, field) => {
61
69
  const bytes = decodeCanonicalBase64(artifact.data_base64);
62
70
  if (bytes === undefined || !bytes.subarray(0, 8).equals(PNG_SIGNATURE))
63
71
  throw new TypeError("Invalid PNG signature");
@@ -65,68 +73,229 @@ const decodePng = (artifact) => {
65
73
  let header;
66
74
  const compressed = [];
67
75
  let sawEnd = false;
76
+ let sawPalette = false;
77
+ let imageDataEnded = false;
78
+ let paletteEntries = 0;
68
79
  let transparentColor;
80
+ let sawTransparency = false;
81
+ let unsupportedReason;
69
82
  while (offset < bytes.length) {
70
83
  if (offset + 12 > bytes.length)
71
84
  throw new TypeError("Truncated PNG chunk");
72
85
  const length = bytes.readUInt32BE(offset);
73
- const type = bytes.subarray(offset + 4, offset + 8).toString("ascii");
86
+ if (length > 0x7fffffff)
87
+ throw new TypeError("Invalid PNG chunk length");
88
+ const type = bytes.subarray(offset + 4, offset + 8).toString("latin1");
74
89
  const dataStart = offset + 8;
75
90
  const dataEnd = dataStart + length;
76
91
  if (dataEnd + 4 > bytes.length)
77
92
  throw new TypeError("Truncated PNG data");
78
93
  const data = bytes.subarray(dataStart, dataEnd);
79
- if (type === "IHDR")
94
+ if (crc32(bytes.subarray(offset + 4, dataEnd)) !== bytes.readUInt32BE(dataEnd))
95
+ throw new TypeError("Invalid PNG chunk checksum");
96
+ if (!/^[A-Za-z]{4}$/u.test(type) || type[2] !== type[2]?.toUpperCase())
97
+ throw new TypeError("Invalid PNG chunk type");
98
+ if (type !== "IDAT" && compressed.length > 0)
99
+ imageDataEnded = true;
100
+ if (type === "IHDR") {
101
+ if (offset !== 8 || header !== undefined)
102
+ throw new TypeError("Invalid PNG header order");
80
103
  header = parseHeader(data);
104
+ }
105
+ else if (header === undefined)
106
+ throw new TypeError("Invalid PNG header order");
81
107
  else if (type === "tRNS") {
82
- if (header?.channels !== 3 || data.length !== 6)
108
+ if (sawTransparency || compressed.length > 0)
109
+ throw new TypeError("Invalid PNG transparency order");
110
+ sawTransparency = true;
111
+ if (header.colorType === 2 && data.length === 6) {
112
+ transparentColor = [
113
+ data.readUInt16BE(0),
114
+ data.readUInt16BE(2),
115
+ data.readUInt16BE(4),
116
+ ];
117
+ }
118
+ else if ((header.colorType === 0 && data.length === 2) ||
119
+ (header.colorType === 3 &&
120
+ sawPalette &&
121
+ data.length > 0 &&
122
+ data.length <= paletteEntries)) {
123
+ unsupportedReason ??=
124
+ "PNG transparency for this color type is not supported.";
125
+ }
126
+ else {
83
127
  throw new TypeError("Unsupported PNG transparency");
84
- transparentColor = [
85
- data.readUInt16BE(0),
86
- data.readUInt16BE(2),
87
- data.readUInt16BE(4),
88
- ];
128
+ }
129
+ }
130
+ else if (type === "PLTE") {
131
+ if (sawPalette ||
132
+ sawTransparency ||
133
+ compressed.length > 0 ||
134
+ length === 0 ||
135
+ length > 768 ||
136
+ length % 3 !== 0 ||
137
+ (header.colorType === 3 && length / 3 > 2 ** header.bitDepth) ||
138
+ (header.colorType !== 2 &&
139
+ header.colorType !== 3 &&
140
+ header.colorType !== 6))
141
+ throw new TypeError("Invalid PNG palette");
142
+ sawPalette = true;
143
+ paletteEntries = length / 3;
89
144
  }
90
- else if (type === "IDAT")
145
+ else if (type === "IDAT") {
146
+ if (imageDataEnded)
147
+ throw new TypeError("Nonconsecutive PNG image data");
91
148
  compressed.push(data);
149
+ }
92
150
  else if (type === "IEND") {
151
+ if (length !== 0 || dataEnd + 4 !== bytes.length)
152
+ throw new TypeError("Invalid PNG end chunk");
93
153
  sawEnd = true;
94
154
  break;
95
155
  }
156
+ else if (/^[A-Z]/u.test(type)) {
157
+ unsupportedReason ??= `Unsupported critical PNG chunk ${type}.`;
158
+ }
96
159
  offset = dataEnd + 4;
97
160
  }
98
161
  if (header === undefined || !sawEnd || compressed.length === 0)
99
162
  throw new TypeError("Incomplete PNG");
100
- const rowBytes = header.width * header.channels;
101
- const expected = (rowBytes + 1) * header.height;
102
- const raw = inflateSync(Buffer.concat(compressed), {
103
- maxOutputLength: expected + 1,
104
- });
105
- if (raw.byteLength !== expected)
106
- throw new TypeError("Unexpected PNG size");
163
+ if (header.colorType === 3 && !sawPalette)
164
+ throw new TypeError("Missing PNG palette");
165
+ if (unsupportedReason !== undefined)
166
+ throw new AnalysisUnsupportedTargetError("compare_web_screenshots", field, unsupportedReason);
167
+ if (!header.supported)
168
+ throw new AnalysisUnsupportedTargetError("compare_web_screenshots", field, "PNG encoding is not supported for pixel comparison.");
169
+ const pixels = BigInt(header.width) * BigInt(header.height);
170
+ const expectedRawBytes = (BigInt(header.width) * BigInt(header.channels) + 1n) *
171
+ BigInt(header.height);
107
172
  return {
173
+ bytes,
108
174
  width: header.width,
109
175
  height: header.height,
110
- rgba: expandRgba(unfilter(raw, header.width, header.height, header.channels), header.channels, transparentColor),
176
+ channels: header.channels,
177
+ compressed,
178
+ transparentColor,
179
+ expectedRawBytes,
180
+ unfilteredBytes: pixels * BigInt(header.channels),
181
+ rgbaBytes: pixels * 4n,
182
+ };
183
+ };
184
+ const decodePng = (plan) => {
185
+ const expected = Number(plan.expectedRawBytes);
186
+ const raw = inflatePng(Buffer.concat(plan.compressed), expected + 1);
187
+ if (raw.byteLength !== expected)
188
+ throw new TypeError("Unexpected PNG size");
189
+ return {
190
+ width: plan.width,
191
+ height: plan.height,
192
+ rgba: expandRgba(unfilter(raw, plan.width, plan.height, plan.channels), plan.channels, plan.transparentColor),
111
193
  };
112
194
  };
195
+ const admitEncodedInputPair = (before, after) => {
196
+ const sourceBytes = BigInt(before.bytes) + BigInt(after.bytes);
197
+ if (sourceBytes > BigInt(PNG_COMPARISON_WORKING_MEMORY_BYTES))
198
+ throw pngWorkingMemoryError(sourceBytes, null, null);
199
+ };
200
+ const admitPngPair = (before, after) => {
201
+ // Input buffers remain live for both plans. For each decode, count the
202
+ // concatenated IDAT, rounded zlib output chunks, any concatenated output and
203
+ // unfiltered rows, plus RGB-to-RGBA output. The first completed RGBA image
204
+ // remains live while the second is decoded.
205
+ const inputBytes = BigInt(before.bytes.byteLength + after.bytes.byteLength);
206
+ const estimate = (current, retained) => {
207
+ const compressedBytes = current.compressed.reduce((total, chunk) => total + BigInt(chunk.byteLength), 0n);
208
+ const rgbaExpansion = current.channels === 3 ? current.rgbaBytes : 0n;
209
+ return (inputBytes +
210
+ (retained?.rgbaBytes ?? 0n) +
211
+ compressedBytes +
212
+ inflateBufferAllowance(current.expectedRawBytes) +
213
+ current.unfilteredBytes +
214
+ rgbaExpansion);
215
+ };
216
+ const estimateBytes = [
217
+ estimate(before, undefined),
218
+ estimate(after, before),
219
+ ].reduce((maximum, value) => (value > maximum ? value : maximum), 0n);
220
+ if (estimateBytes > BigInt(PNG_COMPARISON_WORKING_MEMORY_BYTES))
221
+ throw pngWorkingMemoryError(estimateBytes, before, after);
222
+ };
223
+ const inflateBufferAllowance = (expectedRawBytes) => {
224
+ const chunkBytes = BigInt(PNG_INFLATE_CHUNK_BYTES);
225
+ const maximumOutputBytes = expectedRawBytes + 1n;
226
+ const roundUpToChunk = (bytes) => ((bytes + chunkBytes - 1n) / chunkBytes) * chunkBytes;
227
+ // Node checks maxOutputLength after writing a chunk, so a rejected stream can
228
+ // retain one chunk's worth of output past the limit before it throws.
229
+ const rejectedOutputChunks = roundUpToChunk(maximumOutputBytes + chunkBytes - 1n);
230
+ // Sync zlib retains each output chunk while Buffer.concat creates the final
231
+ // result. A full final chunk also allocates the next scratch chunk first.
232
+ const returnedOutputChunks = roundUpToChunk(maximumOutputBytes);
233
+ const scratchChunk = expectedRawBytes % chunkBytes === 0n ||
234
+ maximumOutputBytes % chunkBytes === 0n
235
+ ? chunkBytes
236
+ : 0n;
237
+ const concatenatedOutput = maximumOutputBytes > chunkBytes ? maximumOutputBytes : 0n;
238
+ const returnedOutput = returnedOutputChunks + scratchChunk + concatenatedOutput;
239
+ return rejectedOutputChunks > returnedOutput
240
+ ? rejectedOutputChunks
241
+ : returnedOutput;
242
+ };
243
+ const pngWorkingMemoryError = (estimateBytes, before, after) => new AnalysisResourceConstraintError("compare_web_screenshots", "memory", "Screenshot comparison exceeds REA's 256 MiB estimated working-memory budget.", {
244
+ boundary: "png-screenshot-comparison",
245
+ estimated_working_memory_bytes: estimateBytes.toString(),
246
+ maximum_working_memory_bytes: PNG_COMPARISON_WORKING_MEMORY_BYTES,
247
+ before_dimensions: before === null ? null : { width: before.width, height: before.height },
248
+ after_dimensions: after === null ? null : { width: after.width, height: after.height },
249
+ }, {
250
+ remediationAction: "Compare smaller screenshots or reduce their viewport dimensions before capture.",
251
+ });
252
+ const inflatePng = (compressed, maxOutputLength) => {
253
+ try {
254
+ return inflateSync(compressed, {
255
+ maxOutputLength,
256
+ chunkSize: PNG_INFLATE_CHUNK_BYTES,
257
+ });
258
+ }
259
+ catch (cause) {
260
+ if (cause instanceof Error &&
261
+ "code" in cause &&
262
+ (cause.code === "Z_DATA_ERROR" ||
263
+ cause.code === "Z_BUF_ERROR" ||
264
+ cause.code === "ERR_BUFFER_TOO_LARGE"))
265
+ throw new TypeError("Invalid PNG image data", { cause });
266
+ throw cause;
267
+ }
268
+ };
113
269
  const parseHeader = (data) => {
114
270
  if (data.byteLength !== 13)
115
271
  throw new TypeError("Invalid PNG header");
116
272
  const width = data.readUInt32BE(0);
117
273
  const height = data.readUInt32BE(4);
118
- const bitDepth = data[8];
119
- const colorType = data[9];
274
+ const bitDepth = data[8] ?? 0;
275
+ const colorType = data[9] ?? -1;
276
+ const validDepth = (colorType === 0 && [1, 2, 4, 8, 16].includes(bitDepth)) ||
277
+ (colorType === 2 && [8, 16].includes(bitDepth)) ||
278
+ (colorType === 3 && [1, 2, 4, 8].includes(bitDepth)) ||
279
+ (colorType === 4 && [8, 16].includes(bitDepth)) ||
280
+ (colorType === 6 && [8, 16].includes(bitDepth));
120
281
  if (width === 0 ||
121
282
  height === 0 ||
122
- !Number.isSafeInteger(width * height) ||
123
- bitDepth !== 8 ||
124
- (colorType !== 2 && colorType !== 6) ||
283
+ width > 0x7fffffff ||
284
+ height > 0x7fffffff ||
285
+ !validDepth ||
125
286
  data[10] !== 0 ||
126
287
  data[11] !== 0 ||
127
- data[12] !== 0)
128
- throw new TypeError("Unsupported PNG");
129
- return { width, height, channels: colorType === 6 ? 4 : 3 };
288
+ (data[12] !== 0 && data[12] !== 1))
289
+ throw new TypeError("Invalid PNG header");
290
+ return {
291
+ width,
292
+ height,
293
+ colorType,
294
+ bitDepth,
295
+ interlace: data[12],
296
+ channels: colorType === 6 ? 4 : 3,
297
+ supported: bitDepth === 8 && (colorType === 2 || colorType === 6) && data[12] === 0,
298
+ };
130
299
  };
131
300
  const unfilter = (raw, width, height, channels) => {
132
301
  const rowBytes = width * channels;
@@ -9,7 +9,7 @@ import { webSourceMapsSchema } from "../domain/webBundleAnalysis.js";
9
9
  import { createWebTextArtifact } from "../domain/webContentArtifact.js";
10
10
  import { safeParseJson } from "../domain/safeJson.js";
11
11
  import { jsonParts } from "../domain/jsonSerialization.js";
12
- import { inspectSourceMapValue, SourceMapFormatFailure, } from "../javascript/sourceMaps/SourceMapFormat.js";
12
+ import { inspectSourceMapValue, sourceMapJsonText, SourceMapFormatFailure, } from "../javascript/sourceMaps/SourceMapFormat.js";
13
13
  import { WEB_SOURCE_MAP_LIMITS } from "../domain/webSourceLocation.js";
14
14
  // Source maps are normally fetched as a small part of a larger inspection.
15
15
  // Bound a stalled server to 30 seconds and bound raw map input retained for
@@ -235,7 +235,7 @@ const readBoundedText = async (response, budget, maxBytes, signal) => {
235
235
  offset += chunk.byteLength;
236
236
  }
237
237
  try {
238
- return new TextDecoder("utf-8", { fatal: true }).decode(joined);
238
+ return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(joined);
239
239
  }
240
240
  catch {
241
241
  throw new SourceMapEncodingError();
@@ -314,7 +314,7 @@ const promiseWithAbort = (promise, signal) => {
314
314
  });
315
315
  };
316
316
  const normalizeSourceMap = (request, text, fetchedUrl, context) => {
317
- const parsedJson = safeParseJson(text);
317
+ const parsedJson = safeParseJson(sourceMapJsonText(text));
318
318
  if (!parsedJson.ok)
319
319
  return emptySourceMapItem(request, "invalid", "Source-map JSON is not a version 3 map.");
320
320
  const retainedBytesBeforeMap = context.budget.expandedBytes;
@@ -17,6 +17,7 @@ export class LocalWebScriptArtifacts {
17
17
  async load(input, options) {
18
18
  let field = ["manifest_path"];
19
19
  let targetPath = input.manifest_path;
20
+ let callerSelected = true;
20
21
  try {
21
22
  const manifestBytes = await readWebArtifactJson(input.manifest_path, 32 * 1024 * 1024, options?.signal);
22
23
  const manifest = webScriptExportManifestSchema.parse(manifestBytes.value);
@@ -34,6 +35,7 @@ export class LocalWebScriptArtifacts {
34
35
  const root = resolve(dirname(input.manifest_path));
35
36
  const sourcePath = join(root, "files", portable);
36
37
  targetPath = sourcePath;
38
+ callerSelected = false;
37
39
  await assertContained(root, sourcePath);
38
40
  const sourceBytes = await readStableArtifact(sourcePath, 16 * 1024 * 1024, options?.signal);
39
41
  await assertContained(root, sourcePath);
@@ -62,7 +64,7 @@ export class LocalWebScriptArtifacts {
62
64
  });
63
65
  }
64
66
  catch (cause) {
65
- return err(webArtifactReadError(cause, { operation: this.operation, field, targetPath }, options?.signal));
67
+ return err(webArtifactReadError(cause, { operation: this.operation, field, targetPath, callerSelected }, options?.signal));
66
68
  }
67
69
  }
68
70
  }
@@ -1,24 +1,34 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { join } from "node:path";
3
3
  import { Readable } from "node:stream";
4
+ import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
5
+ import { ArtifactResourceScope } from "../../artifacts/ArtifactResourceScope.js";
6
+ import { DESTINATION_CASE_COLLISION_PREFIX } from "../../artifacts/ArtifactPaths.js";
4
7
  import { SafeOutputTree } from "../../artifacts/SafeOutputTree.js";
8
+ import { SafeOutputTreeCreationFailure } from "../../artifacts/SafeOutputTreeCreationFailure.js";
5
9
  import { webScriptExportManifestSchema, webScriptExportResultSchema, } from "../../domain/webScriptExport.js";
6
- import { planWebScriptExport } from "../../domain/webScriptExportPlan.js";
10
+ import { planWebScriptExport, } from "../../domain/webScriptExportPlan.js";
7
11
  import { WebScriptExportError } from "../../domain/webScriptExportError.js";
8
12
  const LIMITATIONS = [
9
13
  "Only script bytes retained in this capture are exported. Sources are not refetched or executed, and a response or Debugger source does not prove execution.",
10
- "Ordinary unambiguous URL paths preserve relative module layouts by origin. Query variants, collisions, inline sources, and unrepresentable paths are isolated; their browser module relationships remain unknown.",
14
+ "Ordinary unambiguous URL paths preserve relative module layouts by origin, including case-distinct spellings. Query variants, exact path collisions, file/directory prefixes, inline sources, and unrepresentable paths are isolated. A case-distinct pair is isolated only when the destination filesystem cannot store both spellings; the record names that pair. Browser module relationships of isolated paths remain unknown.",
11
15
  "Local JavaScript analysis does not implement browser import maps, root-relative URL resolution, remote URL loading, or browser runtime behavior. It may strip import queries and fragments; isolated variants are not canonical targets.",
12
16
  "Source-map declarations are retained as metadata. No source maps or missing dependencies are fetched or reconstructed.",
13
17
  "Captured response bytes are browser-decoded bytes; Debugger sources are the exposed text encoded as UTF-8. Redacted bytes are exported exactly as retained, and may no longer parse as JavaScript.",
14
18
  ];
15
19
  /** Exclusively publish verified bytes and a manifest, rolling back partial work. */
16
- export const publishWebScripts = async (input, capture, captureSha256, signal) => {
20
+ export const publishWebScripts = async (input, capture, captureSha256, options) => options.resources.run(async () => {
17
21
  const planned = planWebScriptExport(capture.scripts);
18
- const tree = await SafeOutputTree.create(input.output_directory);
22
+ let tree;
23
+ let result;
19
24
  try {
20
- signal?.throwIfAborted();
21
- const records = planned.map(({ record }) => record);
25
+ tree = await SafeOutputTree.create(input.output_directory);
26
+ options.signal?.throwIfAborted();
27
+ const records = [];
28
+ for (const [index, item] of planned.entries()) {
29
+ options.signal?.throwIfAborted();
30
+ records.push(await publishPlannedScript(tree, item, index, options.signal));
31
+ }
22
32
  const manifest = webScriptExportManifestSchema.parse({
23
33
  capture_path: input.capture_path,
24
34
  capture_sha256: captureSha256,
@@ -42,7 +52,7 @@ export const publishWebScripts = async (input, capture, captureSha256, signal) =
42
52
  });
43
53
  const bytes = Buffer.from(`${JSON.stringify(manifest, null, 2)}\n`);
44
54
  const digest = createHash("sha256").update(bytes).digest("hex");
45
- const result = webScriptExportResultSchema.parse({
55
+ result = webScriptExportResultSchema.parse({
46
56
  ...manifest,
47
57
  manifest: {
48
58
  path: join(tree.outputRoot, "manifest.json"),
@@ -50,25 +60,70 @@ export const publishWebScripts = async (input, capture, captureSha256, signal) =
50
60
  bytes: bytes.length,
51
61
  },
52
62
  });
53
- for (const { script, record } of planned) {
54
- signal?.throwIfAborted();
55
- if (script.content.state === "captured" &&
56
- record.content.state === "exported")
57
- await tree.write(`files/${record.content.relative_path}`, Readable.from([script.content.bytes]), script.content.sha256, signal);
58
- }
59
- await tree.write("manifest.json", Readable.from([bytes]), digest, signal);
60
- signal?.throwIfAborted();
63
+ await tree.write("manifest.json", Readable.from([bytes]), { sha256: digest, bytes: bytes.byteLength }, options.signal);
64
+ options.signal?.throwIfAborted();
61
65
  await tree.commit();
62
66
  return result;
63
67
  }
64
68
  catch (cause) {
65
- try {
66
- await tree.rollback();
67
- }
68
- catch (cleanupCause) {
69
- throw new WebScriptExportError("io", tree.outputRoot, `Publication failed (${message(cause)}); rollback failed (${message(cleanupCause)}). Remove the residual output directory before retrying.`, [tree.outputRoot]);
69
+ if (cause instanceof SafeOutputTreeCreationFailure)
70
+ tree = cause.tree;
71
+ if (tree !== undefined) {
72
+ const cleanup = await options.resources.release({
73
+ kind: "output-tree",
74
+ resource: tree.outputRoot,
75
+ tree,
76
+ });
77
+ if (cleanup.kind === "failed") {
78
+ const cleanupCause = cleanup.cause;
79
+ const diagnostic = tree.published
80
+ ? `Publication completed, but descriptor cleanup failed (${message(cleanupCause)}). The published output remains available.`
81
+ : `Publication failed (${message(cause)}); rollback failed (${message(cleanupCause)}). Remove the residual output directory before retrying.`;
82
+ const error = new WebScriptExportError(cause instanceof ArtifactReaderFailure ? cause.reason : "io", tree.outputRoot, diagnostic, { residualPaths: [tree.outputRoot] });
83
+ if (tree.published && result !== undefined)
84
+ error.retainPartialObservation({
85
+ kind: "web-script-export",
86
+ result,
87
+ });
88
+ throw error;
89
+ }
90
+ if (tree.published && result !== undefined)
91
+ return result;
70
92
  }
71
93
  throw cause;
72
94
  }
95
+ });
96
+ const publishPlannedScript = async (tree, item, index, signal) => {
97
+ const { script, record } = item;
98
+ const content = script.content;
99
+ if (content.state !== "captured" || record.content.state !== "exported")
100
+ return record;
101
+ const write = (relativePath) => tree.write(`files/${relativePath}`, Readable.from([content.bytes]), { sha256: content.sha256, bytes: content.bytes.byteLength }, signal);
102
+ try {
103
+ await write(record.content.relative_path);
104
+ return record;
105
+ }
106
+ catch (cause) {
107
+ const collision = destinationCollisionReason(cause);
108
+ if (collision === undefined || record.content.layout !== "url-path")
109
+ throw cause;
110
+ const relativePath = isolatedScriptPath(script, index);
111
+ await write(relativePath);
112
+ return {
113
+ ...record,
114
+ content: {
115
+ ...record.content,
116
+ relative_path: relativePath,
117
+ layout: "isolated",
118
+ layout_reason: collision,
119
+ },
120
+ };
121
+ }
73
122
  };
123
+ const isolatedScriptPath = (script, index) => `isolated/source-${index + 1}-${createHash("sha256").update(JSON.stringify(script.source)).digest("hex")}.js`;
124
+ const destinationCollisionReason = (cause) => cause instanceof ArtifactReaderFailure &&
125
+ cause.reason === "path" &&
126
+ cause.message.startsWith(DESTINATION_CASE_COLLISION_PREFIX)
127
+ ? cause.message
128
+ : undefined;
74
129
  const message = (cause) => cause instanceof Error ? cause.message : "Unknown publication failure";
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
3
3
  import { readStableArtifact } from "../../artifacts/readStableArtifact.js";
4
- import { AnalysisCancelledError, AnalysisInputError, } from "../../domain/analysisErrorCore.js";
4
+ import { AnalysisAccessDeniedError, AnalysisCancelledError, AnalysisInputError, } from "../../domain/analysisErrorCore.js";
5
5
  import { ArtifactOperationError } from "../../domain/artifactOperationError.js";
6
6
  import { ProviderAdapterError } from "../../domain/providerAdapterError.js";
7
7
  import { safeParseJson } from "../../domain/safeJson.js";
@@ -29,6 +29,11 @@ export const readWebArtifactJson = async (path, maximumBytes, signal) => {
29
29
  export const webArtifactReadError = (cause, context, signal) => {
30
30
  if (signal?.aborted === true)
31
31
  return new AnalysisCancelledError(context.operation);
32
+ const selection = context.callerSelected
33
+ ? selectedFileError(cause, context)
34
+ : undefined;
35
+ if (selection !== undefined)
36
+ return selection;
32
37
  if (cause instanceof ArtifactReaderFailure)
33
38
  return new ArtifactOperationError(context.operation, cause.reason, cause.details, cause.message);
34
39
  if (cause instanceof Error &&
@@ -54,3 +59,20 @@ export const webArtifactReadError = (cause, context, signal) => {
54
59
  },
55
60
  });
56
61
  };
62
+ /**
63
+ * Report a missing, non-regular or unreadable caller-selected file as the
64
+ * caller's selection or a host permission denial, not an artifact fault.
65
+ */
66
+ const selectedFileError = (cause, context) => {
67
+ const selected = (message) => new AnalysisInputError(context.operation, { cause }, [
68
+ { path: context.field, reason: "invalid_value", message },
69
+ ]);
70
+ if (cause instanceof ArtifactReaderFailure)
71
+ return cause.reason === "path" ? selected(cause.message) : undefined;
72
+ const code = cause instanceof Error && "code" in cause ? String(cause.code) : "";
73
+ if (code === "EACCES" || code === "EPERM")
74
+ return new AnalysisAccessDeniedError(context.operation, context.targetPath, code, { cause });
75
+ if (code === "ENOENT" || code === "ENOTDIR")
76
+ return selected(`Selected file could not be read (${code}): ${context.targetPath}`);
77
+ return undefined;
78
+ };
@@ -34,6 +34,7 @@ export class LocalWebSourceLocationArtifacts {
34
34
  operation: "trace_web_source_location",
35
35
  field: ["source_map", "path"],
36
36
  targetPath: input.source_map.path,
37
+ callerSelected: true,
37
38
  }, options?.signal));
38
39
  }
39
40
  }
@@ -69,9 +69,9 @@ export const captureWebExecution = async (input, sources) => {
69
69
  sources.check();
70
70
  const verifiedRequests = requests.result();
71
71
  const verifiedMainScripts = mainScripts.filter((id) => sources.belongsToDocument(id));
72
- const sample = raw === undefined
73
- ? undefined
74
- : normalizePreciseCoverage(raw, sources, retained);
72
+ const sample = parsed?.success === true
73
+ ? normalizePreciseCoverage(parsed.data, sources, retained)
74
+ : undefined;
75
75
  await session.options.progress?.report({
76
76
  phase: "browser_execution",
77
77
  completed: 2,
@@ -1,18 +1,15 @@
1
1
  import { AnalysisOutputError } from "../../domain/analysisErrorCore.js";
2
- import { preciseCoverageSchema } from "./CdpRuntimeProtocol.js";
3
2
  /** Validate source-range bounds against exact retained UTF-16 text without flattening nested counts. */
4
- export const normalizePreciseCoverage = (raw, sources, retained) => {
5
- const parsed = preciseCoverageSchema.safeParse(raw);
6
- if (!parsed.success)
7
- throw new AnalysisOutputError(sources.session.operation, `Malformed precise coverage: ${parsed.error.message}`);
3
+ export const normalizePreciseCoverage = (parsed, sources, retained) => {
4
+ const retainedSources = new Map(retained.map(({ script_id, source }) => [script_id, source]));
8
5
  const scripts = [];
9
6
  let excluded = 0;
10
- for (const script of parsed.data.result) {
7
+ for (const script of parsed.result) {
11
8
  if (!sources.belongsToDocument(script.scriptId)) {
12
9
  excluded += 1;
13
10
  continue;
14
11
  }
15
- const source = retained.find((item) => item.script_id === script.scriptId)?.source;
12
+ const source = retainedSources.get(script.scriptId);
16
13
  scripts.push({
17
14
  script_id: script.scriptId,
18
15
  reported_url: sources.sourceUrl(script.scriptId, script.url),
@@ -35,7 +32,7 @@ export const normalizePreciseCoverage = (raw, sources, retained) => {
35
32
  });
36
33
  }
37
34
  return {
38
- timestamp: parsed.data.timestamp,
35
+ timestamp: parsed.timestamp,
39
36
  coverage: {
40
37
  state: "captured",
41
38
  reason: null,
@@ -1,4 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { TextDecoder } from "node:util";
2
3
  import { isSafeNumber, LosslessNumber } from "lossless-json";
3
4
  import { parseHarJson } from "./HarJson.js";
4
5
  import { WEB_NETWORK_CAPTURE_LIMITS, } from "../../domain/webNetworkCapture.js";
@@ -6,6 +7,19 @@ import { CaptureFormatError } from "./CaptureFormatError.js";
6
7
  import { CaptureRedaction, captureObject, capturePointer, } from "./CaptureRedaction.js";
7
8
  import { createHarValidator } from "./HarSchema.js";
8
9
  import { HAR_CAPTURE_PROVIDER_IDENTITY } from "./CaptureRelease.js";
10
+ /**
11
+ * Decode retained HAR bytes as UTF-8. HAR 1.2 lets writers emit a byte-order
12
+ * mark and requires readers to ignore it, so one leading BOM is skipped.
13
+ */
14
+ export const decodeHarText = (bytes) => {
15
+ try {
16
+ // ignoreBOM: false (the default) is what skips the mark; true keeps it.
17
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
18
+ }
19
+ catch {
20
+ throw new CaptureFormatError("format", "HAR is not valid UTF-8 JSON.");
21
+ }
22
+ };
9
23
  /** Decode a retained HAR with exact numeric lexemes and unchanged upstream schema validation. */
10
24
  export const decodeHarCapture = (text, sensitiveValues) => {
11
25
  const raw = parseHarJson(text);
@@ -1,10 +1,9 @@
1
1
  import { readFile, writeFile } from "node:fs/promises";
2
- import { TextDecoder } from "node:util";
3
2
  import { z } from "zod";
4
3
  import { readStableArtifact } from "../../artifacts/readStableArtifact.js";
5
4
  import { WEB_NETWORK_CAPTURE_LIMITS } from "../../domain/webNetworkCapture.js";
6
5
  import { CaptureFormatError } from "./CaptureFormatError.js";
7
- import { decodeHarCapture } from "./HarCapture.js";
6
+ import { decodeHarCapture, decodeHarText } from "./HarCapture.js";
8
7
  const requestSchema = z.strictObject({
9
8
  snapshot_path: z.string(),
10
9
  reply_path: z.string(),
@@ -16,16 +15,9 @@ const main = async () => {
16
15
  let reply;
17
16
  try {
18
17
  const snapshot = await readStableArtifact(request.snapshot_path, WEB_NETWORK_CAPTURE_LIMITS.inputBytes);
19
- let text;
20
- try {
21
- text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(snapshot.bytes);
22
- }
23
- catch {
24
- throw new CaptureFormatError("format", "HAR is not valid UTF-8 JSON.");
25
- }
26
18
  reply = {
27
19
  ok: true,
28
- value: decodeHarCapture(text, request.sensitive_values),
20
+ value: decodeHarCapture(decodeHarText(snapshot.bytes), request.sensitive_values),
29
21
  };
30
22
  }
31
23
  catch (cause) {
@@ -1,4 +1,4 @@
1
- import { access } from "node:fs/promises";
1
+ import { access, stat } from "node:fs/promises";
2
2
  import { constants } from "node:fs";
3
3
  import { isAbsolute } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
@@ -22,6 +22,8 @@ export class MitmproxyCaptureAdapter {
22
22
  throw new AnalysisCapabilityUnavailableError("mitmproxy", OPERATION, MITMDUMP_REQUIREMENT, { userMessage: MITMDUMP_REQUIREMENT });
23
23
  try {
24
24
  await access(command, constants.R_OK | constants.X_OK);
25
+ if (!(await stat(command)).isFile())
26
+ throw new TypeError("Configured path is not a regular file");
25
27
  }
26
28
  catch (cause) {
27
29
  const reason = `Configured mitmdump executable is unavailable: ${command}.`;
@@ -34,6 +34,7 @@ export class LocalWebModuleArtifacts {
34
34
  operation: "trace_web_module_imports",
35
35
  field: ["import_map", "path"],
36
36
  targetPath: selected.path,
37
+ callerSelected: true,
37
38
  }, options?.signal));
38
39
  }
39
40
  }