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,32 +1,65 @@
1
1
  import { lstat } from "node:fs/promises";
2
+ import { readFileHandleChunks } from "../../filesystem/readFileHandleChunks.js";
3
+ import { OwnedFileHandle } from "../../filesystem/OwnedFileHandle.js";
2
4
  import { ArtifactReaderFailure } from "../ArtifactReader.js";
3
- import { NonRegularFileReadError, openRegularFile, sameRegularFileState, } from "../../filesystem/RegularFile.js";
5
+ import { NonRegularFileReadError, RegularFileAdmissionFailure, openRegularFile, sameRegularFileState, } from "../../filesystem/RegularFile.js";
4
6
  import { abortIfNeeded, hashReadable, } from "../ArtifactHash.js";
5
- /** Hash one stable regular root file from the same descriptor that was checked. */
6
- export const hashStableRootArtifact = async (path, signal) => {
7
- let handle;
7
+ /** Admit a root descriptor without losing ownership when validation cleanup fails. */
8
+ export const openRootArtifact = async (path, resourceScope, signal) => {
8
9
  try {
9
- handle = await openRegularFile(path, {
10
- symlinks: "reject",
11
- signal,
12
- });
10
+ return new OwnedFileHandle(await openRegularFile(path, { symlinks: "reject", signal }));
13
11
  }
14
12
  catch (cause) {
15
- if (cause instanceof NonRegularFileReadError)
16
- throw new ArtifactReaderFailure("format", `Artifact root is not a regular file: ${path}`, { cause });
17
- throw cause;
13
+ const primary = cause instanceof RegularFileAdmissionFailure ? cause.cause : cause;
14
+ const failure = primary instanceof NonRegularFileReadError
15
+ ? new ArtifactReaderFailure("format", `Artifact root is not a regular file: ${path}`, { cause: primary })
16
+ : primary;
17
+ if (cause instanceof RegularFileAdmissionFailure) {
18
+ const resource = `root artifact descriptor for ${path}`;
19
+ const cleanup = await resourceScope.release({
20
+ kind: "file-handle",
21
+ resource,
22
+ handle: cause.owner,
23
+ });
24
+ if (cleanup.kind === "failed")
25
+ throw ArtifactReaderFailure.withCleanup(failure, ArtifactReaderFailure.cleanupObservation(cleanup.cause, resource));
26
+ }
27
+ throw failure;
18
28
  }
29
+ };
30
+ /** Hash one stable regular root file from the same descriptor that was checked. */
31
+ export const hashStableRootArtifact = async (path, resourceScope, signal) => {
32
+ const owner = await openRootArtifact(path, resourceScope, signal);
33
+ const handle = owner.handle;
34
+ let outcome;
19
35
  try {
20
36
  const initial = await handle.stat();
21
- return await hashStableRootArtifactHandle(path, handle, initial, signal);
37
+ outcome = {
38
+ kind: "completed",
39
+ value: await hashStableRootArtifactHandle(path, handle, initial, signal),
40
+ };
22
41
  }
23
- finally {
24
- await handle.close();
42
+ catch (cause) {
43
+ outcome = { kind: "failed", cause };
25
44
  }
45
+ const resource = `root artifact descriptor for ${path}`;
46
+ const cleanup = await resourceScope.release({
47
+ kind: "file-handle",
48
+ resource,
49
+ handle: owner,
50
+ });
51
+ if (cleanup.kind === "failed")
52
+ throw ArtifactReaderFailure.withCleanup(outcome.kind === "failed" ? outcome.cause : cleanup.cause, ArtifactReaderFailure.cleanupObservation(cleanup.cause, resource));
53
+ if (outcome.kind === "failed")
54
+ throw outcome.cause;
55
+ return outcome.value;
26
56
  };
27
57
  /** Hash and revalidate the same open descriptor used for root classification. */
28
58
  export const hashStableRootArtifactHandle = async (path, handle, initial, signal) => {
29
- const digest = await hashReadable(handle.createReadStream({ autoClose: false }), signal);
59
+ const digest = await hashReadable(
60
+ // Read at most the admitted extent plus one byte to detect growth without
61
+ // following an actively appended file indefinitely.
62
+ readFileHandleChunks(handle, { start: 0, end: initial.size }), signal);
30
63
  abortIfNeeded(signal);
31
64
  const [opened, currentPath] = await Promise.all([handle.stat(), lstat(path)]);
32
65
  if (!sameRegularFileState(initial, opened) ||
@@ -3,7 +3,8 @@ import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
3
3
  import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
4
4
  import { NativeDmgArtifactReader } from "../NativeDmgArtifactReader.js";
5
5
  import { ZipArtifactReader } from "../ZipArtifactReader.js";
6
- export const createReader = async (path, format, environment, signal) => {
6
+ import { ZIP_NON_ENTRY_TAIL_LIMITATION } from "../../domain/zipPackageFormat.js";
7
+ export const createReader = (path, format, environment, rootSource) => {
7
8
  switch (format) {
8
9
  case "directory":
9
10
  return new DirectoryArtifactReader(path);
@@ -12,24 +13,31 @@ export const createReader = async (path, format, environment, signal) => {
12
13
  case "apk":
13
14
  case "msix":
14
15
  case "appx":
15
- return new ZipArtifactReader(path, format);
16
+ return new ZipArtifactReader(path, format, undefined, rootSource);
16
17
  case "asar":
17
18
  return new AsarArtifactReader(path);
18
19
  case "mach-o-universal":
19
20
  return process.platform === "darwin"
20
- ? new MachOSliceArtifactReader(path, environment)
21
+ ? new MachOSliceArtifactReader(path, environment, undefined, rootSource)
21
22
  : undefined;
22
23
  case "dmg":
23
24
  if (process.platform !== "darwin")
24
25
  return undefined;
25
- return NativeDmgArtifactReader.create(path, environment, signal);
26
+ return new NativeDmgArtifactReader(path, environment);
26
27
  default:
27
28
  return undefined;
28
29
  }
29
30
  };
30
31
  export const inventoryLimitations = (format, reader) => {
31
32
  if (reader !== undefined)
32
- return [];
33
+ return reader.format === "zip" ||
34
+ reader.format === "ipa" ||
35
+ reader.format === "apk" ||
36
+ reader.format === "msix" ||
37
+ reader.format === "appx"
38
+ ? [ZIP_NON_ENTRY_TAIL_LIMITATION]
39
+ : [];
40
+ // dmg and pkg reach here only after classifyRootFormat matched their bytes.
33
41
  if (format === "dmg" || format === "pkg")
34
42
  return [
35
43
  `${format.toUpperCase()} root hash is observed; child inventory requires a native macOS adapter.`,
@@ -5,23 +5,33 @@ import { ArtifactReaderFailure, } from "../ArtifactReader.js";
5
5
  import { artifactInventoryResultSchema, } from "../../domain/artifactGraph.js";
6
6
  import { createArtifactEdges, createRootNode, indexOccurrencesByPath, materializeDirectoryNodes, rekeyOccurrences, rootOccurrenceFor, } from "./ArtifactGraphConstruction.js";
7
7
  import { artifactContradictionId, artifactGraphDigest, artifactManifestId, } from "../../domain/artifactIdentity.js";
8
- import { classifyAndHashRoot } from "./classify.js";
8
+ import { classifyAndHashRootForInventory } from "./classify.js";
9
9
  import {} from "../ArtifactHash.js";
10
- import { hashStableRootArtifact } from "./hashStableRootArtifact.js";
10
+ import { hashStableRootArtifact, hashStableRootArtifactHandle, } from "./hashStableRootArtifact.js";
11
11
  import { createReader, inventoryLimitations } from "./reader.js";
12
12
  import { scanReader, } from "./scanReader.js";
13
13
  import { STRICT_INTEGRITY_POLICY, } from "./types.js";
14
- export const scanCanonicalArtifactInventory = async (path, options = {}, readerFactory = createReader) => {
14
+ export const scanCanonicalArtifactInventory = async (path, options, readerFactory = createReader) => options.resourceScope.run(() => scanCanonicalArtifactInventoryInScope(path, options, readerFactory));
15
+ export const scanCanonicalArtifactInventoryInScope = async (path, options, readerFactory = createReader) => {
15
16
  const integrity = options.integrity ?? STRICT_INTEGRITY_POLICY;
16
17
  const metadata = await lstat(path);
17
- const { format: rootFormat, digest: rootDigest } = await classifyAndHashRoot(path, metadata.isDirectory(), metadata, options.signal);
18
- const reader = await readerFactory(path, rootFormat, options.environment ?? {}, options.signal);
18
+ const { format: rootFormat, digest: rootDigest, rootSource, } = await classifyAndHashRootForInventory(path, metadata.isDirectory(), metadata, options);
19
+ let reader;
20
+ let readerCreationFailure;
21
+ try {
22
+ reader = readerFactory(path, rootFormat, options.environment ?? {}, rootSource);
23
+ }
24
+ catch (cause) {
25
+ readerCreationFailure = { cause };
26
+ }
19
27
  const ownedReaders = reader === undefined ? [] : [reader];
20
28
  let outcome;
21
29
  try {
30
+ if (readerCreationFailure !== undefined)
31
+ throw readerCreationFailure.cause;
22
32
  if (reader instanceof AsarArtifactReader)
23
33
  await reader.prepareContainer(rootDigest?.sha256, options.signal);
24
- const { nodes, occurrences, pendingContradictions } = await scanReader(reader, ownedReaders, options.signal, integrity);
34
+ const { nodes, occurrences, pendingContradictions, caseCollisionLimitation, } = await scanReader(reader, ownedReaders, options.signal, integrity);
25
35
  outcome = {
26
36
  kind: "completed",
27
37
  snapshot: await buildInventorySnapshot({
@@ -29,38 +39,62 @@ export const scanCanonicalArtifactInventory = async (path, options = {}, readerF
29
39
  metadata,
30
40
  rootFormat,
31
41
  rootDigest,
42
+ rootSource,
43
+ resourceScope: options.resourceScope,
32
44
  reader,
33
45
  signal: options.signal,
34
46
  nodes,
35
47
  occurrences,
36
48
  pendingContradictions,
49
+ caseCollisionLimitation,
37
50
  }),
38
51
  };
39
52
  }
40
53
  catch (cause) {
41
54
  outcome = { kind: "failed", cause };
42
55
  }
43
- let cleanupFailure;
44
- for (const owned of ownedReaders.reverse()) {
45
- try {
46
- await owned.close();
47
- }
48
- catch (cleanupCause) {
49
- const cleanup = ArtifactReaderFailure.cleanupObservation(cleanupCause, `artifact reader for ${path}`);
50
- cleanupFailure = ArtifactReaderFailure.withCleanup(cleanupFailure ??
51
- (outcome.kind === "failed" ? outcome.cause : cleanupCause), cleanup, outcome.kind === "completed"
52
- ? { kind: "artifact-inventory", inventory: outcome.snapshot }
53
- : undefined);
54
- }
55
- }
56
+ const cleanupFailure = await cleanupInventoryOwners({
57
+ path,
58
+ options,
59
+ rootSource,
60
+ ownedReaders,
61
+ outcome,
62
+ });
56
63
  if (cleanupFailure !== undefined)
57
64
  throw cleanupFailure;
58
65
  if (outcome.kind === "failed")
59
66
  throw outcome.cause;
60
67
  return outcome.snapshot;
61
68
  };
69
+ const cleanupInventoryOwners = async ({ path, options, rootSource, ownedReaders, outcome, }) => {
70
+ let cleanupFailure;
71
+ const owners = [...ownedReaders]
72
+ .reverse()
73
+ .map((reader) => ({
74
+ kind: "reader",
75
+ reader,
76
+ resource: `artifact reader for ${path}`,
77
+ }));
78
+ if (rootSource !== undefined)
79
+ owners.push({
80
+ kind: "file-handle",
81
+ handle: rootSource.owner,
82
+ resource: `root artifact descriptor for ${path}`,
83
+ });
84
+ for (const owner of owners) {
85
+ const attempt = await options.resourceScope.release(owner);
86
+ if (attempt.kind === "released")
87
+ continue;
88
+ const primary = cleanupFailure ??
89
+ (outcome.kind === "failed" ? outcome.cause : attempt.cause);
90
+ cleanupFailure = ArtifactReaderFailure.withCleanup(primary, ArtifactReaderFailure.cleanupObservation(attempt.cause, owner.resource), outcome.kind === "completed"
91
+ ? { kind: "artifact-inventory", inventory: outcome.snapshot }
92
+ : undefined);
93
+ }
94
+ return cleanupFailure;
95
+ };
62
96
  const buildInventorySnapshot = async (input) => {
63
- const { path, metadata, rootFormat, rootDigest, reader, signal } = input;
97
+ const { path, metadata, rootFormat, rootDigest, rootSource, reader, signal } = input;
64
98
  materializeDirectoryNodes(input.occurrences, input.nodes);
65
99
  const rootNode = createRootNode({
66
100
  digest: rootDigest,
@@ -91,7 +125,7 @@ const buildInventorySnapshot = async (input) => {
91
125
  ...edge,
92
126
  ordinal,
93
127
  }));
94
- await verifyRootDigest(path, rootDigest, signal);
128
+ await verifyRootDigest(path, rootDigest, rootSource, input.resourceScope, signal);
95
129
  const graphSha256 = artifactGraphDigest({
96
130
  nodes: orderedNodes,
97
131
  occurrences: orderedOccurrences,
@@ -113,7 +147,7 @@ const buildInventorySnapshot = async (input) => {
113
147
  edges: orderedEdges,
114
148
  provenance: reader?.provenance() ?? [],
115
149
  integrity_contradictions: integrityContradictions,
116
- limitations: buildLimitations(rootFormat, reader, integrityContradictions),
150
+ limitations: buildLimitations(rootFormat, reader, integrityContradictions, input.caseCollisionLimitation),
117
151
  };
118
152
  };
119
153
  const buildIntegrityContradictions = (pending, occurrenceByPath, occurrenceById, rootNode) => pending.map((contradiction) => {
@@ -145,10 +179,12 @@ const buildIntegrityContradictions = (pending, occurrenceByPath, occurrenceById,
145
179
  ],
146
180
  };
147
181
  });
148
- const verifyRootDigest = async (path, rootDigest, signal) => {
182
+ const verifyRootDigest = async (path, rootDigest, rootSource, resourceScope, signal) => {
149
183
  if (rootDigest === null)
150
184
  return;
151
- const verified = await hashStableRootArtifact(path, signal);
185
+ const verified = rootSource === undefined
186
+ ? await hashStableRootArtifact(path, resourceScope, signal)
187
+ : await hashStableRootArtifactHandle(path, rootSource.handle, rootSource.initial, signal);
152
188
  if (verified.sha256 !== rootDigest.sha256 ||
153
189
  verified.bytes !== rootDigest.bytes)
154
190
  throw new ArtifactReaderFailure("integrity", "Root artifact changed during inventory");
@@ -166,8 +202,9 @@ const buildManifest = ({ rootNode, rootFormat, graphSha256, orderedNodes, ordere
166
202
  occurrence_count: orderedOccurrences.length,
167
203
  edge_count: orderedEdges.length,
168
204
  });
169
- const buildLimitations = (rootFormat, reader, integrityContradictions) => [
205
+ const buildLimitations = (rootFormat, reader, integrityContradictions, caseCollisionLimitation) => [
170
206
  ...inventoryLimitations(rootFormat, reader),
207
+ ...(caseCollisionLimitation === undefined ? [] : [caseCollisionLimitation]),
171
208
  ...(integrityContradictions.length === 0
172
209
  ? []
173
210
  : [
@@ -1,8 +1,8 @@
1
1
  import { isAbsolute } from "node:path";
2
- import { ArtifactPathRegistry, normalizeArtifactPath, } from "../ArtifactPaths.js";
2
+ import { annotateEnglishUnicodeCaseCollisions, ArtifactPathRegistry, normalizeArtifactPath, } from "../ArtifactPaths.js";
3
3
  import { ArtifactReaderFailure, } from "../ArtifactReader.js";
4
4
  import { AsarArtifactReader } from "../AsarArtifactReader.js";
5
- import { classifyArtifactContent, classifyArtifactBytes, createArtifactNode, createOccurrence, nearestParent, } from "./ArtifactGraphConstruction.js";
5
+ import { classifyArtifactContent, classifyArtifactBytes, createArtifactNode, createOccurrence, noteUnreadContainerSuffix, resolveOccurrenceParents, } from "./ArtifactGraphConstruction.js";
6
6
  import { STRICT_INTEGRITY_POLICY, } from "./types.js";
7
7
  import { hashReadable } from "../ArtifactHash.js";
8
8
  const UNAVAILABLE_UNPACKED_LIMITATION = "ASAR unpacked companion bytes were unavailable; no content hash or child artifact was produced.";
@@ -10,7 +10,12 @@ const emptyScan = () => ({ nodes: new Map(), occurrences: [], pendingContradicti
10
10
  export const scanReader = async (reader, ownedReaders, signal, integrity = STRICT_INTEGRITY_POLICY) => {
11
11
  const { nodes, occurrences, pendingContradictions } = emptyScan();
12
12
  if (reader === undefined)
13
- return { nodes, occurrences, pendingContradictions };
13
+ return {
14
+ nodes,
15
+ occurrences,
16
+ pendingContradictions,
17
+ caseCollisionLimitation: undefined,
18
+ };
14
19
  const context = {
15
20
  reader,
16
21
  signal,
@@ -26,10 +31,13 @@ export const scanReader = async (reader, ownedReaders, signal, integrity = STRIC
26
31
  await visitArtifactEntries(context, reader, "");
27
32
  // Archive directories may appear after their children. Resolve containment
28
33
  // against the complete index before directory identities are materialized.
29
- for (const occurrence of occurrences)
30
- occurrence.parent_occurrence_id =
31
- nearestParent(occurrence.logical_path, context.occurrenceByPath, context.expandedContainerIds)?.occurrence_id ?? null;
32
- return { nodes, occurrences, pendingContradictions };
34
+ resolveOccurrenceParents(occurrences, context.occurrenceByPath, context.expandedContainerIds);
35
+ return {
36
+ nodes,
37
+ occurrences,
38
+ pendingContradictions,
39
+ caseCollisionLimitation: annotateEnglishUnicodeCaseCollisions(occurrences),
40
+ };
33
41
  };
34
42
  const visitArtifactEntries = async (context, currentReader, prefix) => {
35
43
  const stack = [
@@ -39,6 +47,7 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
39
47
  iterator: currentReader.entries(context.signal)[Symbol.asyncIterator](),
40
48
  },
41
49
  ];
50
+ let failure;
42
51
  try {
43
52
  while (stack.length > 0) {
44
53
  const frame = stack.at(-1);
@@ -66,7 +75,9 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
66
75
  occurrence.hash_status = "unavailable";
67
76
  occurrence.limitations.push(UNAVAILABLE_UNPACKED_LIMITATION);
68
77
  }
69
- if (digested !== undefined) {
78
+ if (digested === undefined)
79
+ noteUnreadContainerSuffix(occurrence);
80
+ else {
70
81
  context.nodes.set(digested.node.artifact_id, digested.node);
71
82
  occurrence.artifact_id = digested.node.artifact_id;
72
83
  occurrence.artifact_kind = digested.classification.kind;
@@ -79,7 +90,10 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
79
90
  }
80
91
  context.occurrences.push(occurrence);
81
92
  context.occurrenceByPath.set(logicalPath, occurrence);
82
- if (expandableAsar && digested !== undefined && !digested.mismatched) {
93
+ if (expandableAsar &&
94
+ digested !== undefined &&
95
+ digested.classification.format === "asar" &&
96
+ !digested.mismatched) {
83
97
  const nested = new AsarArtifactReader(entry.adapterKey);
84
98
  context.ownedReaders.push(nested);
85
99
  await nested.prepareContainer(digested.node.sha256, context.signal);
@@ -93,11 +107,24 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
93
107
  }
94
108
  }
95
109
  }
110
+ catch (cause) {
111
+ failure = { cause };
112
+ }
96
113
  finally {
97
114
  // Readers remain owned by the inventory until its complete observation is built.
98
- for (const { iterator } of stack)
99
- await iterator.return?.();
115
+ for (const { iterator, prefix, reader } of stack.reverse()) {
116
+ try {
117
+ await iterator.return?.();
118
+ }
119
+ catch (cause) {
120
+ failure = {
121
+ cause: ArtifactReaderFailure.withCleanup(failure === undefined ? cause : failure.cause, ArtifactReaderFailure.cleanupObservation(cause, `artifact traversal for ${prefix || reader.format}`)),
122
+ };
123
+ }
124
+ }
100
125
  }
126
+ if (failure !== undefined)
127
+ throw failure.cause;
101
128
  };
102
129
  const digestArtifactEntry = async (context, currentReader, entry, logicalPath) => {
103
130
  if ((entry.kind !== "file" && entry.kind !== "slice") || entry.encrypted)
@@ -7,7 +7,7 @@ import { ArtifactReaderFailure, } from "../ArtifactReader.js";
7
7
  import { streamChunkToBuffer } from "../StreamBytes.js";
8
8
  import { hashReadable } from "../ArtifactHash.js";
9
9
  /** Read all relevant textual entries through an already-inventoried reader. */
10
- export const readJavaScriptArtifactFiles = async (reader, snapshot, signal) => {
10
+ export const readJavaScriptArtifactFiles = async (reader, snapshot, resources, signal) => {
11
11
  if (reader instanceof AsarArtifactReader) {
12
12
  const root = snapshot.nodes.find(({ artifact_id }) => artifact_id === snapshot.manifest.root_artifact_id);
13
13
  if (root === undefined)
@@ -17,6 +17,7 @@ export const readJavaScriptArtifactFiles = async (reader, snapshot, signal) => {
17
17
  const inventory = expectedInventory(snapshot);
18
18
  const expected = inventory.files;
19
19
  const context = {
20
+ resources,
20
21
  expected,
21
22
  expectedContainers: inventory.containers,
22
23
  registry: new ArtifactPathRegistry(),
@@ -81,7 +82,7 @@ const visitReader = async (reader, prefix, containerSha256, context) => {
81
82
  await verifyEntryBytes(await frame.reader.open(entry, context.signal), inventory, context.signal);
82
83
  context.containers.push(inventory);
83
84
  const nested = new AsarArtifactReader(entry.adapterKey);
84
- ownedReaders.push(nested);
85
+ ownedReaders.push({ reader: nested, path });
85
86
  stack.push({
86
87
  reader: nested,
87
88
  prefix: path,
@@ -115,21 +116,26 @@ const visitReader = async (reader, prefix, containerSha256, context) => {
115
116
  failure = { cause };
116
117
  }
117
118
  finally {
118
- for (const { iterator } of stack) {
119
+ for (const { iterator, prefix, reader } of stack.reverse()) {
119
120
  try {
120
121
  await iterator.return?.();
121
122
  }
122
123
  catch (cause) {
123
- failure ??= { cause };
124
+ failure = {
125
+ cause: ArtifactReaderFailure.withCleanup(failure === undefined ? cause : failure.cause, ArtifactReaderFailure.cleanupObservation(cause, `JavaScript artifact traversal for ${prefix || reader.format}`)),
126
+ };
124
127
  }
125
128
  }
126
129
  for (const owned of ownedReaders.reverse()) {
127
- try {
128
- await owned.close();
129
- }
130
- catch (cause) {
130
+ const resource = `nested ASAR reader for ${owned.path}`;
131
+ const cleanup = await context.resources.release({
132
+ kind: "reader",
133
+ reader: owned.reader,
134
+ resource,
135
+ });
136
+ if (cleanup.kind === "failed") {
131
137
  failure = {
132
- cause: ArtifactReaderFailure.withCleanup(failure?.cause ?? cause, ArtifactReaderFailure.cleanupObservation(cause, `nested ASAR reader for ${prefix}`)),
138
+ cause: ArtifactReaderFailure.withCleanup(failure === undefined ? cleanup.cause : failure.cause, ArtifactReaderFailure.cleanupObservation(cleanup.cause, resource)),
133
139
  };
134
140
  }
135
141
  }
@@ -0,0 +1,3 @@
1
+ import { JavaScriptAnalysisWorker } from "../../javascript/analysis/JavaScriptAnalysisWorker.js";
2
+ /** Construct the inert artifact analyzer; resources are acquired on the first source. */
3
+ export const createJavaScriptSourceAnalysis = (limits, sourceCount) => new JavaScriptAnalysisWorker(limits, undefined, sourceCount);
@@ -5,13 +5,19 @@ import { BrowserObservationError } from "../domain/browserObservationError.js";
5
5
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
6
6
  import { PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY } from "./providerIdentities.js";
7
7
  const OPERATION = "capture_browser_scenario";
8
- const browserScenarioLimitations = (session) => [
8
+ const browserScenarioLimitations = (session, scenario) => [
9
9
  "Event sequence records provider receipt order; simultaneous browser causality is not inferred.",
10
10
  "Network content is retained only when selected; response bytes are browser-decoded, not compressed wire bytes.",
11
11
  "Request bytes are limited to what Playwright exposes; not_exposed does not establish body absence or multipart file coverage.",
12
12
  "Network content reads settle within 5 seconds each and never wait for unfinished responses or refetch them.",
13
13
  "Playwright scenario events do not expose request initiator stacks; receipt order does not prove causality.",
14
14
  "Storage values are hashed only after declared-secret redaction.",
15
+ ...(scenario.storage.local_storage.length === 0 &&
16
+ scenario.storage.session_storage.length === 0
17
+ ? []
18
+ : [
19
+ "Non-cookie storage seeds use CDP pre-script instrumentation; only pauses in the scenario's private seed script are resumed by this observer.",
20
+ ]),
15
21
  ...(session.eventLimitations?.() ?? []),
16
22
  ...(session.mode === "connect"
17
23
  ? [
@@ -40,7 +46,7 @@ export const browserScenarioCaptureData = (input) => ({
40
46
  steps: [...input.steps],
41
47
  events: input.session.events(),
42
48
  limitations: [
43
- ...browserScenarioLimitations(input.session),
49
+ ...browserScenarioLimitations(input.session, input.scenario),
44
50
  ...(input.limitations ?? []),
45
51
  ],
46
52
  });
@@ -6,6 +6,36 @@ const encodedSecretValues = (secret) => new Set([
6
6
  encodeURIComponent(secret),
7
7
  new URLSearchParams([["value", secret]]).toString().slice("value=".length),
8
8
  ]);
9
+ const secretSpellings = (secret, spellings) => {
10
+ if (secret === "")
11
+ return [];
12
+ if (spellings === "raw")
13
+ return [secret];
14
+ const values = [...encodedSecretValues(secret)];
15
+ if (spellings === "bytes")
16
+ values.push(JSON.stringify(secret).slice(1, -1));
17
+ return [...new Set(values)].filter((value) => value !== "");
18
+ };
19
+ const declaredLiterals = (values, spellings) => [
20
+ ...new Set([...values.values()].flatMap((secret) => secretSpellings(secret, spellings))),
21
+ ];
22
+ /** Pick a marker that does not itself contain a declared secret spelling. */
23
+ const redactionMarker = (id, literals) => [`${REDACTION_PREFIX}${id}]`, "[REDACTED]", "…", ""].find((candidate) => literals.every((literal) => !candidate.includes(literal))) ?? "";
24
+ const replaceSecretLiterals = (value, values, spellings, literals) => {
25
+ const replacements = [...values]
26
+ .flatMap(([id, secret]) => secretSpellings(secret, spellings).map((text) => ({ id, text })))
27
+ .sort((left, right) => right.text.length - left.text.length ||
28
+ (left.id < right.id ? -1 : left.id > right.id ? 1 : 0));
29
+ let output = value;
30
+ for (const replacement of replacements)
31
+ output = output.replaceAll(replacement.text, redactionMarker(replacement.id, literals));
32
+ return output;
33
+ };
34
+ const secretNeedles = (values, literals) => [...values].flatMap(([id, secret]) => secretSpellings(secret, "bytes").map((text) => ({
35
+ id,
36
+ needle: Buffer.from(text),
37
+ marker: Buffer.from(redactionMarker(id, literals)),
38
+ })));
9
39
  /** Resolved secret values kept only for one in-memory scenario session. */
10
40
  export class BrowserScenarioSecrets {
11
41
  values;
@@ -38,35 +68,18 @@ export class BrowserScenarioSecrets {
38
68
  return url.href;
39
69
  }
40
70
  redact(value) {
41
- let output = value;
42
- const replacements = [...this.values].sort(([leftId, left], [rightId, right]) => right.length - left.length ||
43
- (leftId < rightId ? -1 : leftId > rightId ? 1 : 0));
44
- for (const [id, secret] of replacements)
45
- if (secret !== "")
46
- output = output.replaceAll(secret, `${REDACTION_PREFIX}${id}]`);
47
- return output;
71
+ const literals = declaredLiterals(this.values, "raw");
72
+ const output = replaceSecretLiterals(value, this.values, "raw", literals);
73
+ return literals.some((literal) => output.includes(literal)) ? "" : output;
48
74
  }
49
75
  /** Replace declared UTF-8, URI/form, and JSON-escaped secrets without decoding binary data. */
50
76
  redactBytes(value) {
51
- const candidates = [...this.values]
52
- .flatMap(([id, secret]) => {
53
- if (secret === "")
54
- return [];
55
- return [
56
- ...new Set([
57
- ...encodedSecretValues(secret),
58
- JSON.stringify(secret).slice(1, -1),
59
- ]),
60
- ].map((text) => {
61
- const needle = Buffer.from(text);
62
- return {
63
- id,
64
- needle,
65
- marker: Buffer.from(`${REDACTION_PREFIX}${id}]`),
66
- index: value.indexOf(needle),
67
- };
68
- });
69
- })
77
+ const literals = declaredLiterals(this.values, "bytes");
78
+ const candidates = secretNeedles(this.values, literals)
79
+ .map((candidate) => ({
80
+ ...candidate,
81
+ index: value.indexOf(candidate.needle),
82
+ }))
70
83
  .sort((left, right) => right.needle.length - left.needle.length ||
71
84
  (left.id < right.id ? -1 : left.id > right.id ? 1 : 0));
72
85
  const parts = [];
@@ -88,20 +101,22 @@ export class BrowserScenarioSecrets {
88
101
  if (parts.length === 0)
89
102
  return value;
90
103
  parts.push(value.subarray(offset));
91
- return Buffer.concat(parts);
104
+ const redacted = Buffer.concat(parts);
105
+ return literals.some((literal) => redacted.includes(Buffer.from(literal)))
106
+ ? Buffer.alloc(0)
107
+ : redacted;
92
108
  }
93
109
  /** Remove only declared secret values from one URL and report that action. */
94
110
  sanitizeUrl(value) {
95
- let output = value;
96
- const replacements = [...this.values].sort(([leftId, left], [rightId, right]) => right.length - left.length ||
97
- (leftId < rightId ? -1 : leftId > rightId ? 1 : 0));
98
- for (const [id, secret] of replacements) {
99
- if (secret === "")
100
- continue;
101
- const marker = `${REDACTION_PREFIX}${id}]`;
102
- for (const candidate of encodedSecretValues(secret))
103
- output = output.replaceAll(candidate, marker);
104
- }
111
+ const literals = declaredLiterals(this.values, "url");
112
+ const output = replaceSecretLiterals(value, this.values, "url", literals);
113
+ if (literals.some((literal) => output.includes(literal)))
114
+ return {
115
+ url: "",
116
+ origin: null,
117
+ query_parameter_names: [],
118
+ redacted: true,
119
+ };
105
120
  const sanitized = sanitizeBrowserUrl(output);
106
121
  return {
107
122
  ...sanitized,
@@ -7,6 +7,7 @@ import { webMcpDiscoverySchema, } from "../domain/webMcpDiscovery.js";
7
7
  import { browserCaptureComparisonSchema, compareBrowserCaptures, } from "../domain/browserCaptureComparison.js";
8
8
  import { webScreenshotDiffSchema, webScreenshotSchema, } from "../domain/webScreenshot.js";
9
9
  import { AnalysisError } from "../domain/analysisErrorBase.js";
10
+ import { AnalysisInputError } from "../domain/analysisErrorCore.js";
10
11
  import { BrowserObservationError } from "../domain/browserObservationError.js";
11
12
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
12
13
  import {} from "../domain/browserObservationErrors.js";
@@ -173,6 +174,10 @@ export class CdpBrowserProvider {
173
174
  return ok(webScreenshotDiffSchema.parse(comparePngScreenshots(input)));
174
175
  }
175
176
  catch (cause) {
177
+ if (cause instanceof TypeError)
178
+ return err(new AnalysisInputError("compare_web_screenshots", { cause }, [
179
+ { path: [], reason: "invalid_format", message: cause.message },
180
+ ]));
176
181
  return err(providerError(cause, "compare_web_screenshots"));
177
182
  }
178
183
  }