rea-agents 3.2.1 → 4.0.1

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 (434) hide show
  1. package/README.md +183 -332
  2. package/bridge/ghidra/ReaGhidraBridge.java +561 -74
  3. package/bridge/hopper_bridge.py +70 -27
  4. package/bridge/native/ReaNativeUI.swift +157 -0
  5. package/dist/application/AnalysisContextQueries.js +19 -5
  6. package/dist/application/AnalysisSnapshotCache.js +30 -11
  7. package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
  8. package/dist/application/ArtifactExtractionDestination.js +0 -12
  9. package/dist/application/ArtifactGraphConstruction.js +44 -11
  10. package/dist/application/ArtifactInventory/classify.js +7 -15
  11. package/dist/application/ArtifactInventory/hash.js +4 -2
  12. package/dist/application/ArtifactInventory/policy.js +2 -17
  13. package/dist/application/ArtifactInventory/reader.js +3 -3
  14. package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
  15. package/dist/application/ArtifactInventory/scanReader.js +12 -4
  16. package/dist/application/ArtifactInventory/types.js +0 -3
  17. package/dist/application/BinarySession.js +28 -43
  18. package/dist/application/BinarySessionExecution.js +37 -1
  19. package/dist/application/BinaryTargetResolver.js +50 -4
  20. package/dist/application/BrowserEvidence.js +36 -7
  21. package/dist/application/BrowserObservationService.js +17 -44
  22. package/dist/application/BrowserScenarioCaptureService.js +2 -35
  23. package/dist/application/BrowserScenarioEvidence.js +13 -9
  24. package/dist/application/CapabilityClientRequirements.js +2 -11
  25. package/dist/application/CapabilityInventory.js +21 -35
  26. package/dist/application/ClientConfigurationDocument.js +84 -7
  27. package/dist/application/ClientRegistrationIdentity.js +32 -0
  28. package/dist/application/ClientRegistrationStatus.js +59 -6
  29. package/dist/application/DirectAnalysis.js +37 -58
  30. package/dist/application/DirectAnalysisStatus.js +4 -4
  31. package/dist/application/Doctor.js +89 -80
  32. package/dist/application/DoctorDiagnostics.js +2 -26
  33. package/dist/application/DoctorScope.js +8 -14
  34. package/dist/application/ElectronActiveEvidence.js +10 -27
  35. package/dist/application/ElectronActiveObservationService.js +9 -36
  36. package/dist/application/ElectronBoundaryAnalysis.js +2 -0
  37. package/dist/application/ElectronBoundaryGraphNative.js +1 -1
  38. package/dist/application/ElectronEvidence.js +8 -3
  39. package/dist/application/ElectronObservationService.js +9 -25
  40. package/dist/application/EnhancedLiteralTracing.js +4 -8
  41. package/dist/application/EnhancedTools.js +15 -35
  42. package/dist/application/FilesystemSnapshot.js +7 -8
  43. package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
  44. package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
  45. package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
  46. package/dist/application/JavaScriptArtifactFiles.js +5 -0
  47. package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
  48. package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
  49. package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
  50. package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
  51. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
  52. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
  53. package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
  54. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
  55. package/dist/application/JsonFiles.js +1 -1
  56. package/dist/application/LazyAnalysisProvider.js +27 -6
  57. package/dist/application/ManagedMemberComparisonService.js +19 -6
  58. package/dist/application/NativeApiInspection.js +2 -0
  59. package/dist/application/NativeCallRoutes.js +72 -0
  60. package/dist/application/NativeDispatchMetadataInspection.js +33 -0
  61. package/dist/application/NativeUiActionTrace.js +73 -49
  62. package/dist/application/NativeValueTrace.js +320 -0
  63. package/dist/application/ProcessCaptureCapability.js +32 -5
  64. package/dist/application/ProcessCaptureEnvironment.js +9 -26
  65. package/dist/application/ProcessCaptureError.js +1 -5
  66. package/dist/application/ProcessCaptureJournal.js +3 -40
  67. package/dist/application/ProcessCaptureLifecycle.js +102 -111
  68. package/dist/application/ProcessCli.js +18 -25
  69. package/dist/application/ProcessEvidence.js +5 -7
  70. package/dist/application/ProcessFilesystemEffects.js +36 -0
  71. package/dist/application/ProcessHarness.js +41 -120
  72. package/dist/application/ProcessNormalization.js +2 -17
  73. package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
  74. package/dist/application/ReferenceSourceImport.js +3 -4
  75. package/dist/application/Setup.js +236 -84
  76. package/dist/application/SetupClientConfiguration.js +14 -9
  77. package/dist/application/SetupPlan.js +138 -86
  78. package/dist/application/SetupSkill.js +0 -1
  79. package/dist/application/SupportedClients.js +102 -21
  80. package/dist/application/Uninstall.js +31 -20
  81. package/dist/application/Update.js +93 -0
  82. package/dist/application/UpdateMaintenance.js +108 -0
  83. package/dist/application/UpdateRuntime.js +126 -0
  84. package/dist/application/runtime.js +13 -2
  85. package/dist/artifacts/ArtifactPaths.js +6 -8
  86. package/dist/artifacts/ArtifactProvider.js +94 -41
  87. package/dist/artifacts/AsarArtifactReader.js +19 -4
  88. package/dist/artifacts/KeyedArchiveReader.js +110 -0
  89. package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
  90. package/dist/artifacts/ZipArtifactReader.js +18 -1
  91. package/dist/browser/BrowserScenarioSecrets.js +28 -1
  92. package/dist/browser/CdpBrowserProvider.js +36 -15
  93. package/dist/browser/CdpCaptureDocuments.js +22 -8
  94. package/dist/browser/CdpCaptureEventHandlers.js +14 -5
  95. package/dist/browser/CdpCaptureEventHelpers.js +13 -0
  96. package/dist/browser/CdpCaptureEvents.js +10 -1
  97. package/dist/browser/CdpElectronInspection.js +5 -10
  98. package/dist/browser/CdpElectronProvider.js +1 -5
  99. package/dist/browser/CdpElectronScripts.js +1 -1
  100. package/dist/browser/CdpEndpoint.js +3 -2
  101. package/dist/browser/CdpObservationSession.js +14 -10
  102. package/dist/browser/CdpPageCapture.js +1 -1
  103. package/dist/browser/CdpPageCaptureScripts.js +1 -1
  104. package/dist/browser/CdpSafeMetadata.js +5 -4
  105. package/dist/browser/CdpScreenshot.js +16 -5
  106. package/dist/browser/CdpTargetSession.js +25 -4
  107. package/dist/browser/CdpWebMcpDiscovery.js +93 -20
  108. package/dist/browser/JavaScriptRuntimeScope.js +28 -2
  109. package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
  110. package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
  111. package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
  112. package/dist/browser/PlaywrightScenarioActions.js +1 -1
  113. package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
  114. package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
  115. package/dist/browser/PlaywrightScenarioEvents.js +82 -93
  116. package/dist/browser/PlaywrightScenarioSession.js +27 -123
  117. package/dist/browser/PngVisualDiff.js +22 -3
  118. package/dist/browser/V8InspectorCaptureProjection.js +7 -1
  119. package/dist/browser/V8InspectorProvider.js +60 -7
  120. package/dist/browser/WebSourceMapFetcher.js +99 -53
  121. package/dist/cli/artifactCommands.js +56 -12
  122. package/dist/cli/coreAnalysisCommands.js +110 -0
  123. package/dist/cli/managedCommands.js +1 -31
  124. package/dist/cli/setupCommands.js +16 -14
  125. package/dist/cli/utilityCommands.js +61 -4
  126. package/dist/cli.js +5 -7
  127. package/dist/cliApplicationCommands.js +0 -83
  128. package/dist/cliBrowserAdvancedCommands.js +7 -11
  129. package/dist/cliBrowserCommands.js +15 -23
  130. package/dist/cliBrowserContext.js +3 -24
  131. package/dist/cliBrowserScenarioCommands.js +2 -10
  132. package/dist/cliCommandNames.js +82 -7
  133. package/dist/cliElectronCommands.js +10 -36
  134. package/dist/cliJavaScriptRuntimeCommands.js +6 -30
  135. package/dist/cliJsonInput.js +4 -2
  136. package/dist/cliLogging.js +16 -7
  137. package/dist/cliObservationOptions.js +1 -1
  138. package/dist/cliOutput.js +2 -4
  139. package/dist/cliProcessCommands.js +6 -33
  140. package/dist/cliSetup.js +90 -160
  141. package/dist/config/environment.js +2 -78
  142. package/dist/config/parseConfig.js +18 -109
  143. package/dist/config/parsers.js +0 -23
  144. package/dist/contracts/applicationToolContracts.js +1 -118
  145. package/dist/contracts/artifactToolContracts.js +11 -19
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -5
  147. package/dist/contracts/browserToolContracts.js +9 -16
  148. package/dist/contracts/electronToolContracts.js +5 -6
  149. package/dist/contracts/enhancedInputs.js +3 -2
  150. package/dist/contracts/errorSchemas.js +16 -40
  151. package/dist/contracts/functionWorkflowToolContracts.js +2 -2
  152. package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
  153. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
  154. package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
  155. package/dist/contracts/managedToolContracts.js +7 -4
  156. package/dist/contracts/managedWorkflowExamples.js +0 -22
  157. package/dist/contracts/managedWorkflowToolContracts.js +16 -31
  158. package/dist/contracts/nativeToolContracts.js +9 -0
  159. package/dist/contracts/promptContracts.js +6 -6
  160. package/dist/contracts/sessionToolSchemas.js +3 -3
  161. package/dist/contracts/toolContractExamples.js +4 -3
  162. package/dist/contracts/toolContracts.js +18 -7
  163. package/dist/contracts/toolEffects.js +34 -21
  164. package/dist/contracts/toolOutputSchemaGroups.js +18 -5
  165. package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
  166. package/dist/contracts/toolSchemaMetadata.js +5 -8
  167. package/dist/doctorRuntime.js +0 -41
  168. package/dist/domain/analysisErrorPresentation.js +4 -28
  169. package/dist/domain/analysisErrorProjection.js +33 -50
  170. package/dist/domain/analysisProfile.js +1 -1
  171. package/dist/domain/analysisSnapshot.js +77 -3
  172. package/dist/domain/androidApplication.js +5 -4
  173. package/dist/domain/appleApplication.js +5 -4
  174. package/dist/domain/appleAssetCatalog.js +127 -0
  175. package/dist/domain/artifactComparison.js +7 -11
  176. package/dist/domain/artifactGraph.js +8 -6
  177. package/dist/domain/artifactInspection.js +13 -12
  178. package/dist/domain/binaryTarget.js +23 -9
  179. package/dist/domain/browserObservation.js +43 -24
  180. package/dist/domain/browserObservationSchemas.js +2 -1
  181. package/dist/domain/browserScenario.js +7 -107
  182. package/dist/domain/browserScenarioCapture.js +0 -1
  183. package/dist/domain/browserScenarioCaptureValues.js +5 -4
  184. package/dist/domain/browserScenarioDiff.js +1 -3
  185. package/dist/domain/browserScenarioValues.js +16 -107
  186. package/dist/domain/bundleComparison.js +18 -17
  187. package/dist/domain/callPathSchemas.js +17 -7
  188. package/dist/domain/changedBehavior.js +2 -3
  189. package/dist/domain/comparisonSemantics.js +19 -0
  190. package/dist/domain/completionLedgerGeneration.js +3 -2
  191. package/dist/domain/conformancePackage.js +2 -1
  192. package/dist/domain/conformanceTrustGate.js +3 -5
  193. package/dist/domain/customProtocolCapture.js +2 -2
  194. package/dist/domain/digests.js +30 -0
  195. package/dist/domain/dosMz.js +83 -0
  196. package/dist/domain/electronActiveObservation.js +7 -5
  197. package/dist/domain/electronObservation.js +3 -2
  198. package/dist/domain/electronStaticAnalysisNative.js +15 -6
  199. package/dist/domain/emptyArraySchema.js +3 -0
  200. package/dist/domain/errors.js +10 -28
  201. package/dist/domain/evidence.js +5 -3
  202. package/dist/domain/evidenceCompletionLedger.js +3 -2
  203. package/dist/domain/functionComparisonNormalization.js +24 -18
  204. package/dist/domain/functionComparisonResults.js +3 -7
  205. package/dist/domain/functionComparisonSchemas.js +3 -2
  206. package/dist/domain/hopperValues.js +108 -8
  207. package/dist/domain/javascriptApplicationAnalysis.js +4 -7
  208. package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
  209. package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
  210. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
  211. package/dist/domain/javascriptApplicationVersionItems.js +12 -18
  212. package/dist/domain/javascriptAstValues.js +4 -0
  213. package/dist/domain/javascriptExportShapeComparison.js +1 -6
  214. package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
  215. package/dist/domain/javascriptExportShapeVariants.js +15 -2
  216. package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
  217. package/dist/domain/javascriptRuntimeObservation.js +14 -2
  218. package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
  219. package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
  220. package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
  221. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
  222. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
  223. package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
  224. package/dist/domain/javascriptSemanticAnalysis.js +57 -19
  225. package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
  226. package/dist/domain/javascriptSemanticCalls.js +46 -27
  227. package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
  228. package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
  229. package/dist/domain/javascriptSemanticDataEffects.js +22 -10
  230. package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
  231. package/dist/domain/javascriptSemanticObjects.js +13 -3
  232. package/dist/domain/javascriptSemanticProjection.js +144 -38
  233. package/dist/domain/javascriptSemanticPromises.js +14 -27
  234. package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
  235. package/dist/domain/javascriptSemanticResources.js +2 -5
  236. package/dist/domain/javascriptSemanticState.js +4 -0
  237. package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
  238. package/dist/domain/javascriptSemanticTraversal.js +13 -5
  239. package/dist/domain/javascriptSemanticValues.js +10 -9
  240. package/dist/domain/javascriptSourceParser.js +5 -1
  241. package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
  242. package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
  243. package/dist/domain/keyedArchive.js +181 -0
  244. package/dist/domain/managedApplicationGraph.js +4 -3
  245. package/dist/domain/managedArtifact.js +2 -1
  246. package/dist/domain/managedMemberComparison.js +18 -13
  247. package/dist/domain/managedMemberComparisonCoverage.js +2 -1
  248. package/dist/domain/managedMemberComparisonItems.js +27 -7
  249. package/dist/domain/managedMemberComparisonMatch.js +22 -6
  250. package/dist/domain/managedNativeVerificationMatch.js +2 -2
  251. package/dist/domain/managedNativeVerificationSchemas.js +7 -5
  252. package/dist/domain/managedReconstruction.js +6 -5
  253. package/dist/domain/nativeApiBoundary.js +7 -0
  254. package/dist/domain/nativeDataType.js +51 -0
  255. package/dist/domain/nativeInspection.js +0 -1
  256. package/dist/domain/nativeInstruction.js +82 -0
  257. package/dist/domain/nativeInvestigationGraph.js +9 -5
  258. package/dist/domain/nativeUiObservation.js +123 -0
  259. package/dist/domain/nativeValueFlow.js +17 -0
  260. package/dist/domain/nativeValueTrace.js +64 -0
  261. package/dist/domain/objcSwiftMetadata.js +39 -0
  262. package/dist/domain/peInspection.js +1 -0
  263. package/dist/domain/processCapture.js +5 -55
  264. package/dist/domain/processCaptureExample.js +0 -9
  265. package/dist/domain/processCaptureValidation.js +13 -144
  266. package/dist/domain/processComparison.js +3 -25
  267. package/dist/domain/processObservation.js +0 -29
  268. package/dist/domain/processScenario.js +28 -228
  269. package/dist/domain/processTraceDimensionProjection.js +0 -15
  270. package/dist/domain/processTraceEvaluation.js +0 -6
  271. package/dist/domain/protocolCapture.js +8 -36
  272. package/dist/domain/reconstructionCoverage.js +3 -2
  273. package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
  274. package/dist/domain/reconstructionReadinessSchemas.js +4 -3
  275. package/dist/domain/reconstructionVerification.js +2 -1
  276. package/dist/domain/reconstructionVerificationSchemas.js +6 -13
  277. package/dist/domain/referenceSourceClassification.js +0 -110
  278. package/dist/domain/referenceSourceGraph.js +15 -5
  279. package/dist/domain/residualUnknown.js +3 -2
  280. package/dist/domain/runtimeIdentification.js +6 -5
  281. package/dist/domain/sourceMapContents.js +5 -0
  282. package/dist/domain/sourceToBundleComparison.js +3 -10
  283. package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
  284. package/dist/domain/sourceToBundleSignals.js +9 -3
  285. package/dist/domain/staticRuntimeCorrelation.js +5 -11
  286. package/dist/domain/webBundleAnalysis.js +17 -9
  287. package/dist/domain/webBundleAnalyzer.js +1 -1
  288. package/dist/domain/webCaptureDiff.js +5 -11
  289. package/dist/domain/webCaptureDiffSchemas.js +2 -1
  290. package/dist/domain/webMcpDiscovery.js +2 -1
  291. package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
  292. package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
  293. package/dist/dotnet/ManagedMemberRows.js +2 -0
  294. package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
  295. package/dist/dotnet/ManagedPeReader.js +2 -0
  296. package/dist/generatedMcpToolCatalog.js +1 -1
  297. package/dist/generatedPackageMetadata.js +2 -2
  298. package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
  299. package/dist/ghidra/GhidraClient.js +38 -8
  300. package/dist/ghidra/GhidraFunctionValues.js +56 -20
  301. package/dist/ghidra/GhidraInstallation.js +7 -4
  302. package/dist/ghidra/GhidraInventoryValues.js +44 -9
  303. package/dist/ghidra/GhidraLauncher.js +18 -3
  304. package/dist/ghidra/GhidraProvider.js +23 -2
  305. package/dist/ghidra/GhidraRequestQueue.js +45 -4
  306. package/dist/ghidra/GhidraSessionValues.js +5 -0
  307. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  308. package/dist/hopper/HopperProvider.js +29 -6
  309. package/dist/hopper/HopperTargetLease.js +18 -4
  310. package/dist/logger.js +0 -13
  311. package/dist/main/messages.js +0 -1
  312. package/dist/main/reload.js +3 -32
  313. package/dist/main/shutdown.js +1 -2
  314. package/dist/main/transport.js +0 -17
  315. package/dist/main.js +0 -10
  316. package/dist/native/AppleDispatchMetadata.js +582 -0
  317. package/dist/native/AppleObjcProtocols.js +88 -0
  318. package/dist/native/AppleSwiftVtables.js +86 -0
  319. package/dist/native/CommandRunner.js +1 -1
  320. package/dist/native/NativeHostCapabilities.js +23 -0
  321. package/dist/native/NativeMacOSProvider.js +61 -9
  322. package/dist/native/NativeMachoInspection.js +39 -6
  323. package/dist/native/NativeUiHelperRuntime.js +42 -0
  324. package/dist/native/NativeUiObservation.js +174 -0
  325. package/dist/native/parsers/codesign.js +4 -1
  326. package/dist/native/parsers/dyldInfo.js +51 -25
  327. package/dist/native/parsers/lipo.js +13 -4
  328. package/dist/native/parsers/otool.js +84 -39
  329. package/dist/native/parsers/plist.js +2 -1
  330. package/dist/process/ExecFileOutput.js +5 -1
  331. package/dist/process/ProcessOwnership.js +69 -33
  332. package/dist/process/ProcessOwnershipObservation.js +31 -12
  333. package/dist/process/ProviderProcess.js +4 -2
  334. package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
  335. package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
  336. package/dist/reference/ReferenceSourceReaderFile.js +11 -5
  337. package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
  338. package/dist/server/createServer.js +7 -62
  339. package/dist/server/registerApplicationTools/helpers.js +2 -9
  340. package/dist/server/registerApplicationTools.js +0 -4
  341. package/dist/server/registerArtifactComparisonTool.js +1 -1
  342. package/dist/server/registerBrowserScenarioTool.js +4 -2
  343. package/dist/server/registerBrowserTools.js +7 -7
  344. package/dist/server/registerBundleComparisonTool.js +1 -1
  345. package/dist/server/registerCloseLifecycleTool.js +1 -1
  346. package/dist/server/registerElectronTools.js +10 -4
  347. package/dist/server/registerEnhancedTools.js +20 -12
  348. package/dist/server/registerEvidenceTools.js +4 -28
  349. package/dist/server/registerFunctionComparisonTool.js +1 -1
  350. package/dist/server/registerInvestigationTools.js +6 -6
  351. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
  352. package/dist/server/registerManagedTools.js +28 -14
  353. package/dist/server/registerManagedWorkflowTools.js +0 -2
  354. package/dist/server/registerProcessComparisonTool.js +1 -3
  355. package/dist/server/registerSessionRecordTools.js +9 -9
  356. package/dist/server/registerSessionStatusTool.js +1 -1
  357. package/dist/server/registerSessionTools.js +28 -57
  358. package/dist/server/sessionAvailabilityPolicy.js +2 -3
  359. package/dist/server/sessionToolPolicies.js +0 -4
  360. package/dist/server/toolResult.js +8 -10
  361. package/package.json +32 -22
  362. package/skills/reverse-engineer-anything/SKILL.md +15 -11
  363. package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
  364. package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
  365. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
  366. package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
  367. package/dist/application/CommandShimReplay.js +0 -152
  368. package/dist/application/ConfiguredRoots.js +0 -19
  369. package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
  370. package/dist/application/JavaScriptReplayPermission.js +0 -16
  371. package/dist/application/JavaScriptReplayPlanning.js +0 -207
  372. package/dist/application/JavaScriptReplayService.js +0 -274
  373. package/dist/application/LoopbackReplay.js +0 -389
  374. package/dist/application/LoopbackReplayRecorder.js +0 -129
  375. package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
  376. package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
  377. package/dist/application/PermissionAuthority.js +0 -268
  378. package/dist/application/PermissionConfiguration.js +0 -26
  379. package/dist/application/PermissionFailure.js +0 -5
  380. package/dist/application/ProcessCaptureAuthority.js +0 -24
  381. package/dist/application/ProcessCapturePermission.js +0 -13
  382. package/dist/application/ProcessCheckpoints.js +0 -178
  383. package/dist/application/ProcessReactiveCoordinator.js +0 -223
  384. package/dist/application/ProcessReactiveEffects.js +0 -153
  385. package/dist/application/ProcessReactiveHarness.js +0 -106
  386. package/dist/application/ProcessReactiveObservations.js +0 -105
  387. package/dist/application/ProjectPermissionStore.js +0 -199
  388. package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
  389. package/dist/application/Upgrade.js +0 -134
  390. package/dist/browser/SensitiveTextCapture.js +0 -8
  391. package/dist/cliPolicyCommands.js +0 -185
  392. package/dist/config/browserScenario.js +0 -77
  393. package/dist/config/electronAutomation.js +0 -35
  394. package/dist/config/javascriptReplay.js +0 -41
  395. package/dist/config/managedRuntime.js +0 -25
  396. package/dist/config/passiveObservation.js +0 -87
  397. package/dist/config/permissions.js +0 -23
  398. package/dist/config/processCapture.js +0 -47
  399. package/dist/contracts/replayMachineExample.js +0 -37
  400. package/dist/domain/javascriptExportInstrumentation.js +0 -95
  401. package/dist/domain/javascriptReplay.js +0 -360
  402. package/dist/domain/managedRuntimeCorrelation.js +0 -181
  403. package/dist/domain/nodeRuntimeCharacterization.js +0 -63
  404. package/dist/domain/permissionPolicy.js +0 -176
  405. package/dist/domain/processCaptureReactiveSchema.js +0 -68
  406. package/dist/domain/processCaptureReactiveValidation.js +0 -180
  407. package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
  408. package/dist/domain/processReactiveMatching.js +0 -196
  409. package/dist/domain/processReactiveRuntime.js +0 -116
  410. package/dist/domain/processReactiveScenario.js +0 -296
  411. package/dist/domain/processReactiveScenarioPreflight.js +0 -95
  412. package/dist/domain/processReactiveTransition.js +0 -187
  413. package/dist/domain/replayMachine.js +0 -320
  414. package/dist/domain/replayMachineRun.js +0 -168
  415. package/dist/domain/replayMachineRuntime.js +0 -296
  416. package/dist/domain/replayMachineValues.js +0 -84
  417. package/dist/domain/runtimeCharacterization.js +0 -84
  418. package/dist/replay/JavaScriptReplayWorker.js +0 -382
  419. package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
  420. package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
  421. package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
  422. package/dist/replay/LinuxRuntimeClosure.js +0 -44
  423. package/dist/replay/LinuxSeccompPolicy.js +0 -40
  424. package/dist/replay/ReplayOutcome.js +0 -104
  425. package/dist/replay/ReplayProcessLifecycle.js +0 -96
  426. package/dist/replay/ReplaySeccompFile.js +0 -29
  427. package/dist/replay/ReplayWorkerProtocol.js +0 -58
  428. package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
  429. package/dist/server/ProcessCaptureElicitation.js +0 -153
  430. package/dist/server/registerApplicationTools/characterization.js +0 -46
  431. package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
  432. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
  433. package/dist/server/registerReplayMachineTool.js +0 -14
  434. package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
@@ -0,0 +1,171 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstat } from "node:fs/promises";
3
+ import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js";
4
+ import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
5
+ import { analyzeInterfaceBuilderBundle } from "./InterfaceBuilderAnalysis.js";
6
+ import { appleAssetCatalogInputSchema, parseAppleAssetCatalogRecords, projectAppleAssetCatalogPage, } from "../domain/appleAssetCatalog.js";
7
+ import { execFileOutput } from "../process/ExecFileOutput.js";
8
+ const ASSETUTIL = "/usr/bin/assetutil";
9
+ const MAX_CATALOG_BYTES = 64 * 1024 * 1024;
10
+ const MAX_TOTAL_METADATA_BYTES = 64 * 1024 * 1024;
11
+ const RESOURCE_KEY_FIELDS = new Set([
12
+ "image",
13
+ "imageName",
14
+ "image_name",
15
+ "resourceName",
16
+ "resource_name",
17
+ "assetName",
18
+ "asset_name",
19
+ "UIImageName",
20
+ "NSImageName",
21
+ ]);
22
+ /** Inspect compiled asset catalog metadata without extracting rendition bytes. */
23
+ export const analyzeAppleAssetCatalogs = async (input) => {
24
+ if (process.platform !== "darwin" && input.runAssetUtil === undefined)
25
+ throw new ArtifactReaderFailure("unavailable", "Apple asset catalog inspection requires macOS assetutil");
26
+ const page = appleAssetCatalogInputSchema.parse(input.page ?? {});
27
+ const reader = new DirectoryArtifactReader(input.bundlePath);
28
+ const catalogs = [];
29
+ let totalMetadataBytes = 0;
30
+ try {
31
+ for await (const entry of reader.entries(input.signal)) {
32
+ if (entry.kind !== "file" || !entry.path.endsWith("Assets.car"))
33
+ continue;
34
+ const inspected = await inspectAssetCatalogEntry({
35
+ reader,
36
+ entry,
37
+ runAssetUtil: input.runAssetUtil ?? runAssetUtil,
38
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
39
+ });
40
+ totalMetadataBytes += inspected.metadataBytes;
41
+ if (totalMetadataBytes > MAX_TOTAL_METADATA_BYTES)
42
+ throw new ArtifactReaderFailure("limit", `Combined asset catalog metadata exceeds ${MAX_TOTAL_METADATA_BYTES} bytes`);
43
+ catalogs.push(inspected.catalog);
44
+ }
45
+ }
46
+ finally {
47
+ await reader.close();
48
+ }
49
+ if (catalogs.length === 0)
50
+ throw new ArtifactReaderFailure("unavailable", "No compiled Assets.car catalogs were found in the app bundle");
51
+ const interfaceBuilder = await analyzeInterfaceBuilderBundle({
52
+ bundlePath: input.bundlePath,
53
+ targetSha256: input.targetSha256,
54
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
55
+ });
56
+ const resourceReferences = collectInterfaceBuilderResourceKeys(interfaceBuilder.graph.nodes);
57
+ const result = projectAppleAssetCatalogPage({
58
+ targetSha256: input.targetSha256,
59
+ catalogs,
60
+ offset: page.offset,
61
+ limit: page.limit,
62
+ resourceReferences,
63
+ });
64
+ return {
65
+ ...result,
66
+ limitations: [
67
+ ...result.limitations,
68
+ "Exact resource-key joins use only recognized image or asset key fields on decoded Interface Builder resource objects; other archive resource references are not inferred.",
69
+ ...(interfaceBuilder.graph.truncated
70
+ ? [
71
+ "Interface Builder resource-key joins may be incomplete because the decoded UI graph was truncated.",
72
+ ]
73
+ : []),
74
+ ],
75
+ };
76
+ };
77
+ const inspectAssetCatalogEntry = async (input) => {
78
+ const { entry, reader, signal } = input;
79
+ const sha256 = await digestBounded(reader, entry, signal);
80
+ const before = await lstat(entry.adapterKey);
81
+ if (entry.sourceIdentity === undefined ||
82
+ before.dev !== entry.sourceIdentity.device ||
83
+ before.ino !== entry.sourceIdentity.inode)
84
+ throw new ArtifactReaderFailure("integrity", `Asset catalog changed before inspection: ${entry.path}`);
85
+ const output = await input.runAssetUtil(entry.adapterKey, signal);
86
+ const after = await lstat(entry.adapterKey);
87
+ if (before.dev !== after.dev ||
88
+ before.ino !== after.ino ||
89
+ before.size !== after.size ||
90
+ (await digestBounded(reader, entry, signal)) !== sha256)
91
+ throw new ArtifactReaderFailure("integrity", `Asset catalog changed during inspection: ${entry.path}`);
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(output);
95
+ }
96
+ catch (cause) {
97
+ throw new ArtifactReaderFailure("format", `assetutil returned invalid JSON for ${entry.path}`, { cause });
98
+ }
99
+ try {
100
+ return {
101
+ catalog: {
102
+ path: entry.path,
103
+ sha256,
104
+ records: parseAppleAssetCatalogRecords(parsed),
105
+ },
106
+ metadataBytes: Buffer.byteLength(output, "utf8"),
107
+ };
108
+ }
109
+ catch (cause) {
110
+ throw new ArtifactReaderFailure("format", `assetutil returned an unsupported record for ${entry.path}`, { cause });
111
+ }
112
+ };
113
+ /** Return only explicit image or asset fields from decoded resource objects. */
114
+ export const collectInterfaceBuilderResourceKeys = (nodes) => nodes.flatMap((node) => {
115
+ const source = node.evidence.find((item) => item.artifact_path !== null && item.artifact_sha256 !== null);
116
+ const sourcePath = source?.artifact_path;
117
+ const sourceArchiveSha256 = source?.artifact_sha256;
118
+ if (sourcePath == null || sourceArchiveSha256 == null)
119
+ return [];
120
+ return Object.entries(node.attributes).flatMap(([field, value]) => RESOURCE_KEY_FIELDS.has(field) &&
121
+ typeof value === "string" &&
122
+ value.length > 0
123
+ ? [
124
+ {
125
+ sourceNodeId: node.id,
126
+ sourcePath,
127
+ sourceArchiveSha256,
128
+ field,
129
+ key: value,
130
+ },
131
+ ]
132
+ : []);
133
+ });
134
+ const runAssetUtil = async (path, signal) => {
135
+ try {
136
+ return (await execFileOutput(ASSETUTIL, ["--info", path], {
137
+ timeout: 60_000,
138
+ maxBuffer: MAX_CATALOG_BYTES,
139
+ ...(signal === undefined ? {} : { signal }),
140
+ })).stdout;
141
+ }
142
+ catch (cause) {
143
+ if (signal?.aborted === true)
144
+ throw new ArtifactReaderFailure("cancelled", "Asset catalog inspection cancelled");
145
+ const code = typeof cause === "object" && cause !== null && "code" in cause
146
+ ? cause.code
147
+ : undefined;
148
+ throw new ArtifactReaderFailure(code === "ENOENT"
149
+ ? "unavailable"
150
+ : code === "ETIMEDOUT" || code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER"
151
+ ? "limit"
152
+ : "io", `assetutil failed${code === undefined ? "" : ` (${String(code)})`}`, { cause });
153
+ }
154
+ };
155
+ const digestBounded = async (reader, entry, signal) => {
156
+ if (entry.declaredSize === null || entry.declaredSize > MAX_CATALOG_BYTES)
157
+ throw new ArtifactReaderFailure("limit", `Asset catalog exceeds ${MAX_CATALOG_BYTES} bytes: ${entry.path}`);
158
+ const stream = await reader.open(entry, signal);
159
+ const hash = createHash("sha256");
160
+ let length = 0;
161
+ for await (const chunk of stream) {
162
+ if (signal?.aborted === true)
163
+ throw new ArtifactReaderFailure("cancelled", "Asset catalog inspection cancelled");
164
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
165
+ length += bytes.length;
166
+ if (length > MAX_CATALOG_BYTES)
167
+ throw new ArtifactReaderFailure("limit", `Asset catalog exceeds byte limit: ${entry.path}`);
168
+ hash.update(bytes);
169
+ }
170
+ return hash.digest("hex");
171
+ };
@@ -3,15 +3,3 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  /** Choose a fresh temporary destination for an artifact extraction. */
5
5
  export const createArtifactExtractionDestination = () => join(tmpdir(), `rea-extracted-${randomUUID()}`);
6
- /** Stable parent scope used to authorize REA-owned extraction destinations. */
7
- export const artifactExtractionPermissionRoot = () => tmpdir();
8
- /** Stable filesystem scope for the destination selected internally by REA. */
9
- export const artifactExtractionPermissionRequest = () => ({
10
- capability: "artifact_extract",
11
- roots: [artifactExtractionPermissionRoot()],
12
- executables: [],
13
- environment_names: [],
14
- network: "none",
15
- mount: false,
16
- operation_identity: "extract_artifact:temporary_output",
17
- });
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import canonicalize from "canonicalize";
3
3
  import { zipPackageFormatForPath } from "../domain/zipPackageFormat.js";
4
+ import { mzWindowsHeaderOffset, parseDosMzHeader } from "../domain/dosMz.js";
4
5
  /** Index the first occurrence for each canonical logical path. */
5
6
  export const indexOccurrencesByPath = (occurrences) => {
6
7
  const byPath = new Map();
@@ -25,6 +26,15 @@ export const createOccurrence = (entry, path, parent) => ({
25
26
  : { offset: entry.byteOffset, length: entry.declaredSize },
26
27
  limitations: [...entry.limitations],
27
28
  });
29
+ /** Preserve collation order and break distinct-name ties by UTF-16 code units. */
30
+ export const compareDirectoryChildNames = (left, right) => {
31
+ const collated = left.localeCompare(right);
32
+ if (collated !== 0)
33
+ return collated;
34
+ if (left < right)
35
+ return -1;
36
+ return left > right ? 1 : 0;
37
+ };
28
38
  export const materializeDirectoryNodes = (occurrences, nodes) => {
29
39
  const directories = occurrences
30
40
  .filter(({ entry_kind: kind }) => kind === "directory")
@@ -42,11 +52,12 @@ export const materializeDirectoryNodes = (occurrences, nodes) => {
42
52
  for (const directory of directories) {
43
53
  const children = (childrenByParent.get(directory.occurrence_id) ?? [])
44
54
  .map(({ logical_path, artifact_id, entry_kind }) => ({
45
- name: logical_path.split("/").at(-1),
55
+ // Intermediate directory entries may be absent from an archive.
56
+ name: logical_path.slice(directory.logical_path.length + 1),
46
57
  artifact_id,
47
58
  entry_kind,
48
59
  }))
49
- .sort((left, right) => String(left.name).localeCompare(String(right.name)));
60
+ .sort((left, right) => compareDirectoryChildNames(left.name, right.name));
50
61
  const node = createArtifactNode({
51
62
  sha256: digestCanonical({ kind: "directory", children }),
52
63
  size: 0,
@@ -76,7 +87,9 @@ export const createRootNode = (input) => createArtifactNode({
76
87
  kind: input.directory ||
77
88
  ["zip", "ipa", "apk", "msix", "appx", "asar", "dmg", "pkg"].includes(input.format)
78
89
  ? "container"
79
- : classifyArtifactPath(input.path).kind,
90
+ : input.format === "dos-mz"
91
+ ? "executable"
92
+ : classifyArtifactPath(input.path).kind,
80
93
  format: input.format,
81
94
  executable: false,
82
95
  contentState: "materialized",
@@ -156,12 +169,14 @@ export const createArtifactEdges = (rootArtifactId, occurrences, producer) => {
156
169
  }
157
170
  return edges;
158
171
  };
159
- export const nearestParent = (path, occurrences) => {
172
+ export const nearestParent = (path, occurrences, expandedContainerIds) => {
160
173
  const parts = path.split("/");
161
174
  while (parts.length > 1) {
162
175
  parts.pop();
163
176
  const candidate = occurrences.get(parts.join("/"));
164
- if (candidate?.entry_kind === "directory")
177
+ if (candidate !== undefined &&
178
+ (candidate.entry_kind === "directory" ||
179
+ expandedContainerIds.has(candidate.occurrence_id)))
165
180
  return candidate;
166
181
  }
167
182
  return undefined;
@@ -191,7 +206,7 @@ export const classifyArtifactPath = (path) => {
191
206
  return { kind: "resource", format: "file" };
192
207
  };
193
208
  /** Classify executable formats from bytes while retaining path-specific roles. */
194
- export const classifyArtifactContent = (path, prefix) => {
209
+ export const classifyArtifactContent = (path, prefix, fileSize = prefix.length) => {
195
210
  const byPath = classifyArtifactPath(path);
196
211
  if (prefix.length >= 4) {
197
212
  const magic = prefix.readUInt32BE(0);
@@ -215,11 +230,29 @@ export const classifyArtifactContent = (path, prefix) => {
215
230
  format: "elf",
216
231
  };
217
232
  }
218
- if (prefix.length >= 2 && prefix[0] === 0x4d && prefix[1] === 0x5a)
219
- return {
220
- kind: byPath.kind === "native-addon" ? "native-addon" : "executable",
221
- format: "pe",
222
- };
233
+ if (prefix.length >= 2 && prefix[0] === 0x4d && prefix[1] === 0x5a) {
234
+ if (!Number.isSafeInteger(fileSize) ||
235
+ fileSize < prefix.length ||
236
+ prefix.length < Math.min(fileSize, 64))
237
+ return { kind: "unknown", format: "unknown" };
238
+ const windowsOffset = mzWindowsHeaderOffset(prefix);
239
+ if (windowsOffset !== null) {
240
+ if (windowsOffset >= 64 &&
241
+ windowsOffset <= prefix.length - 4 &&
242
+ prefix
243
+ .subarray(windowsOffset, windowsOffset + 4)
244
+ .equals(Buffer.from([0x50, 0x45, 0, 0])))
245
+ return {
246
+ kind: byPath.kind === "native-addon" ? "native-addon" : "executable",
247
+ format: "pe",
248
+ };
249
+ }
250
+ else if (parseDosMzHeader(prefix, fileSize).ok) {
251
+ return { kind: "executable", format: "dos-mz" };
252
+ }
253
+ // Missing bounded evidence and malformed MZ bytes both remain unclassified.
254
+ return { kind: "unknown", format: "unknown" };
255
+ }
223
256
  return byPath;
224
257
  };
225
258
  export const digestCanonical = (value) => {
@@ -1,5 +1,6 @@
1
1
  import { open } from "node:fs/promises";
2
- import { classifyArtifactPath } from "../ArtifactGraphConstruction.js";
2
+ import { classifyArtifactContent } from "../ArtifactGraphConstruction.js";
3
+ import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "./hash.js";
3
4
  import { hasZipSignature, zipPackageFormatForPath, } from "../../domain/zipPackageFormat.js";
4
5
  const classifyContainerExtension = (path) => {
5
6
  const lower = path.toLowerCase();
@@ -19,24 +20,15 @@ export const classifyRoot = async (path, directory) => {
19
20
  return extensionFormat;
20
21
  const handle = await open(path, "r");
21
22
  try {
22
- const magic = Buffer.alloc(4);
23
+ const magic = Buffer.alloc(ARTIFACT_CLASSIFICATION_PREFIX_BYTES);
23
24
  const observed = await handle.read(magic, 0, magic.length, 0);
24
- if (hasZipSignature(magic.subarray(0, observed.bytesRead)))
25
+ const prefix = magic.subarray(0, observed.bytesRead);
26
+ if (hasZipSignature(prefix))
25
27
  return "zip";
26
- if (observed.bytesRead === 4) {
27
- const header = magic.readUInt32BE(0);
28
- if ([0xcafebabe, 0xbebafeca, 0xcafebabf, 0xbfbafeca].includes(header))
29
- return "mach-o-universal";
30
- if ([0xfeedface, 0xfeedfacf, 0xcefaedfe, 0xcffaedfe].includes(header))
31
- return "mach-o";
32
- if (magic.equals(Buffer.from([0x7f, 0x45, 0x4c, 0x46])))
33
- return "elf";
34
- }
35
- if (observed.bytesRead >= 2 && magic[0] === 0x4d && magic[1] === 0x5a)
36
- return "pe";
28
+ return classifyArtifactContent(path, prefix, (await handle.stat()).size)
29
+ .format;
37
30
  }
38
31
  finally {
39
32
  await handle.close();
40
33
  }
41
- return classifyArtifactPath(path).format;
42
34
  };
@@ -1,6 +1,8 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
3
3
  import { streamChunkToBuffer } from "../../artifacts/StreamBytes.js";
4
+ /** Bounded classification evidence; this is not an executable format size limit. */
5
+ export const ARTIFACT_CLASSIFICATION_PREFIX_BYTES = 8_192;
4
6
  export const abortIfNeeded = (signal) => {
5
7
  if (signal?.aborted === true)
6
8
  throw new ArtifactReaderFailure("cancelled", "Artifact inventory cancelled");
@@ -15,8 +17,8 @@ export const hashReadable = async (stream, signal) => {
15
17
  const chunk = streamChunkToBuffer(raw);
16
18
  bytes += chunk.length;
17
19
  hash.update(chunk);
18
- if (prefixBytes < 16) {
19
- const selected = chunk.subarray(0, 16 - prefixBytes);
20
+ if (prefixBytes < ARTIFACT_CLASSIFICATION_PREFIX_BYTES) {
21
+ const selected = chunk.subarray(0, ARTIFACT_CLASSIFICATION_PREFIX_BYTES - prefixBytes);
20
22
  prefixes.push(selected);
21
23
  prefixBytes += selected.length;
22
24
  }
@@ -1,17 +1,2 @@
1
- import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
2
- /** Resolve caller approval and operator policy before native reader selection. */
3
- export const resolveNativeMountPolicy = (approved, enabled) => {
4
- if (!approved)
5
- return { status: "disabled" };
6
- if (!enabled)
7
- throw new ArtifactReaderFailure("unavailable", "Native DMG mounting is disabled by operator policy");
8
- return { status: "approved" };
9
- };
10
- /** Resolve parsed caller intent and operator policy before artifact scanning. */
11
- export const resolveArtifactIntegrityPolicy = (intent, enabled) => {
12
- if (intent.mode === "fail")
13
- return intent;
14
- if (!enabled)
15
- throw new ArtifactReaderFailure("policy", "Integrity continuation requires explicit approval and operator policy");
16
- return intent;
17
- };
1
+ /** Preserve the explicit integrity admission choice without changing verification. */
2
+ export const resolveArtifactIntegrityPolicy = (intent) => intent;
@@ -3,7 +3,7 @@ import { DirectoryArtifactReader } from "../../artifacts/DirectoryArtifactReader
3
3
  import { MachOSliceArtifactReader } from "../../artifacts/MachOSliceArtifactReader.js";
4
4
  import { NativeDmgArtifactReader } from "../../artifacts/NativeDmgArtifactReader.js";
5
5
  import { ZipArtifactReader } from "../../artifacts/ZipArtifactReader.js";
6
- export const createReader = async (path, format, nativeMount, signal) => {
6
+ export const createReader = async (path, format, signal) => {
7
7
  switch (format) {
8
8
  case "directory":
9
9
  return new DirectoryArtifactReader(path);
@@ -20,7 +20,7 @@ export const createReader = async (path, format, nativeMount, signal) => {
20
20
  ? new MachOSliceArtifactReader(path)
21
21
  : undefined;
22
22
  case "dmg":
23
- if (nativeMount.status === "disabled")
23
+ if (process.platform !== "darwin")
24
24
  return undefined;
25
25
  return NativeDmgArtifactReader.create(path, signal);
26
26
  default:
@@ -32,7 +32,7 @@ export const inventoryLimitations = (format, reader) => {
32
32
  return [];
33
33
  if (format === "dmg" || format === "pkg")
34
34
  return [
35
- `${format.toUpperCase()} root hash is observed; child inventory requires an approved native macOS adapter.`,
35
+ `${format.toUpperCase()} root hash is observed; child inventory requires a native macOS adapter.`,
36
36
  ];
37
37
  if (format === "mach-o-universal" && process.platform !== "darwin")
38
38
  return ["Universal Mach-O slices require the native macOS lipo adapter."];
@@ -7,7 +7,7 @@ import { classifyRoot } from "./classify.js";
7
7
  import { hashReadable } from "./hash.js";
8
8
  import { createReader, inventoryLimitations } from "./reader.js";
9
9
  import { scanReader, } from "./scanReader.js";
10
- import { NATIVE_MOUNT_DISABLED, STRICT_INTEGRITY_POLICY, } from "./types.js";
10
+ import { STRICT_INTEGRITY_POLICY, } from "./types.js";
11
11
  export const scanCanonicalArtifactInventory = async (path, options = {}) => {
12
12
  const integrity = options.integrity ?? STRICT_INTEGRITY_POLICY;
13
13
  const metadata = await lstat(path);
@@ -15,7 +15,7 @@ export const scanCanonicalArtifactInventory = async (path, options = {}) => {
15
15
  const rootDigest = metadata.isDirectory()
16
16
  ? null
17
17
  : await hashReadable(createReadStream(path), options.signal);
18
- const reader = await createReader(path, rootFormat, options.nativeMount ?? NATIVE_MOUNT_DISABLED, options.signal);
18
+ const reader = await createReader(path, rootFormat, options.signal);
19
19
  try {
20
20
  const { nodes, occurrences, pendingContradictions } = await scanReader(reader, options.signal, integrity);
21
21
  return await buildInventorySnapshot({
@@ -1,3 +1,4 @@
1
+ import { isAbsolute } from "node:path";
1
2
  import { ArtifactPathRegistry, normalizeArtifactPath, } from "../../artifacts/ArtifactPaths.js";
2
3
  import { ArtifactReaderFailure, } from "../../artifacts/ArtifactReader.js";
3
4
  import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
@@ -19,8 +20,14 @@ export const scanReader = async (reader, signal, integrity = STRICT_INTEGRITY_PO
19
20
  pendingContradictions,
20
21
  occurrenceByPath: new Map(),
21
22
  registry: new ArtifactPathRegistry(),
23
+ expandedContainerIds: new Set(),
22
24
  };
23
25
  await visitArtifactEntries(context, reader, "");
26
+ // Archive directories may appear after their children. Resolve containment
27
+ // against the complete index before directory identities are materialized.
28
+ for (const occurrence of occurrences)
29
+ occurrence.parent_occurrence_id =
30
+ nearestParent(occurrence.logical_path, context.occurrenceByPath, context.expandedContainerIds)?.occurrence_id ?? null;
24
31
  return { nodes, occurrences, pendingContradictions };
25
32
  };
26
33
  const visitArtifactEntries = async (context, currentReader, prefix) => {
@@ -50,8 +57,7 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
50
57
  : `${frame.prefix}/${entry.path}`);
51
58
  const expandableAsar = isExpandableAsar(entry, logicalPath);
52
59
  context.registry.add(logicalPath, expandableAsar ? "directory" : entry.kind);
53
- const parent = nearestParent(logicalPath, context.occurrenceByPath);
54
- const occurrence = createOccurrence(entry, logicalPath, parent?.occurrence_id ?? null);
60
+ const occurrence = createOccurrence(entry, logicalPath, null);
55
61
  let digested;
56
62
  try {
57
63
  digested = await digestArtifactEntry(context, frame.reader, entry, logicalPath);
@@ -75,6 +81,8 @@ const visitArtifactEntries = async (context, currentReader, prefix) => {
75
81
  context.occurrenceByPath.set(logicalPath, occurrence);
76
82
  if (expandableAsar && digested?.mismatched !== true) {
77
83
  const nested = new AsarArtifactReader(entry.adapterKey);
84
+ // Only traversed containers can own members, not opaque ASAR-named files.
85
+ context.expandedContainerIds.add(occurrence.occurrence_id);
78
86
  stack.push({
79
87
  reader: nested,
80
88
  prefix: logicalPath,
@@ -116,7 +124,7 @@ const digestArtifactEntry = async (context, currentReader, entry, logicalPath) =
116
124
  }
117
125
  const classified = entry.kind === "slice"
118
126
  ? { kind: "universal-slice", format: "mach-o" }
119
- : classifyArtifactContent(logicalPath, digest.prefix);
127
+ : classifyArtifactContent(logicalPath, digest.prefix, digest.bytes);
120
128
  return {
121
129
  node: createArtifactNode({
122
130
  sha256: digest.sha256,
@@ -136,7 +144,7 @@ const digestArtifactEntry = async (context, currentReader, entry, logicalPath) =
136
144
  };
137
145
  const isExpandableAsar = (entry, logicalPath) => entry.kind === "file" &&
138
146
  logicalPath.toLowerCase().endsWith(".asar") &&
139
- entry.adapterKey.startsWith("/");
147
+ isAbsolute(entry.adapterKey);
140
148
  const isUnavailableUnpackedEntry = (cause, entry) => entry.unpacked &&
141
149
  cause instanceof ArtifactReaderFailure &&
142
150
  cause.reason === "unavailable";
@@ -1,6 +1,3 @@
1
- export const NATIVE_MOUNT_DISABLED = {
2
- status: "disabled",
3
- };
4
1
  export const STRICT_INTEGRITY_POLICY = {
5
2
  mode: "fail",
6
3
  };
@@ -1,13 +1,14 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { analysisProfilesEqual, } from "../domain/analysisProfile.js";
3
- import { AnalysisCancelledError, ProviderAdapterError, } from "../domain/errors.js";
3
+ import { AnalysisCancelledError, } from "../domain/errors.js";
4
4
  import { err, ok } from "../domain/result.js";
5
+ import { createEvidence } from "../domain/evidence.js";
5
6
  import { GENERATED_MCP_TOOL_CATALOG } from "../generatedMcpToolCatalog.js";
6
7
  import { SessionProviderRouter, } from "./SessionProviderRouter.js";
7
8
  import { BinarySessionRecords } from "./BinarySessionRecords.js";
8
9
  import { binarySessionStatus } from "./BinarySessionStatus.js";
9
10
  import { resolveSessionOpen, } from "./BinarySessionOpen.js";
10
- import { prepareSessionExecution } from "./BinarySessionExecution.js";
11
+ import { bindExecutionTarget, commitExecutionProfile, prepareSessionExecution, } from "./BinarySessionExecution.js";
11
12
  import { closeAnalysisClient } from "./AnalysisClientCleanup.js";
12
13
  const OFFICIAL_OPERATIONS = new Set(GENERATED_MCP_TOOL_CATALOG.filter(({ kind }) => kind === "official-proxy").map(({ name }) => name));
13
14
  const ENHANCED_OPERATIONS = new Set(GENERATED_MCP_TOOL_CATALOG.filter(({ kind }) => kind === "enhanced").map(({ name }) => name));
@@ -143,10 +144,12 @@ export class BinarySession extends BinarySessionRecords {
143
144
  runId,
144
145
  };
145
146
  this.#clearRuntimeAvailability();
146
- if (profile === null)
147
- this.clearSnapshot();
148
- else
149
- this.selectSnapshot(target, profile);
147
+ if (options.snapshot === undefined) {
148
+ if (profile === null)
149
+ this.clearSnapshot();
150
+ else
151
+ this.selectSnapshot(target, profile);
152
+ }
150
153
  if (options.snapshot !== undefined) {
151
154
  const imported = this.importAnalysisSnapshot(options.snapshot);
152
155
  if (!imported.ok) {
@@ -216,7 +219,9 @@ export class BinarySession extends BinarySessionRecords {
216
219
  operation: name,
217
220
  parameters: arguments_,
218
221
  unboundOperationError: (operation, route) => this.#providerRouter.unboundOperationError(operation, route),
219
- lookupSnapshot: (target, profile, operation, parameters) => operation === "decode_interface_builder"
222
+ lookupSnapshot: (target, profile, operation, parameters) => operation === "decode_interface_builder" ||
223
+ operation === "inspect_asset_catalog" ||
224
+ operation === "inspect_keyed_archive"
220
225
  ? undefined
221
226
  : this.lookupSnapshot(target, profile, operation, parameters),
222
227
  });
@@ -234,7 +239,21 @@ export class BinarySession extends BinarySessionRecords {
234
239
  if (profiled.ok &&
235
240
  cacheable &&
236
241
  profile !== undefined &&
237
- name !== "decode_interface_builder")
242
+ name !== "decode_interface_builder" &&
243
+ name !== "inspect_asset_catalog" &&
244
+ name !== "inspect_keyed_archive") {
245
+ const evidence = createEvidence(profiled.value.subject ?? active.target, profiled.value.provider, {
246
+ operation: name,
247
+ parameters: arguments_,
248
+ result: profiled.value.result,
249
+ analysisProfile: profile,
250
+ rawResult: profiled.value.rawResult,
251
+ limitations: profiled.value.limitations,
252
+ locations: profiled.value.locations,
253
+ });
254
+ const recorded = this.recordEvidence(evidence);
255
+ if (!recorded.ok)
256
+ return recorded;
238
257
  this.recordSnapshot({
239
258
  target: active.target,
240
259
  profile,
@@ -242,6 +261,7 @@ export class BinarySession extends BinarySessionRecords {
242
261
  parameters: arguments_,
243
262
  execution: profiled.value,
244
263
  });
264
+ }
245
265
  else if (profiled.ok && capability?.effects.mutatesArtifact === true) {
246
266
  this.invalidateSnapshot();
247
267
  }
@@ -363,38 +383,3 @@ export class BinarySession extends BinarySessionRecords {
363
383
  }
364
384
  }
365
385
  const isAborted = (signal) => signal?.aborted === true;
366
- const commitExecutionProfile = (operation, result, profile) => {
367
- if (!result.ok || profile === undefined)
368
- return result;
369
- const provider = result.value.provider;
370
- if (provider.id !== profile.provider.id ||
371
- provider.name !== profile.provider.name ||
372
- provider.version !== profile.provider.version)
373
- return err(new ProviderAdapterError(profile.provider.id, `${operation}:profile`));
374
- return ok({
375
- ...result.value,
376
- analysisProfile: structuredClone(profile),
377
- });
378
- };
379
- const bindExecutionTarget = (result, operation, target) => {
380
- if (!result.ok)
381
- return result;
382
- const subject = {
383
- path: target.path,
384
- sha256: target.sha256,
385
- format: target.format === "analysis-database"
386
- ? "analysis-database"
387
- : target.format,
388
- ...(target.architecture === undefined
389
- ? {}
390
- : { architecture: target.architecture }),
391
- };
392
- if (result.value.subject !== null &&
393
- result.value.subject.sha256 !== target.sha256) {
394
- if (!isArtifactInventorySubject(operation, result.value.subject, target))
395
- return err(new ProviderAdapterError(result.value.provider.id, `${operation}:subject`));
396
- }
397
- return ok({ ...result.value, subject: result.value.subject ?? subject });
398
- };
399
- const isArtifactInventorySubject = (operation, subject, target) => (operation === "inventory_artifact" || operation === "inspect_artifact") &&
400
- subject.path === (target.sourcePath ?? target.path);
@@ -1,4 +1,4 @@
1
- import { AnalysisCapabilityUnavailableError, NoBinaryOpenError, } from "../domain/errors.js";
1
+ import { AnalysisCapabilityUnavailableError, NoBinaryOpenError, ProviderAdapterError, } from "../domain/errors.js";
2
2
  import { err, ok } from "../domain/result.js";
3
3
  import { isSnapshotCacheable } from "./AnalysisSnapshotCache.js";
4
4
  /** Resolve capability, profile, and snapshot state before invoking a provider. */
@@ -26,3 +26,39 @@ export const prepareSessionExecution = (input) => {
26
26
  : undefined;
27
27
  return ok({ active, capability, profile, cacheable, cached });
28
28
  };
29
+ /** Attach the selected profile only when the provider identity agrees. */
30
+ export const commitExecutionProfile = (operation, result, profile) => {
31
+ if (!result.ok || profile === undefined)
32
+ return result;
33
+ const provider = result.value.provider;
34
+ if (provider.id !== profile.provider.id ||
35
+ provider.name !== profile.provider.name ||
36
+ provider.version !== profile.provider.version)
37
+ return err(new ProviderAdapterError(profile.provider.id, `${operation}:profile`));
38
+ return ok({
39
+ ...result.value,
40
+ analysisProfile: structuredClone(profile),
41
+ });
42
+ };
43
+ /** Bind an execution to the selected target, preserving valid artifact subjects. */
44
+ export const bindExecutionTarget = (result, operation, target) => {
45
+ if (!result.ok)
46
+ return result;
47
+ const subject = {
48
+ path: target.path,
49
+ sha256: target.sha256,
50
+ format: target.format === "analysis-database"
51
+ ? "analysis-database"
52
+ : target.format,
53
+ ...(target.architecture === undefined
54
+ ? {}
55
+ : { architecture: target.architecture }),
56
+ };
57
+ if (result.value.subject !== null &&
58
+ result.value.subject.sha256 !== target.sha256 &&
59
+ !isArtifactInventorySubject(operation, result.value.subject, target))
60
+ return err(new ProviderAdapterError(result.value.provider.id, `${operation}:subject`));
61
+ return ok({ ...result.value, subject: result.value.subject ?? subject });
62
+ };
63
+ const isArtifactInventorySubject = (operation, subject, target) => (operation === "inventory_artifact" || operation === "inspect_artifact") &&
64
+ subject.path === (target.sourcePath ?? target.path);