rea-agents 6.1.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 +7 -5
- package/bridge/ghidra/ReaGhidraBridge.java +32 -4
- package/bridge/hopper_bridge.py +6 -1
- package/dist/android/JadxConfiguration.js +87 -7
- package/dist/android/JadxMcpTransport.js +14 -2
- package/dist/android/JadxProvider.js +57 -35
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CapabilityInventory.js +43 -9
- package/dist/application/ClientConfigurationDocument.js +69 -25
- package/dist/application/DirectAnalysis.js +29 -14
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +15 -19
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/EnhancedTools.js +51 -6
- package/dist/application/EvidenceBundleFiles.js +8 -3
- package/dist/application/InvestigationProviders.js +9 -1
- package/dist/application/JsonFiles.js +42 -9
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +8 -16
- package/dist/application/SetupHost.js +16 -27
- package/dist/application/SetupPlan.js +6 -6
- package/dist/application/Uninstall.js +81 -29
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +12 -12
- package/dist/application/WebScriptExportService.js +30 -4
- package/dist/application/WorkflowEvidence.js +25 -2
- 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 +1 -2
- package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +10 -8
- package/dist/application/binary/BinarySession.js +70 -29
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +1 -1
- package/dist/application/binary/BinarySessionRecords.js +1 -1
- package/dist/application/binary/BinarySessionStatus.js +1 -6
- package/dist/application/binary/CompositeProvider.js +4 -18
- package/dist/application/binary/LazyAnalysisProvider.js +5 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/homebrew.js +48 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +2 -6
- package/dist/application/javascript/JavaScriptApplicationService.js +6 -1
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -3
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +11 -9
- 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 +43 -16
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +46 -6
- package/dist/application/javascript/JavaScriptModuleRelationships.js +1 -1
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- 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 +42 -19
- package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
- package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
- package/dist/application/process/ProcessCli.js +11 -11
- package/dist/application/process/ProcessEvidence.js +0 -1
- package/dist/artifacts/ArtifactProvider.js +39 -14
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +65 -20
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/KeyedArchiveReader.js +21 -3
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +67 -61
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +48 -24
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureEventHandlers.js +2 -4
- package/dist/browser/CdpCaptureEvents.js +0 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- 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 +2 -56
- package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
- 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/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +6 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +32 -27
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +4 -4
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +1 -2
- 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.js +16 -8
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -0
- package/dist/cliJsonInput.js +15 -1
- 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 +6 -0
- package/dist/config/ghidraStartupTimeout.js +4 -9
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +9 -1
- package/dist/config/parseConfig.js +7 -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 +2 -2
- package/dist/contracts/enhancedToolContracts.js +4 -3
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +1 -1
- 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 +5 -10
- 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 +2 -2
- package/dist/contracts/officialToolContracts.js +2 -1
- package/dist/contracts/promptContracts.js +2 -2
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionToolContracts.js +14 -2
- package/dist/contracts/sessionToolSchemas.js +1 -14
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -0
- package/dist/contracts/toolOutputSchemaGroups.js +136 -92
- package/dist/contracts/toolOutputSchemaPrimitives.js +11 -21
- package/dist/contracts/toolSchemaMetadata.js +18 -69
- package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorCore.js +3 -0
- package/dist/domain/analysisErrorPresentation.js +18 -3
- package/dist/domain/analysisErrorProjection.js +24 -5
- 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/androidApplication.js +1 -1
- package/dist/domain/apple/appleApplication.js +1 -1
- package/dist/domain/apple/dylibResolution.js +10 -3
- package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
- package/dist/domain/apple/keyedArchive.js +26 -2
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactInventoryEvidence.js +9 -16
- 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/browserCaptureComparison.js +13 -49
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- 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 +3 -4
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/changedBehavior.js +3 -3
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +12 -0
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +10 -36
- package/dist/domain/evidenceBundle.js +7 -9
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- 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/javascript/electronActiveObservation.js +26 -69
- 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/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +26 -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/{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/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 +9 -3
- 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/javascriptSemanticDataEffects.js +1 -1
- package/dist/domain/javascript/javascriptSemanticGraph.js +88 -46
- 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 +1 -12
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
- 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 +47 -54
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +0 -1
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/localPath.js +1 -1
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedNativeVerification.js +0 -2
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +5 -3
- 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 +13 -12
- 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 +41 -22
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +24 -2
- 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/providerAdapterError.js +2 -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 +3 -3
- package/dist/domain/reconstructionVerificationSchemas.js +2 -1
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +2 -2
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- 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 +0 -2
- package/dist/domain/webScriptExport.js +1 -1
- 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/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
- package/dist/ghidra/GhidraClient.js +91 -32
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +3 -5
- package/dist/ghidra/GhidraInstallation.js +40 -12
- package/dist/ghidra/GhidraJavaLaunch.js +6 -2
- package/dist/ghidra/GhidraLauncher.js +15 -7
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
- package/dist/ghidra/GhidraProviderClient.js +13 -3
- package/dist/ghidra/GhidraSessionError.js +2 -0
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +34 -45
- package/dist/hopper/HopperAnalysisProfile.js +3 -8
- package/dist/hopper/HopperCleanup.js +56 -27
- package/dist/hopper/HopperClient.js +86 -65
- package/dist/hopper/HopperMachOImage.js +3 -2
- package/dist/hopper/HopperProvider.js +16 -18
- package/dist/hopper/HopperRegexSearch.js +3 -6
- package/dist/hopper/HopperTargetLease.js +132 -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/V8InspectorCaptureProjection.js +1 -1
- package/dist/inspector/V8InspectorProvider.js +38 -28
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- 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/native/AppleMachoSelection.js +16 -6
- package/dist/native/CommandRunner.js +9 -7
- package/dist/native/LldbCallTracer.js +8 -2
- package/dist/native/NativeMacOSProvider.js +25 -15
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/process/DarwinProcessRunTokenReader.js +16 -2
- package/dist/process/ExecFileOutput.js +88 -6
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +1 -4
- package/dist/process/ProcessOwnershipObservation.js +11 -5
- package/dist/process/ProviderProcess.js +1 -3
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +13 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +158 -70
- 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 +25 -14
- package/dist/server/createServer.js +49 -36
- 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 -3
- 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 -2
- 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 +4 -5
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
- package/dist/server/registerBrowserScenarioTool.js +3 -4
- package/dist/server/registerBrowserTools.js +13 -16
- package/dist/server/registerBundleComparisonTool.js +5 -6
- package/dist/server/registerCloseLifecycleTool.js +2 -3
- package/dist/server/registerElectronTools.js +10 -13
- package/dist/server/registerEnhancedTools.js +23 -23
- package/dist/server/registerEvidenceTools.js +3 -4
- package/dist/server/registerEvmTools.js +2 -3
- package/dist/server/registerFirmwareTools.js +2 -3
- package/dist/server/registerFunctionComparisonTool.js +7 -8
- package/dist/server/registerInvestigationTools.js +14 -15
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
- package/dist/server/registerOfficialTools.js +4 -19
- package/dist/server/registerProcessComparisonTool.js +8 -8
- package/dist/server/registerRecordedCrashTools.js +2 -3
- package/dist/server/registerSessionRecordTools.js +15 -19
- package/dist/server/registerSessionStatusTool.js +3 -4
- package/dist/server/registerSessionTools.js +12 -18
- package/dist/server/registerWebModuleTool.js +2 -3
- package/dist/server/registerWebNetworkCaptureTool.js +2 -3
- package/dist/server/registerWebRuntimeTools.js +4 -5
- package/dist/server/registerWebScriptTool.js +2 -3
- package/dist/server/registerWebSourceLocationTool.js +2 -3
- package/dist/server/toolResult.js +66 -94
- package/dist/server/toolResultEncoding.js +11 -10
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- 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 +39 -30
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +9 -8
- 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 +16 -6
- 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/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -4,13 +4,11 @@ import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
|
4
4
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
5
5
|
import {} from "../domain/browserObservationErrors.js";
|
|
6
6
|
import { err, ok } from "../domain/result.js";
|
|
7
|
-
import { numberValue, recordValue, cdpStringValue, delayWithCancellation, } from "../browser/CdpCaptureValues.js";
|
|
7
|
+
import { numberValue, recordValue, cdpStringValue, scriptMetadataValues, delayWithCancellation, } from "../browser/CdpCaptureValues.js";
|
|
8
8
|
import { CdpConnection } from "../browser/CdpConnection.js";
|
|
9
9
|
import { authorizeRuntimeTargetLocation, inspectorExclusionKey, } from "./JavaScriptRuntimeScope.js";
|
|
10
10
|
import { createInspectorExclusionCounts, describeInspectorTargetLimitations, finalizeInspectorCapture, } from "./V8InspectorCaptureProjection.js";
|
|
11
11
|
import { discoverV8Inspector, } from "./V8InspectorEndpoint.js";
|
|
12
|
-
/** Public identity committed by passive V8 Inspector observations. */
|
|
13
|
-
export { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
|
|
14
12
|
import { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
|
|
15
13
|
/** Maximum decoded CDP message accepted while observing one Inspector target. */
|
|
16
14
|
export const INSPECTOR_MAX_PAYLOAD_BYTES = 16 * 1024 * 1024;
|
|
@@ -68,7 +66,7 @@ export class V8InspectorProvider {
|
|
|
68
66
|
assertRuntimeKind(target, input.runtime_kind);
|
|
69
67
|
connection = await CdpConnection.connect(target.webSocketUrl, "observe_javascript_runtime", options.signal, { maxPayloadBytes: INSPECTOR_MAX_PAYLOAD_BYTES });
|
|
70
68
|
const state = emptyCaptureState();
|
|
71
|
-
const removeListener = connection.onEvent((event) => ingestEvent(event,
|
|
69
|
+
const removeListener = connection.onEvent((event) => ingestEvent(event, state));
|
|
72
70
|
try {
|
|
73
71
|
await connection.send("Runtime.enable", {}, undefined, options.signal);
|
|
74
72
|
await connection.send("Debugger.enable", {}, undefined, options.signal);
|
|
@@ -102,7 +100,11 @@ export class V8InspectorProvider {
|
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
102
|
if (cleanupFailed) {
|
|
105
|
-
return err(inspectorCleanupError(primaryFailure, cleanupFailure, failed
|
|
103
|
+
return err(inspectorCleanupError(primaryFailure, cleanupFailure, failed, outcome?.ok === true
|
|
104
|
+
? outcome.value
|
|
105
|
+
: outcome?.ok === false
|
|
106
|
+
? outcome.error.partialObservation
|
|
107
|
+
: undefined));
|
|
106
108
|
}
|
|
107
109
|
return (outcome ??
|
|
108
110
|
err(new BrowserObservationError("observe_javascript_runtime", "protocol_error")));
|
|
@@ -132,11 +134,21 @@ export const closeInspectorConnection = async (connection, signal) => {
|
|
|
132
134
|
signal.removeEventListener("abort", onAbort);
|
|
133
135
|
}
|
|
134
136
|
};
|
|
135
|
-
export const inspectorCleanupError = (primaryFailure, cleanupFailure, hasPrimaryFailure) => {
|
|
137
|
+
export const inspectorCleanupError = (primaryFailure, cleanupFailure, hasPrimaryFailure, partialObservation) => {
|
|
136
138
|
const cause = hasPrimaryFailure
|
|
137
139
|
? new AggregateError([primaryFailure, cleanupFailure], "Inspector observation and cleanup both failed")
|
|
138
140
|
: cleanupFailure;
|
|
139
|
-
|
|
141
|
+
const cleanupReason = cleanupFailure instanceof Error
|
|
142
|
+
? cleanupFailure.message
|
|
143
|
+
: String(cleanupFailure);
|
|
144
|
+
return new BrowserObservationError("observe_javascript_runtime", "cleanup_failed", {
|
|
145
|
+
cause,
|
|
146
|
+
cleanup: {
|
|
147
|
+
reason: cleanupReason,
|
|
148
|
+
resources: ["browser_transport"],
|
|
149
|
+
},
|
|
150
|
+
...(partialObservation === undefined ? {} : { partialObservation }),
|
|
151
|
+
});
|
|
140
152
|
};
|
|
141
153
|
const projectTarget = (target) => ({
|
|
142
154
|
target_id: target.id,
|
|
@@ -177,7 +189,7 @@ const emptyCaptureState = () => ({
|
|
|
177
189
|
truncated: false,
|
|
178
190
|
truncationReasons: new Set(),
|
|
179
191
|
});
|
|
180
|
-
const ingestEvent = (event,
|
|
192
|
+
const ingestEvent = (event, state) => {
|
|
181
193
|
if (event.method !== "Debugger.scriptParsed" &&
|
|
182
194
|
event.method !== "Debugger.scriptFailedToParse" &&
|
|
183
195
|
event.method !== "Runtime.executionContextCreated" &&
|
|
@@ -186,7 +198,7 @@ const ingestEvent = (event, input, state) => {
|
|
|
186
198
|
return;
|
|
187
199
|
state.eventsObserved += 1;
|
|
188
200
|
if (event.method === "Debugger.scriptParsed") {
|
|
189
|
-
ingestScript(event,
|
|
201
|
+
ingestScript(event, state);
|
|
190
202
|
return;
|
|
191
203
|
}
|
|
192
204
|
if (event.method === "Debugger.scriptFailedToParse") {
|
|
@@ -194,9 +206,9 @@ const ingestEvent = (event, input, state) => {
|
|
|
194
206
|
retainEvent(state, 0);
|
|
195
207
|
return;
|
|
196
208
|
}
|
|
197
|
-
ingestContext(event,
|
|
209
|
+
ingestContext(event, state);
|
|
198
210
|
};
|
|
199
|
-
const ingestScript = (event,
|
|
211
|
+
const ingestScript = (event, state) => {
|
|
200
212
|
state.scriptsObserved += 1;
|
|
201
213
|
const value = recordValue(event.params);
|
|
202
214
|
const rawUrl = cdpStringValue(value?.url);
|
|
@@ -205,19 +217,20 @@ const ingestScript = (event, input, state) => {
|
|
|
205
217
|
retainEvent(state, 0);
|
|
206
218
|
return;
|
|
207
219
|
}
|
|
220
|
+
const metadata = scriptMetadataValues(value);
|
|
208
221
|
const draft = {
|
|
209
222
|
rawUrl,
|
|
210
223
|
executionContextKey: contextKey(value?.executionContextId),
|
|
211
|
-
cdpHash:
|
|
212
|
-
length:
|
|
213
|
-
isModule:
|
|
224
|
+
cdpHash: metadata.hash,
|
|
225
|
+
length: metadata.length,
|
|
226
|
+
isModule: metadata.isModule,
|
|
214
227
|
};
|
|
215
228
|
const bytes = retainedMetadataBytes(draft);
|
|
216
229
|
if (!retainEvent(state, bytes))
|
|
217
230
|
return;
|
|
218
231
|
state.scripts.push(draft);
|
|
219
232
|
};
|
|
220
|
-
const ingestContext = (event,
|
|
233
|
+
const ingestContext = (event, state) => {
|
|
221
234
|
if (event.method === "Runtime.executionContextsCleared") {
|
|
222
235
|
let byteDelta = 0;
|
|
223
236
|
for (const context of state.contexts.values()) {
|
|
@@ -243,17 +256,18 @@ const ingestContext = (event, input, state) => {
|
|
|
243
256
|
retainEvent(state, 0);
|
|
244
257
|
return;
|
|
245
258
|
}
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
: null;
|
|
259
|
+
const previous = state.contexts.get(key);
|
|
260
|
+
const created = event.method === "Runtime.executionContextCreated";
|
|
249
261
|
const draft = {
|
|
250
262
|
contextKey: key,
|
|
251
|
-
state:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
263
|
+
state: created ? "created" : "destroyed",
|
|
264
|
+
name: created
|
|
265
|
+
? (cdpStringValue(runtimeContext?.name) ?? null)
|
|
266
|
+
: (previous?.name ?? null),
|
|
267
|
+
origin: created
|
|
268
|
+
? (cdpStringValue(runtimeContext?.origin) ?? null)
|
|
269
|
+
: (previous?.origin ?? null),
|
|
255
270
|
};
|
|
256
|
-
const previous = state.contexts.get(key);
|
|
257
271
|
const bytes = retainedMetadataBytes(draft) -
|
|
258
272
|
(previous === undefined ? 0 : retainedMetadataBytes(previous));
|
|
259
273
|
if (!retainEvent(state, bytes))
|
|
@@ -294,14 +308,10 @@ const waitForCapture = async (connection, observationMs, signal) => {
|
|
|
294
308
|
const retainedMetadataBytes = (value) => {
|
|
295
309
|
const strings = "rawUrl" in value
|
|
296
310
|
? [value.rawUrl, value.rawUrl, value.executionContextKey, value.cdpHash]
|
|
297
|
-
: [value.contextKey, value.origin];
|
|
311
|
+
: [value.contextKey, value.name, value.origin];
|
|
298
312
|
return (RETAINED_OBJECT_OVERHEAD_BYTES +
|
|
299
313
|
strings.reduce((total, text) => total + (text?.length ?? 0) * 2, 0));
|
|
300
314
|
};
|
|
301
|
-
const nonnegativeInteger = (value) => {
|
|
302
|
-
const parsed = numberValue(value);
|
|
303
|
-
return parsed === undefined ? 0 : Math.max(0, Math.trunc(parsed));
|
|
304
|
-
};
|
|
305
315
|
const contextKey = (value) => {
|
|
306
316
|
const identifier = numberValue(value);
|
|
307
317
|
return identifier !== undefined && Number.isSafeInteger(identifier)
|
|
@@ -10,6 +10,7 @@ import { ProviderProcessSupervisor, spawnOwnedProviderProcess, } from "../../pro
|
|
|
10
10
|
import { checkRecoveryDeadline, inventoryRecoveryFiles, fingerprintRecoveryFile, recoveryFailureMessage, } from "./RecoveryFiles.js";
|
|
11
11
|
import { RECOVERY_LIMITS } from "./WakaruRelease.js";
|
|
12
12
|
const OPERATION = "recover_javascript_sources";
|
|
13
|
+
const WAKARU_REQUIREMENT = "Provide an absolute REA_WAKARU_COMMAND pointing to Wakaru 1.13.0 on Linux x64; no tool is installed by REA";
|
|
13
14
|
/** Resolve and fingerprint explicitly configured tools; acquire nothing at startup. */
|
|
14
15
|
export const resolveWakaruCommand = async (environment) => {
|
|
15
16
|
const configured = environment.REA_WAKARU_COMMAND;
|
|
@@ -17,7 +18,7 @@ export const resolveWakaruCommand = async (environment) => {
|
|
|
17
18
|
process.arch !== "x64" ||
|
|
18
19
|
configured === undefined ||
|
|
19
20
|
!isAbsolute(configured))
|
|
20
|
-
throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION,
|
|
21
|
+
throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, WAKARU_REQUIREMENT, { userMessage: WAKARU_REQUIREMENT });
|
|
21
22
|
try {
|
|
22
23
|
const command = await realpath(configured);
|
|
23
24
|
await access(command, constants.R_OK | constants.X_OK);
|
|
@@ -29,7 +30,11 @@ export const resolveWakaruCommand = async (environment) => {
|
|
|
29
30
|
return { command, limiter, ...fingerprint };
|
|
30
31
|
}
|
|
31
32
|
catch (cause) {
|
|
32
|
-
|
|
33
|
+
const reason = `Configured Wakaru or util-linux prlimit is unavailable: ${recoveryFailureMessage(cause)}`;
|
|
34
|
+
throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, reason, {
|
|
35
|
+
cause,
|
|
36
|
+
userMessage: reason,
|
|
37
|
+
});
|
|
33
38
|
}
|
|
34
39
|
};
|
|
35
40
|
/** Run one bounded command and verify cleanup before consuming its output. */
|
|
@@ -30,8 +30,11 @@ const executeWakaruRecovery = async (context) => {
|
|
|
30
30
|
arguments: ["--version"],
|
|
31
31
|
});
|
|
32
32
|
if (version.exit_code !== 0 ||
|
|
33
|
-
version.stdout.trim() !== `wakaru ${WAKARU_RELEASE.version}`)
|
|
34
|
-
|
|
33
|
+
version.stdout.trim() !== `wakaru ${WAKARU_RELEASE.version}`) {
|
|
34
|
+
// The message names the mismatch; the reason also keeps the tool's stderr.
|
|
35
|
+
const mismatch = `This adapter requires Wakaru ${WAKARU_RELEASE.version}; reported version: ${version.stdout.trim()}; exit: ${String(version.exit_code)}`;
|
|
36
|
+
throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, `${mismatch}; stderr: ${version.stderr}`, { userMessage: `${mismatch}.` });
|
|
37
|
+
}
|
|
35
38
|
const run = await runWakaruCommand({
|
|
36
39
|
...commandContext,
|
|
37
40
|
staging,
|
package/dist/main/shutdown.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
2
|
+
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
1
3
|
import { MCP_SHUTDOWN_FAILED } from "./messages.js";
|
|
2
4
|
export const createShutdown = (input) => {
|
|
3
|
-
const { handle, session,
|
|
5
|
+
const { handle, session, dependencies, serverLogger } = input;
|
|
4
6
|
let shutdownPromise;
|
|
5
7
|
let unregisterShutdown = () => undefined;
|
|
6
8
|
const shutdown = async () => {
|
|
7
9
|
shutdownPromise ??= (async () => {
|
|
8
|
-
unregisterReload();
|
|
9
10
|
unregisterShutdown();
|
|
10
11
|
const results = await Promise.allSettled([
|
|
11
12
|
handle.close(),
|
|
12
13
|
input.closeAndroid?.(),
|
|
13
|
-
session.close({ retainProviderDocuments: true })
|
|
14
|
+
session.close({ retainProviderDocuments: true }).then((closed) => {
|
|
15
|
+
if (!closed.ok)
|
|
16
|
+
throw closed.error;
|
|
17
|
+
}),
|
|
14
18
|
]);
|
|
15
19
|
for (const result of results)
|
|
16
20
|
if (result.status === "rejected")
|
|
@@ -24,12 +28,16 @@ export const createShutdown = (input) => {
|
|
|
24
28
|
dependencies.setExitCode(1);
|
|
25
29
|
serverLogger.error(MCP_SHUTDOWN_FAILED);
|
|
26
30
|
dependencies.writeStderr(`${MCP_SHUTDOWN_FAILED}\n`);
|
|
31
|
+
if (cause instanceof AnalysisError)
|
|
32
|
+
dependencies.writeStderr(`${projectAnalysisError(cause).message}\n`);
|
|
27
33
|
});
|
|
28
34
|
};
|
|
29
35
|
unregisterShutdown = dependencies.registerShutdown(requestShutdown);
|
|
30
36
|
return { shutdown, request: requestShutdown };
|
|
31
37
|
};
|
|
32
38
|
const describeShutdownFailure = (cause) => {
|
|
39
|
+
if (cause instanceof AnalysisError)
|
|
40
|
+
return { analysis_error: projectAnalysisError(cause) };
|
|
33
41
|
if (cause instanceof Error) {
|
|
34
42
|
const code = "code" in cause ? cause.code : undefined;
|
|
35
43
|
return {
|
package/dist/main/startup.js
CHANGED
|
@@ -7,8 +7,15 @@ export const openInitialTarget = async (session, config, serverLogger, writeStde
|
|
|
7
7
|
});
|
|
8
8
|
if (opened.ok)
|
|
9
9
|
return { ok: true };
|
|
10
|
-
await session.close();
|
|
11
|
-
serverLogger.error({
|
|
10
|
+
const closed = await session.close();
|
|
11
|
+
serverLogger.error({
|
|
12
|
+
error: projectAnalysisError(opened.error),
|
|
13
|
+
...(closed.ok
|
|
14
|
+
? {}
|
|
15
|
+
: { cleanup_error: projectAnalysisError(closed.error) }),
|
|
16
|
+
}, "Initial target failed to open");
|
|
12
17
|
writeStderr(`${projectAnalysisError(opened.error).message}\n`);
|
|
18
|
+
if (!closed.ok)
|
|
19
|
+
writeStderr(`${projectAnalysisError(closed.error).message}\n`);
|
|
13
20
|
return { ok: false, exitCode: 1 };
|
|
14
21
|
};
|
package/dist/main/transport.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createAndroidAnalysisProvider } from "../composition/android.js";
|
|
2
2
|
import { createServer } from "../server/createServer.js";
|
|
3
|
+
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
3
4
|
import { MCP_CONNECTION_LOST, MCP_CONNECTION_START_FAILED, } from "./messages.js";
|
|
4
5
|
export const startMcpTransport = async (dependencies, session, serverContext) => {
|
|
5
6
|
const { serverLogger } = serverContext;
|
|
@@ -26,10 +27,12 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
|
|
|
26
27
|
try {
|
|
27
28
|
handle = dependencies.serve(() => {
|
|
28
29
|
// The SDK can discard a discovery probe and construct a replacement server.
|
|
29
|
-
const android = createAndroidAnalysisProvider(
|
|
30
|
+
const android = createAndroidAnalysisProvider(serverContext.environment);
|
|
30
31
|
androidProviders.push(android);
|
|
31
32
|
return (dependencies.createServer ?? createServer)(session, session, {
|
|
32
33
|
logger: serverContext.logger,
|
|
34
|
+
environment: serverContext.environment,
|
|
35
|
+
delivery: serverContext.delivery,
|
|
33
36
|
...optionalProviders,
|
|
34
37
|
androidAnalysis: android,
|
|
35
38
|
});
|
|
@@ -41,11 +44,28 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
|
|
|
41
44
|
});
|
|
42
45
|
}
|
|
43
46
|
catch (cause) {
|
|
44
|
-
await Promise.allSettled([
|
|
47
|
+
const [binaryCleanup, androidCleanup] = await Promise.allSettled([
|
|
48
|
+
session.close(),
|
|
49
|
+
closeAndroid(),
|
|
50
|
+
]);
|
|
45
51
|
serverLogger.error({
|
|
46
52
|
error: cause instanceof Error ? cause.message : String(cause),
|
|
47
53
|
}, MCP_CONNECTION_START_FAILED);
|
|
48
54
|
dependencies.writeStderr(`${MCP_CONNECTION_START_FAILED}\n`);
|
|
55
|
+
if (binaryCleanup.status === "fulfilled" && !binaryCleanup.value.ok) {
|
|
56
|
+
const cleanupError = projectAnalysisError(binaryCleanup.value.error);
|
|
57
|
+
serverLogger.error({ cleanup_error: cleanupError }, "Binary provider cleanup failed after MCP startup");
|
|
58
|
+
dependencies.writeStderr(`${cleanupError.message}\n`);
|
|
59
|
+
}
|
|
60
|
+
for (const cleanup of [binaryCleanup, androidCleanup]) {
|
|
61
|
+
if (cleanup.status === "rejected") {
|
|
62
|
+
const reason = cleanup.reason instanceof Error
|
|
63
|
+
? cleanup.reason.message
|
|
64
|
+
: String(cleanup.reason);
|
|
65
|
+
serverLogger.error({ cleanup_error: reason }, "Provider cleanup rejected after MCP startup");
|
|
66
|
+
dependencies.writeStderr(`Provider cleanup failed: ${reason}\n`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
49
69
|
return { ok: false };
|
|
50
70
|
}
|
|
51
71
|
return { ok: true, handle, closeAndroid };
|
package/dist/main.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { snapshotEnvironment } from "./process/snapshotEnvironment.js";
|
|
2
3
|
import { pathToFileURL } from "node:url";
|
|
3
4
|
import { realpathSync } from "node:fs";
|
|
4
5
|
import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
5
|
-
import { parseConfig } from "./config.js";
|
|
6
|
+
import { parseConfig } from "./config/parseConfig.js";
|
|
6
7
|
import { createBinarySession } from "./composition/binary.js";
|
|
7
8
|
import { createLogger } from "./logger.js";
|
|
8
9
|
import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
|
|
9
10
|
import { SERVER_START_FAILED } from "./main/messages.js";
|
|
10
|
-
import { createRuntimeState } from "./main/state.js";
|
|
11
11
|
import { openInitialTarget } from "./main/startup.js";
|
|
12
12
|
import { startMcpTransport } from "./main/transport.js";
|
|
13
|
-
import { loadOptionalObservationProviders } from "./composition/optionalObservationProviders.js";
|
|
14
|
-
import {
|
|
13
|
+
import { createOptionalObservationFactories, loadOptionalObservationProviders, } from "./composition/optionalObservationProviders.js";
|
|
14
|
+
import { createToolResultDelivery } from "./server/toolResult.js";
|
|
15
15
|
import { createShutdown } from "./main/shutdown.js";
|
|
16
16
|
const runtimeDependencies = () => ({
|
|
17
17
|
env: process.env,
|
|
@@ -32,10 +32,6 @@ const runtimeDependencies = () => ({
|
|
|
32
32
|
process.stdin.off("close", handler);
|
|
33
33
|
};
|
|
34
34
|
},
|
|
35
|
-
registerReload: (handler) => {
|
|
36
|
-
process.on("SIGHUP", handler);
|
|
37
|
-
return () => process.off("SIGHUP", handler);
|
|
38
|
-
},
|
|
39
35
|
});
|
|
40
36
|
/**
|
|
41
37
|
* Start the long-lived MCP adapter and install idempotent shutdown handlers.
|
|
@@ -43,35 +39,32 @@ const runtimeDependencies = () => ({
|
|
|
43
39
|
* signals close bridge resources without assuming ownership of the Hopper app.
|
|
44
40
|
*/
|
|
45
41
|
export const run = async (dependencies = runtimeDependencies()) => {
|
|
46
|
-
const
|
|
42
|
+
const environment = snapshotEnvironment(dependencies.env);
|
|
43
|
+
const config = parseConfig(environment);
|
|
47
44
|
if (!config.ok) {
|
|
48
45
|
dependencies.writeStderr(`${projectAnalysisError(config.error).message}\n`);
|
|
49
46
|
return 1;
|
|
50
47
|
}
|
|
51
48
|
const logger = createLogger("mcp", config.value.logLevel);
|
|
52
49
|
const serverLogger = logger.child({ layer: "server" });
|
|
53
|
-
const session = createBinarySession(config.value, logger);
|
|
50
|
+
const session = createBinarySession(config.value, logger, environment);
|
|
54
51
|
const opened = await openInitialTarget(session, config.value, serverLogger, dependencies.writeStderr);
|
|
55
52
|
if (!opened.ok)
|
|
56
53
|
return opened.exitCode;
|
|
57
|
-
const runtimeState = createRuntimeState(config.value);
|
|
58
54
|
const transport = await startMcpTransport(dependencies, session, {
|
|
59
55
|
logger,
|
|
60
56
|
serverLogger,
|
|
61
|
-
|
|
57
|
+
environment,
|
|
58
|
+
delivery: createToolResultDelivery(config.value.mcpMaxResponseBytes),
|
|
59
|
+
loadOptionalProviders: dependencies.loadOptionalProviders ??
|
|
60
|
+
(() => loadOptionalObservationProviders(createOptionalObservationFactories(environment))),
|
|
62
61
|
});
|
|
63
62
|
if (!transport.ok)
|
|
64
63
|
return 1;
|
|
65
|
-
const unregisterReload = registerConfigReload({
|
|
66
|
-
dependencies,
|
|
67
|
-
runtimeState,
|
|
68
|
-
serverLogger,
|
|
69
|
-
});
|
|
70
64
|
createShutdown({
|
|
71
65
|
handle: transport.handle,
|
|
72
66
|
closeAndroid: transport.closeAndroid,
|
|
73
67
|
session,
|
|
74
|
-
unregisterReload,
|
|
75
68
|
dependencies,
|
|
76
69
|
serverLogger,
|
|
77
70
|
});
|
|
@@ -182,9 +182,14 @@ const collectFixupCommand = (bytes, { cursor, kind, size }, state) => {
|
|
|
182
182
|
throw new RangeError("Fixup data exceeds the Mach-O slice");
|
|
183
183
|
return { offset, size: length };
|
|
184
184
|
};
|
|
185
|
-
if (kind === LC_DYLD_CHAINED_FIXUPS
|
|
185
|
+
if (kind === LC_DYLD_CHAINED_FIXUPS) {
|
|
186
|
+
if (size < 16)
|
|
187
|
+
throw new RangeError("Truncated chained-fixups command");
|
|
186
188
|
state.chained = range(cursor + 8);
|
|
187
|
-
|
|
189
|
+
}
|
|
190
|
+
else if (kind === LC_DYLD_INFO || kind === LC_DYLD_INFO_ONLY) {
|
|
191
|
+
if (size < 48)
|
|
192
|
+
throw new RangeError("Truncated dyld-info command");
|
|
188
193
|
for (const [at, stream] of [
|
|
189
194
|
[cursor + 16, "bind"],
|
|
190
195
|
[cursor + 24, "weak"],
|
|
@@ -194,11 +199,16 @@ const collectFixupCommand = (bytes, { cursor, kind, size }, state) => {
|
|
|
194
199
|
if (bound.size > 0)
|
|
195
200
|
state.binds.push({ ...bound, stream });
|
|
196
201
|
}
|
|
197
|
-
|
|
202
|
+
}
|
|
203
|
+
else if (DYLIB_COMMANDS.includes(kind)) {
|
|
204
|
+
if (size < 24)
|
|
205
|
+
throw new RangeError("Truncated dylib command");
|
|
198
206
|
const nameOffset = bytes.readUInt32LE(cursor + 8);
|
|
207
|
+
if (nameOffset < 24 || nameOffset >= size)
|
|
208
|
+
throw new RangeError("Dylib install name is outside its load command");
|
|
199
209
|
const end = bytes.indexOf(0, cursor + nameOffset);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
210
|
+
if (end < 0 || end >= cursor + size)
|
|
211
|
+
throw new RangeError("Unterminated dylib install name");
|
|
212
|
+
state.dylibs.push(bytes.toString("utf8", cursor + nameOffset, end));
|
|
203
213
|
}
|
|
204
214
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
|
|
1
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
3
|
import { createReadStream } from "node:fs";
|
|
3
4
|
import { realpath } from "node:fs/promises";
|
|
@@ -28,8 +29,10 @@ export class NativeCommandFailure extends Error {
|
|
|
28
29
|
/** Run allowlisted Xcode tools directly without a shell. */
|
|
29
30
|
export class XcrunCommandRunner {
|
|
30
31
|
resolveTool;
|
|
31
|
-
|
|
32
|
+
environment;
|
|
33
|
+
constructor(environment, resolveTool = (tool, signal) => resolveXcrunTool(tool, this.environment, signal)) {
|
|
32
34
|
this.resolveTool = resolveTool;
|
|
35
|
+
this.environment = snapshotEnvironment(environment);
|
|
33
36
|
}
|
|
34
37
|
run(tool, arguments_, options) {
|
|
35
38
|
if (!ALLOWED_TOOLS.has(tool))
|
|
@@ -37,7 +40,7 @@ export class XcrunCommandRunner {
|
|
|
37
40
|
return this.resolveTool(tool, options.signal).then(async (resolved) => {
|
|
38
41
|
if (!resolved.ok)
|
|
39
42
|
return resolved;
|
|
40
|
-
const captured = await captureProcess(resolved.value.path, arguments_, tool, options);
|
|
43
|
+
const captured = await captureProcess(resolved.value.path, arguments_, tool, options, this.environment);
|
|
41
44
|
return captured.ok
|
|
42
45
|
? ok({
|
|
43
46
|
...captured.value,
|
|
@@ -66,8 +69,8 @@ const ALLOWED_TOOLS = new Set([
|
|
|
66
69
|
"vtool",
|
|
67
70
|
]);
|
|
68
71
|
/** Locate an Xcode tool through `xcrun --find` and sample its executable digest. */
|
|
69
|
-
export const resolveXcrunTool = async (tool, signal) => {
|
|
70
|
-
const found = await captureProcess("/usr/bin/xcrun", ["--find", tool], "xcrun", signal === undefined ? {} : { signal });
|
|
72
|
+
export const resolveXcrunTool = async (tool, environment, signal) => {
|
|
73
|
+
const found = await captureProcess("/usr/bin/xcrun", ["--find", tool], "xcrun", signal === undefined ? {} : { signal }, environment);
|
|
71
74
|
if (!found.ok) {
|
|
72
75
|
return err(new NativeCommandFailure(tool, found.error.reason === "nonzero-exit" ||
|
|
73
76
|
found.error.reason === "unavailable"
|
|
@@ -99,7 +102,7 @@ const failureCapture = (capture, truncated) => ({
|
|
|
99
102
|
signal: capture.signal,
|
|
100
103
|
truncated,
|
|
101
104
|
});
|
|
102
|
-
const captureProcess = async (executable, arguments_, tool, options) => {
|
|
105
|
+
const captureProcess = async (executable, arguments_, tool, options, environment) => {
|
|
103
106
|
const runId = `rea-native-command-${randomUUID()}`;
|
|
104
107
|
try {
|
|
105
108
|
const snapshot = await runOwnedCommand({
|
|
@@ -107,11 +110,10 @@ const captureProcess = async (executable, arguments_, tool, options) => {
|
|
|
107
110
|
arguments: [...arguments_],
|
|
108
111
|
runId,
|
|
109
112
|
env: {
|
|
110
|
-
PATH: "/usr/bin:/bin:/usr/sbin:/sbin",
|
|
111
113
|
LC_ALL: "C",
|
|
112
114
|
LANG: "C",
|
|
113
115
|
},
|
|
114
|
-
hostEnvironment:
|
|
116
|
+
hostEnvironment: environment,
|
|
115
117
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
116
118
|
}, {
|
|
117
119
|
timeoutMs: NATIVE_COMMAND_TIMEOUT_MS,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
|
|
1
2
|
import { randomUUID } from "node:crypto";
|
|
2
3
|
import { open, readFile, writeFile } from "node:fs/promises";
|
|
3
4
|
import { join } from "node:path";
|
|
@@ -18,6 +19,7 @@ import { resolveXcrunTool } from "./CommandRunner.js";
|
|
|
18
19
|
import { readLldbObservationJournal, readBoundedPrefix, readPartialCapture, projectLldbPartialObservation, } from "./LldbRetainedObservations.js";
|
|
19
20
|
const OPERATION = "observe_native_calls";
|
|
20
21
|
const PROVIDER = "native-macos";
|
|
22
|
+
const LLDB_REQUIREMENT = "LLDB from Xcode or the Command Line Tools is not available";
|
|
21
23
|
/** Captured target output kept per stream; the rest is counted, not stored. */
|
|
22
24
|
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
23
25
|
/** LLDB startup, symbol loading and teardown beyond the observation window. */
|
|
@@ -90,16 +92,18 @@ const ATTACH_REMEDIATION = "Allow debugging for this user (Developer Tools acces
|
|
|
90
92
|
export class LldbCallTracer {
|
|
91
93
|
launch;
|
|
92
94
|
resolveTool;
|
|
93
|
-
|
|
95
|
+
environment;
|
|
96
|
+
constructor(environment, launch = runLldb, resolveTool = (tool, signal) => resolveXcrunTool(tool, this.environment, signal)) {
|
|
94
97
|
this.launch = launch;
|
|
95
98
|
this.resolveTool = resolveTool;
|
|
99
|
+
this.environment = snapshotEnvironment(environment);
|
|
96
100
|
}
|
|
97
101
|
async trace(request, signal) {
|
|
98
102
|
const lldb = await this.resolveTool("lldb", signal);
|
|
99
103
|
if (!lldb.ok)
|
|
100
104
|
return err(lldb.error.reason === "cancelled"
|
|
101
105
|
? new AnalysisCancelledError(OPERATION)
|
|
102
|
-
: new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION,
|
|
106
|
+
: new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION, LLDB_REQUIREMENT, { userMessage: LLDB_REQUIREMENT }));
|
|
103
107
|
const root = await PrivateRuntimeRoot.create({ prefix: "rea-lldb-" });
|
|
104
108
|
try {
|
|
105
109
|
return await this.#run(lldb.value, root.path, request, signal);
|
|
@@ -158,6 +162,7 @@ export class LldbCallTracer {
|
|
|
158
162
|
deadlineMs: input.duration_ms + DEADLINE_GRACE_MS,
|
|
159
163
|
pidPath: paths.pid,
|
|
160
164
|
identityAckPath: paths.identityAck,
|
|
165
|
+
environment: this.environment,
|
|
161
166
|
...(signal === undefined ? {} : { signal }),
|
|
162
167
|
});
|
|
163
168
|
const output = exited.kind === "exited"
|
|
@@ -402,6 +407,7 @@ const runLldb = async (executable, arguments_, options) => {
|
|
|
402
407
|
runId: randomUUID(),
|
|
403
408
|
expectedCommand: executable,
|
|
404
409
|
signal: deadline.signal,
|
|
410
|
+
hostEnvironment: options.environment,
|
|
405
411
|
});
|
|
406
412
|
supervisor = new ProviderProcessSupervisor({
|
|
407
413
|
...launched,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
|
|
1
2
|
import { NATIVE_MACOS_PROVIDER_IDENTITY as IDENTITY, nativeMacOSCapabilities, } from "./NativeMacOSProviderMetadata.js";
|
|
2
|
-
export { NATIVE_MACOS_PROVIDER_IDENTITY } from "./NativeMacOSProviderMetadata.js";
|
|
3
3
|
import { inspectAppleDispatchMetadata } from "./AppleDispatchMetadata.js";
|
|
4
4
|
import { observeNativeUi } from "./NativeUiObservation.js";
|
|
5
5
|
import { LldbCallTracer } from "./LldbCallTracer.js";
|
|
@@ -9,6 +9,8 @@ import { open, realpath, stat } from "node:fs/promises";
|
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
11
11
|
import { NATIVE_TOOL_CONTRACTS, } from "../contracts/native/nativeToolContracts.js";
|
|
12
|
+
import { toolContract } from "../contracts/toolContracts.js";
|
|
13
|
+
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
|
12
14
|
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, AnalysisResourceConstraintError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
|
|
13
15
|
import { BinaryTargetError } from "../domain/configurationErrors.js";
|
|
14
16
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
@@ -29,9 +31,11 @@ export class NativeMacOSProvider {
|
|
|
29
31
|
runner;
|
|
30
32
|
tracer;
|
|
31
33
|
#capabilities;
|
|
32
|
-
|
|
34
|
+
#environment;
|
|
35
|
+
constructor(environment, runner = new XcrunCommandRunner(environment), platform = process.platform, tracer = new LldbCallTracer(environment)) {
|
|
33
36
|
this.runner = runner;
|
|
34
37
|
this.tracer = tracer;
|
|
38
|
+
this.#environment = snapshotEnvironment(environment, platform);
|
|
35
39
|
this.#capabilities = nativeMacOSCapabilities(platform);
|
|
36
40
|
}
|
|
37
41
|
identity() {
|
|
@@ -41,17 +45,19 @@ export class NativeMacOSProvider {
|
|
|
41
45
|
return this.#capabilities;
|
|
42
46
|
}
|
|
43
47
|
createClient(target) {
|
|
44
|
-
return new NativeMacOSClient(target, this.runner, this.tracer);
|
|
48
|
+
return new NativeMacOSClient(target, this.runner, this.tracer, this.#environment);
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
51
|
class NativeMacOSClient {
|
|
48
52
|
target;
|
|
49
53
|
runner;
|
|
50
54
|
tracer;
|
|
51
|
-
|
|
55
|
+
environment;
|
|
56
|
+
constructor(target, runner, tracer, environment) {
|
|
52
57
|
this.target = target;
|
|
53
58
|
this.runner = runner;
|
|
54
59
|
this.tracer = tracer;
|
|
60
|
+
this.environment = environment;
|
|
55
61
|
}
|
|
56
62
|
async execute(operation, parameters, options) {
|
|
57
63
|
if (options?.signal?.aborted === true)
|
|
@@ -59,16 +65,15 @@ class NativeMacOSClient {
|
|
|
59
65
|
if (operation === "health")
|
|
60
66
|
return ok(createAnalysisExecution(null, IDENTITY));
|
|
61
67
|
if (operation === "inspect_native_dispatch_metadata") {
|
|
68
|
+
const input = toolContract(operation).inputSchema.safeParse(parameters);
|
|
69
|
+
if (!input.success)
|
|
70
|
+
return err(analysisInputErrorFromIssues(operation, input.error.issues, parameters, {
|
|
71
|
+
cause: input.error,
|
|
72
|
+
}));
|
|
62
73
|
if (this.target.kind !== "executable" || this.target.format !== "mach-o")
|
|
63
74
|
return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, "Binary Apple metadata requires Mach-O; other providers can report symbol-only metadata"));
|
|
64
75
|
try {
|
|
65
|
-
const
|
|
66
|
-
.number()
|
|
67
|
-
.int()
|
|
68
|
-
.min(1)
|
|
69
|
-
.max(20000)
|
|
70
|
-
.parse(parameters.max_records ?? 5000);
|
|
71
|
-
const result = await inspectAppleDispatchMetadata(this.target, maxRecords, options?.signal);
|
|
76
|
+
const result = await inspectAppleDispatchMetadata(this.target, input.data.max_records, options?.signal);
|
|
72
77
|
return ok(createAnalysisExecution(result, result.provider, {
|
|
73
78
|
locations: [{ kind: "artifact-path", path: this.target.path }],
|
|
74
79
|
limitations: result.result.coverage.flatMap(({ reason }) => reason === null ? [] : [reason]),
|
|
@@ -102,6 +107,7 @@ class NativeMacOSClient {
|
|
|
102
107
|
if (operation === "observe_native_ui" ||
|
|
103
108
|
operation === "capture_native_ui_scenario") {
|
|
104
109
|
const result = await observeNativeUi(this.target, operation, parameters, {
|
|
110
|
+
environment: this.environment,
|
|
105
111
|
signal: options?.signal,
|
|
106
112
|
});
|
|
107
113
|
return result.ok
|
|
@@ -127,7 +133,7 @@ class NativeMacOSClient {
|
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
close() {
|
|
130
|
-
return Promise.resolve();
|
|
136
|
+
return Promise.resolve(ok(null));
|
|
131
137
|
}
|
|
132
138
|
#dispatch(operation, parameters, signal) {
|
|
133
139
|
switch (operation) {
|
|
@@ -424,8 +430,10 @@ const translateCommandFailure = (operation, failure) => {
|
|
|
424
430
|
...(capturedOutput === undefined ? {} : { capturedOutput }),
|
|
425
431
|
...(cleanup === undefined ? {} : { cleanup }),
|
|
426
432
|
};
|
|
427
|
-
if (failure.reason === "unavailable")
|
|
428
|
-
|
|
433
|
+
if (failure.reason === "unavailable") {
|
|
434
|
+
const reason = `${failure.tool} is unavailable through xcrun.`;
|
|
435
|
+
return new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, reason, { ...errorOptions, userMessage: reason });
|
|
436
|
+
}
|
|
429
437
|
if (failure.reason === "cancelled")
|
|
430
438
|
return new AnalysisCancelledError(operation, errorOptions);
|
|
431
439
|
if (failure.reason === "timeout")
|
|
@@ -513,8 +521,10 @@ const parseEntitlements = (output) => {
|
|
|
513
521
|
*/
|
|
514
522
|
const unreadablePlist = (path, requested, reason) => {
|
|
515
523
|
const sentence = reason.endsWith(".") ? reason : `${reason}.`;
|
|
524
|
+
// Name the default that is missing and the selection that still works.
|
|
525
|
+
const missingDefault = `The target has no readable Contents/Info.plist at ${path}: ${sentence} Select another plist in the target with the path input (CLI: --relative-path).`;
|
|
516
526
|
return requested === undefined
|
|
517
|
-
? new AnalysisCapabilityUnavailableError(IDENTITY.id, "inspect_plist",
|
|
527
|
+
? new AnalysisCapabilityUnavailableError(IDENTITY.id, "inspect_plist", missingDefault, { userMessage: missingDefault })
|
|
518
528
|
: new AnalysisInputError("inspect_plist", undefined, [
|
|
519
529
|
{
|
|
520
530
|
path: ["path"],
|