rea-agents 4.0.0 → 4.1.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.
- package/README.md +93 -30
- package/bridge/ghidra/ReaGhidraBridge.java +358 -15
- package/bridge/ghidra/ReaGhidraExtensions.java +113 -0
- package/bridge/ghidra/ReaGhidraPrepareCom.java +32 -0
- package/dist/android/AndroidTargetSnapshot.js +34 -0
- package/dist/android/JadxAnalysis.js +191 -0
- package/dist/android/JadxConfiguration.js +41 -0
- package/dist/android/JadxMcpTransport.js +145 -0
- package/dist/android/JadxProtocol.js +101 -0
- package/dist/android/JadxProvider.js +170 -0
- package/dist/android/JadxRelease.js +19 -0
- package/dist/android/JadxSession.js +97 -0
- package/dist/application/AnalysisContextQueries.js +2 -1
- package/dist/application/AnalysisProviderEvaluation.js +5 -3
- package/dist/application/AnalysisProviderRegistry.js +2 -1
- package/dist/application/AnalysisSnapshotCache.js +4 -1
- package/dist/application/AnalysisSnapshotFiles.js +1 -1
- package/dist/application/AndroidAnalysisPort.js +1 -0
- package/dist/application/AndroidAnalysisService.js +37 -0
- package/dist/application/ArtifactExtraction.js +7 -4
- package/dist/application/ArtifactGraphConstruction.js +10 -17
- package/dist/application/ArtifactInventory/scanCanonical.js +8 -7
- package/dist/application/BinarySession.js +16 -3
- package/dist/application/BinarySessionExecution.js +4 -1
- package/dist/application/BinarySessionOpen.js +3 -2
- package/dist/application/BinarySessionRecords.js +9 -3
- package/dist/application/BinaryTargetResolver.js +25 -6
- package/dist/application/BrowserObservationService.js +2 -1
- package/dist/application/BrowserScenarioCaptureService.js +2 -1
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/CallPathTracing.js +2 -1
- package/dist/application/CapabilityInventory.js +18 -0
- package/dist/application/ClientConfigPath.js +3 -1
- package/dist/application/ClientConfigurationDocument.js +11 -1
- package/dist/application/ClientRegistrationStatus.js +8 -1
- package/dist/application/CompositeProvider.js +1 -1
- package/dist/application/DirectAnalysis.js +23 -7
- package/dist/application/DirectAnalysisStatus.js +3 -3
- package/dist/application/Doctor.js +48 -8
- package/dist/application/DoctorDiagnostics.js +7 -5
- package/dist/application/DoctorScope.js +1 -1
- package/dist/application/ElectronActiveEvidence.js +2 -2
- package/dist/application/ElectronActiveObservationService.js +2 -1
- package/dist/application/ElectronBoundaryAnalysis.js +1 -1
- package/dist/application/ElectronObservationService.js +2 -1
- package/dist/application/EnhancedLiteralTracing.js +2 -1
- package/dist/application/EnhancedToolTypes.js +2 -1
- package/dist/application/EnhancedTools.js +3 -1
- package/dist/application/EvidenceBundleCommands.js +2 -1
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/EvidenceInputResolver.js +30 -0
- package/dist/application/EvidenceLedger.js +2 -1
- package/dist/application/FirmwareAnalysisPort.js +1 -0
- package/dist/application/FirmwareAnalysisService.js +35 -0
- package/dist/application/FunctionAnalysisEvidence.js +32 -0
- package/dist/application/InventoryProjectionEvidence.js +2 -1
- package/dist/application/JavaScriptApplicationService.js +50 -3
- package/dist/application/JavaScriptApplicationWorkflowService.js +2 -1
- package/dist/application/JavaScriptArtifactAnalysis.js +4 -2
- package/dist/application/JavaScriptArtifactFiles.js +4 -2
- package/dist/application/JavaScriptArtifactPathResolution.js +6 -2
- package/dist/application/JavaScriptJsonModules.js +3 -2
- package/dist/application/JavaScriptModuleRelationships.js +4 -2
- package/dist/application/JavaScriptRuntimeObservationService.js +2 -1
- package/dist/application/JavaScriptRuntimeReconciliationService.js +2 -1
- package/dist/application/JavaScriptSemanticGraphProjection.js +1 -1
- package/dist/application/JavaScriptSemanticTraceService.js +2 -1
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +3 -1
- package/dist/application/LinuxHopper.js +12 -4
- package/dist/application/MacHopper.js +20 -7
- package/dist/application/ManagedApplicationGraphService.js +2 -1
- package/dist/application/ManagedMemberComparisonService.js +3 -1
- package/dist/application/ManagedNativeVerificationService.js +2 -1
- package/dist/application/ManagedReconstructionService.js +2 -1
- package/dist/application/NativeCallRoutes.js +1 -1
- package/dist/application/NativeDispatchMetadataInspection.js +1 -1
- package/dist/application/NativeUiActionTrace.js +2 -1
- package/dist/application/NativeValueTrace.js +1 -1
- package/dist/application/ProcessCaptureError.js +1 -1
- package/dist/application/ProcessCaptureJournal.js +3 -1
- package/dist/application/ProcessCaptureLifecycle.js +6 -3
- package/dist/application/ProcessCli.js +9 -5
- package/dist/application/ProcessEvidence.js +2 -6
- package/dist/application/ProcessHarness.js +3 -2
- package/dist/application/ProcessNormalization.js +12 -5
- package/dist/application/ProcessSampling.js +3 -1
- package/dist/application/ReconstructionCoverageService.js +2 -1
- package/dist/application/ReconstructionObligationLedgerService.js +2 -1
- package/dist/application/ReferenceSourceImportEntries.js +2 -0
- package/dist/application/ReferenceSourceImportPolicy.js +4 -2
- package/dist/application/ReferenceSourceVcsAdapter.js +35 -4
- package/dist/application/SessionProviderRouter.js +4 -1
- package/dist/application/Setup.js +1 -128
- package/dist/application/SetupClientConfiguration.js +17 -6
- package/dist/application/SetupHost.js +111 -0
- package/dist/application/SetupRegistrationEnvironment.js +1 -2
- package/dist/application/SetupSkill.js +9 -3
- package/dist/application/SetupTypes.js +17 -0
- package/dist/application/StoreFileLock.js +7 -2
- package/dist/application/SupportedClients.js +8 -0
- package/dist/application/Uninstall.js +9 -4
- package/dist/application/UpdateRuntime.js +5 -2
- package/dist/application/WindowsCapabilities.js +7 -7
- package/dist/application/runtime.js +3 -1
- package/dist/artifacts/ArtifactProvider.js +3 -1
- package/dist/artifacts/DirectoryArtifactReader.js +2 -0
- package/dist/artifacts/NativeDmgArtifactReader.js +10 -3
- package/dist/artifacts/NibArchive.js +4 -2
- package/dist/artifacts/SafeOutputTree.js +26 -10
- package/dist/artifacts/ZipArtifactReader.js +1 -0
- package/dist/browser/BrowserProcessStartup.js +3 -1
- package/dist/browser/CdpAuthorizedMainFrame.js +1 -1
- package/dist/browser/CdpBrowserProvider.js +4 -1
- package/dist/browser/CdpCaptureDocuments.js +3 -1
- package/dist/browser/CdpCaptureEventHandlers.js +6 -2
- package/dist/browser/CdpCaptureStorageFingerprints.js +1 -1
- package/dist/browser/CdpCaptureValues.js +6 -2
- package/dist/browser/CdpConnection.js +8 -6
- package/dist/browser/CdpElectronInspection.js +3 -3
- package/dist/browser/CdpElectronProvider.js +4 -1
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpEndpoint.js +22 -10
- package/dist/browser/CdpObservationSession.js +2 -1
- package/dist/browser/CdpOptionalCommand.js +1 -1
- package/dist/browser/CdpPageCapture.js +2 -1
- package/dist/browser/CdpSafeMetadata.js +53 -8
- package/dist/browser/CdpScreenshot.js +1 -1
- package/dist/browser/CdpTargetSession.js +8 -5
- package/dist/browser/CdpWebMcpDiscovery.js +1 -1
- package/dist/browser/ElectronFileScope.js +9 -3
- package/dist/browser/JavaScriptRuntimeScope.js +3 -1
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +3 -1
- package/dist/browser/PlaywrightElectronActiveActions.js +1 -1
- package/dist/browser/PlaywrightElectronActiveProvider.js +6 -2
- package/dist/browser/PlaywrightExecutionBoundary.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +10 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +3 -1
- package/dist/browser/PlaywrightScenarioEvents.js +6 -2
- package/dist/browser/PlaywrightScenarioSession.js +5 -2
- package/dist/browser/V8InspectorEndpoint.js +2 -1
- package/dist/browser/V8InspectorProvider.js +6 -1
- package/dist/browser/WebSourceMapFetcher.js +24 -11
- package/dist/cli/androidCommands.js +81 -0
- package/dist/{cliApplicationCommands.js → cli/applicationCommands.js} +18 -16
- package/dist/{cliBrowserAdvancedCommands.js → cli/browserAdvancedCommands.js} +13 -16
- package/dist/{cliBrowserCommands.js → cli/browserCommands.js} +9 -9
- package/dist/cli/commandCancellation.js +24 -0
- package/dist/cli/coreAnalysisCommands.js +110 -17
- package/dist/{cliElectronCommands.js → cli/electronCommands.js} +14 -13
- package/dist/cli/firmwareCommands.js +75 -0
- package/dist/{cliSetup.js → cli/interactiveSetup.js} +1 -1
- package/dist/cli/javascriptApplicationAnalysis.js +1 -1
- package/dist/cli/managedCommands.js +1 -1
- package/dist/cli/managedProjectGraphCommand.js +1 -1
- package/dist/cli/options.js +7 -1
- package/dist/{cliProcessCommands.js → cli/processCommands.js} +3 -3
- package/dist/cli/referenceSourceImportStatus.js +10 -0
- package/dist/cli/setupCommands.js +4 -2
- package/dist/cli/utilityCommands.js +3 -2
- package/dist/cli.js +10 -15
- package/dist/cliBrowserContext.js +1 -1
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +11 -2
- package/dist/cliEvidenceCommands.js +2 -1
- package/dist/cliJavaScriptRuntimeCommands.js +2 -1
- package/dist/cliJsonInput.js +26 -11
- package/dist/cliLogging.js +2 -1
- package/dist/cliOutput.js +15 -16
- package/dist/config/environment.js +11 -1
- package/dist/config/parseConfig.js +7 -1
- package/dist/config/parsers.js +1 -1
- package/dist/contracts/androidToolContracts.js +77 -0
- package/dist/contracts/applicationToolContracts.js +32 -5
- package/dist/contracts/applicationWorkflowInputContracts.js +13 -13
- package/dist/contracts/artifactComparisonExample.js +7 -14
- package/dist/contracts/enhancedToolContracts.js +31 -0
- package/dist/contracts/errorSchemas.js +4 -2
- package/dist/contracts/evidenceInputContracts.js +13 -0
- package/dist/contracts/firmwareToolContracts.js +38 -0
- package/dist/contracts/officialToolContracts.js +66 -0
- package/dist/contracts/promptContracts.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +4 -0
- package/dist/contracts/sessionToolContracts.js +43 -0
- package/dist/contracts/sessionToolSchemas.js +1 -1
- package/dist/contracts/toolContractExamples.js +5 -0
- package/dist/contracts/toolContractTypes.js +2 -0
- package/dist/contracts/toolContracts.js +7 -130
- package/dist/contracts/toolEffects.js +43 -0
- package/dist/contracts/toolOutputSchemaGroups.js +4 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +1 -0
- package/dist/doctorRuntime.js +5 -1
- package/dist/domain/analysisErrorBase.js +33 -0
- package/dist/domain/analysisErrorCore.js +60 -0
- package/dist/domain/analysisErrorPresentation.js +22 -2
- package/dist/domain/analysisErrorProjection.js +24 -3
- package/dist/domain/analysisSnapshot.js +1 -0
- package/dist/domain/androidAnalysis.js +141 -0
- package/dist/domain/appleAssetCatalog.js +1 -1
- package/dist/domain/artifactGraph.js +1 -0
- package/dist/domain/artifactInspection.js +19 -17
- package/dist/domain/artifactInventoryEvidence.js +20 -25
- package/dist/domain/artifactOperationError.js +16 -0
- package/dist/domain/browserObservation.js +12 -4
- package/dist/domain/browserObservationError.js +23 -0
- package/dist/domain/browserScenario.js +1 -1
- package/dist/domain/browserScenarioCapture.js +1 -1
- package/dist/domain/browserScenarioDiff.js +1 -1
- package/dist/domain/browserScenarioNormalization.js +6 -11
- package/dist/domain/browserScenarioValues.js +3 -1
- package/dist/domain/callPath.js +47 -7
- package/dist/domain/canonicalDigest.js +65 -0
- package/dist/domain/canonicalOrdering.js +11 -0
- package/dist/domain/changedBehavior.js +8 -7
- package/dist/domain/comparisonSemantics.js +2 -4
- package/dist/domain/configurationErrors.js +25 -0
- package/dist/domain/dosCom.js +8 -0
- package/dist/domain/electronActiveObservation.js +3 -1
- package/dist/domain/electronStaticAnalysisBrowser.js +13 -23
- package/dist/domain/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/electronStaticAnalysisValues.js +23 -3
- package/dist/domain/evidence.js +3 -11
- package/dist/domain/evidenceErrors.js +30 -0
- package/dist/domain/firmwareAnalysis.js +121 -0
- package/dist/domain/functionComparison.js +4 -2
- package/dist/domain/functionComparisonDimensions.js +6 -4
- package/dist/domain/functionComparisonNormalization.js +8 -1
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/hopperErrors.js +78 -0
- package/dist/domain/hopperValues.js +2 -1
- package/dist/domain/interfaceBuilderGraph.js +3 -1
- package/dist/domain/javascriptApplicationChangeGraph.js +2 -2
- package/dist/domain/javascriptApplicationGraph.js +13 -22
- package/dist/domain/javascriptApplicationVersionComparison.js +3 -11
- package/dist/domain/javascriptApplicationVersionItems.js +3 -3
- package/dist/domain/javascriptApplicationVersionKeys.js +1 -1
- package/dist/domain/javascriptAstFingerprint.js +1 -1
- package/dist/domain/javascriptExportShapeComparison.js +1 -2
- package/dist/domain/javascriptExportShapeSelection.js +1 -1
- package/dist/domain/javascriptExportShapeVariants.js +7 -3
- package/dist/domain/javascriptFeatureSeed.js +29 -9
- package/dist/domain/javascriptFeatureTrace.js +9 -13
- package/dist/domain/javascriptFeatureTraversal.js +2 -1
- package/dist/domain/javascriptNativeHandoff.js +2 -1
- package/dist/domain/javascriptRuntimeLoadState.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationActive.js +3 -10
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +4 -3
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +8 -14
- package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +5 -2
- package/dist/domain/javascriptRuntimeStaticCandidates.js +8 -4
- package/dist/domain/javascriptSemanticAnalysis.js +40 -3
- package/dist/domain/javascriptSemanticCallResolution.js +2 -1
- package/dist/domain/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascriptSemanticDataEffects.js +2 -1
- package/dist/domain/javascriptSemanticFingerprints.js +1 -1
- package/dist/domain/javascriptSemanticGraph.js +23 -28
- package/dist/domain/javascriptSemanticPrimitives.js +9 -2
- package/dist/domain/javascriptSemanticProjection.js +2 -1
- package/dist/domain/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascriptSemanticProvenance.js +1 -1
- package/dist/domain/javascriptSemanticQuery.js +7 -8
- package/dist/domain/javascriptSemanticQueryAssessment.js +1 -2
- package/dist/domain/javascriptSemanticQueryIdentity.js +1 -2
- package/dist/domain/javascriptSemanticReturns.js +2 -1
- package/dist/domain/javascriptSemanticValues.js +50 -16
- package/dist/domain/javascriptSourceParser.js +4 -2
- package/dist/domain/javascriptStaticAnalysis.js +1 -1
- package/dist/domain/javascriptStaticAnalysisBundler.js +2 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +14 -6
- package/dist/domain/javascriptStaticAnalysisHelpers.js +31 -4
- package/dist/domain/jsonShape.js +6 -2
- package/dist/domain/managedMemberComparison.js +1 -0
- package/dist/domain/managedMemberComparisonItems.js +2 -0
- package/dist/domain/managedNativeVerificationMatch.js +5 -3
- package/dist/domain/nativeDataType.js +2 -0
- package/dist/domain/nativeFunctionAnnotations.js +43 -0
- package/dist/domain/nativeLoadImage.js +95 -0
- package/dist/domain/nativeMetadataRecovery.js +55 -0
- package/dist/domain/processCapture.js +0 -1
- package/dist/domain/processEvidenceProvider.js +11 -0
- package/dist/domain/processTraceComparison.js +1 -1
- package/dist/domain/providerAdapterError.js +17 -0
- package/dist/domain/providerCleanupError.js +1 -1
- package/dist/domain/providerSelectionError.js +44 -0
- package/dist/domain/reconstructionUnknowns.js +1 -1
- package/dist/domain/reconstructionVerification.js +22 -8
- package/dist/domain/referenceSourceClassification.js +5 -6
- package/dist/domain/referenceSourceGraph.js +9 -17
- package/dist/domain/referenceSourceImportParsing.js +38 -23
- package/dist/domain/runtimeIdentification.js +1 -1
- package/dist/domain/runtimeVersion.js +4 -7
- package/dist/domain/safeJson.js +13 -0
- package/dist/domain/sourceToBundleComparison.js +5 -7
- package/dist/domain/sourceToBundleSignals.js +6 -6
- package/dist/domain/staticRuntimeCorrelation.js +9 -7
- package/dist/domain/unknownRegistryError.js +10 -0
- package/dist/domain/webBundleAnalyzerAst.js +22 -5
- package/dist/domain/webBundleAnalyzerInspection.js +20 -14
- package/dist/dotnet/ManagedMemberRows.js +1 -1
- package/dist/dotnet/ManagedMetadataHeaps.js +3 -2
- package/dist/dotnet/ManagedMetadataInventoryRows.js +4 -2
- package/dist/dotnet/ManagedMethodBodyReader.js +8 -1
- package/dist/dotnet/ManagedStaticProvider.js +3 -1
- package/dist/firmware/FirmwareCommand.js +163 -0
- package/dist/firmware/FirmwareFiles.js +190 -0
- package/dist/firmware/FirmwareProvider.js +258 -0
- package/dist/firmware/FirmwarePublication.js +84 -0
- package/dist/firmware/FirmwareRelease.js +32 -0
- package/dist/firmware/FirmwareReports.js +223 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +5 -5
- package/dist/ghidra/GhidraAnalysisProfile.js +37 -8
- package/dist/ghidra/GhidraClient.js +52 -6
- package/dist/ghidra/GhidraDiagnostics.js +3 -0
- package/dist/ghidra/GhidraDoctor.js +38 -14
- package/dist/ghidra/GhidraFunctionValues.js +10 -4
- package/dist/ghidra/GhidraInstallation.js +10 -4
- package/dist/ghidra/GhidraInventoryValues.js +39 -2
- package/dist/ghidra/GhidraLauncher.js +91 -26
- package/dist/ghidra/GhidraLoadImageValues.js +199 -0
- package/dist/ghidra/GhidraProvider.js +129 -13
- package/dist/ghidra/GhidraProviderCapabilities.js +52 -15
- package/dist/ghidra/GhidraRequestQueue.js +2 -2
- package/dist/ghidra/GhidraSessionError.js +31 -4
- package/dist/ghidra/GhidraSessionValues.js +10 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +16 -2
- package/dist/ghidra/GhidraTransport.js +12 -0
- package/dist/ghidra/extensions/GhidraExtensionFailures.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +170 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +21 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotReport.js +84 -0
- package/dist/hopper/BridgeLauncher.js +4 -2
- package/dist/hopper/HopperAnalysisProfile.js +7 -2
- package/dist/hopper/HopperCleanup.js +55 -9
- package/dist/hopper/HopperClient.js +14 -4
- package/dist/hopper/HopperProcessDiagnostic.js +1 -1
- package/dist/hopper/HopperProvider.js +8 -4
- package/dist/hopper/HopperRequestQueue.js +7 -3
- package/dist/hopper/HopperSessionValues.js +1 -1
- package/dist/hopper/HopperSocketConnection.js +1 -1
- package/dist/hopper/HopperTargetLease.js +23 -15
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +7 -8
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -2
- package/dist/hopper/protocol.js +8 -8
- package/dist/ida/IdaConfiguration.js +56 -0
- package/dist/ida/IdaDoctor.js +53 -0
- package/dist/ida/IdaInput.js +62 -0
- package/dist/ida/IdaMcpConnection.js +111 -0
- package/dist/ida/IdaOperationRunner.js +299 -0
- package/dist/ida/IdaProtocolValues.js +178 -0
- package/dist/ida/IdaProvider.js +126 -0
- package/dist/ida/IdaProviderCapabilities.js +60 -0
- package/dist/ida/IdaSessionClient.js +306 -0
- package/dist/ida/IdaWorkspace.js +54 -0
- package/dist/main/shutdown.js +21 -1
- package/dist/main/startup.js +1 -1
- package/dist/main/transport.js +8 -4
- package/dist/main.js +5 -2
- package/dist/native/AppleDispatchMetadata.js +31 -10
- package/dist/native/NativeMacOSProvider.js +87 -15
- package/dist/native/NativeMachoInspection.js +42 -12
- package/dist/native/NativeUiHelperRuntime.js +7 -1
- package/dist/native/NativeUiObservation.js +6 -2
- package/dist/native/parsers/demangle.js +1 -1
- package/dist/native/parsers/dyldInfo.js +3 -3
- package/dist/native/parsers/otool.js +4 -1
- package/dist/native/parsers/plist.js +11 -3
- package/dist/process/PrivateRuntimeRoot.js +13 -3
- package/dist/process/ProcessOwnership.js +5 -73
- package/dist/process/ProcessOwnershipObservation.js +62 -2
- package/dist/process/ProcessOwnershipProcessTree.js +13 -0
- package/dist/process/ProviderProcess.js +24 -7
- package/dist/process/ProviderRunLineage.js +1 -1
- package/dist/process/WindowsAuthority.js +20 -1
- package/dist/reference/ReferenceSourceReaderEntries.js +5 -1
- package/dist/reference/ReferenceSourceReaderFile.js +1 -0
- package/dist/server/createServer.js +25 -2
- package/dist/server/mcpProgress.js +2 -1
- package/dist/server/promptCompletion.js +3 -3
- package/dist/server/registerAndroidTools.js +30 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +5 -1
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +7 -2
- package/dist/server/registerApplicationTools/compareVersions.js +5 -1
- package/dist/server/registerApplicationTools/traceFeature.js +7 -2
- package/dist/server/registerApplicationTools/traceSemantics.js +7 -2
- package/dist/server/registerEnhancedTools.js +28 -1
- package/dist/server/registerFirmwareTools.js +22 -0
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools/helpers.js +2 -1
- package/dist/server/registerManagedTools.js +1 -1
- package/dist/server/registerManagedWorkflowTools/evidence.js +1 -1
- package/dist/server/registerOfficialTools.js +4 -1
- package/dist/server/registerProcessComparisonTool.js +5 -2
- package/dist/server/registerSessionTools.js +3 -1
- package/dist/server/runDerivedOperation.js +1 -1
- package/dist/server/sessionAvailabilityPolicy.js +3 -0
- package/dist/server/sessionEvidence.js +1 -1
- package/dist/server/toolResult.js +2 -1
- package/dist/windows/WindowsNativeLoader.js +108 -0
- package/dist/windows/WindowsOwnedProcess.js +168 -0
- package/dist/windows/WindowsPrivateRuntime.js +137 -0
- package/install.sh +4 -6
- package/native/windows/README.md +102 -0
- package/native/windows/build/manifest.json +9 -0
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +38 -24
- package/scripts/rea.mjs +1 -1
- package/scripts/verify-windows-native-artifact.mjs +39 -0
- package/skills/reverse-engineer-anything/SKILL.md +92 -24
- package/skills/reverse-engineer-anything/references/android-applications.md +31 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +19 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +52 -4
- package/dist/browser/CdpCanonicalJsonDigest.js +0 -9
- package/dist/domain/errors.js +0 -324
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
|
-
import { readFile } from "node:fs/promises";
|
|
3
2
|
import { promisify } from "node:util";
|
|
4
|
-
import {
|
|
3
|
+
import { createSystemProcessOwnershipHost, errorMessage, } from "./ProcessOwnershipObservation.js";
|
|
5
4
|
import { launcherIdentityFailure } from "./ProcessOwnershipIdentity.js";
|
|
6
5
|
import { descendantsOf, liveProcesses } from "./ProcessOwnershipProcessTree.js";
|
|
7
|
-
import { execFileOutput } from "./ExecFileOutput.js";
|
|
8
6
|
const execFileAsync = promisify(execFile);
|
|
9
7
|
/**
|
|
10
8
|
* Terminate one Windows process tree through the platform utility.
|
|
@@ -20,71 +18,16 @@ export const cleanupWindowsProcessTree = async (rootPid, host = systemWindowsPro
|
|
|
20
18
|
const result = await host.terminateTree(rootPid);
|
|
21
19
|
return { cleaned: true, signaled: result === "terminated" };
|
|
22
20
|
}
|
|
23
|
-
catch {
|
|
21
|
+
catch (cause) {
|
|
22
|
+
// The reason string is a pinned validation contract; keep it stable and
|
|
23
|
+
// do not interpolate the cause into caller-visible diagnostics here.
|
|
24
|
+
void cause;
|
|
24
25
|
return {
|
|
25
26
|
cleaned: false,
|
|
26
27
|
reason: "Windows P0 process-tree termination failed; Job Object ownership is unavailable",
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
};
|
|
30
|
-
/** Select the PTY root group and groups led by an observed captured process. */
|
|
31
|
-
export const selectCapturedProcessGroupIds = (rootPid, samples) => {
|
|
32
|
-
const processGroupIds = new Set([rootPid]);
|
|
33
|
-
for (const sample of samples) {
|
|
34
|
-
// A sampled member may transiently inherit an unrelated group. POSIX group
|
|
35
|
-
// leaders have pid === pgid, so only that observation establishes that the
|
|
36
|
-
// group leader itself belonged to the captured tree. Token checks below
|
|
37
|
-
// remain the final authority immediately before observation or signaling.
|
|
38
|
-
if (sample.pid === sample.process_group_id)
|
|
39
|
-
processGroupIds.add(sample.pid);
|
|
40
|
-
}
|
|
41
|
-
return [...processGroupIds];
|
|
42
|
-
};
|
|
43
|
-
/** Parse the NUL-delimited Linux process environment without nameless keys. */
|
|
44
|
-
export const parseProcessEnvironment = (value) => Object.fromEntries(value
|
|
45
|
-
.split("\0")
|
|
46
|
-
.filter((entry) => entry.indexOf("=") > 0)
|
|
47
|
-
.map((entry) => {
|
|
48
|
-
const separator = entry.indexOf("=");
|
|
49
|
-
return [entry.slice(0, separator), entry.slice(separator + 1)];
|
|
50
|
-
}));
|
|
51
|
-
/** Create the operating-system process inspector for an explicit host context. */
|
|
52
|
-
export const createSystemProcessOwnershipHost = (platform = process.platform, hostEnvironment = process.env) => ({
|
|
53
|
-
platform,
|
|
54
|
-
async listProcesses() {
|
|
55
|
-
if (platform === "win32")
|
|
56
|
-
return [];
|
|
57
|
-
const { stdout } = await execFileOutput("ps", ["-axo", "pid=,ppid=,pgid=,stat=,command="], { env: hostEnvironment });
|
|
58
|
-
return stdout
|
|
59
|
-
.split("\n")
|
|
60
|
-
.map((line) => /\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)/u.exec(line))
|
|
61
|
-
.filter((match) => match !== null)
|
|
62
|
-
.map((match) => ({
|
|
63
|
-
pid: Number(match[1]),
|
|
64
|
-
parentPid: Number(match[2]),
|
|
65
|
-
processGroupId: Number(match[3]),
|
|
66
|
-
state: match[4] ?? "",
|
|
67
|
-
command: match[5] ?? "",
|
|
68
|
-
}));
|
|
69
|
-
},
|
|
70
|
-
async environment(pid) {
|
|
71
|
-
if (platform === "linux")
|
|
72
|
-
return parseProcessEnvironment(await readFile(`/proc/${pid}/environ`, "utf8"));
|
|
73
|
-
const { stdout } = await execFileOutput("ps", ["eww", "-p", String(pid)], {
|
|
74
|
-
env: hostEnvironment,
|
|
75
|
-
});
|
|
76
|
-
const observedEnvironment = {};
|
|
77
|
-
for (const match of stdout.matchAll(/(?:^|\s)([A-Za-z_][A-Za-z0-9_]*)=([^\s]*)/gu)) {
|
|
78
|
-
const name = match[1];
|
|
79
|
-
if (name !== undefined)
|
|
80
|
-
observedEnvironment[name] = match[2] ?? "";
|
|
81
|
-
}
|
|
82
|
-
return observedEnvironment;
|
|
83
|
-
},
|
|
84
|
-
signalGroup(processGroupId, signal) {
|
|
85
|
-
process.kill(-processGroupId, signal);
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
31
|
const systemHost = createSystemProcessOwnershipHost();
|
|
89
32
|
const systemWindowsProcessTreeHost = {
|
|
90
33
|
async terminateTree(rootPid) {
|
|
@@ -309,14 +252,3 @@ const scanTokenOwnedProcesses = async (processes, runId, host) => {
|
|
|
309
252
|
}
|
|
310
253
|
return { owned, failures };
|
|
311
254
|
};
|
|
312
|
-
const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
313
|
-
/** Observe one group without signaling it, failing closed on identity doubt. */
|
|
314
|
-
export const observeOwnedProcessGroup = async (ownership, host = systemHost) => observeOwnedProcessGroupWithHost(ownership, host);
|
|
315
|
-
/**
|
|
316
|
-
* Record the live launcher and descendant lineage after run-token validation.
|
|
317
|
-
*
|
|
318
|
-
* The observation is intentionally point-in-time. A verified empty descendant
|
|
319
|
-
* list means no descendants were live during this observation, not that the
|
|
320
|
-
* run never created a short-lived child.
|
|
321
|
-
*/
|
|
322
|
-
export const observeOwnedProcessLineage = async (ownership, host = systemHost) => observeOwnedProcessLineageWithHost(ownership, host);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
1
2
|
import { launcherIdentityFailure } from "./ProcessOwnershipIdentity.js";
|
|
2
3
|
import { descendantsOf, liveProcesses } from "./ProcessOwnershipProcessTree.js";
|
|
4
|
+
import { execFileOutput } from "./ExecFileOutput.js";
|
|
3
5
|
/** Observe one group without signaling it, failing closed on identity doubt. */
|
|
4
6
|
export const observeOwnedProcessGroupWithHost = async (ownership, host) => {
|
|
5
7
|
let members;
|
|
@@ -95,12 +97,70 @@ const unavailableLineage = (ownership, reason) => ({
|
|
|
95
97
|
processGroupId: ownership.processGroupId,
|
|
96
98
|
reason,
|
|
97
99
|
});
|
|
100
|
+
/** Parse the NUL-delimited Linux process environment without nameless keys. */
|
|
101
|
+
export const parseProcessEnvironment = (value) => Object.fromEntries(value
|
|
102
|
+
.split("\0")
|
|
103
|
+
.filter((entry) => entry.indexOf("=") > 0)
|
|
104
|
+
.map((entry) => {
|
|
105
|
+
const separator = entry.indexOf("=");
|
|
106
|
+
return [entry.slice(0, separator), entry.slice(separator + 1)];
|
|
107
|
+
}));
|
|
108
|
+
/** Create the operating-system process inspector for an explicit host context. */
|
|
109
|
+
export const createSystemProcessOwnershipHost = (platform = process.platform, hostEnvironment = process.env) => ({
|
|
110
|
+
platform,
|
|
111
|
+
async listProcesses() {
|
|
112
|
+
if (platform === "win32")
|
|
113
|
+
return [];
|
|
114
|
+
const { stdout } = await execFileOutput("ps", ["-axo", "pid=,ppid=,pgid=,stat=,command="], { env: hostEnvironment });
|
|
115
|
+
return stdout
|
|
116
|
+
.split("\n")
|
|
117
|
+
.map((line) => /\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)/u.exec(line))
|
|
118
|
+
.filter((match) => match !== null)
|
|
119
|
+
.map((match) => ({
|
|
120
|
+
pid: Number(match[1]),
|
|
121
|
+
parentPid: Number(match[2]),
|
|
122
|
+
processGroupId: Number(match[3]),
|
|
123
|
+
state: match[4] ?? "",
|
|
124
|
+
command: match[5] ?? "",
|
|
125
|
+
}));
|
|
126
|
+
},
|
|
127
|
+
async environment(pid) {
|
|
128
|
+
if (platform === "linux")
|
|
129
|
+
return parseProcessEnvironment(await readFile(`/proc/${pid}/environ`, "utf8"));
|
|
130
|
+
const { stdout } = await execFileOutput("ps", ["eww", "-p", String(pid)], {
|
|
131
|
+
env: hostEnvironment,
|
|
132
|
+
});
|
|
133
|
+
const observedEnvironment = {};
|
|
134
|
+
for (const match of stdout.matchAll(/(?:^|\s)([A-Za-z_][A-Za-z0-9_]*)=([^\s]*)/gu)) {
|
|
135
|
+
const name = match[1];
|
|
136
|
+
if (name !== undefined)
|
|
137
|
+
observedEnvironment[name] = match[2] ?? "";
|
|
138
|
+
}
|
|
139
|
+
return observedEnvironment;
|
|
140
|
+
},
|
|
141
|
+
signalGroup(processGroupId, signal) {
|
|
142
|
+
process.kill(-processGroupId, signal);
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
const systemHost = createSystemProcessOwnershipHost();
|
|
146
|
+
/** Observe one group without signaling it, failing closed on identity doubt. */
|
|
147
|
+
export const observeOwnedProcessGroup = async (ownership, host = systemHost) => observeOwnedProcessGroupWithHost(ownership, host);
|
|
148
|
+
/**
|
|
149
|
+
* Record the live launcher and descendant lineage after run-token validation.
|
|
150
|
+
*
|
|
151
|
+
* The observation is intentionally point-in-time. A verified empty descendant
|
|
152
|
+
* list means no descendants were live during this observation, not that the
|
|
153
|
+
* run never created a short-lived child.
|
|
154
|
+
*/
|
|
155
|
+
export const observeOwnedProcessLineage = async (ownership, host = systemHost) => observeOwnedProcessLineageWithHost(ownership, host);
|
|
98
156
|
const processIsGone = async (host, pid) => {
|
|
99
157
|
try {
|
|
100
158
|
return !liveProcesses(await host.listProcesses()).some((process) => process.pid === pid);
|
|
101
159
|
}
|
|
102
|
-
catch {
|
|
160
|
+
catch (cause) {
|
|
161
|
+
// best-effort cleanup: optional liveness probing; failure means not gone.
|
|
162
|
+
void cause;
|
|
103
163
|
return false;
|
|
104
164
|
}
|
|
105
165
|
};
|
|
106
|
-
const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
166
|
+
export const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
@@ -20,3 +20,16 @@ export const descendantsOf = (launcherPid, processes) => {
|
|
|
20
20
|
}
|
|
21
21
|
return descendants;
|
|
22
22
|
};
|
|
23
|
+
/** Select the PTY root group and groups led by an observed captured process. */
|
|
24
|
+
export const selectCapturedProcessGroupIds = (rootPid, samples) => {
|
|
25
|
+
const processGroupIds = new Set([rootPid]);
|
|
26
|
+
for (const sample of samples) {
|
|
27
|
+
// A sampled member may transiently inherit an unrelated group. POSIX group
|
|
28
|
+
// leaders have pid === pgid, so only that observation establishes that the
|
|
29
|
+
// group leader itself belonged to the captured tree. Token checks below
|
|
30
|
+
// remain the final authority immediately before observation or signaling.
|
|
31
|
+
if (sample.pid === sample.process_group_id)
|
|
32
|
+
processGroupIds.add(sample.pid);
|
|
33
|
+
}
|
|
34
|
+
return [...processGroupIds];
|
|
35
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { WindowsOwnedProcess } from "../windows/WindowsOwnedProcess.js";
|
|
2
3
|
const DEFAULT_TERMINATION_GRACE_MS = 250;
|
|
3
4
|
const DEFAULT_KILL_GRACE_MS = 1_000;
|
|
4
5
|
/**
|
|
5
|
-
* Spawn a provider in
|
|
6
|
+
* Spawn a provider in an owned Windows job or dedicated POSIX process group.
|
|
6
7
|
*
|
|
7
8
|
* The caller remains responsible for persisting any ownership manifest and for
|
|
8
9
|
* selecting provider-specific command arguments or environment values.
|
|
@@ -10,17 +11,33 @@ const DEFAULT_KILL_GRACE_MS = 1_000;
|
|
|
10
11
|
export const spawnOwnedProviderProcess = async (options) => {
|
|
11
12
|
const platform = options.platform ?? process.platform;
|
|
12
13
|
const hostEnvironment = options.hostEnvironment ?? process.env;
|
|
14
|
+
const environment = {
|
|
15
|
+
...hostEnvironment,
|
|
16
|
+
...options.env,
|
|
17
|
+
REA_PROCESS_RUN_ID: options.runId,
|
|
18
|
+
};
|
|
19
|
+
if (platform === "win32" && process.platform === "win32") {
|
|
20
|
+
if (options.stdin === "pipe")
|
|
21
|
+
throw new Error("Owned Windows provider processes do not support protocol stdin");
|
|
22
|
+
const child = new WindowsOwnedProcess(options.command, options.arguments, options.cwd, environment, options.windowsVerbatimArguments ?? false);
|
|
23
|
+
return {
|
|
24
|
+
process: child,
|
|
25
|
+
ownership: {
|
|
26
|
+
runId: options.runId,
|
|
27
|
+
leaderPid: child.pid,
|
|
28
|
+
processGroupId: child.pid,
|
|
29
|
+
expectedParentPid: process.pid,
|
|
30
|
+
},
|
|
31
|
+
cleanup: () => child.cleanup(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
13
34
|
const child = spawn(options.command, [...options.arguments], {
|
|
14
35
|
shell: false,
|
|
15
36
|
windowsHide: true,
|
|
16
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
37
|
+
stdio: [options.stdin ?? "ignore", "pipe", "pipe"],
|
|
17
38
|
detached: platform !== "win32",
|
|
18
39
|
windowsVerbatimArguments: options.windowsVerbatimArguments ?? false,
|
|
19
|
-
env:
|
|
20
|
-
...hostEnvironment,
|
|
21
|
-
...options.env,
|
|
22
|
-
REA_PROCESS_RUN_ID: options.runId,
|
|
23
|
-
},
|
|
40
|
+
env: environment,
|
|
24
41
|
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
|
|
25
42
|
});
|
|
26
43
|
await waitForSpawn(child);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { observeOwnedProcessLineage } from "./
|
|
1
|
+
import { observeOwnedProcessLineage } from "./ProcessOwnershipObservation.js";
|
|
2
2
|
/** Retain the latest truthful process-lineage observation for one client. */
|
|
3
3
|
export class ProviderRunLineage {
|
|
4
4
|
#observation = null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { systemWindowsNativeAuthority } from "../windows/WindowsNativeLoader.js";
|
|
1
2
|
/** Stable explanation used whenever the native Windows authority is absent. */
|
|
2
|
-
export const WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON = "
|
|
3
|
+
export const WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON = "Windows native controls are unavailable in this runtime; use the Windows x64 REA package with its matching bundled native artifact.";
|
|
3
4
|
/**
|
|
4
5
|
* Describe native Windows controls without inferring them from taskkill,
|
|
5
6
|
* chmod, symlink creation, or a numeric POSIX open flag.
|
|
@@ -17,6 +18,21 @@ export const windowsNativeCapabilities = (platform) => {
|
|
|
17
18
|
reparse_safe_path_admission: notApplicable,
|
|
18
19
|
};
|
|
19
20
|
}
|
|
21
|
+
if (process.platform === "win32") {
|
|
22
|
+
const loaded = systemWindowsNativeAuthority();
|
|
23
|
+
const capability = loaded.available
|
|
24
|
+
? { available: true, reason: null, proof: "native-authority" }
|
|
25
|
+
: {
|
|
26
|
+
available: false,
|
|
27
|
+
reason: loaded.reason,
|
|
28
|
+
proof: "not-proven",
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
job_object_process_ownership: capability,
|
|
32
|
+
private_runtime_dacl: capability,
|
|
33
|
+
reparse_safe_path_admission: capability,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
20
36
|
const notProven = {
|
|
21
37
|
available: false,
|
|
22
38
|
reason: WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON,
|
|
@@ -30,3 +46,6 @@ export const windowsNativeCapabilities = (platform) => {
|
|
|
30
46
|
};
|
|
31
47
|
/** Whether every native control needed for Windows isolation is proven. */
|
|
32
48
|
export const hasWindowsNativeAuthority = (platform) => Object.values(windowsNativeCapabilities(platform)).every(({ available }) => available);
|
|
49
|
+
/** Preserve the actual loader or operating-system constraint in provider errors. */
|
|
50
|
+
export const windowsNativeAuthorityUnavailableReason = (platform) => windowsNativeCapabilities(platform).job_object_process_ownership.reason ??
|
|
51
|
+
WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON;
|
|
@@ -189,7 +189,11 @@ const applyExclusion = (shouldExclude, path) => {
|
|
|
189
189
|
try {
|
|
190
190
|
return { ok: true, value: shouldExclude?.(path) === true };
|
|
191
191
|
}
|
|
192
|
-
catch {
|
|
192
|
+
catch (cause) {
|
|
193
|
+
// Exclusion predicates are caller-supplied; a throwing predicate fails
|
|
194
|
+
// closed and the caller-visible `{ ok: false }` preserves the rejection
|
|
195
|
+
// without propagating an arbitrary predicate cause.
|
|
196
|
+
void cause;
|
|
193
197
|
return { ok: false };
|
|
194
198
|
}
|
|
195
199
|
};
|
|
@@ -102,6 +102,7 @@ export const readStableFile = async (request) => {
|
|
|
102
102
|
return entryFailure(path, "file", "io", message, safeSize(expected.size));
|
|
103
103
|
}
|
|
104
104
|
finally {
|
|
105
|
+
// best-effort cleanup: file-handle close must not mask the read result.
|
|
105
106
|
await handle?.close().catch(() => undefined);
|
|
106
107
|
}
|
|
107
108
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
|
+
import { isAbsolute } from "node:path";
|
|
2
3
|
import { PRODUCT_IDENTITY } from "../identity.js";
|
|
3
4
|
import { silentLogger } from "../logger.js";
|
|
4
5
|
import { registerApplicationTools } from "./registerApplicationTools.js";
|
|
@@ -9,6 +10,12 @@ import { registerElectronTools } from "./registerElectronTools.js";
|
|
|
9
10
|
import { registerEnhancedTools } from "./registerEnhancedTools.js";
|
|
10
11
|
import { registerJavaScriptRuntimeObservationTools } from "./registerJavaScriptRuntimeObservationTools.js";
|
|
11
12
|
import { registerManagedTools } from "./registerManagedTools.js";
|
|
13
|
+
import { registerFirmwareTools } from "./registerFirmwareTools.js";
|
|
14
|
+
import { FirmwareAnalysisService } from "../application/FirmwareAnalysisService.js";
|
|
15
|
+
import { FirmwareProvider } from "../firmware/FirmwareProvider.js";
|
|
16
|
+
import { registerAndroidTools } from "./registerAndroidTools.js";
|
|
17
|
+
import { AndroidAnalysisService } from "../application/AndroidAnalysisService.js";
|
|
18
|
+
import { JadxProvider } from "../android/JadxProvider.js";
|
|
12
19
|
import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
|
|
13
20
|
import { registerNativeTools } from "./registerNativeTools.js";
|
|
14
21
|
import { registerOfficialTools } from "./registerOfficialTools.js";
|
|
@@ -22,6 +29,15 @@ const installSessionToolAvailability = (server, session, options) => {
|
|
|
22
29
|
return undefined;
|
|
23
30
|
const policy = sessionAvailabilityPolicy(options.availabilityPolicy, {
|
|
24
31
|
optionalFeatures: {
|
|
32
|
+
firmwareInspectionEnabled: options.firmwareAnalysis !== undefined ||
|
|
33
|
+
(process.platform === "linux" &&
|
|
34
|
+
isAbsolute(process.env.REA_BINWALK_COMMAND ?? "")),
|
|
35
|
+
firmwareExtractionEnabled: options.firmwareAnalysis !== undefined ||
|
|
36
|
+
(process.platform === "linux" &&
|
|
37
|
+
isAbsolute(process.env.REA_UNBLOB_COMMAND ?? "")),
|
|
38
|
+
androidAnalysisEnabled: options.androidAnalysis !== undefined ||
|
|
39
|
+
((process.platform === "linux" || process.platform === "darwin") &&
|
|
40
|
+
isAbsolute(process.env.REA_JADX_MCP_JAR ?? "")),
|
|
25
41
|
browserObservationEnabled: options.browserObservation !== undefined,
|
|
26
42
|
browserScenarioEnabled: options.browserScenarioCapture !== undefined,
|
|
27
43
|
electronObservationEnabled: options.electronObservation !== undefined,
|
|
@@ -53,18 +69,21 @@ export const createServer = (analysis, session, options = {}) => {
|
|
|
53
69
|
const server = createMcpServer(session);
|
|
54
70
|
const availability = installSessionToolAvailability(server, session, options);
|
|
55
71
|
const toolLogger = logger.child({ layer: "server" });
|
|
56
|
-
const { activeTarget, recordEvidence, recordEvidenceWithUnknown } = createSessionRecorders(server, session);
|
|
72
|
+
const { evidenceById, activeTarget, recordEvidence, recordEvidenceWithUnknown, } = createSessionRecorders(server, session);
|
|
57
73
|
const toolContext = {
|
|
58
74
|
server,
|
|
59
75
|
analysis,
|
|
60
76
|
session,
|
|
61
77
|
options,
|
|
62
78
|
logger: toolLogger,
|
|
79
|
+
evidenceById,
|
|
63
80
|
activeTarget,
|
|
64
81
|
recordEvidence,
|
|
65
82
|
recordEvidenceWithUnknown,
|
|
66
83
|
};
|
|
67
84
|
registerBinaryAnalysisTools(toolContext);
|
|
85
|
+
registerAndroidTools(server, new AndroidAnalysisService(options.androidAnalysis ?? new JadxProvider()), toolLogger, recordEvidence);
|
|
86
|
+
registerFirmwareTools(server, new FirmwareAnalysisService(options.firmwareAnalysis ?? new FirmwareProvider()), toolLogger, recordEvidence);
|
|
68
87
|
registerObservationTools(toolContext);
|
|
69
88
|
registerGuidedPrompts(server, analysis, session);
|
|
70
89
|
if (session !== undefined) {
|
|
@@ -79,6 +98,9 @@ export const createServer = (analysis, session, options = {}) => {
|
|
|
79
98
|
return server;
|
|
80
99
|
};
|
|
81
100
|
const createSessionRecorders = (server, session) => ({
|
|
101
|
+
evidenceById: session === undefined
|
|
102
|
+
? undefined
|
|
103
|
+
: (evidenceId) => session.evidenceById(evidenceId),
|
|
82
104
|
activeTarget: session === undefined ? undefined : () => session.activeTarget(),
|
|
83
105
|
recordEvidence: session === undefined
|
|
84
106
|
? undefined
|
|
@@ -125,7 +147,7 @@ const registerBinaryAnalysisTools = ({ server, analysis, session, logger, active
|
|
|
125
147
|
session,
|
|
126
148
|
});
|
|
127
149
|
};
|
|
128
|
-
const registerObservationTools = ({ server, options, logger, recordEvidence, recordEvidenceWithUnknown, }) => {
|
|
150
|
+
const registerObservationTools = ({ evidenceById, server, options, logger, recordEvidence, recordEvidenceWithUnknown, }) => {
|
|
129
151
|
const common = { logger, recordEvidence };
|
|
130
152
|
registerBrowserTools(server, {
|
|
131
153
|
...common,
|
|
@@ -145,6 +167,7 @@ const registerObservationTools = ({ server, options, logger, recordEvidence, rec
|
|
|
145
167
|
runtime: options.javascriptRuntimeObservation,
|
|
146
168
|
});
|
|
147
169
|
registerApplicationTools(server, {
|
|
170
|
+
evidenceById,
|
|
148
171
|
logger,
|
|
149
172
|
recordEvidence,
|
|
150
173
|
recordEvidenceWithUnknown,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { uniqueSorted } from "../domain/canonicalOrdering.js";
|
|
2
3
|
import { artifactInventoryResultSchema } from "../domain/artifactGraph.js";
|
|
3
4
|
import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
|
|
4
5
|
import { processCaptureSchema } from "../domain/processCapture.js";
|
|
@@ -14,7 +15,8 @@ export const createPromptCompletionSource = (analysis, session) => ({
|
|
|
14
15
|
async complete(kind, value, context) {
|
|
15
16
|
const candidates = await completionCandidates(kind, analysis, session, context);
|
|
16
17
|
const prefix = normalize(value);
|
|
17
|
-
|
|
18
|
+
const nonEmpty = candidates.filter((candidate) => candidate.length > 0);
|
|
19
|
+
return uniqueSorted(nonEmpty).filter((candidate) => normalize(candidate).startsWith(prefix));
|
|
18
20
|
},
|
|
19
21
|
});
|
|
20
22
|
const completionCandidates = async (kind, analysis, session, context) => {
|
|
@@ -121,6 +123,4 @@ const unknownCandidates = (session) => session === undefined
|
|
|
121
123
|
.listUnknowns()
|
|
122
124
|
.filter(({ status }) => status !== "resolved")
|
|
123
125
|
.map(({ unknown_id: id }) => id);
|
|
124
|
-
const uniqueSorted = (values) => [...new Set(values.filter((value) => value.length > 0))].sort(compareText);
|
|
125
|
-
const compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
126
126
|
const normalize = (value) => value.normalize("NFKC").toLowerCase();
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AndroidAnalysisService } from "../application/AndroidAnalysisService.js";
|
|
2
|
+
import { toolContract } from "../contracts/toolContracts.js";
|
|
3
|
+
import { logToolExecution } from "./toolLogging.js";
|
|
4
|
+
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
5
|
+
import { toCallToolResult } from "./toolResult.js";
|
|
6
|
+
/** Bind Android handlers to their exact named contracts through shared workflows. */
|
|
7
|
+
export const registerAndroidTools = (server, service, logger, recordEvidence) => {
|
|
8
|
+
const handler = (contract) => {
|
|
9
|
+
const name = contract.name;
|
|
10
|
+
return async (input, context) => {
|
|
11
|
+
const result = await logToolExecution(logger, name, () => service.execute(name, input, { signal: context.mcpReq.signal }));
|
|
12
|
+
if (!result.ok)
|
|
13
|
+
return toCallToolResult(result, contract);
|
|
14
|
+
const recorded = recordEvidence?.(result.value);
|
|
15
|
+
return recorded !== undefined && !recorded.ok
|
|
16
|
+
? toCallToolResult(recorded, contract)
|
|
17
|
+
: toCallToolResult(result, contract);
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const packageContract = toolContract("inspect_android_package");
|
|
21
|
+
server.registerTool(packageContract.name, toolRegistrationOptions(packageContract), handler(packageContract));
|
|
22
|
+
const searchContract = toolContract("search_android_classes");
|
|
23
|
+
server.registerTool(searchContract.name, toolRegistrationOptions(searchContract), handler(searchContract));
|
|
24
|
+
const classContract = toolContract("inspect_android_class");
|
|
25
|
+
server.registerTool(classContract.name, toolRegistrationOptions(classContract), handler(classContract));
|
|
26
|
+
const methodContract = toolContract("inspect_android_method");
|
|
27
|
+
server.registerTool(methodContract.name, toolRegistrationOptions(methodContract), handler(methodContract));
|
|
28
|
+
const referencesContract = toolContract("trace_android_references");
|
|
29
|
+
server.registerTool(referencesContract.name, toolRegistrationOptions(referencesContract), handler(referencesContract));
|
|
30
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolvePairedEvidenceRequest } from "../../application/EvidenceInputResolver.js";
|
|
1
2
|
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
|
2
3
|
import { compareJavaScriptExportShapesEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
|
|
3
4
|
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
|
@@ -10,7 +11,10 @@ const contract = applicationToolContract("compare_javascript_export_shapes");
|
|
|
10
11
|
/** Register the execution-free exact JavaScript export-shape comparison. */
|
|
11
12
|
export const registerCompareJavaScriptExportShapesTool = (server, options) => {
|
|
12
13
|
server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
|
|
13
|
-
const
|
|
14
|
+
const resolved = resolvePairedEvidenceRequest(input, options.evidenceById);
|
|
15
|
+
if (!resolved.ok)
|
|
16
|
+
return toCallToolResult(resolved, contract);
|
|
17
|
+
const parsed = resolved.value;
|
|
14
18
|
const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareJavaScriptExportShapesEvidenceValidated(parsed)));
|
|
15
19
|
if (!result.ok)
|
|
16
20
|
return toCallToolResult(result, contract);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInputResolver.js";
|
|
1
2
|
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
|
2
3
|
import { compareSourceToBundleEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
|
|
3
4
|
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
|
@@ -10,11 +11,15 @@ const contract = applicationToolContract("compare_source_to_bundle");
|
|
|
10
11
|
/** Register conservative historical-source to bundle comparison. */
|
|
11
12
|
export const registerCompareSourceToBundleTool = (server, options) => {
|
|
12
13
|
server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
|
|
13
|
-
const
|
|
14
|
+
const resolved = resolveApplicationEvidenceRequest(input, options.evidenceById);
|
|
15
|
+
if (!resolved.ok)
|
|
16
|
+
return toCallToolResult(resolved, contract);
|
|
17
|
+
const parsed = resolved.value;
|
|
18
|
+
const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareSourceToBundleEvidenceValidated(parsed)));
|
|
14
19
|
if (!result.ok)
|
|
15
20
|
return toCallToolResult(result, contract);
|
|
16
21
|
const recorded = recordSessionEvidenceSources(options.recordEvidence, [
|
|
17
|
-
|
|
22
|
+
parsed.application,
|
|
18
23
|
]);
|
|
19
24
|
if (!recorded.ok)
|
|
20
25
|
return toCallToolResult(recorded, contract);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolvePairedEvidenceRequest } from "../../application/EvidenceInputResolver.js";
|
|
1
2
|
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
|
2
3
|
import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
|
|
3
4
|
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
|
@@ -10,7 +11,10 @@ const compareContract = applicationToolContract("compare_application_versions");
|
|
|
10
11
|
/** Register the provider-neutral JavaScript version comparison tool. */
|
|
11
12
|
export const registerCompareApplicationVersionsTool = (server, options) => {
|
|
12
13
|
server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
|
|
13
|
-
const
|
|
14
|
+
const resolved = resolvePairedEvidenceRequest(input, options.evidenceById);
|
|
15
|
+
if (!resolved.ok)
|
|
16
|
+
return toCallToolResult(resolved, compareContract);
|
|
17
|
+
const parsed = resolved.value;
|
|
14
18
|
const result = await logToolExecution(options.logger, compareContract.name, () => Promise.resolve(compareApplicationVersionsEvidenceValidated(parsed)));
|
|
15
19
|
if (!result.ok)
|
|
16
20
|
return toCallToolResult(result, compareContract);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInputResolver.js";
|
|
1
2
|
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
|
2
3
|
import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
|
|
3
4
|
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
|
@@ -9,10 +10,14 @@ const traceContract = applicationToolContract("trace_application_feature");
|
|
|
9
10
|
/** Register the provider-neutral JavaScript feature trace tool. */
|
|
10
11
|
export const registerTraceFeatureTool = (server, options) => {
|
|
11
12
|
server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
|
|
12
|
-
const
|
|
13
|
+
const resolved = resolveApplicationEvidenceRequest(input, options.evidenceById);
|
|
14
|
+
if (!resolved.ok)
|
|
15
|
+
return toCallToolResult(resolved, traceContract);
|
|
16
|
+
const parsed = resolved.value;
|
|
17
|
+
const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)));
|
|
13
18
|
if (!result.ok)
|
|
14
19
|
return toCallToolResult(result, traceContract);
|
|
15
|
-
const sources = [
|
|
20
|
+
const sources = [parsed.application, ...parsed.native_observations];
|
|
16
21
|
const recorded = recordSessionEvidenceSources(options.recordEvidence, sources);
|
|
17
22
|
if (!recorded.ok)
|
|
18
23
|
return toCallToolResult(recorded, traceContract);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInputResolver.js";
|
|
1
2
|
import { recordSessionEvidenceSources } from "../sessionEvidence.js";
|
|
2
3
|
import { traceJavaScriptSemanticsEvidenceValidated } from "../../application/JavaScriptSemanticTraceService.js";
|
|
3
4
|
import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
|
|
@@ -9,11 +10,15 @@ const contract = applicationToolContract("trace_javascript_semantics");
|
|
|
9
10
|
/** Register the bounded JavaScript semantic relation trace tool. */
|
|
10
11
|
export const registerTraceJavaScriptSemanticsTool = (server, options) => {
|
|
11
12
|
server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
|
|
12
|
-
const
|
|
13
|
+
const resolved = resolveApplicationEvidenceRequest(input, options.evidenceById);
|
|
14
|
+
if (!resolved.ok)
|
|
15
|
+
return toCallToolResult(resolved, contract);
|
|
16
|
+
const parsed = resolved.value;
|
|
17
|
+
const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(traceJavaScriptSemanticsEvidenceValidated(parsed)));
|
|
13
18
|
if (!result.ok)
|
|
14
19
|
return toCallToolResult(result, contract);
|
|
15
20
|
const recorded = recordSessionEvidenceSources(options.recordEvidence, [
|
|
16
|
-
|
|
21
|
+
parsed.application,
|
|
17
22
|
]);
|
|
18
23
|
if (!recorded.ok)
|
|
19
24
|
return toCallToolResult(recorded, contract);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { EnhancedTools, } from "../application/EnhancedTools.js";
|
|
2
2
|
import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
|
|
3
3
|
import { toolContract } from "../contracts/toolContracts.js";
|
|
4
|
-
import { UnknownRegistryError } from "../domain/
|
|
4
|
+
import { UnknownRegistryError } from "../domain/unknownRegistryError.js";
|
|
5
5
|
import { createEvidence } from "../domain/evidence.js";
|
|
6
6
|
import { mcpProgressReporter } from "./mcpProgress.js";
|
|
7
7
|
import { logToolExecution } from "./toolLogging.js";
|
|
8
8
|
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
|
|
9
9
|
import { toCallToolResult } from "./toolResult.js";
|
|
10
|
+
import { executeFunctionAnalysisEvidence } from "../application/FunctionAnalysisEvidence.js";
|
|
10
11
|
/** Register composed workflows against the same port as direct bridge tools. */
|
|
11
12
|
// oxlint-disable-next-line max-lines-per-function -- direct SDK calls retain each schema-handler type correlation.
|
|
12
13
|
export const registerEnhancedTools = (server, analysis, options) => {
|
|
@@ -93,6 +94,11 @@ const executeEnhancedTool = async (analysis, registration, contract, request) =>
|
|
|
93
94
|
});
|
|
94
95
|
const parsedInput = validatedCall.input;
|
|
95
96
|
const parameters = jsonParameters(parsedInput);
|
|
97
|
+
if (name === "analyze_function")
|
|
98
|
+
return executeFunctionTool(analysis, registration, contract, {
|
|
99
|
+
context,
|
|
100
|
+
parameters,
|
|
101
|
+
});
|
|
96
102
|
const services = new EnhancedTools({
|
|
97
103
|
execute: (operation, operationParameters, executionOptions) => analysis.execute(operation, operationParameters, {
|
|
98
104
|
...executionOptions,
|
|
@@ -138,6 +144,27 @@ const executeEnhancedTool = async (analysis, registration, contract, request) =>
|
|
|
138
144
|
}
|
|
139
145
|
return toCallToolResult(result, contract);
|
|
140
146
|
};
|
|
147
|
+
const executeFunctionTool = async (analysis, registration, contract, request) => {
|
|
148
|
+
const { context, parameters } = request;
|
|
149
|
+
const progress = mcpProgressReporter(context);
|
|
150
|
+
const result = await logToolExecution(registration.logger, "analyze_function", () => executeFunctionAnalysisEvidence(analysis, parameters, registration.activeTarget?.(), {
|
|
151
|
+
signal: context.mcpReq.signal,
|
|
152
|
+
progress,
|
|
153
|
+
}));
|
|
154
|
+
await progress.report({
|
|
155
|
+
phase: "analyze_function",
|
|
156
|
+
completed: 1,
|
|
157
|
+
total: 1,
|
|
158
|
+
message: result.ok ? "completed" : "failed",
|
|
159
|
+
terminal: true,
|
|
160
|
+
});
|
|
161
|
+
if (result.ok) {
|
|
162
|
+
const recorded = registration.recordEvidence?.(result.value);
|
|
163
|
+
if (recorded !== undefined && !recorded.ok)
|
|
164
|
+
return toCallToolResult(recorded, contract);
|
|
165
|
+
}
|
|
166
|
+
return toCallToolResult(result, contract);
|
|
167
|
+
};
|
|
141
168
|
const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
|
|
142
169
|
const recordWorkflowUnknowns = ({ name, result, evidenceId, recordUnknown, }) => {
|
|
143
170
|
if (!["trace_feature", "trace_call_path", "inspect_native_api"].includes(name) ||
|