rea-agents 6.2.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 (636) hide show
  1. package/README.md +24 -23
  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/bridge/hopper_bridge.py +2 -0
  6. package/dist/adb/AdbConfiguration.js +88 -0
  7. package/dist/adb/AdbDeviceOutput.js +186 -0
  8. package/dist/adb/AdbProvider.js +1190 -0
  9. package/dist/adb/AdbShellOutput.js +309 -0
  10. package/dist/android/AndroidTargetSnapshot.js +104 -22
  11. package/dist/android/JadxConfiguration.js +44 -24
  12. package/dist/android/JadxProvider.js +59 -21
  13. package/dist/android/JadxSession.js +51 -9
  14. package/dist/apktool/ApktoolConfiguration.js +84 -0
  15. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  16. package/dist/apktool/ApktoolProvider.js +506 -0
  17. package/dist/application/AnalysisProvider.js +8 -2
  18. package/dist/application/AppBundleExecutable.js +27 -22
  19. package/dist/application/BinaryTargetResolver.js +85 -19
  20. package/dist/application/BrowserScenarioEvidence.js +2 -2
  21. package/dist/application/CapabilityInventory.js +11 -1
  22. package/dist/application/ClientConfigurationDocument.js +98 -0
  23. package/dist/application/ClientConfigurationFiles.js +91 -0
  24. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  25. package/dist/application/ClientRegistrationStatus.js +75 -27
  26. package/dist/application/DirectAnalysis.js +14 -8
  27. package/dist/application/DirectAnalysisCleanup.js +1 -2
  28. package/dist/application/DirectAnalysisStatus.js +3 -6
  29. package/dist/application/Doctor.js +27 -34
  30. package/dist/application/DoctorDiagnostics.js +1 -1
  31. package/dist/application/EvidenceBundleCommands.js +6 -12
  32. package/dist/application/EvidenceBundleFiles.js +1 -1
  33. package/dist/application/GeminiClientSettings.js +139 -0
  34. package/dist/application/HermesClientHome.js +115 -0
  35. package/dist/application/HopperDownload.js +39 -0
  36. package/dist/application/InvestigationProviders.js +10 -4
  37. package/dist/application/JsonFiles.js +16 -15
  38. package/dist/application/JsonInputFile.js +252 -0
  39. package/dist/application/LinuxHopper.js +6 -13
  40. package/dist/application/MacHopper.js +172 -149
  41. package/dist/application/MipsElfAbiFlags.js +140 -0
  42. package/dist/application/ProviderOperationExecution.js +31 -0
  43. package/dist/application/ReconstructionObligationCandidates.js +16 -3
  44. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  45. package/dist/application/ReferenceSourceImport.js +76 -29
  46. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  47. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  48. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  49. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  50. package/dist/application/RegularFileRead.js +103 -0
  51. package/dist/application/Setup.js +69 -10
  52. package/dist/application/SetupClientConfiguration.js +134 -23
  53. package/dist/application/SetupHost.js +102 -22
  54. package/dist/application/SetupPlan.js +18 -17
  55. package/dist/application/SetupSkill.js +81 -13
  56. package/dist/application/SupportedClients.js +305 -37
  57. package/dist/application/Uninstall.js +172 -8
  58. package/dist/application/UpdateMaintenance.js +23 -23
  59. package/dist/application/Utf8JsonInput.js +71 -0
  60. package/dist/application/WebScriptExportService.js +130 -57
  61. package/dist/application/WebSourceLocationService.js +3 -0
  62. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  63. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  64. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  65. package/dist/application/android/AndroidAnalysisService.js +1 -1
  66. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  67. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  68. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  69. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  70. package/dist/application/binary/BinarySession.js +18 -1
  71. package/dist/application/binary/BinarySessionOpen.js +9 -1
  72. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  73. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  74. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  75. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  76. package/dist/application/evm/EvmInterfaceService.js +3 -0
  77. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  78. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  79. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  80. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  81. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  82. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  83. package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
  84. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  85. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  86. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  87. package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
  88. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  89. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  90. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
  91. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  92. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
  93. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  95. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
  96. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  97. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
  98. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
  99. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
  100. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  101. package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
  102. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  103. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  104. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
  105. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
  106. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  107. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
  108. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
  109. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  110. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  111. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
  112. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
  113. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  114. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  115. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
  116. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  117. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  118. package/dist/application/jeb/JebAnalysisService.js +13 -0
  119. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  120. package/dist/application/native/NativeCallRoutes.js +2 -4
  121. package/dist/application/native/NativeUiActionTrace.js +16 -8
  122. package/dist/application/native/NativeValueTrace.js +23 -6
  123. package/dist/application/process/ProcessCli.js +25 -20
  124. package/dist/artifacts/ArtifactPaths.js +129 -8
  125. package/dist/artifacts/ArtifactProvider.js +34 -31
  126. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  127. package/dist/artifacts/ArtifactReader.js +23 -0
  128. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  129. package/dist/artifacts/AsarArtifactReader.js +218 -80
  130. package/dist/artifacts/AsarHeader.js +24 -0
  131. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  132. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  133. package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
  134. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  135. package/dist/artifacts/SafeOutputTree.js +245 -70
  136. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  137. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  138. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  139. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  140. package/dist/artifacts/ZipArtifactReader.js +77 -27
  141. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  142. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  143. package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
  144. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  145. package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
  146. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
  147. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  148. package/dist/artifacts/inventory/classify.js +87 -25
  149. package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
  150. package/dist/artifacts/inventory/reader.js +13 -5
  151. package/dist/artifacts/inventory/scanCanonical.js +73 -30
  152. package/dist/artifacts/inventory/scanReader.js +43 -20
  153. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
  154. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  155. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  156. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  157. package/dist/browser/CdpBrowserProvider.js +9 -3
  158. package/dist/browser/CdpCaptureDocuments.js +40 -6
  159. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  160. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  161. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  162. package/dist/browser/CdpCaptureEvents.js +4 -9
  163. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  164. package/dist/browser/CdpConnection.js +22 -5
  165. package/dist/browser/CdpElectronInspection.js +2 -2
  166. package/dist/browser/CdpElectronProvider.js +4 -3
  167. package/dist/browser/CdpElectronScripts.js +2 -2
  168. package/dist/browser/CdpPageCapture.js +1 -1
  169. package/dist/browser/CdpTargetSession.js +30 -34
  170. package/dist/browser/CdpWebMcpDiscovery.js +48 -23
  171. package/dist/browser/ElectronFileScope.js +99 -9
  172. package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
  173. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  174. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  175. package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
  176. package/dist/browser/PlaywrightScenarioSession.js +130 -65
  177. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  178. package/dist/browser/PngVisualDiff.js +198 -29
  179. package/dist/browser/WebSourceMapFetcher.js +35 -9
  180. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  181. package/dist/browser/assets/PublishWebScripts.js +75 -20
  182. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  183. package/dist/browser/assets/WebArtifactReads.js +23 -1
  184. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  185. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  186. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  187. package/dist/browser/history/HarCapture.js +14 -0
  188. package/dist/browser/history/HarCaptureProcess.js +2 -10
  189. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  190. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  191. package/dist/cli/adbCommands.js +337 -0
  192. package/dist/cli/analysisViewCommands.js +39 -1
  193. package/dist/cli/apktoolCommands.js +53 -0
  194. package/dist/cli/artifactCommands.js +8 -11
  195. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  196. package/dist/cli/browserAdvancedCommands.js +65 -36
  197. package/dist/cli/coreAnalysisCommands.js +2 -2
  198. package/dist/cli/coreBinaryCommands.js +12 -13
  199. package/dist/cli/coreNativeCommands.js +1 -14
  200. package/dist/cli/electronCommands.js +14 -10
  201. package/dist/cli/evmCommands.js +13 -4
  202. package/dist/cli/firmwareCommands.js +7 -2
  203. package/dist/cli/javascriptApplicationAnalysis.js +19 -13
  204. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  205. package/dist/cli/jebCommands.js +99 -0
  206. package/dist/cli/jsonOutput.js +12 -4
  207. package/dist/cli/referenceSourceImportStatus.js +7 -0
  208. package/dist/cli/setupCommands.js +15 -3
  209. package/dist/cli/streamedJsonOutput.js +83 -4
  210. package/dist/cli/utilityCommands.js +68 -22
  211. package/dist/cli/webScriptCommands.js +20 -1
  212. package/dist/cli/webSourceLocationCommands.js +21 -9
  213. package/dist/cli.js +11 -2
  214. package/dist/cliBrowserScenarioCommands.js +2 -1
  215. package/dist/cliCommandNames.js +32 -0
  216. package/dist/cliJsonInput.js +47 -34
  217. package/dist/cliObservationOptions.js +7 -0
  218. package/dist/composition/adb.js +3 -0
  219. package/dist/composition/apktool.js +3 -0
  220. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  221. package/dist/composition/binaryDiagnostics.js +4 -0
  222. package/dist/composition/browserScenario.js +2 -2
  223. package/dist/composition/directAnalysis.js +14 -7
  224. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  225. package/dist/composition/jeb.js +6 -0
  226. package/dist/config/environment.js +10 -0
  227. package/dist/config/ghidraLanguageOverride.js +9 -0
  228. package/dist/config/mcpInputSchemaProfile.js +27 -0
  229. package/dist/config/parseConfig.js +28 -1
  230. package/dist/contracts/adb/adbToolContracts.js +353 -0
  231. package/dist/contracts/advertisedInputExamples.js +48 -0
  232. package/dist/contracts/analysisDetail.js +10 -0
  233. package/dist/contracts/analysisViewToolContracts.js +17 -2
  234. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  235. package/dist/contracts/artifactComparisonExample.js +5 -5
  236. package/dist/contracts/artifactToolContracts.js +8 -5
  237. package/dist/contracts/browserToolContracts.js +1 -1
  238. package/dist/contracts/compactInputSchema.js +256 -0
  239. package/dist/contracts/errorSchemas.js +3 -1
  240. package/dist/contracts/functionComparisonExample.js +8 -0
  241. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  242. package/dist/contracts/inputSchemaPresentation.js +104 -13
  243. package/dist/contracts/javascript/electronToolContracts.js +16 -3
  244. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  245. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  246. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  247. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  248. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  249. package/dist/contracts/managed/managedToolContracts.js +3 -2
  250. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  251. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  252. package/dist/contracts/native/nativeToolContracts.js +1 -1
  253. package/dist/contracts/officialToolContracts.js +5 -5
  254. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  255. package/dist/contracts/sessionStatusContract.js +3 -2
  256. package/dist/contracts/sessionToolContracts.js +5 -4
  257. package/dist/contracts/sessionToolSchemas.js +9 -4
  258. package/dist/contracts/toolContractExamples.js +6 -0
  259. package/dist/contracts/toolContractTypes.js +3 -0
  260. package/dist/contracts/toolContracts.js +6 -0
  261. package/dist/contracts/toolEffects.js +167 -0
  262. package/dist/contracts/toolOutputSchemaGroups.js +7 -5
  263. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  264. package/dist/contracts/toolSchemaMetadata.js +82 -7
  265. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  266. package/dist/domain/analysisErrorBase.js +5 -0
  267. package/dist/domain/analysisErrorCleanup.js +29 -0
  268. package/dist/domain/analysisErrorPresentation.js +18 -4
  269. package/dist/domain/analysisErrorProjection.js +4 -1
  270. package/dist/domain/analysisSnapshot.js +5 -2
  271. package/dist/domain/analysisView/analysisView.js +53 -5
  272. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  273. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  274. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  275. package/dist/domain/android/androidApplication.js +25 -20
  276. package/dist/domain/android/androidPartialObservation.js +36 -0
  277. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  278. package/dist/domain/apple/appleApplication.js +40 -23
  279. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  280. package/dist/domain/apple/dyldPaths.js +9 -1
  281. package/dist/domain/apple/dylibResolution.js +3 -3
  282. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  283. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  284. package/dist/domain/artifactComparison.js +39 -11
  285. package/dist/domain/artifactGraph.js +6 -4
  286. package/dist/domain/artifactIdentity.js +37 -9
  287. package/dist/domain/artifactInspection.js +10 -50
  288. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  289. package/dist/domain/artifactInventoryEvidence.js +16 -17
  290. package/dist/domain/artifactPathSyntax.js +1 -1
  291. package/dist/domain/binaryTarget.js +16 -0
  292. package/dist/domain/binaryTargetTypes.js +8 -1
  293. package/dist/domain/browserCompleteness.js +3 -2
  294. package/dist/domain/browserObservationSchemas.js +8 -4
  295. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  296. package/dist/domain/browserScenarioNormalization.js +3 -3
  297. package/dist/domain/browserScenarioValues.js +3 -2
  298. package/dist/domain/callPath.js +8 -10
  299. package/dist/domain/canonicalDigest.js +7 -1
  300. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  301. package/dist/domain/canonicalOrdering.js +1 -13
  302. package/dist/domain/changedBehavior.js +2 -3
  303. package/dist/domain/compactStringIdentity.js +9 -0
  304. package/dist/domain/comparisonSemantics.js +0 -5
  305. package/dist/domain/digests.js +0 -3
  306. package/dist/domain/evidence.js +12 -6
  307. package/dist/domain/evidenceBundle.js +51 -33
  308. package/dist/domain/evidenceRecordSummary.js +144 -0
  309. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  310. package/dist/domain/functionComparison.js +2 -1
  311. package/dist/domain/functionComparisonNormalization.js +4 -3
  312. package/dist/domain/functionComparisonResults.js +2 -2
  313. package/dist/domain/functionDossierEvidence.js +2 -1
  314. package/dist/domain/hopperValues.js +11 -15
  315. package/dist/domain/inputIssueProjection.js +16 -1
  316. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  317. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
  318. package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
  319. package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
  320. package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
  321. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  322. package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
  323. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
  324. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  325. package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
  326. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  327. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  328. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  329. package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
  330. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
  331. package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
  332. package/dist/domain/javascript/javascriptAstValues.js +54 -0
  333. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  334. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  335. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  336. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  337. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  338. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  339. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  340. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  341. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  342. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  343. package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
  344. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  345. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  346. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  347. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  348. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  349. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  350. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
  351. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  352. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  353. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  354. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  355. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  356. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  357. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
  358. package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
  359. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  360. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  361. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  362. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  363. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  364. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  365. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  366. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  367. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  368. package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
  369. package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
  370. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
  371. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  372. package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
  373. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
  374. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  375. package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
  376. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  377. package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
  378. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  379. package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
  380. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  381. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
  382. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  383. package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
  384. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
  385. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  386. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  387. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  388. package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
  389. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  390. package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
  391. package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
  392. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  393. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  394. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  395. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  396. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
  397. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  398. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  399. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  400. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  401. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  402. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  403. package/dist/domain/jeb/jebAnalysis.js +114 -0
  404. package/dist/domain/jsonSerialization.js +109 -55
  405. package/dist/domain/jsonShape.js +69 -31
  406. package/dist/domain/jsonValue.js +3 -0
  407. package/dist/domain/localPath.js +10 -4
  408. package/dist/domain/managed/managedApplicationGraph.js +47 -6
  409. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  410. package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
  411. package/dist/domain/managed/managedArtifact.js +1 -0
  412. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  413. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  414. package/dist/domain/native/nativeAotPe.js +1408 -0
  415. package/dist/domain/native/nativeCallObservation.js +2 -4
  416. package/dist/domain/native/nativeInstruction.js +21 -0
  417. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  418. package/dist/domain/native/nativeValueFlow.js +5 -11
  419. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  420. package/dist/domain/native/peResources.js +94 -0
  421. package/dist/domain/nativeConvention.js +33 -0
  422. package/dist/domain/process/processCapture.js +102 -11
  423. package/dist/domain/process/processCaptureCoverage.js +8 -5
  424. package/dist/domain/process/processCaptureExample.js +67 -0
  425. package/dist/domain/process/processCaptureValidation.js +83 -3
  426. package/dist/domain/process/processComparison.js +0 -23
  427. package/dist/domain/process/processScenario.js +62 -10
  428. package/dist/domain/process/processTraceEvaluation.js +4 -4
  429. package/dist/domain/process/processTraceSpecification.js +1 -3
  430. package/dist/domain/propertyListKeys.js +3 -1
  431. package/dist/domain/providerCleanupError.js +6 -2
  432. package/dist/domain/reconstructionCoverage.js +2 -1
  433. package/dist/domain/reconstructionUnknowns.js +4 -3
  434. package/dist/domain/reconstructionVerification.js +3 -2
  435. package/dist/domain/referenceSourceGraph.js +32 -23
  436. package/dist/domain/referenceSourceImportParsing.js +40 -48
  437. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  438. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  439. package/dist/domain/residualUnknown.js +3 -2
  440. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  441. package/dist/domain/swiftSymbolClassification.js +6 -1
  442. package/dist/domain/symbolAnalysis.js +17 -2
  443. package/dist/domain/unicodeCodePointOrder.js +6 -0
  444. package/dist/domain/webBundleAnalyzerInspection.js +23 -3
  445. package/dist/domain/webCaptureDiff.js +170 -30
  446. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  447. package/dist/domain/webInventory.js +3 -2
  448. package/dist/domain/webMcpDiscovery.js +4 -3
  449. package/dist/domain/webScriptExport.js +1 -1
  450. package/dist/domain/webScriptExportError.js +10 -4
  451. package/dist/domain/webScriptExportPlan.js +7 -13
  452. package/dist/domain/zipPackageFormat.js +4 -1
  453. package/dist/domain/zodCollectionSteps.js +24 -0
  454. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  455. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  456. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  457. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  458. package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
  459. package/dist/dotnet/ManagedMemberRows.js +9 -4
  460. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  461. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  462. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  463. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  464. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  465. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  466. package/dist/dotnet/ManagedPeReader.js +41 -25
  467. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  468. package/dist/dotnet/ManagedStaticProvider.js +65 -31
  469. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  470. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  471. package/dist/evaluation/CodexAgentEval.js +43 -13
  472. package/dist/evm/EvmoleFailures.js +0 -2
  473. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  474. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  475. package/dist/filesystem/OwnedFileHandle.js +36 -0
  476. package/dist/filesystem/RegularFile.js +73 -0
  477. package/dist/filesystem/StableFileHash.js +46 -0
  478. package/dist/filesystem/readFileHandleChunks.js +26 -0
  479. package/dist/firmware/FirmwareCommand.js +25 -3
  480. package/dist/firmware/FirmwareFiles.js +23 -8
  481. package/dist/firmware/FirmwareProvider.js +156 -32
  482. package/dist/firmware/FirmwarePublication.js +24 -3
  483. package/dist/firmware/FirmwareRelease.js +1 -0
  484. package/dist/generatedPackageMetadata.js +2 -2
  485. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  486. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  487. package/dist/ghidra/GhidraClient.js +90 -8
  488. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  489. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  490. package/dist/ghidra/GhidraInstallation.js +111 -10
  491. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  492. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  493. package/dist/ghidra/GhidraLauncher.js +123 -58
  494. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  495. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  496. package/dist/ghidra/GhidraProvider.js +57 -9
  497. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  498. package/dist/ghidra/GhidraProviderClient.js +282 -21
  499. package/dist/ghidra/GhidraSessionValues.js +9 -2
  500. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  501. package/dist/hopper/HopperCleanup.js +1 -1
  502. package/dist/hopper/HopperClient.js +15 -6
  503. package/dist/hopper/HopperMachOImage.js +2 -0
  504. package/dist/hopper/HopperProvider.js +13 -2
  505. package/dist/ida/IdaOperationRunner.js +10 -2
  506. package/dist/ida/IdaProvider.js +7 -0
  507. package/dist/ida/IdaSessionClient.js +7 -3
  508. package/dist/ida/IdaWorkspace.js +4 -2
  509. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  510. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  511. package/dist/inspector/V8InspectorProvider.js +60 -8
  512. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  513. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  514. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  515. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  516. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  517. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  518. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  519. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  520. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  521. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  522. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  523. package/dist/javascript/recovery/WakaruReport.js +12 -7
  524. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  525. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  526. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  527. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  528. package/dist/jeb/JebMcpConnection.js +179 -0
  529. package/dist/jeb/JebMcpEndpoint.js +40 -0
  530. package/dist/jeb/JebProvider.js +299 -0
  531. package/dist/main/shutdown.js +76 -32
  532. package/dist/main/transport.js +1 -1
  533. package/dist/mcpDoctor.js +15 -6
  534. package/dist/native/AppleDispatchCoverage.js +25 -12
  535. package/dist/native/AppleDispatchMetadata.js +14 -7
  536. package/dist/native/AppleMachoFixups.js +71 -15
  537. package/dist/native/AppleMachoSelection.js +23 -3
  538. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  539. package/dist/native/AppleObjcProperties.js +17 -7
  540. package/dist/native/LldbCallTracer.js +241 -75
  541. package/dist/native/NativeMacOSProvider.js +100 -20
  542. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  543. package/dist/native/NativeMachoInspection.js +11 -7
  544. package/dist/native/NativeUiHelperRuntime.js +6 -1
  545. package/dist/native/NativeUiObservation.js +4 -3
  546. package/dist/native/pe/PeResourceLayout.js +120 -0
  547. package/dist/native/pe/PeResourceParser.js +286 -0
  548. package/dist/native/pe/PeResourcesProvider.js +63 -0
  549. package/dist/process/BoundedFileBytes.js +30 -7
  550. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  551. package/dist/process/OwnedCommand.js +4 -3
  552. package/dist/process/ProcessOwnership.js +104 -112
  553. package/dist/process/ProcessOwnershipObservation.js +104 -51
  554. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  555. package/dist/process/ProcessRunTokenObservations.js +48 -0
  556. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  557. package/dist/process/ProviderProcess.js +4 -3
  558. package/dist/process/capture/FilesystemSnapshot.js +116 -22
  559. package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
  560. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  561. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  562. package/dist/process/capture/ProcessHarness.js +202 -47
  563. package/dist/process/capture/ProcessNormalization.js +3 -1
  564. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  565. package/dist/process/capture/TerminalRenderer.js +24 -7
  566. package/dist/reference/ReferenceSourceReader.js +22 -5
  567. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  568. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  569. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  570. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  571. package/dist/server/EvidenceMcpServer.js +36 -1
  572. package/dist/server/admittedToolOperation.js +9 -0
  573. package/dist/server/analysisAdmission.js +8 -0
  574. package/dist/server/contractToolHandler.js +21 -0
  575. package/dist/server/createServer.js +118 -47
  576. package/dist/server/registerAdbTools.js +36 -0
  577. package/dist/server/registerAnalysisViewTool.js +4 -9
  578. package/dist/server/registerAndroidTools.js +3 -12
  579. package/dist/server/registerApktoolTools.js +14 -0
  580. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
  581. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  582. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  583. package/dist/server/registerApplicationTools/coverage.js +3 -2
  584. package/dist/server/registerApplicationTools/helpers.js +3 -2
  585. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  586. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  587. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  588. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  589. package/dist/server/registerArtifactComparisonTool.js +5 -2
  590. package/dist/server/registerArtifactTools.js +2 -2
  591. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  592. package/dist/server/registerBrowserScenarioTool.js +10 -7
  593. package/dist/server/registerBrowserTools.js +12 -9
  594. package/dist/server/registerBundleComparisonTool.js +16 -2
  595. package/dist/server/registerCloseLifecycleTool.js +36 -5
  596. package/dist/server/registerElectronTools.js +28 -10
  597. package/dist/server/registerEnhancedTools.js +78 -73
  598. package/dist/server/registerEvidenceTools.js +54 -46
  599. package/dist/server/registerEvmTools.js +4 -9
  600. package/dist/server/registerFirmwareTools.js +3 -11
  601. package/dist/server/registerFunctionComparisonTool.js +5 -2
  602. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  603. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  604. package/dist/server/registerJebTools.js +16 -0
  605. package/dist/server/registerManagedTools.js +7 -4
  606. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  607. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  608. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  609. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  610. package/dist/server/registerOfficialTools.js +31 -25
  611. package/dist/server/registerPeResourcesTool.js +9 -0
  612. package/dist/server/registerProcessComparisonTool.js +5 -2
  613. package/dist/server/registerRecordedCrashTools.js +4 -9
  614. package/dist/server/registerSessionRecordTools.js +2 -1
  615. package/dist/server/registerSessionTools.js +58 -21
  616. package/dist/server/registerWebModuleTool.js +4 -9
  617. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  618. package/dist/server/registerWebRuntimeTools.js +6 -5
  619. package/dist/server/registerWebScriptTool.js +6 -3
  620. package/dist/server/registerWebSourceLocationTool.js +4 -9
  621. package/dist/server/toolResult.js +21 -2
  622. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  623. package/install.sh +7 -4
  624. package/licenses/nativeaot-parser-MIT.txt +28 -0
  625. package/native/windows/build/manifest.json +2 -2
  626. package/native/windows/build/rea-windows-x64.node +0 -0
  627. package/package.json +38 -7
  628. package/scripts/rea.mjs +16 -1
  629. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  630. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  631. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  632. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  633. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
  634. package/dist/artifacts/inventory/policy.js +0 -2
  635. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  636. package/dist/server/registerNativeTools.js +0 -6
@@ -29,6 +29,41 @@ const LC_VERSION_MIN_IPHONEOS = 0x25;
29
29
  const LC_VERSION_MIN_TVOS = 0x2f;
30
30
  const LC_VERSION_MIN_WATCHOS = 0x30;
31
31
  const LC_BUILD_VERSION = 0x32;
32
+ // `mach-o/loader.h` `PLATFORM_*` numbers observed via Apple linker output.
33
+ const PLATFORM_MACOS = 1;
34
+ const PLATFORM_IOS = 2;
35
+ const PLATFORM_TVOS = 3;
36
+ const PLATFORM_WATCHOS = 4;
37
+ const PLATFORM_IOSSIMULATOR = 7;
38
+ const PLATFORM_TVOSSIMULATOR = 8;
39
+ const PLATFORM_WATCHOSSIMULATOR = 9;
40
+ const CPU_TYPE_I386 = 7;
41
+ const CPU_TYPE_X86_64 = 0x01000007;
42
+ /**
43
+ * Legacy `LC_VERSION_MIN_*` commands predate explicit simulator platform
44
+ * IDs. Per Apple's dyld rules the image CPU type distinguishes simulator
45
+ * from device: Intel images are simulator, ARM images are device
46
+ * (tvOS simulator applies to x86_64 only). `LC_BUILD_VERSION` platform
47
+ * numbers are preserved verbatim; unknown future numbers stay unknown
48
+ * downstream, never mapped to nearest.
49
+ */
50
+ const legacyVersionMinPlatform = (command, cpuType) => {
51
+ const isIntel = cpuType === CPU_TYPE_I386 || cpuType === CPU_TYPE_X86_64;
52
+ switch (command) {
53
+ case LC_VERSION_MIN_MACOSX:
54
+ return PLATFORM_MACOS;
55
+ case LC_VERSION_MIN_IPHONEOS:
56
+ return isIntel ? PLATFORM_IOSSIMULATOR : PLATFORM_IOS;
57
+ case LC_VERSION_MIN_TVOS:
58
+ return cpuType === CPU_TYPE_X86_64
59
+ ? PLATFORM_TVOSSIMULATOR
60
+ : PLATFORM_TVOS;
61
+ case LC_VERSION_MIN_WATCHOS:
62
+ return isIntel ? PLATFORM_WATCHOSSIMULATOR : PLATFORM_WATCHOS;
63
+ default:
64
+ return undefined;
65
+ }
66
+ };
32
67
  /** `mach-o/loader.h` `dylib_use_command`: `nameoff == 28` and this marker. */
33
68
  const DYLIB_USE_MARKER = 0x1a741800;
34
69
  const DYLIB_USE_WEAK_LINK = 0x1;
@@ -258,12 +293,7 @@ const decodeCommand = (command, body, index, slice) => {
258
293
  slice.platforms.push(platform);
259
294
  return;
260
295
  }
261
- const legacyPlatform = new Map([
262
- [LC_VERSION_MIN_MACOSX, 1],
263
- [LC_VERSION_MIN_IPHONEOS, 2],
264
- [LC_VERSION_MIN_TVOS, 3],
265
- [LC_VERSION_MIN_WATCHOS, 4],
266
- ]).get(command);
296
+ const legacyPlatform = legacyVersionMinPlatform(command, slice.cpu_type);
267
297
  if (legacyPlatform !== undefined) {
268
298
  if (body.byteLength < 16)
269
299
  throw new MachoFormatIssue("malformed", `load command ${index} is too short for a version-min command`);
@@ -1,50 +1,85 @@
1
1
  import { lstat, realpath } from "node:fs/promises";
2
- import { compareCodePoints } from "../../domain/canonicalOrdering.js";
3
- import { canonicalDigest } from "../../domain/comparisonSemantics.js";
2
+ import { compareUnicodeCodePoints } from "../../domain/unicodeCodePointOrder.js";
3
+ import { digestCanonicalValue } from "../../domain/canonicalDigest.js";
4
4
  import { AsarArtifactReader } from "../AsarArtifactReader.js";
5
5
  import { ArtifactPathRegistry, normalizeArtifactPath, } from "../ArtifactPaths.js";
6
6
  import { ArtifactReaderFailure, } from "../ArtifactReader.js";
7
7
  import { abortIfNeeded } from "../ArtifactHash.js";
8
8
  import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
9
9
  import { SafeOutputTree } from "../SafeOutputTree.js";
10
+ import { SafeOutputTreeCreationFailure } from "../SafeOutputTreeCreationFailure.js";
10
11
  import { ZipArtifactReader } from "../ZipArtifactReader.js";
11
12
  import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
12
13
  import { artifactExtractionResultSchema, } from "../../domain/artifactGraph.js";
13
14
  import { AnalysisUnsupportedTargetError } from "../../domain/analysisErrorCore.js";
14
- import { scanArtifactInventory } from "../inventory/ArtifactInventory.js";
15
+ import {} from "../ArtifactResourceScope.js";
16
+ import { scanArtifactInventoryInScope } from "../inventory/ArtifactInventory.js";
15
17
  /** Extract every regular inventory occurrence into an exclusively owned absent root. */
16
- export const extractArtifact = async (input, signal) => {
18
+ export const extractArtifact = async (input, signal) => input.resourceScope.run(() => extractArtifactInScope(input, signal));
19
+ const extractArtifactInScope = async (input, signal) => {
17
20
  // Cancellation wins over every later refusal, including unsupported formats.
18
21
  abortIfNeeded(signal);
19
22
  const sourcePath = await realpath(input.inputPath);
20
23
  await requireExtractableFormat(sourcePath, input);
21
- const snapshot = await scanArtifactInventory(sourcePath, {
24
+ const snapshot = await scanArtifactInventoryInScope(sourcePath, {
25
+ resourceScope: input.resourceScope,
22
26
  signal,
23
27
  environment: input.environment,
28
+ integrity: { mode: input.integrityPolicy },
24
29
  });
30
+ return materializeArtifactInventoryInScope(input, sourcePath, snapshot, signal);
31
+ };
32
+ /** Materialize a scanned inventory, verifying every current occurrence against it. */
33
+ export const materializeArtifactInventory = async (input, sourcePath, snapshot, signal) => {
34
+ return input.resourceScope.run(() => materializeArtifactInventoryInScope(input, sourcePath, snapshot, signal));
35
+ };
36
+ const materializeArtifactInventoryInScope = async (input, sourcePath, snapshot, signal) => {
37
+ abortIfNeeded(signal);
25
38
  const selectedOccurrences = snapshot.occurrences.filter((occurrence) => (occurrence.entry_kind === "file" || occurrence.entry_kind === "slice") &&
26
39
  occurrence.logical_path !== ".");
27
- const selectedIds = new Set(selectedOccurrences.map(({ occurrence_id: id }) => id));
28
- const occurrences = new Map();
29
- const neededNodes = new Set();
30
- collectOccurrences(snapshot.occurrences, selectedIds, occurrences, neededNodes);
40
+ const regularPaths = new Set(selectedOccurrences.map(({ logical_path: path }) => path));
41
+ const activeOccurrences = selectedOccurrences.filter(({ logical_path }) => {
42
+ // Nested members remain represented by their containing regular file;
43
+ // only entries exposed by the active reader are materialized.
44
+ let path = logical_path;
45
+ for (let slash = path.lastIndexOf("/"); slash >= 0; slash = path.lastIndexOf("/")) {
46
+ path = path.slice(0, slash);
47
+ if (regularPaths.has(path))
48
+ return false;
49
+ }
50
+ return true;
51
+ });
52
+ const selectedIds = new Set(activeOccurrences.map(({ occurrence_id: id }) => id));
53
+ const neededNodes = new Set(activeOccurrences.map(({ artifact_id: id }) => id));
31
54
  const nodes = new Map();
32
- collectNodes(snapshot.nodes, neededNodes, nodes);
55
+ for (const node of snapshot.nodes)
56
+ if (neededNodes.has(node.artifact_id))
57
+ nodes.set(node.artifact_id, node);
33
58
  const inventory = {
34
59
  manifest: snapshot.manifest,
35
- occurrences,
36
- nodes,
60
+ integrityContradictions: snapshot.integrity_contradictions.filter(({ occurrence_id: id }) => selectedIds.has(id)),
37
61
  };
38
- const selected = selectedOccurrences.map((occurrence) => {
62
+ const selected = activeOccurrences.map((occurrence) => {
39
63
  // REA never decrypts archive entries, so an encrypted entry makes the
40
64
  // complete extraction unsupported rather than the archive invalid.
41
65
  if (occurrence.encrypted)
42
66
  throw new AnalysisUnsupportedTargetError("extract_artifact", input.inputPath, `Archive entry ${occurrence.logical_path} is encrypted; REA does not decrypt archive entries, so the archive cannot be extracted completely`);
67
+ // Inventory keeps an ASAR unpacked entry whose companion file is absent,
68
+ // but extraction cannot materialize bytes it never observed.
69
+ if (occurrence.entry_kind === "file" &&
70
+ occurrence.artifact_id === null &&
71
+ occurrence.hash_status === "unavailable")
72
+ throw new ArtifactReaderFailure("unavailable", `ASAR unpacked companion bytes are unavailable for ${occurrence.logical_path}`, undefined, {
73
+ logicalPath: occurrence.logical_path,
74
+ declaredSha256: null,
75
+ calculatedSha256: null,
76
+ unpacked: true,
77
+ });
43
78
  if ((occurrence.entry_kind !== "file" && occurrence.entry_kind !== "slice") ||
44
79
  occurrence.artifact_id === null ||
45
80
  occurrence.logical_path === ".")
46
81
  throw new ArtifactReaderFailure("format", `Selected occurrence is not an extractable regular child file: ${occurrence.logical_path} (${occurrence.occurrence_id})`);
47
- const node = inventory.nodes.get(occurrence.artifact_id);
82
+ const node = nodes.get(occurrence.artifact_id);
48
83
  if (node === undefined)
49
84
  throw new ArtifactReaderFailure("integrity", `Selected occurrence has no inventory node: ${occurrence.occurrence_id}`);
50
85
  return { occurrence, node };
@@ -60,73 +95,36 @@ export const extractArtifact = async (input, signal) => {
60
95
  const materializeSelection = async ({ input, sourcePath, inventory, selected, signal, }) => {
61
96
  const byPath = new Map(selected.map((item) => [item.occurrence.logical_path, item]));
62
97
  const reader = await createReader(sourcePath, input);
98
+ const readerOwner = {
99
+ kind: "reader",
100
+ reader,
101
+ resource: `artifact reader for ${sourcePath}`,
102
+ };
103
+ let localReaderOwner = readerOwner;
63
104
  let output;
64
- let readerCloseAttempted = false;
65
- let readerClosed = false;
105
+ let completed;
66
106
  const extracted = [];
67
107
  try {
68
- output = await SafeOutputTree.create(input.outputRoot);
69
- const materialized = [];
70
- const registry = new ArtifactPathRegistry();
71
- for await (const entry of reader.entries(signal)) {
72
- const path = normalizeArtifactPath(entry.path);
73
- registry.add(path, entry.kind);
74
- const selectedItem = byPath.get(path);
75
- if (selectedItem === undefined) {
76
- if (entry.kind === "file" || entry.kind === "slice")
77
- throw new ArtifactReaderFailure("integrity", `Regular artifact entry is missing from inventory: ${path}`);
78
- continue;
79
- }
80
- preflight(entry);
81
- const stream = await reader.open(entry, signal);
82
- const written = await output.write(path, stream, selectedItem.node.sha256, signal);
83
- extracted.push({
84
- artifact_id: selectedItem.node.artifact_id,
85
- relative_path: written.relativePath,
86
- sha256: written.sha256,
87
- bytes_written: written.bytesWritten,
88
- created: true,
89
- });
90
- materialized.push(selectedItem);
108
+ try {
109
+ output = await SafeOutputTree.create(input.outputRoot);
110
+ }
111
+ catch (cause) {
112
+ if (cause instanceof SafeOutputTreeCreationFailure)
113
+ output = cause.tree;
114
+ throw cause;
91
115
  }
92
- readerCloseAttempted = true;
93
- await reader.close();
94
- readerClosed = true;
95
- extracted.sort((left, right) => compareCodePoints(left.relative_path, right.relative_path));
96
- const result = createExtractionResult(input, inventory, materialized, extracted);
116
+ await writeSelectedEntries({ reader, output, byPath, extracted, signal });
117
+ localReaderOwner = undefined;
118
+ const closeAttempt = await input.resourceScope.release(readerOwner);
119
+ if (closeAttempt.kind === "failed")
120
+ throw ArtifactReaderFailure.withCleanup(closeAttempt.cause, ArtifactReaderFailure.cleanupObservation(closeAttempt.cause, readerOwner.resource));
121
+ extracted.sort((left, right) => compareUnicodeCodePoints(left.relative_path, right.relative_path));
122
+ completed = createExtractionResult(input, inventory, selected, extracted);
97
123
  await output.commit();
98
- return result;
124
+ return completed;
99
125
  }
100
126
  catch (cause) {
101
- const cleanupFailures = [];
102
- if (readerCloseAttempted && !readerClosed)
103
- cleanupFailures.push({
104
- cause,
105
- resource: `artifact reader for ${sourcePath}`,
106
- });
107
- if (!readerCloseAttempted) {
108
- try {
109
- readerCloseAttempted = true;
110
- await reader.close();
111
- }
112
- catch (cleanupCause) {
113
- cleanupFailures.push({
114
- cause: cleanupCause,
115
- resource: `artifact reader for ${sourcePath}`,
116
- });
117
- }
118
- }
119
- if (output !== undefined) {
120
- try {
121
- await output.rollback();
122
- }
123
- catch (cleanupCause) {
124
- cleanupFailures.push({
125
- cause: cleanupCause,
126
- resource: input.outputRoot,
127
- });
128
- }
129
- }
127
+ const cleanupFailures = await releaseExtractionOwners(input.resourceScope, localReaderOwner, output, input.outputRoot);
130
128
  if (cleanupFailures.length > 0) {
131
129
  const observations = cleanupFailures.map(({ cause: cleanupCause, resource }) => ArtifactReaderFailure.cleanupObservation(cleanupCause, resource));
132
130
  throw ArtifactReaderFailure.withCleanup(cause, {
@@ -134,50 +132,94 @@ const materializeSelection = async ({ input, sourcePath, inventory, selected, si
134
132
  resources: [
135
133
  ...new Set(observations.flatMap(({ resources }) => resources)),
136
134
  ],
137
- });
135
+ }, output?.published === true && completed !== undefined
136
+ ? { kind: "artifact-extraction", extraction: completed }
137
+ : undefined);
138
138
  }
139
+ if (output?.published === true && completed !== undefined)
140
+ return completed;
139
141
  throw cause;
140
142
  }
141
143
  };
144
+ const writeSelectedEntries = async ({ reader, output, byPath, extracted, signal, }) => {
145
+ const registry = new ArtifactPathRegistry();
146
+ for await (const entry of reader.entries(signal)) {
147
+ const path = normalizeArtifactPath(entry.path);
148
+ registry.add(path, entry.kind);
149
+ const selectedItem = byPath.get(path);
150
+ if (selectedItem === undefined) {
151
+ if (entry.kind === "file" || entry.kind === "slice")
152
+ throw new ArtifactReaderFailure("integrity", `Regular artifact entry is missing from inventory: ${path}`);
153
+ continue;
154
+ }
155
+ preflight(entry);
156
+ const stream = await reader.open(entry, signal);
157
+ const written = await output.write(path, stream, {
158
+ sha256: selectedItem.node.sha256,
159
+ bytes: selectedItem.node.size,
160
+ }, signal);
161
+ extracted.push({
162
+ artifact_id: selectedItem.node.artifact_id,
163
+ relative_path: written.relativePath,
164
+ sha256: written.sha256,
165
+ bytes_written: written.bytesWritten,
166
+ created: true,
167
+ });
168
+ byPath.delete(path);
169
+ }
170
+ if (byPath.size > 0)
171
+ throw new ArtifactReaderFailure("integrity", `Inventoried regular artifact entries were not materialized: ${[...byPath.keys()].sort(compareUnicodeCodePoints).join(", ")}`);
172
+ };
173
+ const releaseExtractionOwners = async (resourceScope, readerOwner, output, outputRoot) => {
174
+ const failures = [];
175
+ if (readerOwner !== undefined) {
176
+ const attempt = await resourceScope.release(readerOwner);
177
+ if (attempt.kind === "failed")
178
+ failures.push({ cause: attempt.cause, resource: readerOwner.resource });
179
+ }
180
+ if (output !== undefined) {
181
+ const owner = {
182
+ kind: "output-tree",
183
+ tree: output,
184
+ resource: outputRoot,
185
+ };
186
+ const attempt = await resourceScope.release(owner);
187
+ if (attempt.kind === "failed")
188
+ failures.push({ cause: attempt.cause, resource: owner.resource });
189
+ }
190
+ return failures;
191
+ };
142
192
  const createExtractionResult = (input, inventory, selected, extracted) => {
143
193
  const extractionSemantic = {
144
194
  source_manifest_id: inventory.manifest.manifest_id,
145
195
  selected_occurrence_ids: selected
146
196
  .map(({ occurrence }) => occurrence.occurrence_id)
147
- .sort(compareCodePoints),
148
- files_sha256: canonicalDigest(extracted, "Artifact"),
197
+ .sort(compareUnicodeCodePoints),
198
+ files_sha256: digestCanonicalValue(extracted, "Artifact"),
149
199
  output_root_alias: "$OUTPUT_ROOT",
150
200
  };
151
201
  return artifactExtractionResultSchema.parse({
152
202
  manifest: inventory.manifest,
153
203
  extraction_manifest: {
154
204
  ...extractionSemantic,
155
- extraction_id: `aex_${canonicalDigest(extractionSemantic, "Artifact")}`,
205
+ extraction_id: `aex_${digestCanonicalValue(extractionSemantic, "Artifact")}`,
156
206
  },
157
207
  output_root: input.outputRoot,
158
208
  artifacts: extracted,
159
209
  containment_verified: true,
160
210
  cleanup: { attempted: false, verified: true, residual_paths: [] },
161
211
  provenance: [],
212
+ integrity_contradictions: inventory.integrityContradictions,
162
213
  limitations: [
163
214
  "All regular files in the active artifact were materialized; nested archive contents remain represented by their containing file.",
215
+ ...(inventory.integrityContradictions.length === 0
216
+ ? []
217
+ : [
218
+ `${String(inventory.integrityContradictions.length)} extracted file(s) contradict declared integrity metadata; their bytes are observed-untrusted.`,
219
+ ]),
164
220
  ],
165
221
  });
166
222
  };
167
- const collectOccurrences = (items, selected, output, neededNodes) => {
168
- for (const item of items) {
169
- if (!selected.has(item.occurrence_id))
170
- continue;
171
- output.set(item.occurrence_id, item);
172
- if (item.artifact_id !== null)
173
- neededNodes.add(item.artifact_id);
174
- }
175
- };
176
- const collectNodes = (items, selected, output) => {
177
- for (const item of items)
178
- if (selected.has(item.artifact_id))
179
- output.set(item.artifact_id, item);
180
- };
181
223
  const ZIP_FORMATS = ["ipa", "apk", "msix", "appx", "zip"];
182
224
  const isZipFormat = (format) => ZIP_FORMATS.includes(format);
183
225
  /**
@@ -1,5 +1,5 @@
1
- import { compareCodePoints } from "../../domain/canonicalOrdering.js";
2
- import { canonicalDigest } from "../../domain/comparisonSemantics.js";
1
+ import { compareUnicodeCodePoints } from "../../domain/unicodeCodePointOrder.js";
2
+ import { digestCanonicalValue } from "../../domain/canonicalDigest.js";
3
3
  import { artifactEdgeId, artifactIdForContent, occurrenceIdForLocation, } from "../../domain/artifactIdentity.js";
4
4
  import { hasZipSignature, zipPackageFormatForPath, } from "../../domain/zipPackageFormat.js";
5
5
  import { mzWindowsHeaderOffset, parseDosMzHeader } from "../../domain/dosMz.js";
@@ -11,32 +11,55 @@ export const indexOccurrencesByPath = (occurrences) => {
11
11
  byPath.set(occurrence.logical_path, occurrence);
12
12
  return byPath;
13
13
  };
14
- export const createOccurrence = (entry, path, parent) => ({
15
- occurrence_id: `occ_${canonicalDigest({ path, kind: entry.kind }, "Artifact")}`,
16
- artifact_id: null,
17
- parent_occurrence_id: parent,
18
- logical_path: path,
19
- entry_kind: entry.kind,
20
- artifact_kind: entry.kind === "directory"
21
- ? path.toLowerCase().endsWith(".framework")
22
- ? "framework"
23
- : "container"
24
- : classifyArtifactPath(path).kind,
25
- artifact_format: entry.kind === "directory"
26
- ? "directory"
27
- : classifyArtifactPath(path).format,
28
- declared_size: entry.declaredSize,
29
- compressed_size: entry.compressedSize,
30
- executable: entry.executable,
31
- encrypted: entry.encrypted,
32
- hash_status: entry.encrypted ? "unavailable" : "not-hashed",
33
- source_location: entry.byteOffset === null || entry.declaredSize === null
34
- ? null
35
- : { offset: entry.byteOffset, length: entry.declaredSize },
36
- limitations: [...entry.limitations],
37
- });
14
+ /**
15
+ * Create an occurrence before its bytes are read. A container suffix is not a
16
+ * container family until the bytes are classified, so a member named like a
17
+ * container starts with an unknown format.
18
+ */
19
+ export const createOccurrence = (entry, path, parent) => {
20
+ const role = entry.kind === "directory"
21
+ ? {
22
+ kind: path.toLowerCase().endsWith(".framework")
23
+ ? "framework"
24
+ : "container",
25
+ format: "directory",
26
+ }
27
+ : containerSuffixFamily(path) === undefined
28
+ ? classifyArtifactPath(path)
29
+ : { kind: "unknown", format: "unknown" };
30
+ return {
31
+ occurrence_id: `occ_${digestCanonicalValue({ path, kind: entry.kind }, "Artifact")}`,
32
+ artifact_id: null,
33
+ parent_occurrence_id: parent,
34
+ logical_path: path,
35
+ entry_kind: entry.kind,
36
+ artifact_kind: role.kind,
37
+ artifact_format: role.format,
38
+ declared_size: entry.declaredSize,
39
+ compressed_size: entry.compressedSize,
40
+ executable: entry.executable,
41
+ encrypted: entry.encrypted,
42
+ hash_status: entry.encrypted ? "unavailable" : "not-hashed",
43
+ source_location: entry.byteOffset === null || entry.declaredSize === null
44
+ ? null
45
+ : { offset: entry.byteOffset, length: entry.declaredSize },
46
+ limitations: [...entry.limitations],
47
+ };
48
+ };
49
+ /** Record that an unread member's container suffix was not checked against bytes. */
50
+ export const noteUnreadContainerSuffix = (occurrence) => {
51
+ if (occurrence.entry_kind === "directory")
52
+ return;
53
+ const family = containerSuffixFamily(occurrence.logical_path);
54
+ if (family === undefined)
55
+ return;
56
+ occurrence.limitations.push(`The path suffix suggests ${family.toUpperCase()}, but these bytes were not read, so the container family is unknown.`);
57
+ };
58
+ const containerSuffixFamily = (path) => {
59
+ const lower = path.toLowerCase();
60
+ return lower.endsWith(".asar") ? "asar" : zipPackageFormatForPath(lower);
61
+ };
38
62
  /** Compare exact child names independently of host locale and traversal order. */
39
- export const compareDirectoryChildNames = compareCodePoints;
40
63
  export const materializeDirectoryNodes = (occurrences, nodes) => {
41
64
  const directories = occurrences
42
65
  .filter(({ entry_kind: kind }) => kind === "directory")
@@ -59,9 +82,9 @@ export const materializeDirectoryNodes = (occurrences, nodes) => {
59
82
  artifact_id,
60
83
  entry_kind,
61
84
  }))
62
- .sort((left, right) => compareDirectoryChildNames(left.name, right.name));
85
+ .sort((left, right) => compareUnicodeCodePoints(left.name, right.name));
63
86
  const node = createArtifactNode({
64
- sha256: canonicalDigest({ kind: "directory", children }, "Artifact"),
87
+ sha256: digestCanonicalValue({ kind: "directory", children }, "Artifact"),
65
88
  size: 0,
66
89
  format: "directory",
67
90
  contentState: "virtual",
@@ -73,14 +96,14 @@ export const materializeDirectoryNodes = (occurrences, nodes) => {
73
96
  };
74
97
  export const createRootNode = (input) => createArtifactNode({
75
98
  sha256: input.digest?.sha256 ??
76
- canonicalDigest({
99
+ digestCanonicalValue({
77
100
  kind: "directory-root",
78
101
  children: input.occurrences
79
102
  .map(({ logical_path, artifact_id }) => ({
80
103
  logical_path,
81
104
  artifact_id,
82
105
  }))
83
- .sort((left, right) => compareDirectoryChildNames(left.logical_path, right.logical_path)),
106
+ .sort((left, right) => compareUnicodeCodePoints(left.logical_path, right.logical_path)),
84
107
  }, "Artifact"),
85
108
  size: input.digest?.bytes ?? 0,
86
109
  format: input.digest === null
@@ -154,15 +177,13 @@ export const createArtifactEdges = (rootArtifactId, occurrences, producer) => {
154
177
  rootArtifactId;
155
178
  const semantic = {
156
179
  parent_artifact_id: parentArtifactId,
157
- child_artifact_id: occurrence.artifact_id,
158
180
  relation: occurrence.entry_kind === "slice"
159
181
  ? "slice-of"
160
182
  : relationFor(occurrence.logical_path),
161
183
  occurrence_id: occurrence.occurrence_id,
162
- logical_path: occurrence.logical_path,
163
184
  };
164
185
  edges.push({
165
- edge_id: artifactEdgeId(semantic),
186
+ edge_id: artifactEdgeId(semantic, occurrence),
166
187
  ...semantic,
167
188
  producer: occurrence.entry_kind === "slice" ? (producer ?? null) : null,
168
189
  ordinal: edges.length,
@@ -170,29 +191,55 @@ export const createArtifactEdges = (rootArtifactId, occurrences, producer) => {
170
191
  }
171
192
  return edges;
172
193
  };
173
- export const nearestParent = (path, occurrences, expandedContainerIds) => {
174
- const parts = path.split("/");
175
- while (parts.length > 1) {
176
- parts.pop();
177
- const candidate = occurrences.get(parts.join("/"));
178
- if (candidate !== undefined &&
179
- (candidate.entry_kind === "directory" ||
180
- expandedContainerIds.has(candidate.occurrence_id)))
181
- return candidate;
194
+ /** Resolve strict observed ancestors without rebuilding every path prefix. */
195
+ export const resolveOccurrenceParents = (occurrences, byPath, expandedContainerIds) => {
196
+ const root = { children: new Map() };
197
+ for (const occurrence of byPath.values()) {
198
+ if (occurrence.entry_kind !== "directory" &&
199
+ !expandedContainerIds.has(occurrence.occurrence_id))
200
+ continue;
201
+ let branch = root;
202
+ for (const segment of occurrence.logical_path.split("/")) {
203
+ let child = branch.children.get(segment);
204
+ if (child === undefined) {
205
+ child = { children: new Map() };
206
+ branch.children.set(segment, child);
207
+ }
208
+ branch = child;
209
+ }
210
+ branch.occurrence = occurrence;
211
+ }
212
+ for (const occurrence of occurrences) {
213
+ const path = occurrence.logical_path;
214
+ let branch = root;
215
+ let parent;
216
+ // Walk parent segments only. Stop scanning the path once no observed
217
+ // directory or expanded container can be an ancestor.
218
+ for (let start = 0;;) {
219
+ const slash = path.indexOf("/", start);
220
+ if (slash < 0)
221
+ break;
222
+ const segment = path.slice(start, slash);
223
+ const child = branch.children.get(segment);
224
+ if (child === undefined)
225
+ break;
226
+ branch = child;
227
+ parent = branch.occurrence ?? parent;
228
+ start = slash + 1;
229
+ }
230
+ occurrence.parent_occurrence_id = parent?.occurrence_id ?? null;
182
231
  }
183
- return undefined;
184
232
  };
233
+ /**
234
+ * Assign a path role hint. Container families are not path roles: ZIP and
235
+ * ASAR families are chosen only after their bytes have been classified.
236
+ */
185
237
  export const classifyArtifactPath = (path) => {
186
238
  const lower = path.toLowerCase();
187
239
  if (lower.endsWith(".map"))
188
240
  return { kind: "source-map", format: "source-map" };
189
241
  if (/\.(?:m?js|cjs)$/u.test(lower))
190
242
  return { kind: "javascript", format: "javascript-bundle" };
191
- if (lower.endsWith(".asar"))
192
- return { kind: "container", format: "asar" };
193
- const archiveFormat = zipPackageFormatForPath(lower);
194
- if (archiveFormat !== undefined)
195
- return { kind: "container", format: archiveFormat };
196
243
  if (/\.framework(?:\/|$)/u.test(lower))
197
244
  return { kind: "framework", format: "file" };
198
245
  if (/\.(?:node|dylib|so)$/u.test(lower))
@@ -208,7 +255,26 @@ export const classifyArtifactPath = (path) => {
208
255
  };
209
256
  /** Classify executable formats from bytes while retaining path-specific roles. */
210
257
  export const classifyArtifactContent = (path, prefix, fileSize = prefix.length) => {
211
- return artifactRoleForFormat(path, classifyArtifactBytes(prefix, fileSize));
258
+ const format = classifyArtifactBytes(prefix, fileSize);
259
+ if (format === "file" &&
260
+ path.toLowerCase().endsWith(".asar") &&
261
+ hasAsarHeader(prefix))
262
+ return { kind: "container", format: "asar" };
263
+ return artifactRoleForFormat(path, format);
264
+ };
265
+ /**
266
+ * Electron ASAR starts with a size pickle whose payload is one uint32, then
267
+ * a header pickle whose payload begins with a JSON object.
268
+ */
269
+ export const hasAsarHeader = (prefix) => {
270
+ if (prefix.length < 17 || prefix.readUInt32LE(0) !== 4)
271
+ return false;
272
+ const headerSize = prefix.readUInt32LE(4);
273
+ const payloadSize = prefix.readUInt32LE(8);
274
+ if (headerSize < 16 || payloadSize !== headerSize - 4)
275
+ return false;
276
+ const stringLength = prefix.readUInt32LE(12);
277
+ return (stringLength >= 2 && stringLength <= payloadSize - 4 && prefix[16] === 0x7b);
212
278
  };
213
279
  const artifactRoleForFormat = (path, format) => {
214
280
  const byPath = classifyArtifactPath(path);
@@ -1,15 +1,16 @@
1
1
  import { realpath } from "node:fs/promises";
2
2
  import { artifactInventoryResultSchema, } from "../../domain/artifactGraph.js";
3
3
  import { abortIfNeeded } from "../ArtifactHash.js";
4
- import { scanCanonicalArtifactInventory } from "./scanCanonical.js";
4
+ import { scanCanonicalArtifactInventoryInScope } from "./scanCanonical.js";
5
5
  /** Inventory one local artifact and return every graph collection inline. */
6
- export const inventoryArtifact = async (inputPath, options = {}) => {
6
+ export const inventoryArtifact = async (inputPath, options) => {
7
7
  const snapshot = await scanArtifactInventory(inputPath, options);
8
8
  return artifactInventoryResultSchema.parse(snapshot);
9
9
  };
10
10
  /** Scan an artifact once and retain the complete immutable graph for projection. */
11
- export const scanArtifactInventory = async (inputPath, options = {}) => {
11
+ export const scanArtifactInventory = async (inputPath, options) => options.resourceScope.run(() => scanArtifactInventoryInScope(inputPath, options));
12
+ export const scanArtifactInventoryInScope = async (inputPath, options) => {
12
13
  abortIfNeeded(options.signal);
13
14
  const path = await realpath(inputPath);
14
- return scanCanonicalArtifactInventory(path, options);
15
+ return scanCanonicalArtifactInventoryInScope(path, options);
15
16
  };