rea-agents 6.0.0 → 6.2.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 +26 -18
- package/bridge/android/ReaJadxBridge.java +14 -5
- package/bridge/ghidra/ReaGhidraBridge.java +205 -51
- package/bridge/hopper_bridge.py +314 -127
- package/bridge/mitmproxy/capture.py +0 -2
- package/bridge/native/rea_lldb_tracer.py +630 -94
- package/bridge/process/ProcessRunTokenReader.swift +39 -5
- package/bridge/pwntools/recorded_crash_impl.py +4 -0
- package/dist/android/JadxConfiguration.js +274 -31
- package/dist/android/JadxMcpTransport.js +18 -2
- package/dist/android/JadxProtocol.js +6 -0
- package/dist/android/JadxProvider.js +76 -37
- package/dist/android/JadxSession.js +23 -4
- package/dist/application/AnalysisContextQueries.js +8 -35
- package/dist/application/AnalysisDocument.js +32 -0
- package/dist/application/AppBundleExecutable.js +67 -21
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CallPathTracing.js +19 -3
- package/dist/application/CapabilityInventory.js +48 -11
- package/dist/application/ClientConfigurationDocument.js +917 -8
- package/dist/application/ClientRegistrationIdentity.js +26 -5
- package/dist/application/ClientRegistrationStatus.js +29 -14
- package/dist/application/DirectAnalysis.js +56 -51
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +19 -21
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +25 -13
- package/dist/application/EnhancedLiteralTracing.js +22 -25
- package/dist/application/EnhancedTools.js +64 -17
- package/dist/application/EvidenceBundleFiles.js +30 -13
- package/dist/application/FunctionAnalysisEvidence.js +2 -3
- package/dist/application/InventoryProjectionEvidence.js +4 -3
- package/dist/application/InvestigationProviders.js +11 -2
- package/dist/application/JsonFiles.js +83 -28
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionCoverageService.js +7 -4
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReconstructionObligationLedgerService.js +4 -3
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +21 -17
- package/dist/application/SetupClientConfiguration.js +10 -15
- package/dist/application/SetupHost.js +21 -29
- package/dist/application/SetupPlan.js +11 -9
- package/dist/application/SupportedClients.js +34 -1
- package/dist/application/Uninstall.js +82 -29
- package/dist/application/Update.js +18 -3
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +57 -36
- package/dist/application/WebModuleTraceService.js +4 -2
- package/dist/application/WebNetworkCaptureService.js +4 -2
- package/dist/application/WebRuntimeService.js +5 -3
- package/dist/application/WebScriptExportService.js +32 -6
- package/dist/application/WebSourceLocationService.js +4 -2
- package/dist/application/WorkflowEvidence.js +105 -0
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/analysisView/AnalysisViewService.js +76 -0
- package/dist/application/binary/AnalysisClientCleanup.js +30 -5
- package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
- package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
- package/dist/application/binary/BinarySession.js +161 -93
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +4 -4
- package/dist/application/binary/BinarySessionRecords.js +26 -4
- package/dist/application/binary/BinarySessionStatus.js +18 -7
- package/dist/application/binary/CompositeProvider.js +16 -17
- package/dist/application/binary/LazyAnalysisProvider.js +8 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
- package/dist/application/evm/EvmInterfaceService.js +4 -2
- package/dist/application/homebrew.js +48 -0
- package/dist/application/investigation/EvidenceLedger.js +21 -7
- package/dist/application/investigation/InvestigationRecords.js +8 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
- package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
- package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
- package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
- package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
- package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
- package/dist/application/managed/ManagedReconstructionService.js +4 -3
- package/dist/application/process/ProcessCli.js +25 -17
- package/dist/application/process/ProcessEvidence.js +4 -4
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactProvider.js +48 -13
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
- package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
- package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
- package/dist/artifacts/apple/NibArchive.js +81 -14
- package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
- package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +59 -38
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureCompleteness.js +2 -0
- package/dist/browser/CdpCaptureEventHandlers.js +78 -15
- package/dist/browser/CdpCaptureEventTypes.js +5 -1
- package/dist/browser/CdpCaptureEvents.js +25 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpConnection.js +30 -11
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- package/dist/browser/CdpOptionalCommand.js +2 -3
- package/dist/browser/CdpPageCapture.js +23 -1
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
- package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
- package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
- package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +39 -22
- package/dist/browser/WebSourceMapFetcher.js +426 -72
- package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
- package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +41 -1
- package/dist/browser/history/CaptureRelease.js +5 -0
- package/dist/browser/history/HarCaptureAdapter.js +3 -3
- package/dist/browser/history/HarJson.js +3 -2
- package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/applicationCommands.js +2 -3
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +100 -37
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +10 -9
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +7 -3
- package/dist/cli/jsonOutput.js +4 -99
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +3 -5
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/processCommands.js +3 -2
- package/dist/cli/setupCommands.js +16 -15
- package/dist/cli/utilityCommands.js +9 -9
- package/dist/cli/webRuntimeCommands.js +8 -8
- package/dist/cli.js +18 -9
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -1
- package/dist/cliJsonInput.js +24 -5
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -13
- package/dist/composition/electronScenario.js +1 -1
- package/dist/composition/optionalObservationProviders.js +12 -7
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraStartupTimeout.js +12 -0
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +30 -0
- package/dist/config/parseConfig.js +8 -3
- package/dist/config/parsers.js +19 -22
- package/dist/contracts/analysisViewToolContracts.js +56 -0
- package/dist/contracts/applicationToolContracts.js +5 -4
- package/dist/contracts/artifactComparisonExample.js +2 -2
- package/dist/contracts/artifactToolContracts.js +1 -1
- package/dist/contracts/browserScenarioToolContracts.js +1 -1
- package/dist/contracts/browserToolContracts.js +19 -15
- package/dist/contracts/enhancedInputs.js +7 -5
- package/dist/contracts/enhancedToolContracts.js +7 -6
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/hopperMemoryContracts.js +2 -5
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +7 -14
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
- package/dist/contracts/native/nativeToolContracts.js +5 -3
- package/dist/contracts/officialToolContracts.js +16 -16
- package/dist/contracts/promptContracts.js +5 -5
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +3 -7
- package/dist/contracts/sessionStatusContract.js +2 -4
- package/dist/contracts/sessionToolContracts.js +18 -8
- package/dist/contracts/sessionToolSchemas.js +3 -19
- package/dist/contracts/toolContractExamples.js +0 -1
- package/dist/contracts/toolContractHelpers.js +4 -1
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -1
- package/dist/contracts/toolOutputSchemaGroups.js +160 -115
- package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
- package/dist/contracts/toolSchemaMetadata.js +41 -33
- package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorBase.js +8 -3
- package/dist/domain/analysisErrorCore.js +6 -1
- package/dist/domain/analysisErrorPresentation.js +90 -20
- package/dist/domain/analysisErrorProjection.js +130 -32
- package/dist/domain/analysisSnapshot.js +29 -31
- package/dist/domain/analysisView/analysisView.js +243 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +159 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
- package/dist/domain/android/androidAnalysis.js +2 -4
- package/dist/domain/android/androidApplication.js +18 -10
- package/dist/domain/apple/appleApplication.js +42 -15
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dylibResolution.js +130 -12
- package/dist/domain/apple/dylibResolutionFindings.js +9 -7
- package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
- package/dist/domain/apple/keyedArchive.js +35 -3
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactIdentity.js +29 -0
- package/dist/domain/artifactInventoryEvidence.js +28 -40
- package/dist/domain/artifactOperationError.js +3 -3
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +49 -0
- package/dist/domain/binaryTarget.js +39 -13
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCaptureComparison.js +13 -49
- package/dist/domain/browserCompleteness.js +1 -0
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- package/dist/domain/browserObservationError.js +24 -5
- package/dist/domain/browserObservationSchemas.js +14 -3
- package/dist/domain/browserScenario.js +0 -1
- package/dist/domain/browserScenarioCapture.js +1 -2
- package/dist/domain/browserScenarioDiff.js +0 -2
- package/dist/domain/browserScenarioDiffEvidence.js +0 -12
- package/dist/domain/browserScenarioDiffValues.js +2 -2
- package/dist/domain/browserScenarioValues.js +5 -10
- package/dist/domain/bundleComparison.js +3 -2
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalJsonDigestSteps.js +133 -0
- package/dist/domain/canonicalOrdering.js +9 -5
- package/dist/domain/changedBehavior.js +9 -9
- package/dist/domain/comparisonSourceEvidence.js +40 -0
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +13 -1
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +65 -36
- package/dist/domain/evidenceBundle.js +47 -8
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/evidenceErrors.js +12 -1
- package/dist/domain/explicitSensitiveFailure.js +17 -1
- package/dist/domain/firmware/firmwareAnalysis.js +6 -7
- package/dist/domain/functionComparison.js +4 -5
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +23 -34
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +2 -37
- package/dist/domain/hopperErrors.js +23 -2
- package/dist/domain/hopperValues.js +51 -8
- package/dist/domain/immutableJson.js +114 -0
- package/dist/domain/inputIssueProjection.js +3 -0
- package/dist/domain/javascript/electronActiveObservation.js +47 -64
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
- package/dist/domain/javascript/javascriptAstValues.js +20 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
- package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
- package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
- package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascript/javascriptRecovery.js +3 -8
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
- package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptSourceParser.js +6 -2
- package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/jsonSerialization.js +109 -0
- package/dist/domain/jsonValue.js +90 -6
- package/dist/domain/localPath.js +6 -0
- package/dist/domain/managed/managedApplicationGraph.js +10 -10
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedInspectionEvidence.js +16 -0
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
- package/dist/domain/managed/managedNativeVerification.js +3 -11
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +37 -13
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +21 -16
- package/dist/domain/process/processCaptureCoverage.js +67 -0
- package/dist/domain/process/processCaptureExample.js +2 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +81 -13
- package/dist/domain/process/processComparison.js +79 -26
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +35 -12
- package/dist/domain/process/processTraceComparison.js +0 -2
- package/dist/domain/process/processTraceDimensionProjection.js +1 -1
- package/dist/domain/process/processTraceEvaluation.js +15 -11
- package/dist/domain/process/processTraceSpecification.js +3 -4
- package/dist/domain/propertyListKeys.js +1 -1
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +3 -1
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/reconstructionCoverage.js +5 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionVerification.js +9 -46
- package/dist/domain/reconstructionVerificationSchemas.js +4 -3
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +8 -45
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- package/dist/domain/webBundleAnalysis.js +20 -8
- package/dist/domain/webBundleAnalyzerInspection.js +13 -8
- package/dist/domain/webBundleAnalyzerResult.js +41 -2
- package/dist/domain/webCaptureDiff.js +0 -1
- package/dist/domain/webCaptureDiffSchemas.js +6 -3
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webRuntime.js +19 -7
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/domain/webSourceLocation.js +1 -0
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberRows.js +75 -62
- package/dist/dotnet/ManagedMetadataInventory.js +16 -22
- package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
- package/dist/dotnet/ManagedReaderFailure.js +16 -0
- package/dist/dotnet/ManagedStaticProvider.js +3 -5
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +28 -0
- package/dist/evaluation/CodexAgentEval.js +12 -8
- package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
- package/dist/evm/EvmoleInterfaceProvider.js +2 -1
- package/dist/firmware/FirmwareCommand.js +9 -5
- package/dist/firmware/FirmwareFiles.js +1 -1
- package/dist/firmware/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
- package/dist/ghidra/GhidraClient.js +126 -34
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDiagnostics.js +7 -7
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +13 -12
- package/dist/ghidra/GhidraInstallation.js +58 -33
- package/dist/ghidra/GhidraInventoryValues.js +14 -4
- package/dist/ghidra/GhidraJavaLaunch.js +66 -0
- package/dist/ghidra/GhidraLauncher.js +47 -22
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
- package/dist/ghidra/GhidraProviderClient.js +36 -15
- package/dist/ghidra/GhidraSessionError.js +13 -7
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
- package/dist/ghidra/GhidraTransport.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +65 -56
- package/dist/hopper/HopperAnalysisProfile.js +65 -12
- package/dist/hopper/HopperCleanup.js +63 -22
- package/dist/hopper/HopperClient.js +288 -59
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +197 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProvider.js +71 -19
- package/dist/hopper/HopperProviderCapabilities.js +19 -1
- package/dist/hopper/HopperRegexSearch.js +134 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +68 -19
- package/dist/hopper/HopperTargetLease.js +133 -49
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
- package/dist/ida/IdaConfiguration.js +8 -3
- package/dist/ida/IdaInput.js +1 -7
- package/dist/ida/IdaMcpConnection.js +8 -4
- package/dist/ida/IdaOperationRunner.js +3 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +20 -18
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
- package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
- package/dist/inspector/V8InspectorProvider.js +82 -36
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
- package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
- package/dist/main/shutdown.js +11 -3
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +22 -2
- package/dist/main.js +11 -18
- package/dist/mcpDoctor.js +62 -2
- package/dist/native/AppleDispatchCoverage.js +47 -6
- package/dist/native/AppleDispatchDecodeFacts.js +6 -0
- package/dist/native/AppleDispatchMetadata.js +6 -3
- package/dist/native/AppleMachoFixups.js +48 -24
- package/dist/native/AppleMachoSelection.js +48 -22
- package/dist/native/AppleObjcCategories.js +6 -2
- package/dist/native/AppleObjcDispatchFacets.js +5 -2
- package/dist/native/AppleObjcProperties.js +2 -1
- package/dist/native/AppleSwiftDispatchFacets.js +27 -21
- package/dist/native/AppleSwiftVtables.js +21 -15
- package/dist/native/CommandRunner.js +87 -88
- package/dist/native/LldbCallTracer.js +372 -103
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +62 -3
- package/dist/native/NativeMacOSProvider.js +122 -31
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/lipo.js +71 -1
- package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
- package/dist/process/DarwinProcessRunTokenReader.js +23 -10
- package/dist/process/ExecFileOutput.js +108 -6
- package/dist/process/OwnedCommand.js +7 -2
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +204 -57
- package/dist/process/ProcessOwnershipObservation.js +60 -9
- package/dist/process/ProviderProcess.js +39 -10
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +15 -2
- package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
- package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
- package/dist/process/capture/ProcessHarness.js +21 -25
- package/dist/process/capture/ProcessNormalization.js +20 -2
- package/dist/process/capture/ProcessSampling.js +25 -2
- package/dist/process/capture/TerminalRenderer.js +14 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/server/EvidenceMcpServer.js +157 -0
- package/dist/server/createServer.js +61 -41
- package/dist/server/mcpClientMetadata.js +12 -5
- package/dist/server/promptCompletion.js +3 -8
- package/dist/server/registerAnalysisViewTool.js +15 -0
- package/dist/server/registerAndroidTools.js +2 -5
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +4 -5
- package/dist/server/registerApplicationTools/coverage.js +1 -2
- package/dist/server/registerApplicationTools/helpers.js +1 -4
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +13 -10
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
- package/dist/server/registerBrowserScenarioTool.js +3 -6
- package/dist/server/registerBrowserTools.js +13 -18
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +9 -20
- package/dist/server/registerElectronTools.js +10 -15
- package/dist/server/registerEnhancedTools.js +36 -77
- package/dist/server/registerEvidenceTools.js +3 -6
- package/dist/server/registerEvmTools.js +2 -5
- package/dist/server/registerFirmwareTools.js +2 -5
- package/dist/server/registerFunctionComparisonTool.js +15 -12
- package/dist/server/registerInvestigationTools.js +16 -17
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
- package/dist/server/registerOfficialTools.js +4 -21
- package/dist/server/registerProcessComparisonTool.js +74 -48
- package/dist/server/registerRecordedCrashTools.js +2 -5
- package/dist/server/registerSessionRecordTools.js +19 -24
- package/dist/server/registerSessionStatusTool.js +19 -6
- package/dist/server/registerSessionTools.js +20 -18
- package/dist/server/registerWebModuleTool.js +2 -5
- package/dist/server/registerWebNetworkCaptureTool.js +2 -5
- package/dist/server/registerWebRuntimeTools.js +4 -9
- package/dist/server/registerWebScriptTool.js +2 -5
- package/dist/server/registerWebSourceLocationTool.js +2 -5
- package/dist/server/runDerivedOperation.js +15 -3
- package/dist/server/sessionAvailabilityPolicy.js +0 -1
- package/dist/server/toolRegistrationOptions.js +2 -2
- package/dist/server/toolResult.js +75 -51
- package/dist/server/toolResultEncoding.js +34 -0
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- package/install.sh +1 -1
- package/native/windows/README.md +3 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +44 -30
- package/scripts/electron-active-hook-boundaries.cjs +18 -20
- package/scripts/electron-active-hook.cjs +241 -37
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +12 -3
- package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/config.js +0 -1
- package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
- package/dist/contracts/process/processCaptureExample.js +0 -2
- package/dist/contracts/toolOutputSchemas.js +0 -2
- package/dist/ghidra/GhidraDefaults.js +0 -2
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Worker } from "node:worker_threads";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { AnalysisCancelledError, AnalysisOutputError, AnalysisResourceConstraintError, } from "../domain/analysisErrorCore.js";
|
|
4
|
+
import { analysisStringSchema } from "../domain/hopperValues.js";
|
|
5
|
+
import { HopperRemoteError } from "../domain/hopperErrors.js";
|
|
6
|
+
import { err, ok } from "../domain/result.js";
|
|
7
|
+
import { analysisSearchInput } from "../contracts/analysisSearchContract.js";
|
|
8
|
+
const MATCHING_DEADLINE_MS = 5_000;
|
|
9
|
+
const inputSchema = z.strictObject({
|
|
10
|
+
...analysisSearchInput,
|
|
11
|
+
mode: z.literal("regex"),
|
|
12
|
+
});
|
|
13
|
+
const replySchema = z.discriminatedUnion("status", [
|
|
14
|
+
z.strictObject({
|
|
15
|
+
status: z.literal("matched"),
|
|
16
|
+
indices: z.array(z.number().int().nonnegative()),
|
|
17
|
+
}),
|
|
18
|
+
z.strictObject({ status: z.literal("invalid_pattern"), reason: z.string() }),
|
|
19
|
+
]);
|
|
20
|
+
/** Match collected native facts off Hopper's API thread, with cancellable lifetime. */
|
|
21
|
+
export class HopperRegexSearch {
|
|
22
|
+
client;
|
|
23
|
+
#active = new Map();
|
|
24
|
+
constructor(client) {
|
|
25
|
+
this.client = client;
|
|
26
|
+
}
|
|
27
|
+
execute(operation, parameters, options) {
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const signal = options?.signal === undefined
|
|
30
|
+
? controller.signal
|
|
31
|
+
: AbortSignal.any([controller.signal, options.signal]);
|
|
32
|
+
const pending = this.#execute(operation, parameters, {
|
|
33
|
+
...options,
|
|
34
|
+
signal,
|
|
35
|
+
});
|
|
36
|
+
this.#active.set(controller, pending);
|
|
37
|
+
void pending.then(() => this.#active.delete(controller), () => this.#active.delete(controller));
|
|
38
|
+
return pending;
|
|
39
|
+
}
|
|
40
|
+
/** Abort matching workers before their provider session closes. */
|
|
41
|
+
async close() {
|
|
42
|
+
for (const controller of this.#active.keys())
|
|
43
|
+
controller.abort();
|
|
44
|
+
await Promise.all(this.#active.values());
|
|
45
|
+
}
|
|
46
|
+
async #execute(operation, parameters, options) {
|
|
47
|
+
const input = inputSchema.safeParse(parameters);
|
|
48
|
+
if (!input.success)
|
|
49
|
+
return err(new HopperRemoteError(-32000, `Invalid search arguments: ${input.error.message}`, { diagnosticType: "invalid_request", operation }));
|
|
50
|
+
const inventoryOptions = {
|
|
51
|
+
...options,
|
|
52
|
+
...(options.progress === undefined
|
|
53
|
+
? {}
|
|
54
|
+
: {
|
|
55
|
+
progress: {
|
|
56
|
+
report: (update) => options.progress?.report({
|
|
57
|
+
...update,
|
|
58
|
+
completed: update.total === null || update.total === 0
|
|
59
|
+
? 0
|
|
60
|
+
: Math.min(0.5, update.completed / update.total / 2),
|
|
61
|
+
total: 1,
|
|
62
|
+
}) ?? Promise.resolve(),
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
};
|
|
66
|
+
const inventory = await this.client.callTool(operation === "search_strings" ? "list_strings" : "list_procedures", input.data.document === undefined
|
|
67
|
+
? {}
|
|
68
|
+
: { document: input.data.document }, inventoryOptions);
|
|
69
|
+
if (!inventory.ok)
|
|
70
|
+
return inventory;
|
|
71
|
+
const parsed = z.array(analysisStringSchema).safeParse(inventory.value);
|
|
72
|
+
if (!parsed.success)
|
|
73
|
+
return err(new AnalysisOutputError(operation, "Hopper search inventory is malformed"));
|
|
74
|
+
if (options.signal?.aborted)
|
|
75
|
+
return err(new AnalysisCancelledError(operation));
|
|
76
|
+
await options.progress
|
|
77
|
+
?.report({
|
|
78
|
+
phase: "hopper_regex",
|
|
79
|
+
completed: 0.5,
|
|
80
|
+
total: 1,
|
|
81
|
+
message: "Matching inventory in cancellable regex worker",
|
|
82
|
+
})
|
|
83
|
+
.catch(() => undefined);
|
|
84
|
+
if (options.signal?.aborted)
|
|
85
|
+
return err(new AnalysisCancelledError(operation));
|
|
86
|
+
let worker;
|
|
87
|
+
try {
|
|
88
|
+
worker = new Worker(new URL("./HopperRegexWorker.js", import.meta.url), {
|
|
89
|
+
workerData: {
|
|
90
|
+
pattern: input.data.pattern,
|
|
91
|
+
caseSensitive: input.data.case_sensitive,
|
|
92
|
+
values: parsed.data.map((item) => item.value),
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (cause) {
|
|
97
|
+
return err(new AnalysisOutputError(operation, `Cannot start regex worker: ${cause instanceof Error ? cause.message : String(cause)}`, { cause }));
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
return await new Promise((resolve) => {
|
|
101
|
+
const finish = (result) => {
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
104
|
+
resolve(result);
|
|
105
|
+
};
|
|
106
|
+
const onAbort = () => finish(err(new AnalysisCancelledError(operation)));
|
|
107
|
+
const timer = setTimeout(() => finish(err(new AnalysisResourceConstraintError(operation, "cpu", "Regex matching exceeded its supervised deadline; the Hopper API thread remains available.", { matching_deadline_ms: MATCHING_DEADLINE_MS }, {
|
|
108
|
+
remediationAction: "Simplify the ECMAScript Unicode regex or use literal mode, then retry in the same session.",
|
|
109
|
+
}))), MATCHING_DEADLINE_MS);
|
|
110
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
111
|
+
if (options.signal?.aborted)
|
|
112
|
+
onAbort();
|
|
113
|
+
worker.once("message", (message) => {
|
|
114
|
+
const reply = replySchema.safeParse(message);
|
|
115
|
+
if (!reply.success)
|
|
116
|
+
return finish(err(new AnalysisOutputError(operation, "Regex worker reply is malformed")));
|
|
117
|
+
if (reply.data.status === "invalid_pattern")
|
|
118
|
+
return finish(err(new HopperRemoteError(-32000, `Invalid regex pattern: ${reply.data.reason}`, { diagnosticType: "invalid_request", operation })));
|
|
119
|
+
const indices = reply.data.indices;
|
|
120
|
+
if (indices.some((index, position) => index >= parsed.data.length ||
|
|
121
|
+
(position > 0 && index <= (indices[position - 1] ?? -1))))
|
|
122
|
+
return finish(err(new AnalysisOutputError(operation, "Regex worker returned invalid inventory indices")));
|
|
123
|
+
const selected = new Set(indices);
|
|
124
|
+
finish(ok(parsed.data.filter((_, index) => selected.has(index))));
|
|
125
|
+
});
|
|
126
|
+
worker.once("error", (cause) => finish(err(new AnalysisOutputError(operation, `Regex worker failed: ${cause.message}`, { cause }))));
|
|
127
|
+
worker.once("exit", (code) => finish(err(new AnalysisOutputError(operation, `Regex worker exited without a result (${code})`))));
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
await worker.terminate();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const input = z
|
|
4
|
+
.strictObject({
|
|
5
|
+
pattern: z.string().min(1),
|
|
6
|
+
caseSensitive: z.boolean(),
|
|
7
|
+
values: z.array(z.string()),
|
|
8
|
+
})
|
|
9
|
+
.parse(workerData);
|
|
10
|
+
let expression;
|
|
11
|
+
try {
|
|
12
|
+
expression = new RegExp(input.pattern, input.caseSensitive ? "u" : "iu");
|
|
13
|
+
}
|
|
14
|
+
catch (cause) {
|
|
15
|
+
parentPort?.postMessage({
|
|
16
|
+
status: "invalid_pattern",
|
|
17
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (expression !== undefined) {
|
|
21
|
+
const indices = [];
|
|
22
|
+
for (const [index, value] of input.values.entries()) {
|
|
23
|
+
if (expression.test(value))
|
|
24
|
+
indices.push(index);
|
|
25
|
+
}
|
|
26
|
+
parentPort?.postMessage({ status: "matched", indices });
|
|
27
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hopperOperationStage } from "./HopperOperationStage.js";
|
|
2
|
+
import { HopperCancelledError, HopperProcessError, HopperProtocolError, HopperRemoteError, HopperTimeoutError, } from "../domain/hopperErrors.js";
|
|
2
3
|
import { err } from "../domain/result.js";
|
|
4
|
+
/** Node timer ceiling; larger deadlines would be clamped instead of honored. */
|
|
5
|
+
const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
3
6
|
/** FIFO that keeps the wire serialized until Hopper actually replies. */
|
|
4
7
|
export class HopperRequestQueue {
|
|
5
8
|
send;
|
|
@@ -8,10 +11,18 @@ export class HopperRequestQueue {
|
|
|
8
11
|
constructor(send) {
|
|
9
12
|
this.send = send;
|
|
10
13
|
}
|
|
11
|
-
/**
|
|
14
|
+
/** Settle the caller on reply, cancellation, or deadline; retain active wire work. */
|
|
12
15
|
run(id, method, params, options) {
|
|
13
16
|
if (options.signal?.aborted === true)
|
|
14
17
|
return Promise.resolve(err(new HopperCancelledError()));
|
|
18
|
+
const timeoutMs = options.timeoutMs;
|
|
19
|
+
if (timeoutMs !== undefined &&
|
|
20
|
+
(!Number.isInteger(timeoutMs) ||
|
|
21
|
+
timeoutMs < 0 ||
|
|
22
|
+
timeoutMs > MAX_TIMEOUT_MS))
|
|
23
|
+
return Promise.resolve(err(new HopperProtocolError(`Hopper timeoutMs must be an integer between 0 and ${String(MAX_TIMEOUT_MS)}`)));
|
|
24
|
+
if (timeoutMs === 0)
|
|
25
|
+
return Promise.resolve(err(new HopperTimeoutError(0, method, id, "not_started", hopperOperationStage(method))));
|
|
15
26
|
return new Promise((resolve) => {
|
|
16
27
|
let entry;
|
|
17
28
|
const onAbort = options.signal === undefined ? undefined : () => this.#cancel(entry);
|
|
@@ -25,12 +36,18 @@ export class HopperRequestQueue {
|
|
|
25
36
|
onAbort,
|
|
26
37
|
callerState: "waiting",
|
|
27
38
|
callerSettled: false,
|
|
39
|
+
transmitted: false,
|
|
28
40
|
startedAt: undefined,
|
|
29
41
|
heartbeat: undefined,
|
|
42
|
+
deadline: undefined,
|
|
43
|
+
deadlineAt: timeoutMs === undefined ? undefined : performance.now() + timeoutMs,
|
|
44
|
+
timeoutMs,
|
|
30
45
|
};
|
|
31
46
|
this.#queue.push(entry);
|
|
32
47
|
if (onAbort !== undefined)
|
|
33
48
|
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
49
|
+
if (timeoutMs !== undefined)
|
|
50
|
+
entry.deadline = setTimeout(() => this.#cancel(entry, this.#timeoutError(entry, timeoutMs)), timeoutMs);
|
|
34
51
|
if (this.#active !== undefined || this.#queue.length > 1)
|
|
35
52
|
this.#report(entry, `${method} queued behind ${String(this.#size() - 1)} Hopper request(s)`);
|
|
36
53
|
this.#drain();
|
|
@@ -41,17 +58,10 @@ export class HopperRequestQueue {
|
|
|
41
58
|
const entry = this.#active;
|
|
42
59
|
if (entry === undefined || entry.id !== id)
|
|
43
60
|
return false;
|
|
61
|
+
this.#expireIfElapsed(entry);
|
|
44
62
|
this.#releaseWire(entry);
|
|
45
|
-
if (!entry.callerSettled)
|
|
46
|
-
|
|
47
|
-
? err(new HopperRemoteError(result.error.code, result.error.safeMessage, {
|
|
48
|
-
diagnosticType: result.error.diagnosticType,
|
|
49
|
-
operation: entry.method,
|
|
50
|
-
requestId: entry.id,
|
|
51
|
-
}))
|
|
52
|
-
: result;
|
|
53
|
-
this.#settleCaller(entry, contextual, "waiting");
|
|
54
|
-
}
|
|
63
|
+
if (!entry.callerSettled)
|
|
64
|
+
this.#settleCaller(entry, result.ok ? result : err(withRequestContext(result.error, entry)), "waiting");
|
|
55
65
|
this.#active = undefined;
|
|
56
66
|
this.#drain();
|
|
57
67
|
return true;
|
|
@@ -120,6 +130,10 @@ export class HopperRequestQueue {
|
|
|
120
130
|
const entry = this.#queue.shift();
|
|
121
131
|
if (entry === undefined)
|
|
122
132
|
return;
|
|
133
|
+
if (this.#expireIfElapsed(entry)) {
|
|
134
|
+
this.#drain();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
123
137
|
if (entry.signal?.aborted === true) {
|
|
124
138
|
this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
|
|
125
139
|
this.#drain();
|
|
@@ -128,6 +142,17 @@ export class HopperRequestQueue {
|
|
|
128
142
|
this.#active = entry;
|
|
129
143
|
entry.startedAt = performance.now();
|
|
130
144
|
this.#report(entry, `${entry.method} started on Hopper's serial bridge`);
|
|
145
|
+
this.#expireIfElapsed(entry);
|
|
146
|
+
// A progress observer may cancel or tear down synchronously before send.
|
|
147
|
+
// No native work exists yet, so it is safe to release this reserved slot.
|
|
148
|
+
if (this.#active !== entry || entry.callerSettled) {
|
|
149
|
+
if (this.#active === entry) {
|
|
150
|
+
this.#active = undefined;
|
|
151
|
+
this.#releaseWire(entry);
|
|
152
|
+
this.#drain();
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
131
156
|
entry.heartbeat = setInterval(() => {
|
|
132
157
|
if (entry.callerSettled || entry.startedAt === undefined)
|
|
133
158
|
return;
|
|
@@ -135,30 +160,44 @@ export class HopperRequestQueue {
|
|
|
135
160
|
this.#report(entry, `${entry.method} is still running in Hopper (${String(elapsed)} ms elapsed)`);
|
|
136
161
|
}, 1_000);
|
|
137
162
|
try {
|
|
138
|
-
|
|
163
|
+
entry.transmitted = true;
|
|
164
|
+
this.send({ id: entry.id, method: entry.method, params: entry.params }, () => this.accept(entry.id, err(new HopperProcessError(null, undefined, entry.method, entry.id, "unreachable", hopperOperationStage(entry.method)))));
|
|
139
165
|
}
|
|
140
166
|
catch (cause) {
|
|
141
167
|
this.accept(entry.id, err(new HopperProtocolError("Hopper socket write failed", { cause })));
|
|
142
168
|
}
|
|
143
169
|
}
|
|
144
|
-
#
|
|
170
|
+
#timeoutError(entry, timeoutMs) {
|
|
171
|
+
return new HopperTimeoutError(timeoutMs, entry.method, entry.id, entry.transmitted ? "busy" : "not_started", hopperOperationStage(entry.method));
|
|
172
|
+
}
|
|
173
|
+
#expireIfElapsed(entry) {
|
|
174
|
+
if (entry.deadlineAt !== undefined &&
|
|
175
|
+
entry.timeoutMs !== undefined &&
|
|
176
|
+
performance.now() >= entry.deadlineAt)
|
|
177
|
+
this.#settleCaller(entry, err(this.#timeoutError(entry, entry.timeoutMs)), "cancelled");
|
|
178
|
+
return entry.callerSettled;
|
|
179
|
+
}
|
|
180
|
+
#cancel(entry, error = new HopperCancelledError()) {
|
|
145
181
|
if (entry.callerSettled)
|
|
146
182
|
return;
|
|
147
183
|
if (this.#active === entry) {
|
|
148
|
-
this.#settleCaller(entry, err(
|
|
184
|
+
this.#settleCaller(entry, err(error), "cancelled");
|
|
149
185
|
return;
|
|
150
186
|
}
|
|
151
187
|
const index = this.#queue.indexOf(entry);
|
|
152
188
|
if (index < 0)
|
|
153
189
|
return;
|
|
154
190
|
this.#queue.splice(index, 1);
|
|
155
|
-
this.#settleCaller(entry, err(
|
|
191
|
+
this.#settleCaller(entry, err(error), "cancelled");
|
|
156
192
|
}
|
|
157
193
|
#settleCaller(entry, result, callerState) {
|
|
158
194
|
if (entry.callerSettled)
|
|
159
195
|
return;
|
|
160
196
|
entry.callerSettled = true;
|
|
161
197
|
entry.callerState = callerState;
|
|
198
|
+
if (entry.deadline !== undefined)
|
|
199
|
+
clearTimeout(entry.deadline);
|
|
200
|
+
entry.deadline = undefined;
|
|
162
201
|
if (this.#active === entry && entry.heartbeat !== undefined) {
|
|
163
202
|
clearInterval(entry.heartbeat);
|
|
164
203
|
entry.heartbeat = undefined;
|
|
@@ -195,6 +234,16 @@ export class HopperRequestQueue {
|
|
|
195
234
|
}
|
|
196
235
|
}
|
|
197
236
|
}
|
|
198
|
-
const withRequestContext = (error, entry) =>
|
|
199
|
-
|
|
200
|
-
|
|
237
|
+
const withRequestContext = (error, entry) => {
|
|
238
|
+
if (error instanceof HopperProcessError)
|
|
239
|
+
return new HopperProcessError(error.exitCode, error.diagnostic, error.operation ?? entry.method, error.requestId ?? entry.id, error.providerState, error.operation === undefined && error.stage === "connection"
|
|
240
|
+
? hopperOperationStage(entry.method)
|
|
241
|
+
: error.stage);
|
|
242
|
+
if (error instanceof HopperRemoteError)
|
|
243
|
+
return new HopperRemoteError(error.code, error.safeMessage, {
|
|
244
|
+
diagnosticType: error.diagnosticType,
|
|
245
|
+
operation: error.operation ?? entry.method,
|
|
246
|
+
requestId: error.requestId ?? entry.id,
|
|
247
|
+
});
|
|
248
|
+
return error;
|
|
249
|
+
};
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { chmod, lstat, mkdir, realpath, rm } from "node:fs/promises";
|
|
2
|
+
import { chmod, lstat, mkdir, realpath, rm, rmdir } from "node:fs/promises";
|
|
3
3
|
import { createConnection, createServer, } from "node:net";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { HopperStartError } from "../domain/hopperErrors.js";
|
|
6
6
|
import { safeParseJson } from "../domain/safeJson.js";
|
|
7
|
-
|
|
7
|
+
/** Shared private parent of Hopper lease sockets; it outlives individual sessions. */
|
|
8
|
+
export const HOPPER_TARGET_LEASE_DIRECTORY = join("/tmp", `rea-hopper-${process.getuid?.() ?? 0}`);
|
|
8
9
|
/** Keep two REA processes from opening duplicate Hopper documents for one target/profile. */
|
|
9
10
|
export const acquireHopperTargetLease = async (input) => {
|
|
10
|
-
const directory = input.directory ?? leaseDirectory;
|
|
11
|
-
await ensureLeaseDirectory(directory);
|
|
12
11
|
// The canonical path only derives the lease key; it never authorizes access.
|
|
13
12
|
// Common expected `realpath` failures include a missing target or path
|
|
14
13
|
// component (ENOENT, ENOTDIR), an unreadable component (EACCES), or a
|
|
@@ -17,43 +16,105 @@ export const acquireHopperTargetLease = async (input) => {
|
|
|
17
16
|
// still yields a deterministic key, but aliases may take separate leases
|
|
18
17
|
// whenever `realpath` cannot resolve them.
|
|
19
18
|
const targetPath = await realpath(input.targetPath).catch(() => resolve(input.targetPath));
|
|
19
|
+
return acquireLease({
|
|
20
|
+
...input,
|
|
21
|
+
identity: {
|
|
22
|
+
targetPath,
|
|
23
|
+
targetKind: input.targetKind,
|
|
24
|
+
loaderArgs: input.loaderArgs,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
/** Reserve the Linux demo's singleton application before it can forward a target to another owner. */
|
|
29
|
+
export const acquireLinuxHopperApplicationLease = (input) => acquireLease({ ...input, identity: { application: "linux-hopper-demo" } });
|
|
30
|
+
const acquireLease = async (input) => {
|
|
31
|
+
const directory = input.directory ?? HOPPER_TARGET_LEASE_DIRECTORY;
|
|
32
|
+
await ensureLeaseDirectory(directory);
|
|
20
33
|
const key = createHash("sha256")
|
|
21
|
-
.update(JSON.stringify(
|
|
22
|
-
targetPath,
|
|
23
|
-
targetKind: input.targetKind,
|
|
24
|
-
loaderArgs: input.loaderArgs,
|
|
25
|
-
}))
|
|
34
|
+
.update(JSON.stringify(input.identity))
|
|
26
35
|
.digest("hex")
|
|
27
36
|
.slice(0, 32);
|
|
28
37
|
const socketPath = join(directory, `${key}.sock`);
|
|
29
38
|
const owner = { runId: input.runId, processId: process.pid };
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
const acquisition = await tryAcquireLease(socketPath, owner);
|
|
40
|
+
if (typeof acquisition !== "string")
|
|
41
|
+
return acquisition;
|
|
42
|
+
// Serialize stale cleanup through the replacement bind: otherwise two
|
|
43
|
+
// recoverers can unlink the socket that one of them has just acquired.
|
|
44
|
+
const recoveryPath = `${socketPath}.recovery`;
|
|
45
|
+
await reserveRecovery(recoveryPath);
|
|
46
|
+
let recovered;
|
|
47
|
+
try {
|
|
48
|
+
recovered = await tryAcquireLease(socketPath, owner);
|
|
49
|
+
if (recovered === "stale")
|
|
50
|
+
await rm(socketPath, { force: true });
|
|
51
|
+
if (typeof recovered === "string")
|
|
52
|
+
recovered = await tryAcquireLease(socketPath, owner);
|
|
53
|
+
if (typeof recovered !== "string")
|
|
54
|
+
return recovered;
|
|
55
|
+
throw new HopperStartError({
|
|
56
|
+
userMessage: "REA could not reserve Hopper for this request. Close competing REA sessions and retry.",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
try {
|
|
61
|
+
await rmdir(recoveryPath);
|
|
48
62
|
}
|
|
63
|
+
catch (cause) {
|
|
64
|
+
if (typeof recovered !== "string" && recovered?.acquired)
|
|
65
|
+
await recovered.lease.release();
|
|
66
|
+
throw new HopperStartError({
|
|
67
|
+
cause,
|
|
68
|
+
userMessage: `REA could not remove its Hopper recovery directory at ${JSON.stringify(recoveryPath)}. Check this directory's write access before retrying.`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const reserveRecovery = async (recoveryPath) => {
|
|
74
|
+
try {
|
|
75
|
+
await mkdir(recoveryPath, { mode: 0o700 });
|
|
76
|
+
}
|
|
77
|
+
catch (cause) {
|
|
78
|
+
const busy = typeof cause === "object" &&
|
|
79
|
+
cause !== null &&
|
|
80
|
+
Reflect.get(cause, "code") === "EEXIST";
|
|
81
|
+
throw new HopperStartError({
|
|
82
|
+
cause,
|
|
83
|
+
userMessage: busy
|
|
84
|
+
? `REA could not reserve Hopper lease recovery at ${JSON.stringify(recoveryPath)}; the existing socket was left unchanged. Retry after concurrent startup finishes. If recovery was interrupted, stop REA sessions and remove this recovery directory before retrying.`
|
|
85
|
+
: `REA could not create its Hopper recovery directory at ${JSON.stringify(recoveryPath)}; the existing socket was left unchanged. Check the parent directory's write access before retrying.`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const tryAcquireLease = async (socketPath, owner) => {
|
|
90
|
+
const server = createServer((socket) => sendOwner(socket, owner));
|
|
91
|
+
if (!(await bind(server, socketPath))) {
|
|
49
92
|
const existingOwner = await readOwner(socketPath);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
93
|
+
return typeof existingOwner === "string"
|
|
94
|
+
? existingOwner
|
|
95
|
+
: { acquired: false, owner: existingOwner };
|
|
53
96
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
97
|
+
try {
|
|
98
|
+
await chmod(socketPath, 0o600);
|
|
99
|
+
}
|
|
100
|
+
catch (cause) {
|
|
101
|
+
await closeServer(server);
|
|
102
|
+
throw cause;
|
|
103
|
+
}
|
|
104
|
+
let released = false;
|
|
105
|
+
return {
|
|
106
|
+
acquired: true,
|
|
107
|
+
lease: {
|
|
108
|
+
release: async () => {
|
|
109
|
+
if (released)
|
|
110
|
+
return;
|
|
111
|
+
// Node removes a bound Unix socket on close. A second unlink here
|
|
112
|
+
// could remove a new owner's socket bound after that close.
|
|
113
|
+
await closeServer(server);
|
|
114
|
+
released = true;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
57
118
|
};
|
|
58
119
|
const ensureLeaseDirectory = async (directory) => {
|
|
59
120
|
let directoryStat;
|
|
@@ -95,14 +156,26 @@ const bind = (server, socketPath) => new Promise((resolveBind, reject) => {
|
|
|
95
156
|
const sendOwner = (socket, owner) => {
|
|
96
157
|
socket.end(`${JSON.stringify(owner)}\n`);
|
|
97
158
|
};
|
|
98
|
-
const readOwner = (socketPath) => new Promise((resolveOwner) => {
|
|
159
|
+
const readOwner = (socketPath) => new Promise((resolveOwner, rejectOwner) => {
|
|
99
160
|
const socket = createConnection(socketPath);
|
|
100
161
|
let response = "";
|
|
101
|
-
|
|
162
|
+
let settled = false;
|
|
163
|
+
const fail = (reason, cause) => {
|
|
164
|
+
if (settled)
|
|
165
|
+
return;
|
|
166
|
+
settled = true;
|
|
167
|
+
clearTimeout(timer);
|
|
102
168
|
socket.destroy();
|
|
103
|
-
|
|
104
|
-
|
|
169
|
+
rejectOwner(new HopperStartError({
|
|
170
|
+
cause,
|
|
171
|
+
userMessage: `REA could not verify the existing Hopper lease (${reason}); it was left unchanged. Retry when the owning REA session is responsive.`,
|
|
172
|
+
}));
|
|
173
|
+
};
|
|
174
|
+
const timer = setTimeout(() => fail("owner response timed out"), 250);
|
|
105
175
|
const finish = (owner) => {
|
|
176
|
+
if (settled)
|
|
177
|
+
return;
|
|
178
|
+
settled = true;
|
|
106
179
|
clearTimeout(timer);
|
|
107
180
|
socket.destroy();
|
|
108
181
|
resolveOwner(owner);
|
|
@@ -114,23 +187,34 @@ const readOwner = (socketPath) => new Promise((resolveOwner) => {
|
|
|
114
187
|
return;
|
|
115
188
|
const parsed = safeParseJson(response.slice(0, newline));
|
|
116
189
|
if (!parsed.ok) {
|
|
117
|
-
|
|
190
|
+
fail("malformed owner response");
|
|
118
191
|
return;
|
|
119
192
|
}
|
|
120
193
|
const value = parsed.value;
|
|
121
|
-
|
|
122
|
-
value
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
194
|
+
const runId = typeof value === "object" && value !== null
|
|
195
|
+
? Reflect.get(value, "runId")
|
|
196
|
+
: undefined;
|
|
197
|
+
const processId = typeof value === "object" && value !== null
|
|
198
|
+
? Reflect.get(value, "processId")
|
|
199
|
+
: undefined;
|
|
200
|
+
if (typeof runId === "string" &&
|
|
201
|
+
runId.length > 0 &&
|
|
202
|
+
typeof processId === "number" &&
|
|
203
|
+
Number.isSafeInteger(processId) &&
|
|
204
|
+
processId > 0)
|
|
205
|
+
finish({ runId, processId });
|
|
206
|
+
else
|
|
207
|
+
fail("invalid owner identity");
|
|
208
|
+
});
|
|
209
|
+
socket.on("error", (cause) => {
|
|
210
|
+
if (cause.code === "ENOENT")
|
|
211
|
+
finish("missing");
|
|
212
|
+
else if (cause.code === "ECONNREFUSED")
|
|
213
|
+
finish("stale");
|
|
129
214
|
else
|
|
130
|
-
|
|
215
|
+
fail(cause.code ?? "owner connection failed", cause);
|
|
131
216
|
});
|
|
132
|
-
socket.on("
|
|
133
|
-
socket.on("end", () => finish(undefined));
|
|
217
|
+
socket.on("end", () => fail("owner closed without a complete response"));
|
|
134
218
|
});
|
|
135
219
|
const closeServer = (server) => new Promise((resolveClose, reject) => {
|
|
136
220
|
if (!server.listening) {
|
|
@@ -50,6 +50,9 @@ export const runLinuxPrivateDisplayProbe = async (strategy, options) => {
|
|
|
50
50
|
arguments: command.arguments,
|
|
51
51
|
runId: randomUUID(),
|
|
52
52
|
expectedCommand: null,
|
|
53
|
+
...(options.environment === undefined
|
|
54
|
+
? {}
|
|
55
|
+
: { hostEnvironment: options.environment }),
|
|
53
56
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
54
57
|
});
|
|
55
58
|
}
|
|
@@ -111,6 +114,9 @@ const evaluatedProbe = async (strategy, options, timeoutMs, runner) => {
|
|
|
111
114
|
try {
|
|
112
115
|
processResult = await runner(strategy, {
|
|
113
116
|
helperPath: options.helperPath,
|
|
117
|
+
...(options.environment === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { environment: options.environment }),
|
|
114
120
|
timeoutMs,
|
|
115
121
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
116
122
|
});
|
|
@@ -40,7 +40,7 @@ const registrationSchema = z.union([
|
|
|
40
40
|
export const readIdaConfiguration = (path) => {
|
|
41
41
|
try {
|
|
42
42
|
if (statSync(path).size > 65_536)
|
|
43
|
-
return err(
|
|
43
|
+
return err(idaConfigurationError("REA_IDA_MCP_CONFIG exceeds the 64 KiB registration size."));
|
|
44
44
|
const input = JSON.parse(readFileSync(path, "utf8"));
|
|
45
45
|
const envelope = z
|
|
46
46
|
.object({ mcpServers: z.object({ "ida-pro-mcp": z.unknown() }) })
|
|
@@ -48,9 +48,14 @@ export const readIdaConfiguration = (path) => {
|
|
|
48
48
|
const parsed = registrationSchema.safeParse(envelope.success ? envelope.data.mcpServers["ida-pro-mcp"] : input);
|
|
49
49
|
return parsed.success
|
|
50
50
|
? ok(parsed.data)
|
|
51
|
-
: err(
|
|
51
|
+
: err(idaConfigurationError("REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md.", parsed.error));
|
|
52
52
|
}
|
|
53
53
|
catch (cause) {
|
|
54
|
-
return err(
|
|
54
|
+
return err(idaConfigurationError(`Cannot read IDA MCP registration ${path}; provide a readable JSON configuration.`, cause));
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
|
+
/** A REA_IDA_MCP_CONFIG rejection that names the setting it concerns. */
|
|
58
|
+
export const idaConfigurationError = (constraint, cause) => new ConfigurationError(constraint, {
|
|
59
|
+
...(cause === undefined ? {} : { cause }),
|
|
60
|
+
settings: [{ setting: "REA_IDA_MCP_CONFIG", constraint }],
|
|
61
|
+
});
|
package/dist/ida/IdaInput.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
1
|
import { TOOL_CONTRACTS } from "../contracts/toolContracts.js";
|
|
3
2
|
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
|
4
3
|
import { jsonObjectSchema } from "../domain/jsonValue.js";
|
|
@@ -8,12 +7,7 @@ import { projectInputIssues } from "../domain/inputIssueProjection.js";
|
|
|
8
7
|
/** Apply the named public contract and IDA's explicit-address boundary before startup. */
|
|
9
8
|
export const parseIdaInput = (operation, parameters) => {
|
|
10
9
|
const contract = TOOL_CONTRACTS.find(({ name }) => name === operation);
|
|
11
|
-
const
|
|
12
|
-
if (schema instanceof z.ZodObject) {
|
|
13
|
-
const shape = schema.shape;
|
|
14
|
-
parameters = Object.fromEntries(Object.entries(parameters).filter(([key, value]) => value !== null || shape[key]?.safeParse(undefined).success !== true));
|
|
15
|
-
}
|
|
16
|
-
const parsed = (schema instanceof z.ZodObject ? schema.strict() : schema)?.safeParse(parameters);
|
|
10
|
+
const parsed = contract?.inputSchema.safeParse(parameters);
|
|
17
11
|
if (parsed?.success !== true)
|
|
18
12
|
return err(new AnalysisInputError(operation, { cause: parsed?.error }, parsed?.error === undefined
|
|
19
13
|
? []
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
|
|
1
2
|
import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
|
|
2
|
-
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
|
3
|
+
import { DEFAULT_INHERITED_ENV_VARS, StdioClientTransport, } from "@modelcontextprotocol/client/stdio";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
5
6
|
import { AnalysisProtocolError } from "../domain/analysisErrorCore.js";
|
|
@@ -66,7 +67,7 @@ export const redactIdaTransportFailure = (cause, config) => {
|
|
|
66
67
|
return new Error(message, { cause });
|
|
67
68
|
};
|
|
68
69
|
/** Create a standard SDK connection to an existing upstream registration. */
|
|
69
|
-
export const createIdaMcpConnection = (config) => {
|
|
70
|
+
export const createIdaMcpConnection = (config, environment) => {
|
|
70
71
|
const client = new Client({ name: "rea-ida-provider", version: "1" });
|
|
71
72
|
const transportFailure = (cause) => {
|
|
72
73
|
throw redactIdaTransportFailure(cause, config);
|
|
@@ -76,9 +77,12 @@ export const createIdaMcpConnection = (config) => {
|
|
|
76
77
|
command: config.command,
|
|
77
78
|
args: config.args,
|
|
78
79
|
env: {
|
|
79
|
-
|
|
80
|
+
// The SDK always merges ambient defaults. Its string-only environment
|
|
81
|
+
// API requires empty values to suppress omitted caller-selected keys.
|
|
82
|
+
...Object.fromEntries(DEFAULT_INHERITED_ENV_VARS.map((key) => [key, ""])),
|
|
83
|
+
...Object.fromEntries(Object.entries(snapshotEnvironment(environment)).filter((entry) => entry[1] !== undefined)),
|
|
80
84
|
IDA_MCP_MAX_WORKERS: "1",
|
|
81
|
-
...config.env,
|
|
85
|
+
...snapshotEnvironment(config.env),
|
|
82
86
|
},
|
|
83
87
|
stderr: "pipe",
|
|
84
88
|
})
|