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,5 +1,6 @@
1
1
  import { constants } from "node:fs";
2
2
  import { open } from "node:fs/promises";
3
+ import { OwnedFileHandle } from "./OwnedFileHandle.js";
3
4
  /** Identifies a selected path that cannot be read as one regular file. */
4
5
  export class NonRegularFileReadError extends Error {
5
6
  path;
@@ -11,6 +12,31 @@ export class NonRegularFileReadError extends Error {
11
12
  this.code = directory ? "EISDIR" : "ENOTFILE";
12
13
  }
13
14
  }
15
+ /** Admission failed and the opened descriptor could not be confirmed closed. */
16
+ export class RegularFileAdmissionFailure extends Error {
17
+ path;
18
+ cleanupCause;
19
+ owner;
20
+ cause;
21
+ constructor(path, admissionCause, cleanupCause, owner) {
22
+ super(`Selected input failed admission and its descriptor close failed: ${path}`);
23
+ this.path = path;
24
+ this.cleanupCause = cleanupCause;
25
+ this.owner = owner;
26
+ this.name = "RegularFileAdmissionFailure";
27
+ this.cause = admissionCause;
28
+ }
29
+ }
30
+ /** A regular input no longer matches the extent or identity admitted for reading. */
31
+ export class RegularFileChangedError extends Error {
32
+ path;
33
+ code = "ESTALE";
34
+ constructor(path) {
35
+ super(`Selected input changed while being read: ${path}`);
36
+ this.path = path;
37
+ this.name = "RegularFileChangedError";
38
+ }
39
+ }
14
40
  /** Open and verify the selected file descriptor without blocking on pipes. */
15
41
  export const openRegularFile = async (path, options) => {
16
42
  options.signal?.throwIfAborted();
@@ -18,6 +44,7 @@ export const openRegularFile = async (path, options) => {
18
44
  (constants.O_NONBLOCK ?? 0) |
19
45
  (constants.O_NOCTTY ?? 0) |
20
46
  (options.symlinks === "reject" ? (constants.O_NOFOLLOW ?? 0) : 0));
47
+ const owner = new OwnedFileHandle(handle);
21
48
  try {
22
49
  options.signal?.throwIfAborted();
23
50
  const metadata = await handle.stat();
@@ -27,7 +54,12 @@ export const openRegularFile = async (path, options) => {
27
54
  return handle;
28
55
  }
29
56
  catch (cause) {
30
- await handle.close().catch(() => undefined);
57
+ try {
58
+ await owner.close();
59
+ }
60
+ catch (cleanupCause) {
61
+ throw new RegularFileAdmissionFailure(path, cause, cleanupCause, owner);
62
+ }
31
63
  throw cause;
32
64
  }
33
65
  };
@@ -0,0 +1,46 @@
1
+ import { createHash } from "node:crypto";
2
+ import { stat } from "node:fs/promises";
3
+ import { openRegularFile, RegularFileChangedError, sameRegularFileState, } from "./RegularFile.js";
4
+ /** Hash one regular file from its admitted descriptor and verify its path state. */
5
+ export const hashStableFile = async (path, signal) => {
6
+ const handle = await openRegularFile(path, {
7
+ symlinks: "follow",
8
+ signal,
9
+ });
10
+ try {
11
+ const initial = await handle.stat();
12
+ if (!Number.isSafeInteger(initial.size) || initial.size < 0)
13
+ throw new RangeError(`Regular file size cannot be represented safely: ${path}`);
14
+ const hash = createHash("sha256");
15
+ const chunk = Buffer.allocUnsafe(64 * 1024);
16
+ let position = 0;
17
+ while (position <= initial.size) {
18
+ signal?.throwIfAborted();
19
+ const length = Math.min(chunk.length, initial.size - position + 1);
20
+ if (length <= 0)
21
+ break;
22
+ const read = await handle.read(chunk, 0, length, position);
23
+ signal?.throwIfAborted();
24
+ if (read.bytesRead === 0)
25
+ break;
26
+ hash.update(chunk.subarray(0, read.bytesRead));
27
+ position += read.bytesRead;
28
+ if (position > initial.size)
29
+ throw new RegularFileChangedError(path);
30
+ }
31
+ signal?.throwIfAborted();
32
+ const [opened, currentPath] = await Promise.all([
33
+ handle.stat(),
34
+ stat(path),
35
+ ]);
36
+ signal?.throwIfAborted();
37
+ if (position !== initial.size ||
38
+ !sameRegularFileState(initial, opened) ||
39
+ !sameRegularFileState(initial, currentPath))
40
+ throw new RegularFileChangedError(path);
41
+ return { sha256: hash.digest("hex"), bytes: position };
42
+ }
43
+ finally {
44
+ await handle.close();
45
+ }
46
+ };
@@ -0,0 +1,26 @@
1
+ import { Readable } from "node:stream";
2
+ /** Stream positional reads while leaving descriptor cleanup to its owner. */
3
+ export const readFileHandleChunks = (handle, options = {}) => {
4
+ const start = options.start ?? 0;
5
+ const end = options.end ?? Infinity;
6
+ if (!Number.isSafeInteger(start) ||
7
+ start < 0 ||
8
+ (end !== Infinity && (!Number.isSafeInteger(end) || end < start)))
9
+ throw new RangeError("Invalid file read range");
10
+ return Readable.from((async function* () {
11
+ let position = start;
12
+ while (position <= end) {
13
+ options.signal?.throwIfAborted();
14
+ const chunk = Buffer.allocUnsafe(Math.min(64 * 1024, end - position + 1));
15
+ const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);
16
+ options.signal?.throwIfAborted();
17
+ if (bytesRead === 0)
18
+ return;
19
+ position += bytesRead;
20
+ yield chunk.subarray(0, bytesRead);
21
+ }
22
+ })(), {
23
+ objectMode: false,
24
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
25
+ });
26
+ };
@@ -76,15 +76,35 @@ export const runFirmwareCommand = async (context) => {
76
76
  NO_COLOR: "1",
77
77
  },
78
78
  });
79
+ let diagnosticTruncated = false;
79
80
  const supervisor = new ProviderProcessSupervisor({
80
81
  ...spawned,
81
82
  ownsProcessLifetime: true,
82
83
  cleanup: spawned.cleanup ?? (() => cleanupOwnedProcessGroup(spawned.ownership)),
84
+ }, {
85
+ maxDiagnosticBytes: FIRMWARE_LIMITS.diagnosticBytes,
86
+ onDiagnostic: (event) => {
87
+ if (event.type === "output" && event.truncated === true)
88
+ diagnosticTruncated = true;
89
+ },
83
90
  });
91
+ const checkDiagnostics = () => {
92
+ if (diagnosticTruncated) {
93
+ const snapshot = supervisor.snapshot();
94
+ throw new AnalysisOutputError(operation, `Tool diagnostics exceeded the ${FIRMWARE_LIMITS.diagnosticBytes}-byte capture budget`, {
95
+ capturedOutput: {
96
+ stdout: snapshot.stdout.text,
97
+ stderr: snapshot.stderr.text,
98
+ truncated: true,
99
+ },
100
+ });
101
+ }
102
+ };
84
103
  let failure;
85
104
  try {
86
105
  const deadline = Date.now() + FIRMWARE_LIMITS.timeoutMs;
87
- while (!(await supervisor.waitForExit(100))) {
106
+ while (!(await supervisor.waitForOutputClose(100))) {
107
+ checkDiagnostics();
88
108
  if (signal.aborted)
89
109
  throw new AnalysisCancelledError(operation);
90
110
  if (Date.now() >= deadline)
@@ -92,6 +112,7 @@ export const runFirmwareCommand = async (context) => {
92
112
  if (context.outputBudget !== undefined)
93
113
  await inventoryFirmwareOutput(context.outputBudget.root, context.outputBudget.bytes, context.outputBudget.entries, operation, signal);
94
114
  }
115
+ checkDiagnostics();
95
116
  if (signal.aborted)
96
117
  throw new AnalysisCancelledError(operation);
97
118
  }
@@ -100,8 +121,8 @@ export const runFirmwareCommand = async (context) => {
100
121
  }
101
122
  const stopped = await supervisor.stop();
102
123
  const snapshot = supervisor.snapshot();
103
- supervisor.dispose();
104
- if (stopped.status === "incomplete")
124
+ if (stopped.status === "incomplete") {
125
+ context.retainCleanup(supervisor);
105
126
  throw new ProviderCleanupError(engine, [runId, context.cwd], {
106
127
  reason: stopped.reason,
107
128
  leader_pid: spawned.ownership.leaderPid,
@@ -114,6 +135,7 @@ export const runFirmwareCommand = async (context) => {
114
135
  stderr_bytes: snapshot.stderr.bytes,
115
136
  previous_error: failure instanceof Error ? failure.message : null,
116
137
  });
138
+ }
117
139
  if (failure !== undefined)
118
140
  throw failure;
119
141
  if (snapshot.exitCode !== 0 &&
@@ -1,12 +1,16 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { constants, createReadStream, createWriteStream } from "node:fs";
3
- import { chmod, lstat, open, readdir, readlink, realpath, } from "node:fs/promises";
3
+ import { chmod, lstat, opendir, open, readlink, realpath, } from "node:fs/promises";
4
4
  import { isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { Transform } from "node:stream";
6
6
  import { pipeline } from "node:stream/promises";
7
7
  import { AnalysisCancelledError, AnalysisInputError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
8
8
  import { readBoundedFileBytes } from "../process/BoundedFileBytes.js";
9
9
  import { FIRMWARE_LIMITS } from "./FirmwareRelease.js";
10
+ const throwIfFirmwareInventoryCancelled = (signal, operation) => {
11
+ if (signal?.aborted === true)
12
+ throw new AnalysisCancelledError(operation);
13
+ };
10
14
  /** Hash a regular tool or extracted file without retaining its bytes in memory. */
11
15
  export const hashFirmwareFile = async (path, signal) => {
12
16
  const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
@@ -120,8 +124,7 @@ export const inventoryFirmwareOutput = async (root, maxBytes, maxEntries, operat
120
124
  let bytes = 0;
121
125
  let count = 0;
122
126
  while (pending.length > 0) {
123
- if (signal?.aborted === true)
124
- throw new AnalysisCancelledError(operation);
127
+ throwIfFirmwareInventoryCancelled(signal, operation);
125
128
  const directory = pending.pop();
126
129
  if (directory === undefined)
127
130
  break;
@@ -134,15 +137,27 @@ export const inventoryFirmwareOutput = async (root, maxBytes, maxEntries, operat
134
137
  !directoryStat.isDirectory() ||
135
138
  directoryStat.isSymbolicLink())
136
139
  continue;
137
- const names = await readdir(directory).catch((cause) => {
140
+ const handle = await opendir(directory).catch((cause) => {
138
141
  if (cause instanceof Error && "code" in cause && cause.code === "ENOENT")
139
- return [];
142
+ return undefined;
140
143
  throw cause;
141
144
  });
145
+ if (handle === undefined)
146
+ continue;
147
+ const names = [];
148
+ try {
149
+ for await (const entry of handle) {
150
+ throwIfFirmwareInventoryCancelled(signal, operation);
151
+ count++;
152
+ if (count > maxEntries)
153
+ throw new AnalysisOutputError(operation, `Staging entry budget exceeded (${maxEntries})`);
154
+ names.push(entry.name);
155
+ }
156
+ }
157
+ finally {
158
+ await handle.close().catch(() => undefined);
159
+ }
142
160
  for (const name of names.sort()) {
143
- count++;
144
- if (count > maxEntries)
145
- throw new AnalysisOutputError(operation, `Staging entry budget exceeded (${maxEntries})`);
146
161
  const path = join(directory, name);
147
162
  const stat = await lstat(path).catch((cause) => {
148
163
  if (cause instanceof Error &&
@@ -3,9 +3,11 @@ import { z } from "zod";
3
3
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
4
4
  import { firmwareResultSchemas, } from "../domain/firmware/firmwareAnalysis.js";
5
5
  import { AnalysisError } from "../domain/analysisErrorBase.js";
6
+ import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
6
7
  import { AnalysisCancelledError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
7
8
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
8
9
  import { ProviderCleanupError } from "../domain/providerCleanupError.js";
10
+ import { jsonValueSchema } from "../domain/jsonValue.js";
9
11
  import { err, ok } from "../domain/result.js";
10
12
  import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
11
13
  import { publishFirmwareExtraction } from "./FirmwarePublication.js";
@@ -14,6 +16,19 @@ import { admitFirmwareVersion } from "./FirmwareVersion.js";
14
16
  import { firmwareToolUnavailable, resolveFirmwareCommand, runFirmwareCommand, readFirmwareCommandReport, } from "./FirmwareCommand.js";
15
17
  import { inventoryFirmwareOutput, snapshotFirmware } from "./FirmwareFiles.js";
16
18
  import { normalizeBinwalkReport, normalizeUnblobReport, } from "./FirmwareReports.js";
19
+ const combineCleanupFailures = (failures) => {
20
+ if (failures.length < 2)
21
+ return failures[0];
22
+ return new ProviderCleanupError("firmware", failures.flatMap((failure) => [...failure.cleanupResources]), {
23
+ reason: "Multiple owned firmware resources could not be cleaned",
24
+ failures: failures.map((failure) => ({
25
+ engine: failure.providerId,
26
+ operation: failure.operation,
27
+ resources: [...failure.cleanupResources],
28
+ reason: failure.diagnostics?.reason ?? failure.message,
29
+ })),
30
+ }, { operation: "close_firmware", cause: new AggregateError(failures) });
31
+ };
17
32
  const waitForPredecessor = (predecessor, operation, signal) => new Promise((resolve, reject) => {
18
33
  const abort = () => reject(new AnalysisCancelledError(operation));
19
34
  signal?.addEventListener("abort", abort, { once: true });
@@ -35,13 +50,16 @@ export class FirmwareProvider {
35
50
  environment;
36
51
  launcher;
37
52
  #tail = Promise.resolve();
38
- #cleanupFailure;
53
+ #closed = false;
54
+ #pendingCleanup = new Map();
39
55
  constructor(environment = process.env, launcher) {
40
56
  this.environment = environment;
41
57
  this.launcher = launcher;
42
58
  }
43
59
  /** Inspect regions or explicitly extract selected bytes without changing the source. */
44
60
  async execute(request, options) {
61
+ if (this.#closed)
62
+ return err(new AnalysisCancelledError(request.operation));
45
63
  const predecessor = this.#tail;
46
64
  let release = () => { };
47
65
  this.#tail = new Promise((resolve) => {
@@ -58,12 +76,65 @@ export class FirmwareProvider {
58
76
  : new AnalysisCancelledError(request.operation));
59
77
  }
60
78
  try {
79
+ if (this.#closed)
80
+ return err(new AnalysisCancelledError(request.operation));
81
+ const cleanup = await this.#retryCleanup();
82
+ if (cleanup.processUnverified && cleanup.failure !== undefined)
83
+ return err(cleanup.failure);
61
84
  return await this.#execute(request, options);
62
85
  }
63
86
  finally {
64
87
  release();
65
88
  }
66
89
  }
90
+ /** Retry every retained owner, reporting failures without discarding other roots. */
91
+ async close() {
92
+ this.#closed = true;
93
+ await this.#tail;
94
+ const cleanup = await this.#retryCleanup();
95
+ if (cleanup.failure !== undefined)
96
+ throw cleanup.failure;
97
+ }
98
+ async #retryCleanup() {
99
+ const failures = [];
100
+ let processUnverified = false;
101
+ for (const [path, pending] of this.#pendingCleanup) {
102
+ try {
103
+ const stopped = await pending.supervisor?.stop();
104
+ if (stopped?.status === "incomplete") {
105
+ processUnverified = true;
106
+ failures.push(new ProviderCleanupError(pending.engine, [path], { reason: stopped.reason }, { operation: pending.operation }));
107
+ continue;
108
+ }
109
+ delete pending.supervisor;
110
+ }
111
+ catch (cause) {
112
+ processUnverified = true;
113
+ failures.push(new ProviderCleanupError(pending.engine, [path], { reason: cause instanceof Error ? cause.message : String(cause) }, { operation: pending.operation, cause }));
114
+ continue;
115
+ }
116
+ try {
117
+ if (pending.tree !== undefined) {
118
+ await pending.tree.rollback();
119
+ delete pending.tree;
120
+ }
121
+ }
122
+ catch (cause) {
123
+ failures.push(new ProviderCleanupError(pending.engine, [path, pending.tree?.outputRoot ?? path], { reason: cause instanceof Error ? cause.message : String(cause) }, { operation: pending.operation, cause }));
124
+ }
125
+ try {
126
+ await pending.root.close();
127
+ if (pending.tree === undefined)
128
+ this.#pendingCleanup.delete(path);
129
+ }
130
+ catch (cause) {
131
+ // A verified stopped process cannot use this root. Keep ownership for
132
+ // later removal without blocking a new operation's disjoint workspace.
133
+ failures.push(new ProviderCleanupError(pending.engine, [path], { reason: cause instanceof Error ? cause.message : String(cause) }, { operation: pending.operation, cause }));
134
+ }
135
+ }
136
+ return { failure: combineCleanupFailures(failures), processUnverified };
137
+ }
67
138
  async #execute(request, options) {
68
139
  let root;
69
140
  const engineName = request.operation === "inspect_firmware_regions" ? "binwalk" : "unblob";
@@ -73,12 +144,11 @@ export class FirmwareProvider {
73
144
  : AbortSignal.any([options.signal, deadline]);
74
145
  let outcome;
75
146
  try {
76
- if (this.#cleanupFailure !== undefined)
77
- return err(this.#cleanupFailure);
78
147
  if (signal.aborted)
79
148
  throw new AnalysisCancelledError(request.operation);
80
149
  const command = await resolveFirmwareCommand(this.environment, engineName, request.operation);
81
150
  root = await PrivateRuntimeRoot.create({ prefix: "rea-firmware-" });
151
+ const ownedRoot = root;
82
152
  const target = await snapshotFirmware(request, root.path, signal);
83
153
  const run = (args, outputBudget) => runFirmwareCommand({
84
154
  engine: engineName,
@@ -88,6 +158,14 @@ export class FirmwareProvider {
88
158
  cwd: root?.path ?? "",
89
159
  environment: this.environment,
90
160
  signal,
161
+ retainCleanup: (supervisor) => {
162
+ this.#pendingCleanup.set(ownedRoot.path, {
163
+ supervisor,
164
+ root: ownedRoot,
165
+ engine: engineName,
166
+ operation: request.operation,
167
+ });
168
+ },
91
169
  ...(this.launcher === undefined ? {} : { launcher: this.launcher }),
92
170
  ...(outputBudget === undefined
93
171
  ? {}
@@ -186,6 +264,15 @@ export class FirmwareProvider {
186
264
  selection: target.selection,
187
265
  engine,
188
266
  signal,
267
+ retainCleanup: (tree) => {
268
+ const pending = this.#pendingCleanup.get(ownedRoot.path) ?? {
269
+ root: ownedRoot,
270
+ engine: engineName,
271
+ operation: request.operation,
272
+ };
273
+ pending.tree = tree;
274
+ this.#pendingCleanup.set(ownedRoot.path, pending);
275
+ },
189
276
  });
190
277
  raw = { report, execution: processRun, version_execution: versionRun };
191
278
  }
@@ -229,36 +316,73 @@ export class FirmwareProvider {
229
316
  : String(cause),
230
317
  },
231
318
  }));
232
- if (!outcome.ok && outcome.error.cleanupIncomplete) {
233
- this.#cleanupFailure =
234
- root === undefined ||
235
- outcome.error.cleanupResources.includes(root.path)
236
- ? outcome.error
237
- : new ProviderCleanupError(engineName, [...outcome.error.cleanupResources, root.path], outcome.error instanceof ProviderAdapterError
238
- ? (outcome.error.diagnostics ?? {
239
- reason: outcome.error.message,
240
- })
241
- : { reason: outcome.error.message }, { cause: outcome.error });
242
- }
243
319
  }
244
- // Never remove a workspace while process ownership remains uncertain.
245
- if (this.#cleanupFailure !== undefined)
246
- return err(this.#cleanupFailure);
247
- try {
248
- await root?.close();
249
- }
250
- catch (cause) {
251
- this.#cleanupFailure = new ProviderCleanupError(engineName, [
252
- root?.path ?? "unknown",
253
- ...(outcome.ok && request.operation === "extract_firmware"
254
- ? [request.input.output_directory]
255
- : []),
256
- ], {
257
- reason: cause instanceof Error ? cause.message : String(cause),
258
- previous_result: outcome.ok ? outcome.value.result : null,
320
+ const finished = await finishFirmwareWorkspace(root, outcome, engineName, request);
321
+ if (!finished.ok &&
322
+ finished.error.cleanupIncomplete &&
323
+ root !== undefined &&
324
+ !this.#pendingCleanup.has(root.path))
325
+ this.#pendingCleanup.set(root.path, {
326
+ root,
327
+ engine: engineName,
328
+ operation: request.operation,
259
329
  });
260
- return err(this.#cleanupFailure);
261
- }
262
- return outcome;
330
+ return finished;
263
331
  }
264
332
  }
333
+ /** Keep a completed extraction beside cleanup failure, or skip removal when ownership is uncertain. */
334
+ export const finishFirmwareWorkspace = async (root, outcome, engineName, request) => {
335
+ if (!outcome.ok && outcome.error.cleanupIncomplete) {
336
+ if (root === undefined ||
337
+ outcome.error.cleanupResources.includes(root.path))
338
+ return outcome;
339
+ return err(new ProviderCleanupError(engineName, [...outcome.error.cleanupResources, root.path], outcome.error instanceof ProviderAdapterError
340
+ ? (outcome.error.diagnostics ?? { reason: outcome.error.message })
341
+ : { reason: outcome.error.message }, {
342
+ cause: outcome.error,
343
+ operation: request.operation,
344
+ ...(outcome.error.partialObservation === undefined
345
+ ? {}
346
+ : { partialObservation: outcome.error.partialObservation }),
347
+ }));
348
+ }
349
+ try {
350
+ await root?.close();
351
+ }
352
+ catch (cause) {
353
+ const cleanup = new ProviderCleanupError(engineName, [
354
+ root?.path ?? "unknown",
355
+ ...(outcome.ok && request.operation === "extract_firmware"
356
+ ? [request.input.output_directory]
357
+ : []),
358
+ ], { reason: cause instanceof Error ? cause.message : String(cause) }, {
359
+ cause,
360
+ operation: request.operation,
361
+ ...(outcome.ok
362
+ ? {
363
+ partialObservation: completedFirmwareObservation(outcome.value),
364
+ }
365
+ : outcome.error.partialObservation === undefined
366
+ ? {}
367
+ : { partialObservation: outcome.error.partialObservation }),
368
+ });
369
+ return err(outcome.ok
370
+ ? cleanup
371
+ : analysisErrorWithCleanupFailure(outcome.error, cleanup, request.operation));
372
+ }
373
+ return outcome;
374
+ };
375
+ const completedFirmwareObservation = (execution) => ({
376
+ kind: "firmware",
377
+ result: execution.result,
378
+ provenance: jsonValueSchema.parse({
379
+ raw_result: execution.rawResult,
380
+ provider: execution.provider,
381
+ subject: execution.subject,
382
+ locations: execution.locations,
383
+ limitations: execution.limitations,
384
+ ...(execution.analysisProfile === undefined
385
+ ? {}
386
+ : { analysis_profile: execution.analysisProfile }),
387
+ }),
388
+ });
@@ -1,13 +1,16 @@
1
1
  import { createReadStream } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { SafeOutputTree } from "../artifacts/SafeOutputTree.js";
4
+ import { SafeOutputTreeCreationFailure } from "../artifacts/SafeOutputTreeCreationFailure.js";
4
5
  import { AnalysisOutputError } from "../domain/analysisErrorCore.js";
5
6
  import { ProviderCleanupError } from "../domain/providerCleanupError.js";
7
+ import { jsonValueSchema } from "../domain/jsonValue.js";
6
8
  import { firmwareResultSchemas } from "../domain/firmware/firmwareAnalysis.js";
7
9
  import { hashFirmwareFile } from "./FirmwareFiles.js";
8
10
  /** Publish verified regular files, preserving links as metadata and rolling back failed writes. */
9
11
  export const publishFirmwareExtraction = async (context) => {
10
12
  let tree;
13
+ let result;
11
14
  try {
12
15
  const materialized = new Set(context.entries
13
16
  .filter((entry) => entry.kind === "file")
@@ -37,7 +40,7 @@ export const publishFirmwareExtraction = async (context) => {
37
40
  (context.normalized.sizes.has(logicalPath) &&
38
41
  context.normalized.sizes.get(logicalPath) !== entry.size))
39
42
  throw new AnalysisOutputError("extract_firmware", `Extracted bytes disagree with provider report: ${entry.relativePath}`);
40
- await tree.write(entry.relativePath, createReadStream(entry.path), sha256, context.signal);
43
+ await tree.write(entry.relativePath, createReadStream(entry.path), { sha256, bytes: entry.size }, context.signal);
41
44
  files.push({
42
45
  relative_path: entry.relativePath,
43
46
  path: join(tree.outputRoot, entry.relativePath),
@@ -50,7 +53,7 @@ export const publishFirmwareExtraction = async (context) => {
50
53
  original_file_range: null,
51
54
  });
52
55
  }
53
- const result = firmwareResultSchemas.extract_firmware.parse({
56
+ result = firmwareResultSchemas.extract_firmware.parse({
54
57
  engine: context.engine,
55
58
  selection: context.selection,
56
59
  output_directory: tree.outputRoot,
@@ -68,17 +71,35 @@ export const publishFirmwareExtraction = async (context) => {
68
71
  return result;
69
72
  }
70
73
  catch (cause) {
74
+ if (cause instanceof SafeOutputTreeCreationFailure)
75
+ tree = cause.tree;
71
76
  try {
72
77
  await tree?.rollback();
73
78
  }
74
79
  catch (cleanupCause) {
80
+ if (tree !== undefined)
81
+ context.retainCleanup(tree);
82
+ const publishedResult = tree?.published === true && result !== undefined
83
+ ? {
84
+ kind: "firmware",
85
+ result: jsonValueSchema.parse(result),
86
+ }
87
+ : undefined;
75
88
  throw new ProviderCleanupError("unblob", [context.outputDirectory], {
76
89
  reason: cleanupCause instanceof Error
77
90
  ? cleanupCause.message
78
91
  : String(cleanupCause),
79
92
  previous_error: cause instanceof Error ? cause.message : String(cause),
80
- }, { cause: cleanupCause });
93
+ }, {
94
+ cause: cleanupCause,
95
+ operation: "extract_firmware",
96
+ ...(publishedResult === undefined
97
+ ? {}
98
+ : { partialObservation: publishedResult }),
99
+ });
81
100
  }
101
+ if (tree?.published === true && result !== undefined)
102
+ return result;
82
103
  throw cause;
83
104
  }
84
105
  };
@@ -27,6 +27,7 @@ export const UNBLOB_PROVIDER_IDENTITY = {
27
27
  export const FIRMWARE_LIMITS = {
28
28
  inputBytes: 128 * 1024 * 1024,
29
29
  reportBytes: 8 * 1024 * 1024,
30
+ diagnosticBytes: 8 * 1024 * 1024,
30
31
  addressSpaceBytes: 1024 * 1024 * 1024,
31
32
  timeoutMs: 120_000,
32
33
  };
@@ -1,9 +1,9 @@
1
1
  /** Generated from package.json and package-lock.json; do not edit. */
2
2
  export const PACKAGE_METADATA = {
3
3
  name: "rea-agents",
4
- version: "6.3.0", // x-release-please-version
4
+ version: "6.4.0", // x-release-please-version
5
5
  serverSdkVersion: "2.3.1",
6
6
  clientSdkVersion: "2.3.1",
7
7
  coreSdkVersion: "2.3.1",
8
- skillVersion: "34",
8
+ skillVersion: "37",
9
9
  };