rea-agents 3.2.0 → 4.0.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 (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,108 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { z } from "zod";
4
+ import { PRODUCT_IDENTITY } from "../identity.js";
5
+ import { isOwnedClientRegistrationCommand } from "./ClientRegistrationIdentity.js";
6
+ import { readClientRegistrationStatuses } from "./ClientRegistrationStatus.js";
7
+ import { parseClientConfiguration } from "./ClientConfigurationDocument.js";
8
+ import { supportedClients } from "./SupportedClients.js";
9
+ const setupPlanSchema = z.object({
10
+ status: z.literal("planned"),
11
+ plannedActions: z.array(z.object({
12
+ id: z.string(),
13
+ kind: z.enum(["configure_client", "install_skill"]),
14
+ label: z.string(),
15
+ target: z.string(),
16
+ detail: z.string(),
17
+ external: z.literal(false),
18
+ operation: z.enum(["create", "update", "install"]),
19
+ backupPath: z.string().optional(),
20
+ commands: z.array(z.string()).optional(),
21
+ })),
22
+ });
23
+ /** Discover owned registrations and an existing REA skill without writes. */
24
+ export const existingMaintenanceScope = async (home, entryPoint) => {
25
+ const registrations = await readClientRegistrationStatuses(home, entryPoint);
26
+ const supported = supportedClients(home);
27
+ const clients = [];
28
+ for (const registration of registrations) {
29
+ if ((registration.state !== "aligned" && registration.state !== "stale") ||
30
+ !isOwnedClientRegistrationCommand(registration.command, entryPoint))
31
+ continue;
32
+ const client = supported.find(({ name }) => name === registration.client);
33
+ if (client === undefined)
34
+ continue;
35
+ const { servers } = parseClientConfiguration(await readFile(client.configPath, "utf8"), client.format);
36
+ const enabled = z
37
+ .object({
38
+ enabled: z.boolean().optional(),
39
+ disabled: z.boolean().optional(),
40
+ })
41
+ .parse(servers[PRODUCT_IDENTITY.mcpServerKey]);
42
+ if (enabled.enabled !== false && enabled.disabled !== true)
43
+ clients.push(client.name);
44
+ }
45
+ let skill = false;
46
+ try {
47
+ const content = await readFile(join(home, ".agents", "skills", PRODUCT_IDENTITY.skillName, "SKILL.md"), "utf8");
48
+ skill =
49
+ content.startsWith(`---\nname: ${PRODUCT_IDENTITY.skillName}\n`) ||
50
+ content.startsWith(`---\r\nname: ${PRODUCT_IDENTITY.skillName}\r\n`);
51
+ }
52
+ catch (cause) {
53
+ if (!(cause instanceof Error && "code" in cause && cause.code === "ENOENT"))
54
+ throw cause;
55
+ }
56
+ return { clients, skill };
57
+ };
58
+ /** Ask the verified new executable to plan only existing REA integrations. */
59
+ export const planIntegrationMaintenance = async (home, entryPoint, execute) => {
60
+ try {
61
+ const scope = await existingMaintenanceScope(home, entryPoint);
62
+ if (scope.clients.length === 0 && !scope.skill)
63
+ return { status: "current", plannedActions: [] };
64
+ const command = [
65
+ process.execPath,
66
+ entryPoint,
67
+ "setup",
68
+ ...scope.clients.flatMap((client) => ["--client", client]),
69
+ `--skill=${String(scope.skill)}`,
70
+ ];
71
+ const execution = await execute([...command, "--dry-run", "--json"]);
72
+ if (!execution.ok)
73
+ return { status: "unavailable", remediation: execution.error };
74
+ const plan = setupPlanSchema.safeParse(JSON.parse(execution.value));
75
+ if (!plan.success)
76
+ return {
77
+ status: "unavailable",
78
+ remediation: `The updated setup executable returned an invalid maintenance plan: ${plan.error.message}`,
79
+ };
80
+ if (plan.data.plannedActions.length === 0)
81
+ return { status: "current", plannedActions: [] };
82
+ const allowedIds = new Set([
83
+ ...scope.clients.map((client) => `configure_client:${client}`),
84
+ ...(scope.skill ? ["install_skill"] : []),
85
+ ]);
86
+ if (plan.data.plannedActions.some(({ id }) => !allowedIds.has(id)))
87
+ return {
88
+ status: "unavailable",
89
+ remediation: "The updated setup plan included an integration outside the existing REA maintenance scope.",
90
+ };
91
+ return {
92
+ status: "planned",
93
+ scope,
94
+ command,
95
+ plannedActions: plan.data.plannedActions.map(({ backupPath, commands, ...action }) => ({
96
+ ...action,
97
+ ...(backupPath === undefined ? {} : { backupPath }),
98
+ ...(commands === undefined ? {} : { commands }),
99
+ })),
100
+ };
101
+ }
102
+ catch (cause) {
103
+ return {
104
+ status: "unavailable",
105
+ remediation: cause instanceof Error ? cause.message : String(cause),
106
+ };
107
+ }
108
+ };
@@ -0,0 +1,126 @@
1
+ import { realpath } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { basename, dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import spawn from "cross-spawn";
6
+ import { z } from "zod";
7
+ import { PRODUCT_IDENTITY } from "../identity.js";
8
+ import { err, ok } from "../domain/result.js";
9
+ import { updateInstallCommand, } from "./Update.js";
10
+ import { planIntegrationMaintenance } from "./UpdateMaintenance.js";
11
+ /** Run an updater subprocess with complete diagnostics and isolated machine output. */
12
+ export const runUpdateCommand = (command, output = "structured") => new Promise((resolveResult) => {
13
+ const [executable, ...args] = command;
14
+ if (executable === undefined) {
15
+ resolveResult(err("No executable supplied."));
16
+ return;
17
+ }
18
+ const environment = { ...process.env };
19
+ // A fresh installed entry point must not inherit npx's invocation identity.
20
+ delete environment.npm_command;
21
+ const child = spawn(executable, args, {
22
+ stdio: ["ignore", "pipe", "pipe"],
23
+ env: environment,
24
+ windowsHide: true,
25
+ });
26
+ let stdout = "";
27
+ let stderr = "";
28
+ child.stdout?.setEncoding("utf8");
29
+ child.stderr?.setEncoding("utf8");
30
+ child.stdout?.on("data", (chunk) => {
31
+ stdout += chunk;
32
+ if (output === "human")
33
+ process.stderr.write(chunk);
34
+ });
35
+ child.stderr?.on("data", (chunk) => {
36
+ stderr += chunk;
37
+ if (output === "human")
38
+ process.stderr.write(chunk);
39
+ });
40
+ child.once("error", (cause) => resolveResult(err(cause.message)));
41
+ child.once("close", (code, signal) => resolveResult(code === 0
42
+ ? ok(stdout.trim())
43
+ : err(stderr.trim() ||
44
+ stdout.trim() ||
45
+ (signal === null
46
+ ? `Process exited with code ${String(code)}.`
47
+ : `Process terminated by ${signal}.`))));
48
+ });
49
+ const requireCommandOutput = async (command) => {
50
+ const result = await runUpdateCommand(command);
51
+ if (!result.ok)
52
+ throw new Error(result.error);
53
+ return result.value;
54
+ };
55
+ /** Resolve the global prefix only when it owns the running package. */
56
+ export const detectNpmInstallation = async (packageRoot, host) => {
57
+ let canonicalPackageRoot;
58
+ try {
59
+ canonicalPackageRoot = await host.canonicalPath(packageRoot);
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ try {
65
+ const npmRoot = await host.globalRoot();
66
+ const globalPackageRoot = await host.canonicalPath(resolve(npmRoot, PRODUCT_IDENTITY.packageName));
67
+ if (canonicalPackageRoot === globalPackageRoot) {
68
+ const prefix = await host.globalPrefix();
69
+ return prefix.length === 0
70
+ ? undefined
71
+ : { prefix, packageRoot: canonicalPackageRoot };
72
+ }
73
+ }
74
+ catch {
75
+ // The curl installer uses a Unix prefix that may differ from npm's current default.
76
+ }
77
+ const nodeModules = dirname(canonicalPackageRoot);
78
+ const library = dirname(nodeModules);
79
+ if (basename(canonicalPackageRoot) !== PRODUCT_IDENTITY.packageName ||
80
+ basename(nodeModules) !== "node_modules" ||
81
+ basename(library) !== "lib")
82
+ return undefined;
83
+ return { prefix: dirname(library), packageRoot: canonicalPackageRoot };
84
+ };
85
+ /** Create npm, registry, verification, and read-only maintenance effects. */
86
+ export const systemUpdateHost = (packageRoot = fileURLToPath(new URL("../..", import.meta.url)), home = homedir()) => ({
87
+ installation: () => detectNpmInstallation(packageRoot, {
88
+ canonicalPath: realpath,
89
+ globalRoot: () => requireCommandOutput(["npm", "root", "--global"]),
90
+ globalPrefix: () => requireCommandOutput(["npm", "prefix", "--global"]),
91
+ }),
92
+ latestVersion: async (installation) => {
93
+ const response = await runUpdateCommand([
94
+ "npm",
95
+ "view",
96
+ "--global",
97
+ ...(installation === undefined ? [] : ["--prefix", installation.prefix]),
98
+ PRODUCT_IDENTITY.packageName,
99
+ "dist-tags.latest",
100
+ "--json",
101
+ "--fetch-retries=0",
102
+ "--fetch-timeout=10000",
103
+ ]);
104
+ if (!response.ok)
105
+ return response;
106
+ try {
107
+ const parsed = z.string().min(1).safeParse(JSON.parse(response.value));
108
+ return parsed.success
109
+ ? ok(parsed.data)
110
+ : err(`Invalid npm release metadata: ${parsed.error.message}`);
111
+ }
112
+ catch (cause) {
113
+ return err(cause instanceof Error ? cause.message : String(cause));
114
+ }
115
+ },
116
+ installVersion: async (installation, version, output) => {
117
+ const result = await runUpdateCommand(updateInstallCommand(installation, version), output);
118
+ return result.ok ? ok(undefined) : result;
119
+ },
120
+ installedVersion: (installation) => runUpdateCommand([
121
+ process.execPath,
122
+ join(installation.packageRoot, "scripts", "rea.mjs"),
123
+ "--version",
124
+ ]),
125
+ planMaintenance: (installation) => planIntegrationMaintenance(home, join(installation.packageRoot, "scripts", "rea.mjs"), runUpdateCommand),
126
+ });
@@ -4,7 +4,10 @@ import { silentLogger } from "../logger.js";
4
4
  import { GENERATED_AUXILIARY_PROVIDERS } from "../generatedMcpToolCatalog.js";
5
5
  import { AnalysisProviderRegistry } from "./AnalysisProviderRegistry.js";
6
6
  import { composeBinarySession } from "./BinarySessionComposition.js";
7
+ import { nativeHostCapabilities } from "../native/NativeHostCapabilities.js";
7
8
  import { LazyAnalysisProvider } from "./LazyAnalysisProvider.js";
9
+ import { ManagedStaticProvider } from "../dotnet/ManagedStaticProvider.js";
10
+ import { SessionProviderRouter } from "./SessionProviderRouter.js";
8
11
  /**
9
12
  * Compose the target-switching runtime shared directly by CLI and MCP adapters.
10
13
  * This is the sole production wiring point, so both adapters share identical
@@ -21,12 +24,16 @@ export const createBinarySession = (config, logger = silentLogger) => {
21
24
  const generated = auxiliary.get(id);
22
25
  if (generated === undefined)
23
26
  throw new TypeError(`Missing generated provider metadata for ${id}`);
24
- return new LazyAnalysisProvider({ ...generated, load });
27
+ return new LazyAnalysisProvider({
28
+ ...generated,
29
+ capabilities: nativeHostCapabilities(generated.capabilities),
30
+ load,
31
+ });
25
32
  };
26
33
  return composeBinarySession(new AnalysisProviderRegistry([hopper, ghidra], config.analysisProvider), [
27
34
  lazyProvider("rea-artifact-graph", async () => {
28
35
  const { ArtifactProvider } = await import("../artifacts/ArtifactProvider.js");
29
- return new ArtifactProvider(config.artifactNativeMountEnabled, config.artifactIntegrityContinueEnabled);
36
+ return new ArtifactProvider();
30
37
  }),
31
38
  lazyProvider("native-macos", async () => {
32
39
  const { NativeMacOSProvider } = await import("../native/NativeMacOSProvider.js");
@@ -38,3 +45,7 @@ export const createBinarySession = (config, logger = silentLogger) => {
38
45
  }),
39
46
  ]);
40
47
  };
48
+ /** Compose an execution-free managed session without native provider selection. */
49
+ export const createManagedBinarySession = () => composeBinarySession(SessionProviderRouter.selectable(new AnalysisProviderRegistry([]), [
50
+ new ManagedStaticProvider(),
51
+ ]));
@@ -19,20 +19,19 @@ export const normalizeArtifactPath = (input) => {
19
19
  /** Reject exact, Unicode-normalized, case-folded, and prefix collisions. */
20
20
  export class ArtifactPathRegistry {
21
21
  #root = { kind: undefined, children: new Map() };
22
- #folded = new Set();
23
22
  add(path, kind) {
24
- const folded = path.toLocaleLowerCase("en-US");
25
- if (this.#folded.has(folded))
26
- throw new ArtifactReaderFailure("path", `Artifact path collision: ${path}`);
27
23
  const parts = path.split("/");
28
24
  let node = this.#root;
29
25
  for (const [index, part] of parts.entries()) {
30
26
  if (node.kind !== undefined && node.kind !== "directory")
31
27
  throw new ArtifactReaderFailure("path", `Artifact prefix conflict: ${path}`);
32
- let child = node.children.get(part);
28
+ const foldedPart = part.toLocaleLowerCase("en-US");
29
+ let child = node.children.get(foldedPart);
30
+ if (child !== undefined && child.spelling !== part)
31
+ throw new ArtifactReaderFailure("path", `Artifact path collision: ${path}`);
33
32
  if (child === undefined) {
34
- child = { kind: undefined, children: new Map() };
35
- node.children.set(part, child);
33
+ child = { spelling: part, kind: undefined, children: new Map() };
34
+ node.children.set(foldedPart, child);
36
35
  }
37
36
  node = child;
38
37
  if (index === parts.length - 1) {
@@ -43,6 +42,5 @@ export class ArtifactPathRegistry {
43
42
  }
44
43
  }
45
44
  node.kind = kind;
46
- this.#folded.add(folded);
47
45
  }
48
46
  }
@@ -1,7 +1,10 @@
1
1
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
2
+ import { inspectBundleKeyedArchive } from "./KeyedArchiveReader.js";
3
+ import { basename, dirname } from "node:path";
2
4
  import { inventoryArtifact } from "../application/ArtifactInventory.js";
3
5
  import { extractArtifact } from "../application/ArtifactExtraction.js";
4
6
  import { analyzeInterfaceBuilderBundle } from "../application/InterfaceBuilderAnalysis.js";
7
+ import { analyzeAppleAssetCatalogs } from "../application/AppleAssetCatalogAnalysis.js";
5
8
  import { ARTIFACT_ANALYSIS_OPERATIONS, artifactInventoryInputSchema, artifactExtractionExecutionSchema, } from "../contracts/artifactToolContracts.js";
6
9
  import { AnalysisCapabilityUnavailableError, ArtifactOperationError, } from "../domain/errors.js";
7
10
  import { interfaceBuilderLimitsSchema } from "../domain/interfaceBuilderGraph.js";
@@ -10,35 +13,43 @@ import { ArtifactReaderFailure } from "./ArtifactReader.js";
10
13
  import { ARTIFACT_GRAPH_PROVIDER } from "../application/InvestigationProviders.js";
11
14
  import { createEvidence } from "../domain/evidence.js";
12
15
  import { createArtifactInspection } from "../domain/artifactInspection.js";
13
- import { resolveArtifactIntegrityPolicy, resolveNativeMountPolicy, } from "../application/ArtifactInventory/policy.js";
16
+ import { resolveArtifactIntegrityPolicy } from "../application/ArtifactInventory/policy.js";
14
17
  const IDENTITY = Object.freeze(ARTIFACT_GRAPH_PROVIDER);
15
18
  /** Read-only inventory and exclusively owned extraction provider. */
16
19
  export class ArtifactProvider {
17
- nativeMountEnabled;
18
- integrityContinueEnabled;
19
- constructor(nativeMountEnabled = false, integrityContinueEnabled = false) {
20
- this.nativeMountEnabled = nativeMountEnabled;
21
- this.integrityContinueEnabled = integrityContinueEnabled;
20
+ #capabilities;
21
+ constructor(platform = process.platform) {
22
+ this.#capabilities = Object.freeze(ARTIFACT_ANALYSIS_OPERATIONS.map((operation) => {
23
+ const common = {
24
+ provider: IDENTITY,
25
+ operation,
26
+ effects: Object.freeze({
27
+ mutatesArtifact: false,
28
+ launchesProcess: operation !== "decode_interface_builder" &&
29
+ operation !== "inspect_keyed_archive",
30
+ mayShowUi: false,
31
+ mayAccessNetwork: false,
32
+ mayWriteFilesystem: operation === "extract_artifact" ||
33
+ operation === "inspect_artifact" ||
34
+ operation === "inventory_artifact",
35
+ changesPermissions: false,
36
+ requiresRoot: false,
37
+ }),
38
+ limitations: Object.freeze([
39
+ "DMG child inventory automatically uses a read-only native macOS mount; PKG remains root-hash-only.",
40
+ "ASAR files discovered in filesystem-backed inventories are expanded without bulk extraction; other nested containers remain recorded only.",
41
+ ]),
42
+ };
43
+ return Object.freeze(operation === "inspect_asset_catalog" && platform !== "darwin"
44
+ ? {
45
+ ...common,
46
+ available: false,
47
+ availabilityCode: "unsupported_host",
48
+ reason: "Apple asset catalogs require macOS assetutil.",
49
+ }
50
+ : { ...common, available: true, reason: null });
51
+ }));
22
52
  }
23
- #capabilities = Object.freeze(ARTIFACT_ANALYSIS_OPERATIONS.map((operation) => Object.freeze({
24
- provider: IDENTITY,
25
- operation,
26
- available: true,
27
- reason: null,
28
- effects: Object.freeze({
29
- mutatesArtifact: false,
30
- launchesProcess: operation !== "decode_interface_builder",
31
- mayShowUi: false,
32
- mayAccessNetwork: false,
33
- mayWriteFilesystem: operation === "extract_artifact",
34
- changesPermissions: false,
35
- requiresRoot: false,
36
- }),
37
- limitations: Object.freeze([
38
- "DMG child inventory is macOS-only and requires per-call approval plus operator policy; PKG remains root-hash-only.",
39
- "ASAR files discovered in filesystem-backed inventories are expanded without bulk extraction; other nested containers remain recorded only.",
40
- ]),
41
- })));
42
53
  identity() {
43
54
  return IDENTITY;
44
55
  }
@@ -46,17 +57,13 @@ export class ArtifactProvider {
46
57
  return this.#capabilities;
47
58
  }
48
59
  createClient(target) {
49
- return new ArtifactClient(target, this.nativeMountEnabled, this.integrityContinueEnabled);
60
+ return new ArtifactClient(target);
50
61
  }
51
62
  }
52
63
  class ArtifactClient {
53
64
  target;
54
- nativeMountEnabled;
55
- integrityContinueEnabled;
56
- constructor(target, nativeMountEnabled, integrityContinueEnabled) {
65
+ constructor(target) {
57
66
  this.target = target;
58
- this.nativeMountEnabled = nativeMountEnabled;
59
- this.integrityContinueEnabled = integrityContinueEnabled;
60
67
  }
61
68
  async execute(operation, parameters, options) {
62
69
  if (operation === "health")
@@ -88,6 +95,37 @@ class ArtifactClient {
88
95
  })),
89
96
  }));
90
97
  }
98
+ if (operation === "inspect_keyed_archive") {
99
+ const standalone = this.target.kind === "artifact" && this.target.format === "plist";
100
+ if (standalone &&
101
+ parameters.path !== undefined &&
102
+ parameters.path !== "." &&
103
+ parameters.path !== basename(this.target.path))
104
+ throw new ArtifactReaderFailure("path", "For an active plist, path must select that archive (omit path or use its basename)");
105
+ const bundlePath = standalone
106
+ ? dirname(this.target.path)
107
+ : this.target.sourcePath;
108
+ if (bundlePath === undefined ||
109
+ (!standalone && !bundlePath.toLowerCase().endsWith(".app")))
110
+ throw new ArtifactReaderFailure("unavailable", "inspect_keyed_archive requires an active plist or .app bundle");
111
+ const result = await inspectBundleKeyedArchive({
112
+ bundlePath,
113
+ targetSha256: this.target.sha256,
114
+ parameters: standalone
115
+ ? { ...parameters, path: basename(this.target.path) }
116
+ : parameters,
117
+ ...(options?.signal === undefined ? {} : { signal: options.signal }),
118
+ });
119
+ if (standalone && result.archive_sha256 !== this.target.sha256)
120
+ throw new ArtifactReaderFailure("integrity", `Active archive digest changed: expected ${this.target.sha256}, observed ${result.archive_sha256}`);
121
+ return ok(createAnalysisExecution(result, IDENTITY, {
122
+ limitations: result.limitations,
123
+ locations: [{ kind: "artifact-path", path: result.archive_path }],
124
+ }));
125
+ }
126
+ if (operation === "inspect_asset_catalog") {
127
+ return await this.inspectAssetCatalog(parameters, options);
128
+ }
91
129
  if (operation === "extract_artifact") {
92
130
  const parsed = artifactExtractionExecutionSchema.parse(parameters);
93
131
  const result = await extractArtifact({
@@ -124,13 +162,31 @@ class ArtifactClient {
124
162
  close() {
125
163
  return Promise.resolve();
126
164
  }
165
+ async inspectAssetCatalog(parameters, options) {
166
+ const bundlePath = this.target.sourcePath;
167
+ if (this.target.kind !== "executable" ||
168
+ bundlePath === undefined ||
169
+ !bundlePath.toLowerCase().endsWith(".app"))
170
+ throw new ArtifactReaderFailure("unavailable", "inspect_asset_catalog requires an active .app bundle target");
171
+ const result = await analyzeAppleAssetCatalogs({
172
+ bundlePath,
173
+ targetSha256: this.target.sha256,
174
+ page: parameters,
175
+ ...(options?.signal === undefined ? {} : { signal: options.signal }),
176
+ });
177
+ return ok(createAnalysisExecution(result, IDENTITY, {
178
+ limitations: result.limitations,
179
+ locations: result.catalogs.map(({ path }) => ({
180
+ kind: "artifact-path",
181
+ path,
182
+ })),
183
+ }));
184
+ }
127
185
  async inspectArtifact(parameters, options) {
128
186
  const parsed = artifactInventoryInputSchema.parse(parameters);
129
- const inventoryParameters = artifactInventoryInputSchema.parse({
130
- native_mount_approved: parsed.native_mount_approved,
187
+ const inventoryParameters = {
131
188
  integrity_policy: parsed.integrity_policy,
132
- integrity_continue_approved: parsed.integrity_continue_approved,
133
- });
189
+ };
134
190
  await options?.progress?.report({
135
191
  phase: "inspect_artifact.inventory",
136
192
  completed: 0,
@@ -168,12 +224,9 @@ class ArtifactClient {
168
224
  inventory(parsed, options) {
169
225
  return inventoryArtifact(this.target.sourcePath ?? this.target.path, {
170
226
  ...(options?.signal === undefined ? {} : { signal: options.signal }),
171
- nativeMount: resolveNativeMountPolicy(parsed.native_mount_approved === true, this.nativeMountEnabled),
172
- integrity: resolveArtifactIntegrityPolicy(parsed.integrity_policy === "fail"
173
- ? { mode: "fail" }
174
- : {
175
- mode: parsed.integrity_policy,
176
- }, this.integrityContinueEnabled),
227
+ integrity: resolveArtifactIntegrityPolicy({
228
+ mode: parsed.integrity_policy,
229
+ }),
177
230
  });
178
231
  }
179
232
  }
@@ -1,5 +1,6 @@
1
+ import { sep } from "node:path";
1
2
  import { Readable } from "node:stream";
2
- import { extractFile, listPackage, statFile } from "@electron/asar";
3
+ import { extractFile, listPackage, statFile, uncache } from "@electron/asar";
3
4
  import { ArtifactReaderFailure, } from "./ArtifactReader.js";
4
5
  /**
5
6
  * Official Electron ASAR adapter. Individual files remain caller-bounded.
@@ -17,6 +18,8 @@ export class AsarArtifactReader {
17
18
  async *entries(signal) {
18
19
  let paths;
19
20
  try {
21
+ // ASAR caches headers by path even after the archive has been replaced.
22
+ uncache(this.path);
20
23
  paths = listPackage(this.path, { isPack: false }).sort((left, right) => left.localeCompare(right, "en"));
21
24
  }
22
25
  catch (cause) {
@@ -24,12 +27,19 @@ export class AsarArtifactReader {
24
27
  }
25
28
  for (const listed of paths) {
26
29
  abortIfNeeded(signal);
27
- const path = listed.replace(/^\/+|\/+$/gu, "");
30
+ // @electron/asar returns paths assembled with the host path module.
31
+ // Keep that spelling for its API calls, but expose archive paths with
32
+ // portable separators. On POSIX, backslashes can be literal filename
33
+ // characters and must remain untouched.
34
+ const path = toArtifactPath(listed);
28
35
  if (path.length === 0)
29
36
  continue;
37
+ const providerPath = listed.startsWith(sep)
38
+ ? listed.slice(sep.length)
39
+ : listed;
30
40
  let metadata;
31
41
  try {
32
- metadata = statFile(this.path, path, false);
42
+ metadata = statFile(this.path, providerPath, false);
33
43
  }
34
44
  catch (cause) {
35
45
  throw asarFailure(this.path, `stat ${path}`, cause);
@@ -58,7 +68,7 @@ export class AsarArtifactReader {
58
68
  : [
59
69
  "Official ASAR extraction buffers each individually bounded file.",
60
70
  ],
61
- adapterKey: path,
71
+ adapterKey: providerPath,
62
72
  };
63
73
  }
64
74
  }
@@ -81,6 +91,7 @@ export class AsarArtifactReader {
81
91
  }
82
92
  }
83
93
  close() {
94
+ uncache(this.path);
84
95
  return Promise.resolve();
85
96
  }
86
97
  provenance() {
@@ -91,6 +102,10 @@ const abortIfNeeded = (signal) => {
91
102
  if (signal?.aborted === true)
92
103
  throw new ArtifactReaderFailure("cancelled", "ASAR operation cancelled");
93
104
  };
105
+ const toArtifactPath = (listed) => {
106
+ const portable = sep === "\\" ? listed.replaceAll("\\", "/") : listed;
107
+ return portable.replace(/^\/+|\/+$/gu, "");
108
+ };
94
109
  const asarFailure = (path, operation, cause) => cause instanceof ArtifactReaderFailure
95
110
  ? cause
96
111
  : new ArtifactReaderFailure("format", `Malformed or unreadable ASAR during ${operation}: ${path}`, { cause });
@@ -0,0 +1,110 @@
1
+ import { createHash } from "node:crypto";
2
+ import { TextDecoder } from "node:util";
3
+ import { parse, parseBinary } from "plist";
4
+ import { z } from "zod";
5
+ import { keyedArchiveInputSchema, keyedArchiveResultSchema, projectKeyedArchive, } from "../domain/keyedArchive.js";
6
+ import { DirectoryArtifactReader } from "./DirectoryArtifactReader.js";
7
+ import { ArtifactReaderFailure } from "./ArtifactReader.js";
8
+ const MAX_BYTES = 64 * 1024 * 1024;
9
+ /** Parse inert plist bytes, preserving data and dates with explicit typed values. */
10
+ export const decodeKeyedArchiveBytes = (bytes, selection) => {
11
+ if (bytes.length > MAX_BYTES)
12
+ throw new RangeError("Keyed archive exceeds 64 MiB");
13
+ const binary = bytes.subarray(0, 8).toString("ascii") === "bplist00";
14
+ const parsed = binary
15
+ ? parseBinary(bytes)
16
+ : parse(decodeXmlPlistText(bytes));
17
+ return {
18
+ archive_format: binary ? "binary-plist" : "xml-plist",
19
+ ...projectKeyedArchive(normalizePlist(parsed), selection),
20
+ };
21
+ };
22
+ const decodeXmlPlistText = (bytes) => {
23
+ const encoding = bytes[0] === 0xff && bytes[1] === 0xfe
24
+ ? "utf-16le"
25
+ : bytes[0] === 0xfe && bytes[1] === 0xff
26
+ ? "utf-16be"
27
+ : "utf-8";
28
+ const text = new TextDecoder(encoding, { fatal: true }).decode(bytes);
29
+ const declared = /^<\?xml\s[^?]*\bencoding\s*=\s*["']([^"']+)["']/u
30
+ .exec(text)?.[1]
31
+ ?.toLowerCase();
32
+ if (declared !== undefined &&
33
+ ((encoding !== "utf-8" && declared !== encoding && declared !== "utf-16") ||
34
+ (encoding === "utf-8" && declared.startsWith("utf-16"))))
35
+ throw new TypeError("XML encoding declaration disagrees with its bytes");
36
+ return text;
37
+ };
38
+ const normalizePlist = (value, depth = 0) => {
39
+ if (depth > 128)
40
+ throw new RangeError("Plist exceeds 128 nesting levels");
41
+ if (value instanceof Uint8Array)
42
+ return {
43
+ $plist_type: "data",
44
+ base64: Buffer.from(value).toString("base64"),
45
+ };
46
+ if (value instanceof Date)
47
+ return { $plist_type: "date", iso8601: value.toISOString() };
48
+ if (Array.isArray(value))
49
+ return value.map((item) => normalizePlist(item, depth + 1));
50
+ if (value !== null && typeof value === "object")
51
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [
52
+ key,
53
+ normalizePlist(item, depth + 1),
54
+ ]));
55
+ return z
56
+ .union([z.string(), z.number().finite(), z.boolean(), z.null()])
57
+ .parse(value);
58
+ };
59
+ /** Read exactly one regular, contained bundle entry without following symlinks. */
60
+ export const inspectBundleKeyedArchive = async (input) => {
61
+ const selected = keyedArchiveInputSchema.parse(input.parameters);
62
+ if (selected.path.startsWith("/") ||
63
+ selected.path
64
+ .split("/")
65
+ .some((part) => part === ".." || part === "." || part.length === 0))
66
+ throw new ArtifactReaderFailure("path", "Archive path must be a canonical relative bundle path");
67
+ const reader = new DirectoryArtifactReader(input.bundlePath);
68
+ try {
69
+ for await (const entry of reader.entries(input.signal)) {
70
+ if (entry.path !== selected.path)
71
+ continue;
72
+ if (entry.kind !== "file")
73
+ throw new ArtifactReaderFailure("path", "Archive must be a regular file, not a symlink or directory");
74
+ if ((entry.declaredSize ?? 0) > MAX_BYTES)
75
+ throw new ArtifactReaderFailure("limit", "Keyed archive exceeds 64 MiB");
76
+ const stream = await reader.open(entry, input.signal);
77
+ const chunks = [];
78
+ let size = 0;
79
+ for await (const chunk of stream) {
80
+ if (input.signal?.aborted) {
81
+ stream.destroy();
82
+ throw new ArtifactReaderFailure("cancelled", "Archive inspection cancelled");
83
+ }
84
+ const bytes = z.instanceof(Buffer).parse(chunk);
85
+ size += bytes.length;
86
+ if (size > MAX_BYTES) {
87
+ stream.destroy();
88
+ throw new ArtifactReaderFailure("limit", "Keyed archive exceeds 64 MiB");
89
+ }
90
+ chunks.push(bytes);
91
+ }
92
+ const bytes = Buffer.concat(chunks, size);
93
+ try {
94
+ return keyedArchiveResultSchema.parse({
95
+ target_sha256: input.targetSha256,
96
+ archive_path: entry.path,
97
+ archive_sha256: createHash("sha256").update(bytes).digest("hex"),
98
+ ...decodeKeyedArchiveBytes(bytes, selected),
99
+ });
100
+ }
101
+ catch (cause) {
102
+ throw new ArtifactReaderFailure(cause instanceof RangeError ? "limit" : "format", "Cannot decode selected Foundation keyed archive", { cause });
103
+ }
104
+ }
105
+ throw new ArtifactReaderFailure("path", `Archive not found in bundle: ${selected.path}`);
106
+ }
107
+ finally {
108
+ await reader.close();
109
+ }
110
+ };