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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { reconcileCapturedWebScript, stableWebScriptKey, } from "../domain/webInventory.js";
|
|
2
|
-
import {
|
|
2
|
+
import { requiredScriptSource, sourceExcluded, sourceResult, } from "./CdpCaptureValues.js";
|
|
3
3
|
export const captureScripts = async (options) => {
|
|
4
4
|
const { context, events, rawResources, resources, frameIds } = options;
|
|
5
5
|
const state = {
|
|
@@ -42,8 +42,7 @@ const buildScriptDraft = async (script, state) => {
|
|
|
42
42
|
};
|
|
43
43
|
const captureScriptSource = async (script, state) => {
|
|
44
44
|
const { context } = state;
|
|
45
|
-
const
|
|
46
|
-
const content = cdpStringValue(result.scriptSource) ?? "";
|
|
45
|
+
const content = requiredScriptSource(await context.connection.send("Debugger.getScriptSource", { scriptId: script.scriptId }, context.sessionId, context.signal), context.operation);
|
|
47
46
|
return sourceResult(content);
|
|
48
47
|
};
|
|
49
48
|
const keyAndBuildInventory = (drafts, scriptCount) => {
|
|
@@ -56,7 +56,7 @@ const parseCsp = (value, baseUrl, allowedOrigins) => {
|
|
|
56
56
|
for (const rawDirective of (value ?? "").split(";")) {
|
|
57
57
|
const [rawName, ...tokens] = rawDirective.trim().split(/\s+/u);
|
|
58
58
|
const name = (rawName ?? "").toLowerCase();
|
|
59
|
-
if (!/^[a-z][a-z0-9
|
|
59
|
+
if (!/^[a-z][a-z0-9\x2d]*$/u.test(name))
|
|
60
60
|
continue;
|
|
61
61
|
const sources = [];
|
|
62
62
|
for (const token of tokens) {
|
|
@@ -79,9 +79,9 @@ const parseCsp = (value, baseUrl, allowedOrigins) => {
|
|
|
79
79
|
};
|
|
80
80
|
const cspSource = (token, baseUrl, allowedOrigins) => {
|
|
81
81
|
const lower = token.toLowerCase();
|
|
82
|
-
if (/^'[a-z0-9
|
|
82
|
+
if (/^'[a-z0-9\x2d]+'$/u.test(lower))
|
|
83
83
|
return { kind: "keyword", value: lower };
|
|
84
|
-
if (/^[a-z][a-z0-9
|
|
84
|
+
if (/^[a-z][a-z0-9+.\x2d]*:$/u.test(lower))
|
|
85
85
|
return { kind: "scheme", value: lower };
|
|
86
86
|
const hostOrigin = cspHostSourceOrigin(token, baseUrl);
|
|
87
87
|
if (hostOrigin === undefined)
|
|
@@ -98,14 +98,14 @@ const cspSource = (token, baseUrl, allowedOrigins) => {
|
|
|
98
98
|
* `undefined` when the token is not a host-source at all.
|
|
99
99
|
*/
|
|
100
100
|
const cspHostSourceOrigin = (token, baseUrl) => {
|
|
101
|
-
const match = /^(?:([a-z][a-z0-9
|
|
101
|
+
const match = /^(?:([a-z][a-z0-9+.\x2d]*):\/\/)?([^\x2f?#]+)(?:\/[^?#]*)?$/iu.exec(token);
|
|
102
102
|
const authority = match?.[2];
|
|
103
103
|
if (authority === undefined || authority.length === 0)
|
|
104
104
|
return undefined;
|
|
105
105
|
const scheme = (match?.[1] ?? schemeOf(baseUrl))?.toLowerCase();
|
|
106
|
-
if (scheme === undefined || !/^[a-z][a-z0-9
|
|
106
|
+
if (scheme === undefined || !/^[a-z][a-z0-9+.\x2d]*$/u.test(scheme))
|
|
107
107
|
return undefined;
|
|
108
|
-
if (!/^(?:\*|(?:\*\.)?[a-z0-9
|
|
108
|
+
if (!/^(?:\*|(?:\*\.)?[a-z0-9\x2d]+(?:\.[a-z0-9\x2d]+)*\.?)(?::(?:\*|\d+))?$/iu.test(authority))
|
|
109
109
|
return undefined;
|
|
110
110
|
if (authority.includes("*"))
|
|
111
111
|
return null;
|
|
@@ -194,7 +194,7 @@ const linkParameters = (value) => {
|
|
|
194
194
|
const name = (separator < 0 ? raw : raw.slice(0, separator))
|
|
195
195
|
.trim()
|
|
196
196
|
.toLowerCase();
|
|
197
|
-
if (!/^[a-z][a-z0-9
|
|
197
|
+
if (!/^[a-z][a-z0-9\x2d]*$/u.test(name))
|
|
198
198
|
continue;
|
|
199
199
|
const parameter = separator < 0 ? "" : raw.slice(separator + 1).trim();
|
|
200
200
|
parameters.set(name, unquote(parameter));
|
|
@@ -221,7 +221,7 @@ const permissionFeatures = (value) => [
|
|
|
221
221
|
...new Set((value ?? "")
|
|
222
222
|
.split(",")
|
|
223
223
|
.map((entry) => entry.split("=", 1)[0]?.trim().toLowerCase() ?? "")
|
|
224
|
-
.filter((feature) => /^[a-z][a-z0-9
|
|
224
|
+
.filter((feature) => /^[a-z][a-z0-9\x2d]*$/u.test(feature))),
|
|
225
225
|
].sort();
|
|
226
226
|
const wellKnownHint = (url) => {
|
|
227
227
|
try {
|
|
@@ -259,7 +259,7 @@ const referrerPolicy = (value) => {
|
|
|
259
259
|
const token = raw.trim().toLowerCase();
|
|
260
260
|
if (token === "")
|
|
261
261
|
continue;
|
|
262
|
-
if (!/^[a-z
|
|
262
|
+
if (!/^[a-z\x2d]+$/u.test(token))
|
|
263
263
|
return null;
|
|
264
264
|
if (referrerPolicies.has(token))
|
|
265
265
|
policy = token;
|
|
@@ -268,7 +268,7 @@ const referrerPolicy = (value) => {
|
|
|
268
268
|
};
|
|
269
269
|
const policyToken = (value) => {
|
|
270
270
|
const token = (value ?? "").trim().toLowerCase();
|
|
271
|
-
return /^[a-z][a-z0-9_
|
|
271
|
+
return /^[a-z][a-z0-9_.\x2d]*$/u.test(token) ? token : null;
|
|
272
272
|
};
|
|
273
273
|
const nonnegativeInteger = (value) => {
|
|
274
274
|
const number = numberValue(value === undefined ? undefined : Number(value));
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { browserScenarioCaptureSchema,
|
|
1
|
+
import { browserScenarioCaptureSchema, } from "../domain/browserScenarioCapture.js";
|
|
2
|
+
import { classifyBrowserScenarioCompleteness, browserScenarioStepSchema, browserStepArtifactsSchema, } from "../domain/browserScenarioCaptureValues.js";
|
|
2
3
|
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
3
4
|
import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
4
5
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
5
6
|
import { err, ok } from "../domain/result.js";
|
|
7
|
+
import { browserScenarioCleanupObservation, browserScenarioOperationFailure, browserScenarioCaptureData, } from "./BrowserScenarioPartialObservation.js";
|
|
6
8
|
const OPERATION = "capture_browser_scenario";
|
|
7
|
-
let defaultFactory;
|
|
8
|
-
const lazyPlaywrightFactory = {
|
|
9
|
-
async open(scenario, options) {
|
|
10
|
-
defaultFactory ??= import("./PlaywrightScenarioSession.js").then(({ PlaywrightScenarioSessionFactory }) => new PlaywrightScenarioSessionFactory());
|
|
11
|
-
return (await defaultFactory).open(scenario, options);
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
export { PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY } from "./providerIdentities.js";
|
|
15
9
|
import { PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY } from "./providerIdentities.js";
|
|
16
10
|
const SNAPSHOT_KINDS = [
|
|
17
11
|
"screenshot",
|
|
@@ -147,7 +141,7 @@ const runScenario = async (factory, scenario, options) => {
|
|
|
147
141
|
const startedAt = Date.now();
|
|
148
142
|
const session = await factory.open(scenario, options.signal === undefined ? {} : { signal: options.signal });
|
|
149
143
|
const steps = [];
|
|
150
|
-
let
|
|
144
|
+
let operationOutcome = { ok: true };
|
|
151
145
|
try {
|
|
152
146
|
steps.push(await initialStep({
|
|
153
147
|
session,
|
|
@@ -169,49 +163,70 @@ const runScenario = async (factory, scenario, options) => {
|
|
|
169
163
|
failed ||= step.status !== "completed";
|
|
170
164
|
}
|
|
171
165
|
}
|
|
172
|
-
|
|
173
|
-
|
|
166
|
+
catch (cause) {
|
|
167
|
+
operationOutcome = { ok: false, cause };
|
|
168
|
+
}
|
|
169
|
+
let cleanupOutcome;
|
|
170
|
+
try {
|
|
171
|
+
cleanupOutcome = { ok: true, cleanup: await session.close() };
|
|
172
|
+
}
|
|
173
|
+
catch (cause) {
|
|
174
|
+
cleanupOutcome = { ok: false, cause };
|
|
174
175
|
}
|
|
175
|
-
|
|
176
|
+
if (!cleanupOutcome.ok) {
|
|
177
|
+
const cleanup = browserScenarioCleanupObservation(cleanupOutcome.cause);
|
|
178
|
+
const partialObservation = {
|
|
179
|
+
kind: "browser-scenario-observation",
|
|
180
|
+
capture: browserScenarioCaptureData({
|
|
181
|
+
session,
|
|
182
|
+
scenario,
|
|
183
|
+
startedAt,
|
|
184
|
+
steps,
|
|
185
|
+
cleanup: "incomplete",
|
|
186
|
+
limitations: [
|
|
187
|
+
"Scenario observations are partial because browser cleanup could not be confirmed.",
|
|
188
|
+
],
|
|
189
|
+
}),
|
|
190
|
+
};
|
|
191
|
+
if (!operationOutcome.ok)
|
|
192
|
+
throw browserScenarioOperationFailure(operationOutcome.cause, partialObservation, { cause: cleanupOutcome.cause });
|
|
193
|
+
throw new BrowserObservationError(OPERATION, "cleanup_failed", {
|
|
194
|
+
cause: cleanupOutcome.cause,
|
|
195
|
+
cleanup,
|
|
196
|
+
partialObservation,
|
|
197
|
+
detail: `Browser scenario cleanup could not be confirmed: ${cleanup.reason}. Collected steps and events are retained in partial_observation. Review the reported resources before retrying.`,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (!operationOutcome.ok)
|
|
201
|
+
throw browserScenarioOperationFailure(operationOutcome.cause, {
|
|
202
|
+
kind: "browser-scenario-observation",
|
|
203
|
+
capture: browserScenarioCaptureData({
|
|
204
|
+
session,
|
|
205
|
+
scenario,
|
|
206
|
+
startedAt,
|
|
207
|
+
steps,
|
|
208
|
+
cleanup: cleanupOutcome.cleanup,
|
|
209
|
+
limitations: [
|
|
210
|
+
"Scenario capture ended after an operation failed; uncollected steps are not represented.",
|
|
211
|
+
],
|
|
212
|
+
}),
|
|
213
|
+
});
|
|
176
214
|
const completeness = globalCompleteness(scenario, session, steps);
|
|
177
215
|
return browserScenarioCaptureSchema.parse({
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
},
|
|
185
|
-
scenario: {
|
|
186
|
-
start_origin: new URL(scenario.start_url.url).origin,
|
|
187
|
-
action_count: scenario.actions.length,
|
|
188
|
-
secret_references: scenario.secrets.map(({ secret_id: id }) => id).sort(),
|
|
189
|
-
network_content: scenario.capture.network,
|
|
190
|
-
},
|
|
191
|
-
duration_ms: Date.now() - startedAt,
|
|
192
|
-
steps,
|
|
193
|
-
events,
|
|
216
|
+
...browserScenarioCaptureData({
|
|
217
|
+
session,
|
|
218
|
+
scenario,
|
|
219
|
+
startedAt,
|
|
220
|
+
steps,
|
|
221
|
+
cleanup: cleanupOutcome.cleanup,
|
|
222
|
+
}),
|
|
194
223
|
completeness,
|
|
195
|
-
limitations: [
|
|
196
|
-
"Event sequence records provider receipt order; simultaneous browser causality is not inferred.",
|
|
197
|
-
"Network content is retained only when selected; response bytes are browser-decoded, not compressed wire bytes.",
|
|
198
|
-
"Request bytes are limited to what Playwright exposes; not_exposed does not establish body absence or multipart file coverage.",
|
|
199
|
-
"Network content reads settle within 5 seconds each and never wait for unfinished responses or refetch them.",
|
|
200
|
-
"Playwright scenario events do not expose request initiator stacks; receipt order does not prove causality.",
|
|
201
|
-
"Storage values are hashed only after declared-secret redaction.",
|
|
202
|
-
...(session.eventLimitations?.() ?? []),
|
|
203
|
-
...(session.mode === "connect"
|
|
204
|
-
? [
|
|
205
|
-
"CDP attachment cannot recover pre-attach events or guarantee launch-time context options.",
|
|
206
|
-
]
|
|
207
|
-
: []),
|
|
208
|
-
],
|
|
209
224
|
});
|
|
210
225
|
};
|
|
211
226
|
/** Controlled Playwright/CDP scenario driver with exact process ownership. */
|
|
212
227
|
export class PlaywrightBrowserScenarioProvider {
|
|
213
228
|
factory;
|
|
214
|
-
constructor(factory
|
|
229
|
+
constructor(factory) {
|
|
215
230
|
this.factory = factory;
|
|
216
231
|
}
|
|
217
232
|
identity() {
|
|
@@ -1,63 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
3
|
+
import { electronActiveTimelineEventSchema, } from "../domain/javascript/electronActiveObservation.js";
|
|
3
4
|
const OPERATION = "capture_electron_scenario";
|
|
4
|
-
const hookEventSchema = z.strictObject({
|
|
5
|
-
sequence: z.number().int().min(1),
|
|
6
|
-
correlation_id: z.string().nullable(),
|
|
7
|
-
kind: z.enum([
|
|
8
|
-
"main-handler-invocation",
|
|
9
|
-
"main-event-invocation",
|
|
10
|
-
"utility-process-fork",
|
|
11
|
-
"utility-process-message",
|
|
12
|
-
"ipc-main-to-renderer",
|
|
13
|
-
"ipc-utility-to-main",
|
|
14
|
-
"ipc-renderer-send",
|
|
15
|
-
"ipc-renderer-invoke",
|
|
16
|
-
"ipc-renderer-post-message",
|
|
17
|
-
"app-lifecycle",
|
|
18
|
-
"window-lifecycle",
|
|
19
|
-
"web-contents-lifecycle",
|
|
20
|
-
"navigation",
|
|
21
|
-
"shell-attempt",
|
|
22
|
-
"process-lifecycle",
|
|
23
|
-
"permission",
|
|
24
|
-
"popup-attempt",
|
|
25
|
-
"download",
|
|
26
|
-
"protocol",
|
|
27
|
-
"preload",
|
|
28
|
-
"native-addon",
|
|
29
|
-
"updater",
|
|
30
|
-
"error",
|
|
31
|
-
]),
|
|
32
|
-
event: z.string().nullable(),
|
|
33
|
-
phase: z.enum(["attempted", "completed", "blocked", "failed", "observed"]),
|
|
34
|
-
channel: z.string().nullable(),
|
|
35
|
-
direction: z
|
|
36
|
-
.enum([
|
|
37
|
-
"renderer-to-main",
|
|
38
|
-
"main-to-renderer",
|
|
39
|
-
"main-to-utility",
|
|
40
|
-
"utility-to-main",
|
|
41
|
-
])
|
|
42
|
-
.nullable(),
|
|
43
|
-
sender: z.string().nullable(),
|
|
44
|
-
receiver: z.string().nullable(),
|
|
45
|
-
frame: z.string().nullable(),
|
|
46
|
-
target: z.string().nullable(),
|
|
47
|
-
argument_shapes: z.array(z.string()),
|
|
48
|
-
result_shape: z.string().nullable(),
|
|
49
|
-
process_type: z.string().nullable(),
|
|
50
|
-
source: z.string(),
|
|
51
|
-
capture_method: z.enum(["api-wrapper", "event-emitter", "process-hook"]),
|
|
52
|
-
artifact_path: z.string().nullable(),
|
|
53
|
-
artifact_sha256: z
|
|
54
|
-
.string()
|
|
55
|
-
.regex(/^[a-f0-9]{64}$/u)
|
|
56
|
-
.nullable(),
|
|
57
|
-
error: z.boolean(),
|
|
58
|
-
});
|
|
59
5
|
const hookSnapshotSchema = z.strictObject({
|
|
60
|
-
events: z.array(
|
|
6
|
+
events: z.array(electronActiveTimelineEventSchema),
|
|
61
7
|
retention_budget_bytes: z.number().int().min(0),
|
|
62
8
|
estimated_retained_bytes: z.number().int().min(0),
|
|
63
9
|
event_serialized_byte_upper_bound: z.number().int().min(0),
|
|
@@ -14,12 +14,16 @@ import { runElectronActions, readApplicationState, runWithExecutionLimits, } fro
|
|
|
14
14
|
import { projectElectronActiveCapture } from "./PlaywrightElectronActiveProjection.js";
|
|
15
15
|
const OPERATION = "capture_electron_scenario";
|
|
16
16
|
const STARTUP_TIMEOUT_MS = 60_000;
|
|
17
|
-
/** Public identity for provider-owned Electron runtime experiments. */
|
|
18
|
-
export { PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY } from "./providerIdentities.js";
|
|
19
17
|
import { PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY } from "./providerIdentities.js";
|
|
20
18
|
const hookPath = fileURLToPath(new URL("../../scripts/electron-active-hook.cjs", import.meta.url));
|
|
21
19
|
/** Launch an owned Electron application through the official Playwright API. */
|
|
22
20
|
export class PlaywrightElectronActiveProvider {
|
|
21
|
+
environment;
|
|
22
|
+
launch;
|
|
23
|
+
constructor(environment, launch = (options) => electron.launch(options)) {
|
|
24
|
+
this.environment = environment;
|
|
25
|
+
this.launch = launch;
|
|
26
|
+
}
|
|
23
27
|
identity() {
|
|
24
28
|
return PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY;
|
|
25
29
|
}
|
|
@@ -42,10 +46,10 @@ export class PlaywrightElectronActiveProvider {
|
|
|
42
46
|
const captureBaseline = await systemProcessOwnershipHost.captureBaseline?.(options.signal);
|
|
43
47
|
if (options.signal?.aborted)
|
|
44
48
|
throw new BrowserObservationError(OPERATION, "cancelled");
|
|
45
|
-
application = await
|
|
49
|
+
application = await this.launch({
|
|
46
50
|
executablePath: paths.executable,
|
|
47
51
|
cwd: paths.root,
|
|
48
|
-
env: safeElectronEnvironment(runId),
|
|
52
|
+
env: safeElectronEnvironment(this.environment, runId),
|
|
49
53
|
args: ["-r", hookPath, paths.application, ...input.args],
|
|
50
54
|
timeout: Math.max(1, startupDeadline - Date.now()),
|
|
51
55
|
});
|
|
@@ -258,7 +262,7 @@ const canonicalPaths = async (input) => {
|
|
|
258
262
|
: await realpath(input.application_root);
|
|
259
263
|
return { executable, application, root };
|
|
260
264
|
};
|
|
261
|
-
const safeElectronEnvironment = (runId) => Object.fromEntries([
|
|
265
|
+
const safeElectronEnvironment = (environment, runId) => Object.fromEntries([
|
|
262
266
|
...[
|
|
263
267
|
"HOME",
|
|
264
268
|
"LANG",
|
|
@@ -269,7 +273,7 @@ const safeElectronEnvironment = (runId) => Object.fromEntries([
|
|
|
269
273
|
"DISPLAY",
|
|
270
274
|
"WAYLAND_DISPLAY",
|
|
271
275
|
]
|
|
272
|
-
.map((name) => [name,
|
|
276
|
+
.map((name) => [name, environment[name]])
|
|
273
277
|
.filter((entry) => entry[1] !== undefined),
|
|
274
278
|
["REA_PROCESS_RUN_ID", runId],
|
|
275
279
|
]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { browserStepArtifactsSchema, } from "../domain/
|
|
3
|
+
import { browserStepArtifactsSchema, } from "../domain/browserScenarioCaptureValues.js";
|
|
4
4
|
const historyValueSchema = z.strictObject({
|
|
5
5
|
length: z.number().int().min(0),
|
|
6
6
|
navigation_entries: z.array(z.strictObject({
|
|
@@ -2,9 +2,90 @@ import { chmod, mkdtemp, rm } from "node:fs/promises";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { chromium, } from "playwright-core";
|
|
5
|
+
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
5
6
|
import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
6
7
|
import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
|
|
7
8
|
const OPERATION = "capture_browser_scenario";
|
|
9
|
+
/** Owns one browser connection and optional private profile through cleanup retries. */
|
|
10
|
+
export class PlaywrightScenarioBrowserCleanupOwner {
|
|
11
|
+
resources;
|
|
12
|
+
#browserClosed = false;
|
|
13
|
+
#profileRemoved;
|
|
14
|
+
#closePromise;
|
|
15
|
+
#eventFinalizationPromise;
|
|
16
|
+
/** Keep the narrow provider actions needed to release one opened browser. */
|
|
17
|
+
constructor(resources) {
|
|
18
|
+
this.resources = resources;
|
|
19
|
+
this.#profileRemoved = resources.removeProfile === undefined;
|
|
20
|
+
}
|
|
21
|
+
close(finishEvents, signal) {
|
|
22
|
+
const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
|
|
23
|
+
if (this.#closePromise === undefined) {
|
|
24
|
+
this.#closePromise = cleanup;
|
|
25
|
+
void cleanup.catch(() => {
|
|
26
|
+
if (this.#closePromise === cleanup)
|
|
27
|
+
this.#closePromise = undefined;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return this.#awaitCleanup(cleanup, signal);
|
|
31
|
+
}
|
|
32
|
+
async #awaitCleanup(cleanup, signal) {
|
|
33
|
+
try {
|
|
34
|
+
await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
|
|
35
|
+
}
|
|
36
|
+
catch (cause) {
|
|
37
|
+
throw new BrowserObservationError(OPERATION, "cleanup_failed", {
|
|
38
|
+
cause,
|
|
39
|
+
cleanup: {
|
|
40
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
41
|
+
resources: [
|
|
42
|
+
"browser_transport",
|
|
43
|
+
...(this.resources.removeProfile === undefined
|
|
44
|
+
? []
|
|
45
|
+
: ["browser_profile"]),
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async #closeResources(finishEvents) {
|
|
52
|
+
const failures = [];
|
|
53
|
+
const eventFinalization = (this.#eventFinalizationPromise ??=
|
|
54
|
+
Promise.resolve().then(async () => {
|
|
55
|
+
await finishEvents?.();
|
|
56
|
+
}));
|
|
57
|
+
try {
|
|
58
|
+
await eventFinalization;
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
failures.push(cause);
|
|
62
|
+
}
|
|
63
|
+
if (!this.#browserClosed) {
|
|
64
|
+
try {
|
|
65
|
+
await this.resources.closeBrowser();
|
|
66
|
+
this.#browserClosed = true;
|
|
67
|
+
}
|
|
68
|
+
catch (cause) {
|
|
69
|
+
failures.push(cause);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (this.#browserClosed &&
|
|
73
|
+
!this.#profileRemoved &&
|
|
74
|
+
this.resources.removeProfile !== undefined) {
|
|
75
|
+
try {
|
|
76
|
+
await this.resources.removeProfile();
|
|
77
|
+
this.#profileRemoved = true;
|
|
78
|
+
}
|
|
79
|
+
catch (cause) {
|
|
80
|
+
failures.push(cause);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (failures.length === 1)
|
|
84
|
+
throw failures[0];
|
|
85
|
+
if (failures.length > 1)
|
|
86
|
+
throw new AggregateError(failures, "Browser session cleanup failed");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
8
89
|
const allowedBrowserEnvironment = (environment) => {
|
|
9
90
|
const allowed = [
|
|
10
91
|
"DBUS_SESSION_BUS_ADDRESS",
|
|
@@ -69,23 +150,57 @@ const configureAttachedEnvironment = async (context, page, scenario) => {
|
|
|
69
150
|
await session.detach();
|
|
70
151
|
}
|
|
71
152
|
};
|
|
72
|
-
|
|
153
|
+
/** Preserve an operation failure while reporting any incomplete cleanup. */
|
|
154
|
+
export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fallbackCleanupResources = ["browser_transport"]) => {
|
|
155
|
+
try {
|
|
156
|
+
await cleanup();
|
|
157
|
+
}
|
|
158
|
+
catch (cleanupFailure) {
|
|
159
|
+
const cleanupDetails = cleanupFailure instanceof AnalysisError &&
|
|
160
|
+
cleanupFailure.cleanup !== undefined
|
|
161
|
+
? cleanupFailure.cleanup
|
|
162
|
+
: {
|
|
163
|
+
reason: cleanupFailure instanceof Error
|
|
164
|
+
? cleanupFailure.message
|
|
165
|
+
: String(cleanupFailure),
|
|
166
|
+
resources: cleanupFailure instanceof AnalysisError
|
|
167
|
+
? cleanupFailure.cleanupResources
|
|
168
|
+
: fallbackCleanupResources,
|
|
169
|
+
};
|
|
170
|
+
throw new BrowserObservationError(OPERATION, "cleanup_failed", {
|
|
171
|
+
cause: new AggregateError([primaryFailure, cleanupFailure], "Browser scenario operation and cleanup both failed", { cause: primaryFailure }),
|
|
172
|
+
cleanup: cleanupDetails,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
throw primaryFailure;
|
|
176
|
+
};
|
|
177
|
+
/** Launch or attach using the caller-selected environment and browser engine. */
|
|
178
|
+
export const openPlaywrightScenarioBrowser = async (scenario, environment, launcher = chromium) => {
|
|
73
179
|
if (scenario.browser.mode === "connect") {
|
|
74
|
-
const browser = await
|
|
180
|
+
const browser = await launcher.connectOverCDP(scenario.browser.cdp_endpoint, { timeout: 0 });
|
|
181
|
+
const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
|
|
182
|
+
closeBrowser: () => browser.close(),
|
|
183
|
+
removeProfile: undefined,
|
|
184
|
+
});
|
|
75
185
|
try {
|
|
76
186
|
const target = await findConnectedPage(browser, scenario.browser.target_id);
|
|
77
187
|
await configureAttachedEnvironment(target.context, target.page, scenario);
|
|
78
|
-
return {
|
|
188
|
+
return {
|
|
189
|
+
...target,
|
|
190
|
+
browser,
|
|
191
|
+
profilePath: undefined,
|
|
192
|
+
cleanup,
|
|
193
|
+
};
|
|
79
194
|
}
|
|
80
195
|
catch (cause) {
|
|
81
|
-
|
|
82
|
-
throw cause;
|
|
196
|
+
return failBrowserScenarioOperation(() => cleanup.close(), cause);
|
|
83
197
|
}
|
|
84
198
|
}
|
|
85
199
|
const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
|
|
86
|
-
|
|
200
|
+
let context;
|
|
87
201
|
try {
|
|
88
|
-
|
|
202
|
+
await chmod(profilePath, 0o700);
|
|
203
|
+
context = await launcher.launchPersistentContext(profilePath, {
|
|
89
204
|
executablePath: resolve(scenario.browser.executable_path),
|
|
90
205
|
headless: scenario.browser.headless,
|
|
91
206
|
acceptDownloads: false,
|
|
@@ -105,43 +220,28 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
|
|
|
105
220
|
handleSIGTERM: false,
|
|
106
221
|
timeout: 0,
|
|
107
222
|
});
|
|
108
|
-
const browser = context.browser();
|
|
109
|
-
if (browser === null) {
|
|
110
|
-
await context.close();
|
|
111
|
-
throw new BrowserObservationError(OPERATION, "protocol_error");
|
|
112
|
-
}
|
|
113
|
-
const page = context.pages()[0] ?? (await context.newPage());
|
|
114
|
-
return { context, page, browser, profilePath };
|
|
115
223
|
}
|
|
116
224
|
catch (cause) {
|
|
117
|
-
|
|
118
|
-
throw cause;
|
|
225
|
+
return failBrowserScenarioOperation(() => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }), cause, ["browser_profile"]);
|
|
119
226
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// In connect mode Playwright's Browser.close disconnects its CDP client;
|
|
125
|
-
// it does not close the externally owned browser process.
|
|
126
|
-
if (profilePath === undefined)
|
|
127
|
-
await browser.close();
|
|
128
|
-
else
|
|
129
|
-
await context.close();
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
if (profilePath !== undefined)
|
|
133
|
-
await rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
|
|
134
|
-
}
|
|
135
|
-
})();
|
|
136
|
-
// best-effort cleanup: the bounded execution boundary below observes the
|
|
137
|
-
// same cleanup promise; this early attachment only prevents unhandled rejection.
|
|
138
|
-
void cleanup.catch(() => undefined);
|
|
139
|
-
// The shared execution boundary rejects cancellation/timeouts instead of
|
|
140
|
-
// returning a successful capture whose browser or profile may still exist.
|
|
227
|
+
const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
|
|
228
|
+
closeBrowser: () => context.close(),
|
|
229
|
+
removeProfile: () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }),
|
|
230
|
+
});
|
|
141
231
|
try {
|
|
142
|
-
|
|
232
|
+
const browser = context.browser();
|
|
233
|
+
if (browser === null)
|
|
234
|
+
throw new BrowserObservationError(OPERATION, "protocol_error");
|
|
235
|
+
const page = context.pages()[0] ?? (await context.newPage());
|
|
236
|
+
return {
|
|
237
|
+
context,
|
|
238
|
+
page,
|
|
239
|
+
browser,
|
|
240
|
+
profilePath,
|
|
241
|
+
cleanup,
|
|
242
|
+
};
|
|
143
243
|
}
|
|
144
244
|
catch (cause) {
|
|
145
|
-
|
|
245
|
+
return failBrowserScenarioOperation(() => cleanup.close(), cause);
|
|
146
246
|
}
|
|
147
247
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { browserScenarioEventSchema, } from "../domain/
|
|
1
|
+
import { browserScenarioEventSchema, } from "../domain/browserScenarioCaptureValues.js";
|
|
2
2
|
import { PlaywrightScenarioNetwork } from "./network/PlaywrightScenarioNetwork.js";
|
|
3
3
|
/** Arrival-ordered Playwright event capture with current-step attribution. */
|
|
4
4
|
export class PlaywrightScenarioEvents {
|