rea-agents 6.1.0 → 6.3.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 (573) hide show
  1. package/README.md +24 -24
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +8 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +64 -36
  7. package/dist/android/JadxSession.js +51 -9
  8. package/dist/application/BinaryTargetResolver.js +68 -20
  9. package/dist/application/BrowserEvidence.js +3 -8
  10. package/dist/application/BrowserScenarioEvidence.js +4 -20
  11. package/dist/application/CapabilityInventory.js +43 -9
  12. package/dist/application/ClientConfigurationDocument.js +97 -25
  13. package/dist/application/ClientRegistrationStatus.js +19 -6
  14. package/dist/application/DirectAnalysis.js +41 -20
  15. package/dist/application/DirectAnalysisCleanup.js +71 -0
  16. package/dist/application/DirectAnalysisStatus.js +3 -7
  17. package/dist/application/Doctor.js +40 -53
  18. package/dist/application/DoctorDiagnostics.js +2 -3
  19. package/dist/application/EnhancedTools.js +51 -6
  20. package/dist/application/EvidenceBundleFiles.js +8 -3
  21. package/dist/application/InvestigationProviders.js +13 -5
  22. package/dist/application/JsonFiles.js +56 -23
  23. package/dist/application/LinuxHopper.js +11 -7
  24. package/dist/application/MacHopper.js +15 -18
  25. package/dist/application/RealHopperAssertions.js +0 -11
  26. package/dist/application/ReconstructionObligationCandidates.js +10 -3
  27. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  28. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  29. package/dist/application/RegularFileRead.js +17 -0
  30. package/dist/application/Setup.js +26 -23
  31. package/dist/application/SetupClientConfiguration.js +18 -7
  32. package/dist/application/SetupHost.js +20 -29
  33. package/dist/application/SetupPlan.js +24 -20
  34. package/dist/application/SetupSkill.js +57 -8
  35. package/dist/application/SupportedClients.js +43 -0
  36. package/dist/application/Uninstall.js +98 -30
  37. package/dist/application/UpdateMaintenance.js +13 -7
  38. package/dist/application/UpdateRuntime.js +12 -12
  39. package/dist/application/Utf8JsonInput.js +64 -0
  40. package/dist/application/WebScriptExportService.js +38 -5
  41. package/dist/application/WorkflowEvidence.js +25 -2
  42. package/dist/application/XrefsAddressResolution.js +45 -0
  43. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  44. package/dist/application/android/AndroidAnalysisService.js +1 -1
  45. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  46. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  47. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  48. package/dist/application/binary/AnalysisSnapshotCache.js +13 -10
  49. package/dist/application/binary/BinarySession.js +86 -29
  50. package/dist/application/binary/BinarySessionComposition.js +1 -3
  51. package/dist/application/binary/BinarySessionExecution.js +3 -5
  52. package/dist/application/binary/BinarySessionOpen.js +10 -2
  53. package/dist/application/binary/BinarySessionRecords.js +1 -1
  54. package/dist/application/binary/BinarySessionStatus.js +1 -6
  55. package/dist/application/binary/CompositeProvider.js +4 -18
  56. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  57. package/dist/application/binary/SessionProviderRouter.js +27 -135
  58. package/dist/application/homebrew.js +48 -0
  59. package/dist/application/javascript/ElectronActiveEvidence.js +10 -14
  60. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  61. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  62. package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
  63. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  64. package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
  65. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  66. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
  67. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
  68. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  69. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  70. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  71. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +46 -29
  72. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  73. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
  74. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
  75. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  76. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  77. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
  78. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  79. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  80. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
  81. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  82. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
  83. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  84. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
  85. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  86. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  87. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
  88. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
  89. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  90. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
  91. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
  92. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  93. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  94. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  95. package/dist/application/native/NativeCallRoutes.js +2 -4
  96. package/dist/application/process/ProcessCli.js +11 -11
  97. package/dist/application/process/ProcessEvidence.js +0 -1
  98. package/dist/artifacts/ArtifactProvider.js +53 -30
  99. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  100. package/dist/artifacts/ArtifactReader.js +31 -0
  101. package/dist/artifacts/AsarArtifactReader.js +81 -17
  102. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  103. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  104. package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
  105. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  106. package/dist/artifacts/SafeOutputTree.js +16 -2
  107. package/dist/artifacts/ZipArtifactReader.js +11 -4
  108. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  109. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  110. package/dist/artifacts/apple/KeyedArchiveReader.js +68 -42
  111. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  112. package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
  113. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
  114. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  115. package/dist/artifacts/inventory/classify.js +33 -14
  116. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  117. package/dist/artifacts/inventory/reader.js +3 -3
  118. package/dist/artifacts/inventory/scanCanonical.js +64 -34
  119. package/dist/artifacts/inventory/scanReader.js +12 -20
  120. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  121. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  122. package/dist/browser/CdpBrowserProvider.js +6 -6
  123. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  124. package/dist/browser/CdpCaptureEvents.js +0 -1
  125. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  126. package/dist/browser/CdpCaptureValues.js +20 -0
  127. package/dist/browser/CdpElectronInspection.js +2 -2
  128. package/dist/browser/CdpElectronProvider.js +4 -5
  129. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  130. package/dist/browser/CdpElectronScripts.js +4 -5
  131. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  132. package/dist/browser/CdpSafeMetadata.js +10 -10
  133. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  134. package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
  135. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  136. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  137. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  138. package/dist/browser/PlaywrightScenarioBrowser.js +269 -66
  139. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  140. package/dist/browser/PlaywrightScenarioSession.js +41 -32
  141. package/dist/browser/WebSourceMapFetcher.js +32 -6
  142. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  143. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  144. package/dist/browser/history/CaptureFailures.js +6 -2
  145. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  146. package/dist/catalogIdentity.js +0 -1
  147. package/dist/cli/analysisViewCommands.js +36 -0
  148. package/dist/cli/artifactCommands.js +11 -12
  149. package/dist/cli/coreAnalysisCommands.js +3 -3
  150. package/dist/cli/coreBinaryCommands.js +37 -28
  151. package/dist/cli/coreNativeCommands.js +9 -10
  152. package/dist/cli/electronCommands.js +12 -13
  153. package/dist/cli/interactiveSetup.js +6 -6
  154. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  155. package/dist/cli/jsonOutput.js +3 -2
  156. package/dist/cli/managedCommands.js +7 -8
  157. package/dist/cli/nativeCallCommands.js +1 -2
  158. package/dist/cli/omittableDefaults.js +50 -0
  159. package/dist/cli/processCommands.js +3 -2
  160. package/dist/cli/setupCommands.js +16 -15
  161. package/dist/cli/streamedJsonOutput.js +83 -4
  162. package/dist/cli/utilityCommands.js +10 -12
  163. package/dist/cli.js +19 -8
  164. package/dist/cliBrowserScenarioCommands.js +2 -2
  165. package/dist/cliCommandNames.js +1 -0
  166. package/dist/cliJsonFile.js +179 -0
  167. package/dist/cliJsonInput.js +60 -33
  168. package/dist/cliObservationOptions.js +4 -0
  169. package/dist/cliOutput.js +0 -38
  170. package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
  171. package/dist/composition/binary.js +9 -9
  172. package/dist/composition/browserScenario.js +2 -1
  173. package/dist/composition/directAnalysis.js +20 -14
  174. package/dist/composition/electronScenario.js +1 -1
  175. package/dist/composition/optionalObservationProviders.js +12 -7
  176. package/dist/config/environment.js +6 -0
  177. package/dist/config/ghidraStartupTimeout.js +4 -9
  178. package/dist/config/homeDirectory.js +12 -0
  179. package/dist/config/mcpResponseBudget.js +9 -1
  180. package/dist/config/parseConfig.js +7 -3
  181. package/dist/config/parsers.js +19 -22
  182. package/dist/contracts/analysisViewToolContracts.js +56 -0
  183. package/dist/contracts/applicationToolContracts.js +5 -4
  184. package/dist/contracts/artifactComparisonExample.js +7 -7
  185. package/dist/contracts/artifactToolContracts.js +1 -1
  186. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  187. package/dist/contracts/browserToolContracts.js +19 -15
  188. package/dist/contracts/enhancedInputs.js +2 -2
  189. package/dist/contracts/enhancedToolContracts.js +4 -3
  190. package/dist/contracts/errorSchemas.js +3 -1
  191. package/dist/contracts/evm/evmToolContracts.js +1 -1
  192. package/dist/contracts/functionComparisonExample.js +8 -0
  193. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  194. package/dist/contracts/inputSchemaPresentation.js +181 -0
  195. package/dist/contracts/investigationExamples.js +4 -3
  196. package/dist/contracts/javascript/electronToolContracts.js +3 -2
  197. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
  198. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
  199. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  200. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  201. package/dist/contracts/managed/managedToolContracts.js +8 -12
  202. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  203. package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
  204. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  205. package/dist/contracts/native/nativeToolContracts.js +2 -2
  206. package/dist/contracts/officialToolContracts.js +2 -1
  207. package/dist/contracts/promptContracts.js +2 -2
  208. package/dist/contracts/providerSelection.js +1 -1
  209. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  210. package/dist/contracts/sessionStatusContract.js +3 -2
  211. package/dist/contracts/sessionToolContracts.js +17 -4
  212. package/dist/contracts/sessionToolSchemas.js +4 -16
  213. package/dist/contracts/toolContracts.js +2 -0
  214. package/dist/contracts/toolEffects.js +1 -0
  215. package/dist/contracts/toolOutputSchemaGroups.js +138 -94
  216. package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
  217. package/dist/contracts/toolSchemaMetadata.js +18 -69
  218. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  219. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  220. package/dist/contracts/webScriptToolContracts.js +1 -1
  221. package/dist/doctorRuntime.js +7 -5
  222. package/dist/domain/analysisErrorBase.js +5 -0
  223. package/dist/domain/analysisErrorCore.js +3 -0
  224. package/dist/domain/analysisErrorPresentation.js +22 -5
  225. package/dist/domain/analysisErrorProjection.js +24 -5
  226. package/dist/domain/analysisSnapshot.js +31 -31
  227. package/dist/domain/analysisView/analysisView.js +241 -0
  228. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  229. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  230. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  231. package/dist/domain/android/androidApplication.js +1 -1
  232. package/dist/domain/android/androidPartialObservation.js +36 -0
  233. package/dist/domain/apple/appleApplication.js +1 -1
  234. package/dist/domain/apple/dylibResolution.js +10 -3
  235. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  236. package/dist/domain/apple/keyedArchive.js +26 -2
  237. package/dist/domain/artifactComparison.js +15 -6
  238. package/dist/domain/artifactGraph.js +17 -4
  239. package/dist/domain/artifactIdentity.js +8 -8
  240. package/dist/domain/artifactInspection.js +8 -8
  241. package/dist/domain/artifactInventoryEvidence.js +9 -16
  242. package/dist/domain/artifactOperationError.js +3 -3
  243. package/dist/domain/artifactPartialObservation.js +1 -0
  244. package/dist/domain/artifactPathSyntax.js +49 -0
  245. package/dist/domain/binaryTarget.js +39 -13
  246. package/dist/domain/browserCaptureComparison.js +13 -49
  247. package/dist/domain/browserCompleteness.js +3 -2
  248. package/dist/domain/browserNetworkEvidence.js +10 -4
  249. package/dist/domain/browserObservation.js +0 -1
  250. package/dist/domain/browserObservationSchemas.js +14 -3
  251. package/dist/domain/browserScenario.js +0 -1
  252. package/dist/domain/browserScenarioCapture.js +1 -2
  253. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  254. package/dist/domain/browserScenarioDiff.js +0 -2
  255. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  256. package/dist/domain/browserScenarioDiffValues.js +2 -2
  257. package/dist/domain/browserScenarioNormalization.js +3 -3
  258. package/dist/domain/browserScenarioValues.js +6 -6
  259. package/dist/domain/callPath.js +15 -18
  260. package/dist/domain/callPathSchemas.js +2 -2
  261. package/dist/domain/canonicalDigest.js +7 -1
  262. package/dist/domain/canonicalOrdering.js +1 -13
  263. package/dist/domain/changedBehavior.js +5 -6
  264. package/dist/domain/comparisonSemantics.js +0 -5
  265. package/dist/domain/completionLedgerGeneration.js +2 -1
  266. package/dist/domain/configurationErrors.js +12 -0
  267. package/dist/domain/conformancePackage.js +4 -3
  268. package/dist/domain/digests.js +0 -3
  269. package/dist/domain/evidence.js +19 -40
  270. package/dist/domain/evidenceBundle.js +58 -42
  271. package/dist/domain/evidenceCompletionLedger.js +2 -1
  272. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  273. package/dist/domain/functionComparison.js +6 -6
  274. package/dist/domain/functionComparisonDimensions.js +120 -87
  275. package/dist/domain/functionComparisonNormalization.js +26 -36
  276. package/dist/domain/functionComparisonResults.js +3 -6
  277. package/dist/domain/functionComparisonSchemas.js +2 -8
  278. package/dist/domain/functionDossierEvidence.js +4 -38
  279. package/dist/domain/hopperValues.js +11 -15
  280. package/dist/domain/javascript/electronActiveObservation.js +29 -71
  281. package/dist/domain/javascript/electronObservation.js +14 -3
  282. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
  283. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
  284. package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
  285. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  286. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  287. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  288. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
  289. package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
  290. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  291. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  292. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  293. package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
  294. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
  295. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  296. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  297. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  298. package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
  299. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  300. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
  301. package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
  302. package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
  303. package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
  304. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  305. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  306. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
  307. package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
  308. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  309. package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
  310. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  311. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  312. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  313. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  314. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  315. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
  316. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
  317. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  318. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  319. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  320. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
  321. package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
  322. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  323. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  324. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  325. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
  326. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  327. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  328. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  329. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  330. package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
  331. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  332. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  333. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  334. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
  335. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  336. package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
  337. package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
  338. package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
  339. package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
  340. package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
  341. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  342. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  343. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  344. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  345. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  346. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  347. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  348. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  349. package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
  350. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  351. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  352. package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
  353. package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
  354. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  355. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  356. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  357. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
  358. package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
  359. package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
  360. package/dist/domain/jsonSerialization.js +109 -55
  361. package/dist/domain/jsonShape.js +46 -19
  362. package/dist/domain/localPath.js +10 -4
  363. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  364. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  365. package/dist/domain/managed/managedArtifact.js +6 -4
  366. package/dist/domain/managed/managedMemberComparison.js +2 -9
  367. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  368. package/dist/domain/managed/managedNativeVerification.js +0 -2
  369. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  370. package/dist/domain/native/binaryLayout.js +2 -3
  371. package/dist/domain/native/nativeApiBoundary.js +1 -1
  372. package/dist/domain/native/nativeCallObservation.js +3 -3
  373. package/dist/domain/native/nativeInstruction.js +7 -0
  374. package/dist/domain/native/nativeValueFlow.js +5 -11
  375. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  376. package/dist/domain/native/recordedCrash.js +2 -3
  377. package/dist/domain/offsetDateTime.js +17 -0
  378. package/dist/domain/process/processCapture.js +22 -20
  379. package/dist/domain/process/processCaptureCoverage.js +70 -0
  380. package/dist/domain/process/processCaptureExample.js +45 -1
  381. package/dist/domain/process/processCaptureParsing.js +1 -34
  382. package/dist/domain/process/processCaptureValidation.js +82 -13
  383. package/dist/domain/process/processComparison.js +39 -43
  384. package/dist/domain/process/processObservation.js +10 -2
  385. package/dist/domain/process/processScenario.js +24 -2
  386. package/dist/domain/process/processTraceComparison.js +0 -2
  387. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  388. package/dist/domain/process/processTraceEvaluation.js +19 -15
  389. package/dist/domain/process/processTraceSpecification.js +4 -7
  390. package/dist/domain/providerAdapterError.js +2 -0
  391. package/dist/domain/providerCleanupError.js +6 -2
  392. package/dist/domain/reconstructionCoverage.js +7 -3
  393. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  394. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  395. package/dist/domain/reconstructionUnknowns.js +4 -3
  396. package/dist/domain/reconstructionVerification.js +6 -5
  397. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  398. package/dist/domain/referenceSourceGraph.js +27 -28
  399. package/dist/domain/referenceSourceImportParsing.js +34 -45
  400. package/dist/domain/residualUnknown.js +3 -2
  401. package/dist/domain/staticRuntimeCorrelation.js +4 -3
  402. package/dist/domain/stringPatterns.js +6 -0
  403. package/dist/domain/swiftSymbolClassification.js +66 -0
  404. package/dist/domain/symbolAnalysis.js +83 -20
  405. package/dist/domain/unicodeCodePointOrder.js +6 -0
  406. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  407. package/dist/domain/webCaptureDiff.js +71 -30
  408. package/dist/domain/webCaptureDiffSchemas.js +8 -11
  409. package/dist/domain/webEventListeners.js +3 -2
  410. package/dist/domain/webExecution.js +3 -2
  411. package/dist/domain/webInventory.js +3 -2
  412. package/dist/domain/webMcpDiscovery.js +4 -3
  413. package/dist/domain/webRuntime.js +0 -2
  414. package/dist/domain/webScriptExport.js +2 -2
  415. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  416. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  417. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  418. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  419. package/dist/dotnet/ManagedMemberRows.js +75 -62
  420. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  421. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  422. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  423. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  424. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  425. package/dist/dotnet/ManagedStaticProvider.js +13 -12
  426. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  427. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  428. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  429. package/dist/evaluation/CodexAgentEval.js +12 -8
  430. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  431. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  432. package/dist/filesystem/RegularFile.js +41 -0
  433. package/dist/firmware/FirmwareCommand.js +9 -5
  434. package/dist/firmware/FirmwareProvider.js +4 -4
  435. package/dist/generatedPackageMetadata.js +2 -2
  436. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  437. package/dist/ghidra/GhidraClient.js +105 -36
  438. package/dist/ghidra/GhidraClientStartup.js +0 -2
  439. package/dist/ghidra/GhidraDoctor.js +6 -5
  440. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  441. package/dist/ghidra/GhidraInstallation.js +151 -22
  442. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  443. package/dist/ghidra/GhidraLauncher.js +58 -26
  444. package/dist/ghidra/GhidraProvider.js +6 -2
  445. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  446. package/dist/ghidra/GhidraProviderClient.js +13 -3
  447. package/dist/ghidra/GhidraSessionError.js +2 -0
  448. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  449. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  450. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  451. package/dist/hopper/BridgeLauncher.js +34 -45
  452. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  453. package/dist/hopper/HopperCleanup.js +56 -27
  454. package/dist/hopper/HopperClient.js +86 -65
  455. package/dist/hopper/HopperMachOImage.js +3 -2
  456. package/dist/hopper/HopperProvider.js +16 -18
  457. package/dist/hopper/HopperRegexSearch.js +3 -6
  458. package/dist/hopper/HopperTargetLease.js +132 -49
  459. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  460. package/dist/ida/IdaConfiguration.js +8 -3
  461. package/dist/ida/IdaInput.js +1 -7
  462. package/dist/ida/IdaMcpConnection.js +8 -4
  463. package/dist/ida/IdaOperationRunner.js +5 -3
  464. package/dist/ida/IdaProvider.js +8 -12
  465. package/dist/ida/IdaSessionClient.js +24 -20
  466. package/dist/ida/IdaWorkspace.js +12 -13
  467. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  468. package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
  469. package/dist/inspector/V8InspectorProvider.js +97 -35
  470. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  471. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  472. package/dist/main/shutdown.js +81 -29
  473. package/dist/main/startup.js +9 -2
  474. package/dist/main/transport.js +23 -3
  475. package/dist/main.js +11 -18
  476. package/dist/native/AppleMachoSelection.js +16 -6
  477. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  478. package/dist/native/AppleObjcProperties.js +17 -7
  479. package/dist/native/CommandRunner.js +9 -7
  480. package/dist/native/LldbCallTracer.js +249 -77
  481. package/dist/native/NativeMacOSProvider.js +32 -17
  482. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  483. package/dist/native/NativeUiHelperRuntime.js +11 -2
  484. package/dist/native/NativeUiObservation.js +2 -2
  485. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  486. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  487. package/dist/process/ExecFileOutput.js +88 -6
  488. package/dist/process/PrivateRuntimeRoot.js +10 -5
  489. package/dist/process/ProcessOwnership.js +1 -4
  490. package/dist/process/ProcessOwnershipObservation.js +18 -16
  491. package/dist/process/ProviderProcess.js +1 -3
  492. package/dist/process/capture/FilesystemSnapshot.js +131 -24
  493. package/dist/process/capture/ProcessCaptureError.js +13 -0
  494. package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
  495. package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
  496. package/dist/process/capture/ProcessHarness.js +16 -33
  497. package/dist/process/capture/ProcessNormalization.js +20 -2
  498. package/dist/process/capture/ProcessSampling.js +25 -2
  499. package/dist/process/capture/TerminalRenderer.js +14 -0
  500. package/dist/process/snapshotEnvironment.js +14 -0
  501. package/dist/server/EvidenceMcpServer.js +25 -14
  502. package/dist/server/analysisAdmission.js +8 -0
  503. package/dist/server/createServer.js +71 -59
  504. package/dist/server/mcpClientMetadata.js +12 -5
  505. package/dist/server/promptCompletion.js +3 -8
  506. package/dist/server/registerAnalysisViewTool.js +15 -0
  507. package/dist/server/registerAndroidTools.js +2 -3
  508. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -6
  509. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  510. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  511. package/dist/server/registerApplicationTools/coverage.js +1 -2
  512. package/dist/server/registerApplicationTools/helpers.js +4 -4
  513. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  514. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  515. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  516. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  517. package/dist/server/registerArtifactComparisonTool.js +4 -5
  518. package/dist/server/registerArtifactTools.js +2 -2
  519. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  520. package/dist/server/registerBrowserScenarioTool.js +3 -4
  521. package/dist/server/registerBrowserTools.js +13 -16
  522. package/dist/server/registerBundleComparisonTool.js +5 -6
  523. package/dist/server/registerCloseLifecycleTool.js +8 -7
  524. package/dist/server/registerElectronTools.js +10 -13
  525. package/dist/server/registerEnhancedTools.js +82 -77
  526. package/dist/server/registerEvidenceTools.js +54 -47
  527. package/dist/server/registerEvmTools.js +2 -3
  528. package/dist/server/registerFirmwareTools.js +2 -3
  529. package/dist/server/registerFunctionComparisonTool.js +7 -8
  530. package/dist/server/registerInvestigationTools.js +14 -15
  531. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  532. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  533. package/dist/server/registerManagedTools.js +7 -4
  534. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  535. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  536. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  537. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  538. package/dist/server/registerOfficialTools.js +32 -41
  539. package/dist/server/registerProcessComparisonTool.js +8 -8
  540. package/dist/server/registerRecordedCrashTools.js +2 -3
  541. package/dist/server/registerSessionRecordTools.js +15 -19
  542. package/dist/server/registerSessionStatusTool.js +3 -4
  543. package/dist/server/registerSessionTools.js +19 -19
  544. package/dist/server/registerWebModuleTool.js +2 -3
  545. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  546. package/dist/server/registerWebRuntimeTools.js +4 -5
  547. package/dist/server/registerWebScriptTool.js +2 -3
  548. package/dist/server/registerWebSourceLocationTool.js +2 -3
  549. package/dist/server/toolResult.js +66 -94
  550. package/dist/server/toolResultEncoding.js +11 -10
  551. package/dist/windows/WindowsNativeLoader.js +1 -0
  552. package/dist/windows/WindowsOwnedProcess.js +60 -15
  553. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  554. package/native/windows/README.md +3 -1
  555. package/native/windows/build/manifest.json +2 -2
  556. package/native/windows/build/rea-windows-x64.node +0 -0
  557. package/package.json +42 -30
  558. package/scripts/rea.mjs +3 -6
  559. package/skills/reverse-engineer-anything/SKILL.md +14 -13
  560. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  561. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  562. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  563. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +18 -0
  564. package/dist/artifacts/inventory/policy.js +0 -2
  565. package/dist/config.js +0 -1
  566. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  567. package/dist/contracts/process/processCaptureExample.js +0 -2
  568. package/dist/contracts/toolOutputSchemas.js +0 -2
  569. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  570. package/dist/main/reload.js +0 -12
  571. package/dist/main/state.js +0 -3
  572. package/dist/server/registerNativeTools.js +0 -6
  573. package/dist/server/sessionToolPolicies.js +0 -2
@@ -1,7 +1,10 @@
1
- import { constants, createReadStream } from "node:fs";
2
- import { lstat, open, realpath } from "node:fs/promises";
1
+ import { constants, createReadStream, createWriteStream, } from "node:fs";
2
+ import { lstat, mkdtemp, open, realpath, rm, } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { createHash } from "node:crypto";
3
5
  import { isAbsolute, join, relative, sep } from "node:path";
4
- import { Readable } from "node:stream";
6
+ import { Readable, Transform } from "node:stream";
7
+ import { pipeline } from "node:stream/promises";
5
8
  import { getRawHeader, listPackage, statFile, uncache } from "@electron/asar";
6
9
  import { ArtifactReaderFailure, } from "./ArtifactReader.js";
7
10
  import { closeAsarHandle, readValidatedAsarEntry } from "./AsarEntryStream.js";
@@ -15,24 +18,28 @@ import { closeAsarHandle, readValidatedAsarEntry } from "./AsarEntryStream.js";
15
18
  export class AsarArtifactReader {
16
19
  path;
17
20
  openUnpackedFile;
21
+ removeSnapshot;
18
22
  format = "asar";
19
23
  #archiveSize;
20
24
  #headerSize;
21
25
  #entries = new Map();
22
- constructor(path, openUnpackedFile = open) {
26
+ #snapshot;
27
+ #snapshotRoot;
28
+ constructor(path, openUnpackedFile = open, removeSnapshot = (path) => rm(path, { recursive: true, force: true })) {
23
29
  this.path = path;
24
30
  this.openUnpackedFile = openUnpackedFile;
31
+ this.removeSnapshot = removeSnapshot;
25
32
  }
26
33
  async *entries(signal) {
27
34
  let paths;
28
35
  try {
29
- // ASAR caches headers by path even after the archive has been replaced.
36
+ await this.prepareContainer(undefined, signal);
37
+ const snapshotPath = this.#snapshotPath();
30
38
  this.#resetArchiveState();
31
39
  this.#entries.clear();
32
- uncache(this.path);
33
- paths = listPackage(this.path, { isPack: false }).sort((left, right) => left.localeCompare(right, "en"));
34
- this.#headerSize = getRawHeader(this.path).headerSize;
35
- const archiveMetadata = await lstat(this.path);
40
+ paths = listPackage(snapshotPath, { isPack: false }).sort((left, right) => left.localeCompare(right, "en"));
41
+ this.#headerSize = getRawHeader(snapshotPath).headerSize;
42
+ const archiveMetadata = await lstat(snapshotPath);
36
43
  if (!archiveMetadata.isFile() || archiveMetadata.isSymbolicLink())
37
44
  throw new ArtifactReaderFailure("format", "ASAR container is not a regular file");
38
45
  this.#archiveSize = archiveMetadata.size;
@@ -54,7 +61,7 @@ export class AsarArtifactReader {
54
61
  : listed;
55
62
  let metadata;
56
63
  try {
57
- metadata = statFile(this.path, providerPath, false);
64
+ metadata = statFile(this.#snapshotPath(), providerPath, false);
58
65
  }
59
66
  catch (cause) {
60
67
  throw asarFailure(this.path, `stat ${path}`, cause);
@@ -138,7 +145,7 @@ export class AsarArtifactReader {
138
145
  throw new ArtifactReaderFailure("format", `ASAR entry range is outside its container: ${producedEntry.path}`);
139
146
  let handle;
140
147
  try {
141
- const openedHandle = await open(this.path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
148
+ const openedHandle = await open(this.#snapshotPath(), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
142
149
  handle = openedHandle;
143
150
  const observed = await openedHandle.stat();
144
151
  abortIfNeeded(signal);
@@ -161,16 +168,73 @@ export class AsarArtifactReader {
161
168
  throw asarFailure(this.path, `read ${producedEntry.path}`, cause);
162
169
  }
163
170
  }
164
- /** Open raw container bytes to verify the inventory identity before analysis. */
165
- openContainer(signal) {
171
+ /** Capture once per reader lifetime; bind all interpretation to these exact bytes. */
172
+ async prepareContainer(expectedSha256, signal) {
166
173
  abortIfNeeded(signal);
167
- return createReadStream(this.path, signal === undefined ? {} : { signal });
174
+ if (this.#snapshot === undefined && this.#snapshotRoot !== undefined)
175
+ await this.close();
176
+ if (this.#snapshot === undefined) {
177
+ try {
178
+ this.#snapshotRoot = await mkdtemp(join(tmpdir(), "rea-asar-snapshot-"));
179
+ const snapshotPath = join(this.#snapshotRoot, "container.asar");
180
+ const hash = createHash("sha256");
181
+ const handle = await open(this.path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
182
+ const source = handle.createReadStream();
183
+ const digesting = new Transform({
184
+ transform(chunk, _encoding, callback) {
185
+ hash.update(chunk);
186
+ callback(null, chunk);
187
+ },
188
+ });
189
+ await pipeline(source, digesting, createWriteStream(snapshotPath, { flags: "wx", mode: 0o600 }), signal === undefined ? {} : { signal });
190
+ this.#snapshot = { path: snapshotPath, sha256: hash.digest("hex") };
191
+ }
192
+ catch (cause) {
193
+ const primary = signal?.aborted === true
194
+ ? new ArtifactReaderFailure("cancelled", "ASAR operation cancelled", { cause })
195
+ : asarFailure(this.path, "snapshot", cause);
196
+ try {
197
+ await this.close();
198
+ }
199
+ catch (cleanupCause) {
200
+ throw ArtifactReaderFailure.withCleanup(primary, ArtifactReaderFailure.cleanupObservation(cleanupCause, this.path));
201
+ }
202
+ throw primary;
203
+ }
204
+ }
205
+ if (expectedSha256 !== undefined &&
206
+ this.#snapshot.sha256 !== expectedSha256)
207
+ throw new ArtifactReaderFailure("integrity", `ASAR container changed before interpretation: ${this.path}`);
208
+ }
209
+ /** Read the same captured container that supplies headers and packed members. */
210
+ async openContainer(signal) {
211
+ await this.prepareContainer(undefined, signal);
212
+ return createReadStream(this.#snapshotPath(), signal === undefined ? {} : { signal });
168
213
  }
169
- close() {
170
- uncache(this.path);
214
+ async close() {
215
+ const root = this.#snapshotRoot;
216
+ if (root !== undefined) {
217
+ try {
218
+ await this.removeSnapshot(root);
219
+ }
220
+ catch (cause) {
221
+ throw ArtifactReaderFailure.withCleanup(cause, {
222
+ reason: `Could not remove ASAR snapshot: ${root}`,
223
+ resources: [root],
224
+ });
225
+ }
226
+ this.#snapshotRoot = undefined;
227
+ }
228
+ if (this.#snapshot !== undefined)
229
+ uncache(this.#snapshot.path);
230
+ this.#snapshot = undefined;
171
231
  this.#resetArchiveState();
172
232
  this.#entries.clear();
173
- return Promise.resolve();
233
+ }
234
+ #snapshotPath() {
235
+ if (this.#snapshot === undefined)
236
+ throw new ArtifactReaderFailure("integrity", "ASAR snapshot is not available");
237
+ return this.#snapshot.path;
174
238
  }
175
239
  provenance() {
176
240
  return [];
@@ -1,6 +1,7 @@
1
1
  import { constants } from "node:fs";
2
2
  import { lstat, open, opendir, realpath } from "node:fs/promises";
3
3
  import { isAbsolute, join, relative, sep } from "node:path";
4
+ import { compareUnicodeCodePoints } from "../domain/unicodeCodePointOrder.js";
4
5
  import { ArtifactReaderFailure, } from "./ArtifactReader.js";
5
6
  /** Deterministic, non-symlink-following directory reader. */
6
7
  export class DirectoryArtifactReader {
@@ -38,7 +39,7 @@ export class DirectoryArtifactReader {
38
39
  await handle.close().catch(() => undefined);
39
40
  }
40
41
  await withDirectoryIoContext("inspect directory", directory, () => assertContainedDirectory(root, directory));
41
- children.sort((left, right) => left.localeCompare(right, "en"));
42
+ children.sort(compareUnicodeCodePoints);
42
43
  const directories = [];
43
44
  for (const name of children) {
44
45
  abortIfNeeded(signal);
@@ -12,7 +12,7 @@ export class MachOSliceArtifactReader {
12
12
  runner;
13
13
  format = "file";
14
14
  #command;
15
- constructor(path, runner = new XcrunCommandRunner()) {
15
+ constructor(path, environment, runner = new XcrunCommandRunner(environment)) {
16
16
  this.path = path;
17
17
  this.runner = runner;
18
18
  }
@@ -175,7 +175,7 @@ const lipoMatchesSlice = (reported, observed, structurallyUnique) => {
175
175
  reported.cpu_type_code !== null ||
176
176
  reported.cpu_subtype_code !== null;
177
177
  return ((hasPhysicalIdentity || structurallyUnique) &&
178
- reported.name === observed.architecture &&
178
+ lipoNameMatches(reported.name, observed.architecture) &&
179
179
  (reported.file_offset === null ||
180
180
  reported.file_offset === observed.slice_offset) &&
181
181
  (reported.size === null || reported.size === observed.slice_size) &&
@@ -187,6 +187,13 @@ const lipoMatchesSlice = (reported, observed, structurallyUnique) => {
187
187
  observed.fat_alignment_exponent === null ||
188
188
  reported.alignment === 2 ** observed.fat_alignment_exponent));
189
189
  };
190
+ /**
191
+ * Newer lipo names an arm64e ABI variant `arm64e.<variant>` (for example
192
+ * `arm64e.v1` for pointer-auth ABI version 1). The FAT table names that slice
193
+ * `arm64e`; its physical identity is still compared field by field.
194
+ */
195
+ const lipoNameMatches = (reported, observed) => reported === observed ||
196
+ (observed === "arm64e" && /^arm64e\.[A-Za-z0-9_]+$/u.test(reported));
190
197
  const parseSliceKeyInteger = (value) => {
191
198
  if (value === undefined || !/^\d+$/u.test(value))
192
199
  return null;
@@ -1,47 +1,51 @@
1
1
  import { mkdtemp, realpath, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { basename, join } from "node:path";
4
- import { parse } from "plist";
5
- import { z } from "zod";
6
4
  import { ArtifactReaderFailure, } from "./ArtifactReader.js";
7
5
  import { DirectoryArtifactReader } from "./DirectoryArtifactReader.js";
8
- import { execFileOutput } from "../process/ExecFileOutput.js";
9
- const DETACH_TIMEOUT_MS = 120_000;
10
- const attachOutputSchema = z.object({
11
- "system-entities": z.array(z.object({
12
- "dev-entry": z.string().startsWith("/dev/"),
13
- "mount-point": z.string().optional(),
14
- })),
15
- });
16
- const infoOutputSchema = z.object({
17
- images: z.array(z.object({
18
- "system-entities": z.array(z.object({ "dev-entry": z.string() })),
19
- })),
20
- });
21
- const systemHost = {
6
+ import { execFileOutput, execFileOutputFailure, } from "../process/ExecFileOutput.js";
7
+ import { parseNativeDmgAttachOutput, parseNativeDmgInfo, resolveNativeDmgOwnership, } from "./NativeDmgOwnership.js";
8
+ const HDIUTIL_COMMAND_TIMEOUT_MS = 120_000;
9
+ // APFS ejects and busy reporting can lag a detach attempt.
10
+ const DETACH_SETTLE_DELAYS_MS = [250, 500, 1000];
11
+ const delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
12
+ class NativeDmgCommandFailure extends ArtifactReaderFailure {
13
+ stdout;
14
+ processNotStarted;
15
+ constructor(reason, message, stdout, options) {
16
+ super(reason, message, options?.cause === undefined ? undefined : { cause: options.cause });
17
+ this.stdout = stdout;
18
+ this.processNotStarted = options?.processNotStarted ?? false;
19
+ }
20
+ }
21
+ const createSystemHost = (environment) => ({
22
+ delay,
22
23
  async run(arguments_, signal, options) {
23
24
  try {
24
25
  const { stdout, stderr } = await execFileOutput("/usr/bin/hdiutil", [...arguments_], {
26
+ env: environment,
27
+ stopSignal: "SIGTERM",
25
28
  ...(options === undefined ? {} : { timeout: options.timeoutMs }),
26
29
  ...(signal === undefined ? {} : { signal }),
27
30
  });
28
31
  return { stdout, stderr, exitCode: 0 };
29
32
  }
30
33
  catch (cause) {
34
+ const output = execFileOutputFailure(cause);
31
35
  if (cause instanceof Error && cause.name === "AbortError")
32
- throw new ArtifactReaderFailure("cancelled", "DMG operation cancelled");
33
- const exitCode = processExitCode(cause);
36
+ throw new NativeDmgCommandFailure("cancelled", "DMG operation cancelled", output?.stdout ?? "", { cause });
37
+ const exitCode = typeof output?.code === "number" ? output.code : processExitCode(cause);
34
38
  if (exitCode !== undefined)
35
39
  return {
36
- stdout: processOutput(cause, "stdout"),
37
- stderr: processOutput(cause, "stderr"),
40
+ stdout: output?.stdout ?? processOutput(cause, "stdout"),
41
+ stderr: output?.stderr ?? processOutput(cause, "stderr"),
38
42
  exitCode,
39
43
  cause,
40
44
  };
41
- throw new ArtifactReaderFailure(commandFailureReason(cause, arguments_[0]), `hdiutil ${arguments_[0] ?? "operation"} failed: ${describeCommandFailure(cause, arguments_)}`, { cause });
45
+ throw new NativeDmgCommandFailure(commandFailureReason(cause, arguments_[0]), `hdiutil ${arguments_[0] ?? "operation"} failed: ${describeCommandFailure(cause, arguments_)}`, output?.stdout ?? "", { cause, processNotStarted: processNotStarted(cause) });
42
46
  }
43
47
  },
44
- };
48
+ });
45
49
  /** Read-only macOS DMG adapter that owns attachment and reverse-order detach. */
46
50
  export class NativeDmgArtifactReader {
47
51
  path;
@@ -50,16 +54,22 @@ export class NativeDmgArtifactReader {
50
54
  #provenance = [];
51
55
  #directory;
52
56
  #devices = [];
57
+ #inventoryConfirmedDevices = new Set();
53
58
  #mountRoot;
59
+ #baselineDevices = new Set();
60
+ #attachOutput;
61
+ #attachOutputReturned = false;
62
+ #attachMayHaveMounted = false;
63
+ #ownershipUncertainty;
54
64
  constructor(path, host) {
55
65
  this.path = path;
56
66
  this.host = host;
57
67
  }
58
68
  /** Verify and attach one image beneath an exclusively owned temporary root. */
59
- static async create(path, signal, host = systemHost) {
60
- if (process.platform !== "darwin" && host === systemHost)
69
+ static async create(path, environment, signal, host) {
70
+ if (process.platform !== "darwin" && host === undefined)
61
71
  throw new ArtifactReaderFailure("unavailable", "Native DMG traversal is available only on macOS");
62
- const reader = new NativeDmgArtifactReader(path, host);
72
+ const reader = new NativeDmgArtifactReader(path, host ?? createSystemHost(environment));
63
73
  await reader.attach(signal);
64
74
  return reader;
65
75
  }
@@ -79,48 +89,102 @@ export class NativeDmgArtifactReader {
79
89
  return structuredClone(this.#provenance);
80
90
  }
81
91
  async close() {
82
- let detachFailure;
83
- const remainingDevices = [];
92
+ let detachFailure = await this.#reconcileAttachState();
93
+ let remainingDevices = [];
84
94
  for (const device of [...this.#devices].reverse()) {
85
- try {
86
- await runChecked(this.host, ["detach", device], undefined, {
87
- timeoutMs: DETACH_TIMEOUT_MS,
88
- });
89
- this.#provenance.push(command(["detach", device], ["mount"]));
95
+ const failure = await this.#detach(device);
96
+ if (failure !== undefined) {
97
+ remainingDevices.push(device);
98
+ detachFailure ??= failure;
90
99
  }
91
- catch (cause) {
92
- // Detaching a synthesized APFS container also ejects the image that
93
- // backs it, so a later whole disk of the same image may already be
94
- // gone. Only a device that is still attached is a cleanup failure.
95
- if (await this.#isAttached(device)) {
96
- remainingDevices.push(device);
97
- detachFailure ??= cause;
100
+ }
101
+ // APFS container detach may briefly leave its backing image listed.
102
+ for (const delayMs of DETACH_SETTLE_DELAYS_MS) {
103
+ if (remainingDevices.length === 0)
104
+ break;
105
+ await (this.host.delay ?? delay)(delayMs);
106
+ const stillAttached = [];
107
+ for (const device of remainingDevices) {
108
+ if (!(await this.#isAttached(device)))
109
+ continue;
110
+ const failure = await this.#detach(device);
111
+ if (failure !== undefined) {
112
+ stillAttached.push(device);
113
+ detachFailure = failure;
98
114
  }
99
115
  }
116
+ remainingDevices = stillAttached;
100
117
  }
118
+ if (remainingDevices.length === 0)
119
+ detachFailure = undefined;
101
120
  this.#devices = remainingDevices.reverse();
102
- if (this.#devices.length === 0 && this.#mountRoot !== undefined)
121
+ if (this.#devices.length === 0 &&
122
+ this.#mountRoot !== undefined &&
123
+ !this.#attachMayHaveMounted)
103
124
  await rm(this.#mountRoot, { recursive: true, force: true }).then(() => {
104
125
  this.#mountRoot = undefined;
105
126
  this.#directory = undefined;
106
127
  }, (cause) => {
107
128
  detachFailure ??= cause;
108
129
  });
130
+ if (this.#attachMayHaveMounted) {
131
+ detachFailure ??= new Error(this.#ownershipUncertainty ??
132
+ "hdiutil attachment ownership remains unknown");
133
+ }
109
134
  if (detachFailure !== undefined)
110
- throw new ArtifactReaderFailure("unavailable", `DMG detach or mount-root cleanup failed for ${JSON.stringify(this.path)}: ${failureMessage(detachFailure)}`, { cause: detachFailure });
135
+ throw new ArtifactReaderFailure("unavailable", `DMG detach or mount-root cleanup failed for ${JSON.stringify(this.path)}: ${failureMessage(detachFailure)}`, {
136
+ cause: detachFailure,
137
+ cleanup: {
138
+ reason: failureMessage(detachFailure),
139
+ resources: [
140
+ ...this.#devices.map((device) => `DMG device ${device}`),
141
+ ...(this.#attachMayHaveMounted
142
+ ? [
143
+ `DMG attachment ownership unknown at mount root ${this.#mountRoot ?? this.path}`,
144
+ ]
145
+ : []),
146
+ ...(this.#mountRoot === undefined
147
+ ? []
148
+ : [`DMG mount root ${this.#mountRoot}`]),
149
+ ],
150
+ },
151
+ });
111
152
  }
112
- /**
113
- * Report whether hdiutil still lists a device; unknown state counts as
114
- * attached. Like detach, this cleanup query runs after the inventory
115
- * snapshot has captured provenance, so it is not recorded there.
116
- */
117
- async #isAttached(device) {
153
+ /** Detach one device; return the failure only while it remains attached. */
154
+ async #detach(device) {
118
155
  try {
119
- const info = await runChecked(this.host, ["info", "-plist"], undefined, {
120
- timeoutMs: DETACH_TIMEOUT_MS,
156
+ await runChecked(this.host, ["detach", device], undefined, {
157
+ timeoutMs: HDIUTIL_COMMAND_TIMEOUT_MS,
121
158
  });
122
- const parsed = infoOutputSchema.parse(parse(info.stdout));
123
- return parsed.images.some((image) => image["system-entities"].some((entity) => entity["dev-entry"] === device));
159
+ this.#provenance.push(command(["detach", device], ["mount"]));
160
+ return undefined;
161
+ }
162
+ catch (cause) {
163
+ return (await this.#isAttached(device)) ? cause : undefined;
164
+ }
165
+ }
166
+ async #reconcileAttachState() {
167
+ if (!this.#attachMayHaveMounted)
168
+ return undefined;
169
+ try {
170
+ await this.#resolveAttachOwnership();
171
+ return undefined;
172
+ }
173
+ catch (cause) {
174
+ this.#ownershipUncertainty = failureMessage(cause);
175
+ return cause;
176
+ }
177
+ }
178
+ /** Treat unknown hdiutil state as attached during cleanup. */
179
+ async #isAttached(device) {
180
+ try {
181
+ const parsed = await this.#readInfo();
182
+ const isListed = parsed.images.some((image) => image["system-entities"].some((entity) => entity["dev-entry"] === device));
183
+ if (isListed) {
184
+ this.#inventoryConfirmedDevices.add(device);
185
+ return true;
186
+ }
187
+ return !this.#inventoryConfirmedDevices.has(device);
124
188
  }
125
189
  catch {
126
190
  return true;
@@ -129,44 +193,62 @@ export class NativeDmgArtifactReader {
129
193
  async attach(signal) {
130
194
  await runChecked(this.host, ["verify", this.path], signal);
131
195
  this.#provenance.push(command(["verify", this.path], ["read"]));
132
- this.#mountRoot = await realpath(await mkdtemp(join(tmpdir(), "rea-dmg-")));
196
+ const baseline = await this.#readInfo();
197
+ this.#baselineDevices = new Set(baseline.images.flatMap((image) => image["system-entities"].map(({ "dev-entry": device }) => device)));
198
+ const mountRoot = await realpath(await mkdtemp(join(tmpdir(), "rea-dmg-")));
199
+ this.#mountRoot = mountRoot;
133
200
  try {
201
+ this.#attachMayHaveMounted = true;
134
202
  const attached = await runChecked(this.host, [
135
203
  "attach",
136
204
  "-readonly",
137
205
  "-nobrowse",
138
206
  "-plist",
139
207
  "-mountroot",
140
- this.#mountRoot,
208
+ mountRoot,
141
209
  this.path,
142
- ], signal);
143
- const parsed = attachOutputSchema.parse(parse(attached.stdout));
144
- const devices = [
145
- ...new Set(parsed["system-entities"].map((entity) => entity["dev-entry"])),
146
- ];
147
- // Detaching an observed whole disk also detaches its partitions. Do not
148
- // subsequently detach the now-unavailable child devices.
149
- this.#devices = devices.filter((device) => !devices.some((parent) => /^\/dev\/disk\d+$/u.test(parent) &&
150
- device.startsWith(`${parent}s`) &&
151
- /^\d+$/u.test(device.slice(parent.length + 1))));
152
- if (this.#devices.length === 0)
210
+ ], signal, { timeoutMs: HDIUTIL_COMMAND_TIMEOUT_MS });
211
+ this.#attachOutputReturned = true;
212
+ let parsed;
213
+ try {
214
+ parsed = parseNativeDmgAttachOutput(attached.stdout);
215
+ }
216
+ catch (cause) {
217
+ throw new ArtifactReaderFailure("format", "hdiutil returned a malformed attachment plist", { cause });
218
+ }
219
+ if (parsed["system-entities"].length === 0)
153
220
  throw new ArtifactReaderFailure("format", "hdiutil returned no attached devices");
154
- for (const entity of parsed["system-entities"])
155
- if (entity["mount-point"] !== undefined &&
156
- !entity["mount-point"].startsWith(`${this.#mountRoot}/`))
157
- throw new ArtifactReaderFailure("path", "hdiutil mounted outside the owned root");
221
+ this.#attachOutput = parsed;
222
+ const ownership = await this.#resolveAttachOwnership();
223
+ if (ownership !== "owned")
224
+ throw new ArtifactReaderFailure(ownership === "unknown" ? "unavailable" : "path", ownership === "unknown"
225
+ ? `DMG attachment ownership is uncertain: ${this.#ownershipUncertainty ?? "no unique mount under the owned root"}`
226
+ : "hdiutil did not mount a new image beneath the owned root");
158
227
  this.#provenance.push(command([
159
228
  "attach",
160
229
  "-readonly",
161
230
  "-nobrowse",
162
231
  "-plist",
163
232
  "-mountroot",
164
- this.#mountRoot,
233
+ mountRoot,
165
234
  this.path,
166
235
  ], ["read", "mount"]));
167
- this.#directory = new DirectoryArtifactReader(this.#mountRoot);
236
+ this.#directory = new DirectoryArtifactReader(mountRoot);
168
237
  }
169
238
  catch (cause) {
239
+ if (cause instanceof NativeDmgCommandFailure && cause.stdout !== "") {
240
+ try {
241
+ this.#attachOutput = parseNativeDmgAttachOutput(cause.stdout);
242
+ this.#attachOutputReturned = true;
243
+ }
244
+ catch {
245
+ // The original command failure remains primary; fresh info still recovers mounts.
246
+ }
247
+ }
248
+ if (cause instanceof NativeDmgCommandFailure && cause.processNotStarted) {
249
+ this.#attachMayHaveMounted = false;
250
+ this.#ownershipUncertainty = undefined;
251
+ }
170
252
  let cleanupFailure;
171
253
  try {
172
254
  await this.close();
@@ -175,12 +257,61 @@ export class NativeDmgArtifactReader {
175
257
  cleanupFailure = cleanupCause;
176
258
  }
177
259
  if (cleanupFailure !== undefined)
178
- throw new ArtifactReaderFailure("unavailable", `DMG attach failed and cleanup could not detach every device: ${failureMessage(cause)}; cleanup: ${failureMessage(cleanupFailure)}`, { cause: new AggregateError([cause, cleanupFailure]) });
260
+ throw ArtifactReaderFailure.withCleanup(cause, ArtifactReaderFailure.cleanupObservation(cleanupFailure, `DMG mount root ${this.#mountRoot ?? this.path}`));
179
261
  throw cause;
180
262
  }
181
263
  }
264
+ async #readInfo() {
265
+ const info = await runChecked(this.host, ["info", "-plist"], undefined, {
266
+ timeoutMs: HDIUTIL_COMMAND_TIMEOUT_MS,
267
+ });
268
+ return parseNativeDmgInfo(info.stdout);
269
+ }
270
+ async #resolveAttachOwnership() {
271
+ const mountRoot = this.#mountRoot;
272
+ if (mountRoot === undefined)
273
+ throw new Error("DMG mount root is unavailable for ownership discovery");
274
+ const ownership = resolveNativeDmgOwnership({
275
+ info: await this.#readInfo(),
276
+ ...(this.#attachOutput === undefined
277
+ ? {}
278
+ : { attachOutput: this.#attachOutput }),
279
+ attachOutputReturned: this.#attachOutputReturned,
280
+ mountRoot,
281
+ baselineDevices: this.#baselineDevices,
282
+ });
283
+ if (ownership.status === "owned") {
284
+ this.#devices = [...ownership.devices];
285
+ if (ownership.source === "info")
286
+ for (const device of ownership.devices)
287
+ this.#inventoryConfirmedDevices.add(device);
288
+ this.#attachMayHaveMounted = false;
289
+ this.#ownershipUncertainty = undefined;
290
+ return "owned";
291
+ }
292
+ if (ownership.status === "unknown") {
293
+ this.#ownershipUncertainty = ownership.reason;
294
+ return "unknown";
295
+ }
296
+ this.#attachMayHaveMounted = false;
297
+ this.#ownershipUncertainty = undefined;
298
+ this.#devices = [];
299
+ return "none";
300
+ }
182
301
  }
183
302
  const failureMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
303
+ const processNotStarted = (cause) => {
304
+ if (!(cause instanceof Error))
305
+ return false;
306
+ const syscall = Reflect.get(cause, "syscall");
307
+ const code = Reflect.get(cause, "code");
308
+ const errno = Reflect.get(cause, "errno");
309
+ return (typeof syscall === "string" &&
310
+ syscall.startsWith("spawn ") &&
311
+ (typeof code === "string" ||
312
+ typeof code === "number" ||
313
+ typeof errno === "number"));
314
+ };
184
315
  const runChecked = async (host, arguments_, signal, options) => {
185
316
  let result;
186
317
  try {
@@ -190,10 +321,9 @@ const runChecked = async (host, arguments_, signal, options) => {
190
321
  if (cause instanceof ArtifactReaderFailure)
191
322
  throw cause;
192
323
  if (cause instanceof Error && cause.name === "AbortError")
193
- throw new ArtifactReaderFailure("cancelled", "DMG operation cancelled", {
194
- cause,
195
- });
196
- throw new ArtifactReaderFailure(commandFailureReason(cause, arguments_[0]), `hdiutil ${arguments_[0] ?? "operation"} failed: ${describeCommandFailure(cause, arguments_)}`, { cause });
324
+ throw new NativeDmgCommandFailure("cancelled", "DMG operation cancelled", execFileOutputFailure(cause)?.stdout ?? "", { cause });
325
+ const output = execFileOutputFailure(cause);
326
+ throw new NativeDmgCommandFailure(commandFailureReason(cause, arguments_[0]), `hdiutil ${arguments_[0] ?? "operation"} failed: ${describeCommandFailure(cause, arguments_)}`, output?.stdout ?? "", { cause, processNotStarted: processNotStarted(cause) });
197
327
  }
198
328
  if (result.exitCode !== 0) {
199
329
  const failure = {
@@ -208,9 +338,9 @@ const runChecked = async (host, arguments_, signal, options) => {
208
338
  const reason = commandFailureReason(failure, arguments_[0]);
209
339
  const details = describeCommandFailure(failure, arguments_);
210
340
  const unknownVerifyFailure = arguments_[0] === "verify" && reason === "unavailable";
211
- throw new ArtifactReaderFailure(reason, unknownVerifyFailure
341
+ throw new NativeDmgCommandFailure(reason, unknownVerifyFailure
212
342
  ? `hdiutil verify failed; captured diagnostics do not establish the failure cause: ${details}`
213
- : `hdiutil ${arguments_[0] ?? "operation"} failed: ${details}`, result.cause === undefined ? undefined : { cause: result.cause });
343
+ : `hdiutil ${arguments_[0] ?? "operation"} failed: ${details}`, result.stdout, { cause: result.cause ?? failure });
214
344
  }
215
345
  return { stdout: result.stdout, exitCode: 0 };
216
346
  };