rea-agents 6.1.0 → 6.3.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 +24 -24
- package/bridge/ghidra/ReaGhidraBridge.java +32 -4
- package/bridge/hopper_bridge.py +8 -1
- package/dist/android/JadxConfiguration.js +87 -7
- package/dist/android/JadxMcpTransport.js +14 -2
- package/dist/android/JadxProvider.js +64 -36
- package/dist/android/JadxSession.js +51 -9
- package/dist/application/BinaryTargetResolver.js +68 -20
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +4 -20
- package/dist/application/CapabilityInventory.js +43 -9
- package/dist/application/ClientConfigurationDocument.js +97 -25
- package/dist/application/ClientRegistrationStatus.js +19 -6
- package/dist/application/DirectAnalysis.js +41 -20
- package/dist/application/DirectAnalysisCleanup.js +71 -0
- package/dist/application/DirectAnalysisStatus.js +3 -7
- package/dist/application/Doctor.js +40 -53
- package/dist/application/DoctorDiagnostics.js +2 -3
- package/dist/application/EnhancedTools.js +51 -6
- package/dist/application/EvidenceBundleFiles.js +8 -3
- package/dist/application/InvestigationProviders.js +13 -5
- package/dist/application/JsonFiles.js +56 -23
- package/dist/application/LinuxHopper.js +11 -7
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionObligationCandidates.js +10 -3
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/RegularFileRead.js +17 -0
- package/dist/application/Setup.js +26 -23
- package/dist/application/SetupClientConfiguration.js +18 -7
- package/dist/application/SetupHost.js +20 -29
- package/dist/application/SetupPlan.js +24 -20
- package/dist/application/SetupSkill.js +57 -8
- package/dist/application/SupportedClients.js +43 -0
- package/dist/application/Uninstall.js +98 -30
- package/dist/application/UpdateMaintenance.js +13 -7
- package/dist/application/UpdateRuntime.js +12 -12
- package/dist/application/Utf8JsonInput.js +64 -0
- package/dist/application/WebScriptExportService.js +38 -5
- 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/android/AndroidAnalysisService.js +1 -1
- 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 +13 -10
- package/dist/application/binary/BinarySession.js +86 -29
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +10 -2
- 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 +10 -14
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
- 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 +46 -29
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
- package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/application/process/ProcessCli.js +11 -11
- package/dist/application/process/ProcessEvidence.js +0 -1
- package/dist/artifacts/ArtifactProvider.js +53 -30
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/AsarArtifactReader.js +81 -17
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- 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 +68 -42
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/classify.js +33 -14
- package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +64 -34
- package/dist/artifacts/inventory/scanReader.js +12 -20
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +6 -6
- package/dist/browser/CdpCaptureEventHandlers.js +2 -4
- package/dist/browser/CdpCaptureEvents.js +0 -1
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -5
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +4 -5
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/CdpWebMcpDiscovery.js +16 -13
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
- 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 +269 -66
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +41 -32
- package/dist/browser/WebSourceMapFetcher.js +32 -6
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- 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 +37 -28
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +12 -13
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +2 -12
- package/dist/cli/jsonOutput.js +3 -2
- 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/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +10 -12
- package/dist/cli.js +19 -8
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -0
- package/dist/cliJsonFile.js +179 -0
- package/dist/cliJsonInput.js +60 -33
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -14
- 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 +7 -7
- 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/errorSchemas.js +3 -1
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +181 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +3 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/managed/managedToolContracts.js +8 -12
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
- 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/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +17 -4
- package/dist/contracts/sessionToolSchemas.js +4 -16
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -0
- package/dist/contracts/toolOutputSchemaGroups.js +138 -94
- package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
- 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/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorCore.js +3 -0
- package/dist/domain/analysisErrorPresentation.js +22 -5
- package/dist/domain/analysisErrorProjection.js +24 -5
- package/dist/domain/analysisSnapshot.js +31 -31
- package/dist/domain/analysisView/analysisView.js +241 -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/android/androidPartialObservation.js +36 -0
- 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 +17 -4
- package/dist/domain/artifactIdentity.js +8 -8
- package/dist/domain/artifactInspection.js +8 -8
- 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/browserCompleteness.js +3 -2
- 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/browserScenarioCaptureValues.js +2 -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/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +6 -6
- package/dist/domain/callPath.js +15 -18
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +5 -6
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +12 -0
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +19 -40
- package/dist/domain/evidenceBundle.js +58 -42
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +6 -6
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +26 -36
- package/dist/domain/functionComparisonResults.js +3 -6
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +4 -38
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/javascript/electronActiveObservation.js +29 -71
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
- package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
- package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
- package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
- package/dist/domain/javascript/javascriptAstValues.js +22 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
- package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
- package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
- package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
- package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
- package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
- package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
- package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
- package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
- package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
- package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
- package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +46 -19
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +10 -6
- package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- 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 +3 -3
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +22 -20
- package/dist/domain/process/processCaptureCoverage.js +70 -0
- package/dist/domain/process/processCaptureExample.js +45 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +82 -13
- package/dist/domain/process/processComparison.js +39 -43
- 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 +19 -15
- package/dist/domain/process/processTraceSpecification.js +4 -7
- package/dist/domain/providerAdapterError.js +2 -0
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +7 -3
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +6 -5
- package/dist/domain/reconstructionVerificationSchemas.js +2 -1
- package/dist/domain/referenceSourceGraph.js +27 -28
- package/dist/domain/referenceSourceImportParsing.js +34 -45
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +4 -3
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +66 -0
- package/dist/domain/symbolAnalysis.js +83 -20
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +9 -1
- package/dist/domain/webCaptureDiff.js +71 -30
- package/dist/domain/webCaptureDiffSchemas.js +8 -11
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webRuntime.js +0 -2
- package/dist/domain/webScriptExport.js +2 -2
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
- 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 +13 -12
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- 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/filesystem/RegularFile.js +41 -0
- 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 +105 -36
- 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 +151 -22
- package/dist/ghidra/GhidraJavaLaunch.js +6 -2
- package/dist/ghidra/GhidraLauncher.js +58 -26
- 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 +5 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +24 -20
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
- package/dist/inspector/V8InspectorProvider.js +97 -35
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/main/shutdown.js +81 -29
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +23 -3
- package/dist/main.js +11 -18
- package/dist/native/AppleMachoSelection.js +16 -6
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/CommandRunner.js +9 -7
- package/dist/native/LldbCallTracer.js +249 -77
- package/dist/native/NativeMacOSProvider.js +32 -17
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- 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 +18 -16
- package/dist/process/ProviderProcess.js +1 -3
- package/dist/process/capture/FilesystemSnapshot.js +131 -24
- package/dist/process/capture/ProcessCaptureError.js +13 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
- package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
- package/dist/process/capture/ProcessHarness.js +16 -33
- 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/analysisAdmission.js +8 -0
- package/dist/server/createServer.js +71 -59
- 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 +6 -6
- 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 +4 -4
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +4 -5
- package/dist/server/registerArtifactTools.js +2 -2
- 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 +8 -7
- package/dist/server/registerElectronTools.js +10 -13
- package/dist/server/registerEnhancedTools.js +82 -77
- package/dist/server/registerEvidenceTools.js +54 -47
- 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/registerManagedTools.js +7 -4
- 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 +32 -41
- 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 +19 -19
- 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 +42 -30
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +14 -13
- 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 +18 -0
- package/dist/artifacts/inventory/policy.js +0 -2
- 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/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/registerNativeTools.js +0 -6
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -2,9 +2,168 @@ 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
|
+
const throwIfScenarioCancelled = (signal) => {
|
|
10
|
+
if (signal?.aborted === true)
|
|
11
|
+
throw new BrowserObservationError(OPERATION, "cancelled");
|
|
12
|
+
};
|
|
13
|
+
/** Owns one browser connection and optional private profile through cleanup retries. */
|
|
14
|
+
export class PlaywrightScenarioBrowserCleanupOwner {
|
|
15
|
+
resources;
|
|
16
|
+
#browserClosed = false;
|
|
17
|
+
#profileRemoved;
|
|
18
|
+
#closePromise;
|
|
19
|
+
#eventFinalizationPromise;
|
|
20
|
+
/** Keep the narrow provider actions needed to release one opened browser. */
|
|
21
|
+
constructor(resources) {
|
|
22
|
+
this.resources = resources;
|
|
23
|
+
this.#profileRemoved = resources.removeProfile === undefined;
|
|
24
|
+
}
|
|
25
|
+
close(finishEvents, signal) {
|
|
26
|
+
const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
|
|
27
|
+
if (this.#closePromise === undefined) {
|
|
28
|
+
this.#closePromise = cleanup;
|
|
29
|
+
void cleanup.then(() => this.resources.onSettled?.(this.#browserClosed), () => {
|
|
30
|
+
if (this.#closePromise === cleanup)
|
|
31
|
+
this.#closePromise = undefined;
|
|
32
|
+
this.resources.onSettled?.(this.#browserClosed);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return this.#awaitCleanup(cleanup, signal);
|
|
36
|
+
}
|
|
37
|
+
async #awaitCleanup(cleanup, signal) {
|
|
38
|
+
try {
|
|
39
|
+
await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
|
|
40
|
+
}
|
|
41
|
+
catch (cause) {
|
|
42
|
+
throw new BrowserObservationError(OPERATION, "cleanup_failed", {
|
|
43
|
+
cause,
|
|
44
|
+
cleanup: {
|
|
45
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
46
|
+
resources: [
|
|
47
|
+
"browser_transport",
|
|
48
|
+
...(this.resources.removeProfile === undefined
|
|
49
|
+
? []
|
|
50
|
+
: ["browser_profile"]),
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async #closeResources(finishEvents) {
|
|
57
|
+
const failures = [];
|
|
58
|
+
const eventFinalization = (this.#eventFinalizationPromise ??=
|
|
59
|
+
Promise.resolve().then(async () => {
|
|
60
|
+
await finishEvents?.();
|
|
61
|
+
}));
|
|
62
|
+
try {
|
|
63
|
+
await eventFinalization;
|
|
64
|
+
}
|
|
65
|
+
catch (cause) {
|
|
66
|
+
failures.push(cause);
|
|
67
|
+
}
|
|
68
|
+
if (!this.#browserClosed) {
|
|
69
|
+
try {
|
|
70
|
+
await this.resources.closeBrowser();
|
|
71
|
+
this.#browserClosed = true;
|
|
72
|
+
}
|
|
73
|
+
catch (cause) {
|
|
74
|
+
failures.push(cause);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (this.#browserClosed &&
|
|
78
|
+
!this.#profileRemoved &&
|
|
79
|
+
this.resources.removeProfile !== undefined) {
|
|
80
|
+
try {
|
|
81
|
+
await this.resources.removeProfile();
|
|
82
|
+
this.#profileRemoved = true;
|
|
83
|
+
}
|
|
84
|
+
catch (cause) {
|
|
85
|
+
failures.push(cause);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (failures.length === 1)
|
|
89
|
+
throw failures[0];
|
|
90
|
+
if (failures.length > 1)
|
|
91
|
+
throw new AggregateError(failures, "Browser session cleanup failed");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const attachedScenarioAdmissions = new Map();
|
|
95
|
+
const releaseAttachedScenario = (key, admission) => {
|
|
96
|
+
const waiter = admission.waiters.shift();
|
|
97
|
+
if (waiter === undefined) {
|
|
98
|
+
admission.active = false;
|
|
99
|
+
if (admission.cleanupOwner === undefined &&
|
|
100
|
+
attachedScenarioAdmissions.get(key) === admission)
|
|
101
|
+
attachedScenarioAdmissions.delete(key);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (waiter.onAbort !== undefined)
|
|
105
|
+
waiter.signal?.removeEventListener("abort", waiter.onAbort);
|
|
106
|
+
if (waiter.signal?.aborted === true) {
|
|
107
|
+
waiter.reject(new BrowserObservationError(OPERATION, "cancelled"));
|
|
108
|
+
releaseAttachedScenario(key, admission);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
waiter.resolve(createAttachedScenarioRelease(key, admission));
|
|
112
|
+
};
|
|
113
|
+
const createAttachedScenarioRelease = (key, admission) => {
|
|
114
|
+
let released = false;
|
|
115
|
+
return () => {
|
|
116
|
+
if (released)
|
|
117
|
+
return;
|
|
118
|
+
released = true;
|
|
119
|
+
releaseAttachedScenario(key, admission);
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
const acquireAttachedScenario = (scenario, signal) => {
|
|
123
|
+
if (signal?.aborted === true)
|
|
124
|
+
return Promise.reject(new BrowserObservationError(OPERATION, "cancelled"));
|
|
125
|
+
const key = JSON.stringify([scenario.cdp_endpoint, scenario.target_id]);
|
|
126
|
+
const admission = attachedScenarioAdmissions.get(key) ??
|
|
127
|
+
{
|
|
128
|
+
active: false,
|
|
129
|
+
waiters: [],
|
|
130
|
+
cleanupOwner: undefined,
|
|
131
|
+
};
|
|
132
|
+
attachedScenarioAdmissions.set(key, admission);
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
const grant = (release) => resolve({ admission, release });
|
|
135
|
+
if (!admission.active) {
|
|
136
|
+
admission.active = true;
|
|
137
|
+
grant(createAttachedScenarioRelease(key, admission));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const waiter = {
|
|
141
|
+
signal,
|
|
142
|
+
resolve: (release) => grant(release),
|
|
143
|
+
reject,
|
|
144
|
+
onAbort: undefined,
|
|
145
|
+
};
|
|
146
|
+
admission.waiters.push(waiter);
|
|
147
|
+
if (signal !== undefined) {
|
|
148
|
+
const onAbort = () => {
|
|
149
|
+
const index = admission.waiters.indexOf(waiter);
|
|
150
|
+
if (index < 0)
|
|
151
|
+
return;
|
|
152
|
+
admission.waiters.splice(index, 1);
|
|
153
|
+
signal.removeEventListener("abort", onAbort);
|
|
154
|
+
reject(new BrowserObservationError(OPERATION, "cancelled"));
|
|
155
|
+
if (!admission.active && admission.waiters.length === 0)
|
|
156
|
+
releaseAttachedScenario(key, admission);
|
|
157
|
+
};
|
|
158
|
+
waiter.onAbort = onAbort;
|
|
159
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
160
|
+
if (signal.aborted) {
|
|
161
|
+
onAbort();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
};
|
|
8
167
|
const allowedBrowserEnvironment = (environment) => {
|
|
9
168
|
const allowed = [
|
|
10
169
|
"DBUS_SESSION_BUS_ADDRESS",
|
|
@@ -25,12 +184,14 @@ const allowedBrowserEnvironment = (environment) => {
|
|
|
25
184
|
.map((name) => [name, environment[name]])
|
|
26
185
|
.filter((entry) => entry[1] !== undefined));
|
|
27
186
|
};
|
|
28
|
-
const findConnectedPage = async (browser, targetId) => {
|
|
187
|
+
const findConnectedPage = async (browser, targetId, signal) => {
|
|
29
188
|
for (const context of browser.contexts())
|
|
30
189
|
for (const page of context.pages()) {
|
|
31
190
|
const session = await context.newCDPSession(page);
|
|
32
191
|
try {
|
|
192
|
+
throwIfScenarioCancelled(signal);
|
|
33
193
|
const { targetInfo } = await session.send("Target.getTargetInfo");
|
|
194
|
+
throwIfScenarioCancelled(signal);
|
|
34
195
|
if (targetInfo.targetId !== targetId)
|
|
35
196
|
continue;
|
|
36
197
|
return { context, page };
|
|
@@ -41,51 +202,108 @@ const findConnectedPage = async (browser, targetId) => {
|
|
|
41
202
|
}
|
|
42
203
|
throw new BrowserObservationError(OPERATION, "target_not_found");
|
|
43
204
|
};
|
|
44
|
-
const configureAttachedEnvironment = async (context, page,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
height: scenario.environment.viewport.height,
|
|
48
|
-
});
|
|
205
|
+
const configureAttachedEnvironment = async (context, page, environment, signal) => {
|
|
206
|
+
// setViewportSize also resizes the external browser window. The scenario's
|
|
207
|
+
// CDP metrics override below supplies the viewport and expires on disconnect.
|
|
49
208
|
await page.emulateMedia({
|
|
50
|
-
colorScheme:
|
|
51
|
-
reducedMotion:
|
|
209
|
+
colorScheme: environment.color_scheme,
|
|
210
|
+
reducedMotion: environment.reduced_motion,
|
|
52
211
|
});
|
|
212
|
+
throwIfScenarioCancelled(signal);
|
|
53
213
|
const session = await context.newCDPSession(page);
|
|
214
|
+
throwIfScenarioCancelled(signal);
|
|
215
|
+
// Chromium resets these overrides when the CDP session detaches. Keep it on
|
|
216
|
+
// the scenario transport until cleanup disconnects the attached browser.
|
|
217
|
+
await session.send("Emulation.setDeviceMetricsOverride", {
|
|
218
|
+
width: environment.viewport.width,
|
|
219
|
+
height: environment.viewport.height,
|
|
220
|
+
deviceScaleFactor: environment.viewport.device_scale_factor,
|
|
221
|
+
mobile: false,
|
|
222
|
+
dontSetVisibleSize: true,
|
|
223
|
+
});
|
|
224
|
+
throwIfScenarioCancelled(signal);
|
|
225
|
+
await session.send("Emulation.setLocaleOverride", {
|
|
226
|
+
locale: environment.locale,
|
|
227
|
+
});
|
|
228
|
+
throwIfScenarioCancelled(signal);
|
|
229
|
+
await session.send("Emulation.setTimezoneOverride", {
|
|
230
|
+
timezoneId: environment.timezone,
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
/** Preserve an operation failure while reporting any incomplete cleanup. */
|
|
234
|
+
export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fallbackCleanupResources = ["browser_transport"]) => {
|
|
54
235
|
try {
|
|
55
|
-
await
|
|
56
|
-
width: scenario.environment.viewport.width,
|
|
57
|
-
height: scenario.environment.viewport.height,
|
|
58
|
-
deviceScaleFactor: scenario.environment.viewport.device_scale_factor,
|
|
59
|
-
mobile: false,
|
|
60
|
-
});
|
|
61
|
-
await session.send("Emulation.setLocaleOverride", {
|
|
62
|
-
locale: scenario.environment.locale,
|
|
63
|
-
});
|
|
64
|
-
await session.send("Emulation.setTimezoneOverride", {
|
|
65
|
-
timezoneId: scenario.environment.timezone,
|
|
66
|
-
});
|
|
236
|
+
await cleanup();
|
|
67
237
|
}
|
|
68
|
-
|
|
69
|
-
|
|
238
|
+
catch (cleanupFailure) {
|
|
239
|
+
const cleanupDetails = cleanupFailure instanceof AnalysisError &&
|
|
240
|
+
cleanupFailure.cleanup !== undefined
|
|
241
|
+
? cleanupFailure.cleanup
|
|
242
|
+
: {
|
|
243
|
+
reason: cleanupFailure instanceof Error
|
|
244
|
+
? cleanupFailure.message
|
|
245
|
+
: String(cleanupFailure),
|
|
246
|
+
resources: cleanupFailure instanceof AnalysisError
|
|
247
|
+
? cleanupFailure.cleanupResources
|
|
248
|
+
: fallbackCleanupResources,
|
|
249
|
+
};
|
|
250
|
+
throw new BrowserObservationError(OPERATION, "cleanup_failed", {
|
|
251
|
+
cause: new AggregateError([primaryFailure, cleanupFailure], "Browser scenario operation and cleanup both failed", { cause: primaryFailure }),
|
|
252
|
+
cleanup: cleanupDetails,
|
|
253
|
+
});
|
|
70
254
|
}
|
|
255
|
+
throw primaryFailure;
|
|
71
256
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
257
|
+
const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal) => {
|
|
258
|
+
const lease = await acquireAttachedScenario(browserRequest, signal);
|
|
259
|
+
let cleanupOwner;
|
|
260
|
+
try {
|
|
261
|
+
const priorOwner = lease.admission.cleanupOwner;
|
|
262
|
+
if (priorOwner !== undefined)
|
|
263
|
+
await priorOwner.close();
|
|
264
|
+
throwIfScenarioCancelled(signal);
|
|
265
|
+
const browser = await launcher.connectOverCDP(browserRequest.cdp_endpoint);
|
|
266
|
+
const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
|
|
267
|
+
closeBrowser: () => browser.close(),
|
|
268
|
+
onSettled: (browserClosed) => {
|
|
269
|
+
if (browserClosed && lease.admission.cleanupOwner === cleanup)
|
|
270
|
+
lease.admission.cleanupOwner = undefined;
|
|
271
|
+
lease.release();
|
|
272
|
+
},
|
|
273
|
+
removeProfile: undefined,
|
|
274
|
+
});
|
|
275
|
+
cleanupOwner = cleanup;
|
|
276
|
+
lease.admission.cleanupOwner = cleanup;
|
|
277
|
+
throwIfScenarioCancelled(signal);
|
|
278
|
+
const target = await withPlaywrightExecutionBoundary(() => findConnectedPage(browser, browserRequest.target_id, signal), undefined, signal);
|
|
279
|
+
throwIfScenarioCancelled(signal);
|
|
280
|
+
await withPlaywrightExecutionBoundary(() => configureAttachedEnvironment(target.context, target.page, environment, signal), undefined, signal);
|
|
281
|
+
return {
|
|
282
|
+
...target,
|
|
283
|
+
browser,
|
|
284
|
+
profilePath: undefined,
|
|
285
|
+
cleanup,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
catch (cause) {
|
|
289
|
+
if (cleanupOwner === undefined) {
|
|
290
|
+
lease.release();
|
|
82
291
|
throw cause;
|
|
83
292
|
}
|
|
293
|
+
const cleanup = cleanupOwner;
|
|
294
|
+
return failBrowserScenarioOperation(() => cleanup.close(), cause);
|
|
84
295
|
}
|
|
296
|
+
};
|
|
297
|
+
/** Launch or attach using the caller-selected environment and browser engine. */
|
|
298
|
+
export const openPlaywrightScenarioBrowser = async (scenario, environment, options = {}) => {
|
|
299
|
+
const launcher = options.launcher ?? chromium;
|
|
300
|
+
if (scenario.browser.mode === "connect")
|
|
301
|
+
return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal);
|
|
85
302
|
const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
|
|
86
|
-
|
|
303
|
+
let context;
|
|
87
304
|
try {
|
|
88
|
-
|
|
305
|
+
await chmod(profilePath, 0o700);
|
|
306
|
+
context = await launcher.launchPersistentContext(profilePath, {
|
|
89
307
|
executablePath: resolve(scenario.browser.executable_path),
|
|
90
308
|
headless: scenario.browser.headless,
|
|
91
309
|
acceptDownloads: false,
|
|
@@ -105,43 +323,28 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
|
|
|
105
323
|
handleSIGTERM: false,
|
|
106
324
|
timeout: 0,
|
|
107
325
|
});
|
|
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
326
|
}
|
|
116
327
|
catch (cause) {
|
|
117
|
-
|
|
118
|
-
throw cause;
|
|
328
|
+
return failBrowserScenarioOperation(() => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }), cause, ["browser_profile"]);
|
|
119
329
|
}
|
|
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.
|
|
330
|
+
const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
|
|
331
|
+
closeBrowser: () => context.close(),
|
|
332
|
+
removeProfile: () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }),
|
|
333
|
+
});
|
|
141
334
|
try {
|
|
142
|
-
|
|
335
|
+
const browser = context.browser();
|
|
336
|
+
if (browser === null)
|
|
337
|
+
throw new BrowserObservationError(OPERATION, "protocol_error");
|
|
338
|
+
const page = context.pages()[0] ?? (await context.newPage());
|
|
339
|
+
return {
|
|
340
|
+
context,
|
|
341
|
+
page,
|
|
342
|
+
browser,
|
|
343
|
+
profilePath,
|
|
344
|
+
cleanup,
|
|
345
|
+
};
|
|
143
346
|
}
|
|
144
347
|
catch (cause) {
|
|
145
|
-
|
|
348
|
+
return failBrowserScenarioOperation(() => cleanup.close(), cause);
|
|
146
349
|
}
|
|
147
350
|
};
|
|
@@ -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 {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {} from "playwright-core";
|
|
2
2
|
import { BrowserObservationError } from "../domain/browserObservationError.js";
|
|
3
3
|
import { BrowserScenarioSecrets } from "./BrowserScenarioSecrets.js";
|
|
4
|
-
import {
|
|
4
|
+
import { failBrowserScenarioOperation, openPlaywrightScenarioBrowser, } from "./PlaywrightScenarioBrowser.js";
|
|
5
5
|
import { performPlaywrightScenarioAction } from "./PlaywrightScenarioActions.js";
|
|
6
6
|
import { capturePlaywrightStepArtifacts } from "./PlaywrightScenarioArtifacts.js";
|
|
7
7
|
import { PlaywrightScenarioEvents } from "./PlaywrightScenarioEvents.js";
|
|
8
8
|
import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
|
|
9
|
+
import { browserScenarioCaptureData, browserScenarioOperationFailure, } from "./BrowserScenarioPartialObservation.js";
|
|
9
10
|
const OPERATION = "capture_browser_scenario";
|
|
10
11
|
const storageSeeds = (blocks, secrets) => {
|
|
11
12
|
const seeds = {};
|
|
@@ -66,10 +67,8 @@ export class PlaywrightScenarioSession {
|
|
|
66
67
|
product = "Chromium";
|
|
67
68
|
version;
|
|
68
69
|
initialUrl;
|
|
69
|
-
closed = false;
|
|
70
70
|
secrets;
|
|
71
71
|
eventCapture;
|
|
72
|
-
signal;
|
|
73
72
|
constructor(opened, options) {
|
|
74
73
|
this.opened = opened;
|
|
75
74
|
this.mode = options.mode;
|
|
@@ -77,7 +76,6 @@ export class PlaywrightScenarioSession {
|
|
|
77
76
|
options.mode === "launch" ? "provider-owned" : "external";
|
|
78
77
|
this.secrets = options.secrets;
|
|
79
78
|
this.eventCapture = options.eventCapture;
|
|
80
|
-
this.signal = options.signal;
|
|
81
79
|
this.version = opened.browser.version();
|
|
82
80
|
this.initialUrl = opened.page.url();
|
|
83
81
|
}
|
|
@@ -87,23 +85,28 @@ export class PlaywrightScenarioSession {
|
|
|
87
85
|
const secrets = BrowserScenarioSecrets.resolve(scenario, environment);
|
|
88
86
|
if (secrets === undefined)
|
|
89
87
|
throw new BrowserObservationError(OPERATION, "secret_unavailable");
|
|
90
|
-
const
|
|
88
|
+
const startedAt = Date.now();
|
|
89
|
+
const opening = openPlaywrightScenarioBrowser(scenario, environment, {
|
|
90
|
+
signal: options.signal,
|
|
91
|
+
});
|
|
91
92
|
let opened;
|
|
93
|
+
let events;
|
|
92
94
|
try {
|
|
93
95
|
opened = await withPlaywrightExecutionBoundary(() => opening, undefined, options.signal);
|
|
94
96
|
}
|
|
95
97
|
catch (cause) {
|
|
96
98
|
void opening
|
|
97
|
-
.then((lateOpened) =>
|
|
99
|
+
.then((lateOpened) => lateOpened.cleanup.close(undefined, options.signal))
|
|
98
100
|
.catch((cause) => {
|
|
99
101
|
// best-effort cleanup: late-open cleanup must not mask the boundary failure.
|
|
100
102
|
void cause;
|
|
101
103
|
});
|
|
102
104
|
throw cause;
|
|
103
105
|
}
|
|
106
|
+
let session;
|
|
104
107
|
try {
|
|
105
108
|
await withPlaywrightExecutionBoundary(() => initializePage(opened.context, opened.page, scenario, secrets), undefined, options.signal);
|
|
106
|
-
|
|
109
|
+
events = new PlaywrightScenarioEvents({
|
|
107
110
|
page: opened.page,
|
|
108
111
|
context: opened.context,
|
|
109
112
|
ownsContext: scenario.browser.mode === "launch",
|
|
@@ -112,12 +115,18 @@ export class PlaywrightScenarioSession {
|
|
|
112
115
|
network: scenario.capture.network,
|
|
113
116
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
114
117
|
});
|
|
115
|
-
|
|
118
|
+
session = new PlaywrightScenarioSession(opened, {
|
|
116
119
|
mode: scenario.browser.mode,
|
|
117
120
|
secrets,
|
|
118
121
|
eventCapture: events,
|
|
119
|
-
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
120
122
|
});
|
|
123
|
+
}
|
|
124
|
+
catch (cause) {
|
|
125
|
+
return failBrowserScenarioOperation(() => opened.cleanup.close(events === undefined
|
|
126
|
+
? undefined
|
|
127
|
+
: () => events?.finish() ?? Promise.resolve(), options.signal), cause);
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
121
130
|
await withPlaywrightExecutionBoundary(() => opened.page.goto(secrets.url(scenario.start_url), {
|
|
122
131
|
waitUntil: "load",
|
|
123
132
|
timeout: 0,
|
|
@@ -125,8 +134,28 @@ export class PlaywrightScenarioSession {
|
|
|
125
134
|
return session;
|
|
126
135
|
}
|
|
127
136
|
catch (cause) {
|
|
128
|
-
|
|
129
|
-
|
|
137
|
+
let cleanup;
|
|
138
|
+
let cleanupFailure;
|
|
139
|
+
try {
|
|
140
|
+
cleanup = await session.close();
|
|
141
|
+
}
|
|
142
|
+
catch (failure) {
|
|
143
|
+
cleanup = "incomplete";
|
|
144
|
+
cleanupFailure = { cause: failure };
|
|
145
|
+
}
|
|
146
|
+
throw browserScenarioOperationFailure(cause, {
|
|
147
|
+
kind: "browser-scenario-observation",
|
|
148
|
+
capture: browserScenarioCaptureData({
|
|
149
|
+
session,
|
|
150
|
+
scenario,
|
|
151
|
+
startedAt,
|
|
152
|
+
steps: [],
|
|
153
|
+
cleanup,
|
|
154
|
+
limitations: [
|
|
155
|
+
"Scenario navigation failed before the initial state was captured.",
|
|
156
|
+
],
|
|
157
|
+
}),
|
|
158
|
+
}, cleanupFailure);
|
|
130
159
|
}
|
|
131
160
|
}
|
|
132
161
|
currentUrl() {
|
|
@@ -167,17 +196,7 @@ export class PlaywrightScenarioSession {
|
|
|
167
196
|
}), undefined, signal);
|
|
168
197
|
}
|
|
169
198
|
async close() {
|
|
170
|
-
|
|
171
|
-
return this.mode === "launch"
|
|
172
|
-
? "terminated-owned-process"
|
|
173
|
-
: "disconnected-external";
|
|
174
|
-
this.closed = true;
|
|
175
|
-
try {
|
|
176
|
-
await this.eventCapture.finish();
|
|
177
|
-
}
|
|
178
|
-
finally {
|
|
179
|
-
await closePlaywrightScenarioBrowser(this.opened, this.signal);
|
|
180
|
-
}
|
|
199
|
+
await this.opened.cleanup.close(() => this.eventCapture.finish());
|
|
181
200
|
return this.mode === "launch"
|
|
182
201
|
? "terminated-owned-process"
|
|
183
202
|
: "disconnected-external";
|
|
@@ -186,13 +205,3 @@ export class PlaywrightScenarioSession {
|
|
|
186
205
|
return this.secrets.redact(error instanceof Error ? error.message : "browser action failed");
|
|
187
206
|
}
|
|
188
207
|
}
|
|
189
|
-
/** Production Playwright/CDP session factory. */
|
|
190
|
-
export class PlaywrightScenarioSessionFactory {
|
|
191
|
-
environment;
|
|
192
|
-
constructor(environment = process.env) {
|
|
193
|
-
this.environment = environment;
|
|
194
|
-
}
|
|
195
|
-
open(scenario, options = {}) {
|
|
196
|
-
return PlaywrightScenarioSession.open(scenario, this.environment, options);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
@@ -106,6 +106,12 @@ class SourceMapEncodingError extends Error {
|
|
|
106
106
|
this.name = "SourceMapEncodingError";
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
class SourceMapRedirectLocationError extends Error {
|
|
110
|
+
constructor(url, location) {
|
|
111
|
+
super(`Source-map redirect from ${JSON.stringify(url)} supplied an invalid Location URL: ${JSON.stringify(location)}.`);
|
|
112
|
+
this.name = "SourceMapRedirectLocationError";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
109
115
|
const fetchOne = async (request, input, signal, host, budget) => {
|
|
110
116
|
if (!approvedUrl(request.fetchUrl, input.allowed_origins))
|
|
111
117
|
return emptySourceMapItem(request, "policy_filtered", "Declared source-map URL is outside the approved exact origins.");
|
|
@@ -131,13 +137,25 @@ const fetchOne = async (request, input, signal, host, budget) => {
|
|
|
131
137
|
throw cause;
|
|
132
138
|
if (cause instanceof SourceMapEncodingError)
|
|
133
139
|
return emptySourceMapItem(request, "invalid", cause.message);
|
|
134
|
-
return emptySourceMapItem(request, "fetch_failed", cause instanceof
|
|
140
|
+
return emptySourceMapItem(request, "fetch_failed", cause instanceof SourceMapRedirectLocationError ||
|
|
141
|
+
cause instanceof SourceMapSizeLimitError ||
|
|
142
|
+
cause instanceof SourceMapDeadlineError
|
|
135
143
|
? cause.message
|
|
136
|
-
:
|
|
137
|
-
? cause.message
|
|
138
|
-
: "Source-map fetch or validation failed.");
|
|
144
|
+
: "Source-map fetch or validation failed.");
|
|
139
145
|
}
|
|
140
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Fetch redirect statuses per WHATWG Fetch (redirect status list:
|
|
149
|
+
* 301, 302, 303, 307, 308). Single owner for redirect decisions.
|
|
150
|
+
* 300/304/305/306 carry `Location` without being redirects — following
|
|
151
|
+
* them would replace the observed failure with an unrelated map.
|
|
152
|
+
* See https://fetch.spec.whatwg.org/#redirect-status
|
|
153
|
+
*/
|
|
154
|
+
export const isFetchRedirectStatus = (status) => status === 301 ||
|
|
155
|
+
status === 302 ||
|
|
156
|
+
status === 303 ||
|
|
157
|
+
status === 307 ||
|
|
158
|
+
status === 308;
|
|
141
159
|
const fetchFollowingApprovedRedirects = async (initialUrl, allowedOrigins, signal, host) => {
|
|
142
160
|
let current = initialUrl;
|
|
143
161
|
const visited = new Set();
|
|
@@ -163,13 +181,21 @@ const fetchFollowingApprovedRedirects = async (initialUrl, allowedOrigins, signa
|
|
|
163
181
|
await response.body?.cancel(signal.reason).catch(() => undefined);
|
|
164
182
|
throw signal.reason;
|
|
165
183
|
}
|
|
166
|
-
|
|
184
|
+
// `Location` is a redirect target only for Fetch redirect statuses.
|
|
185
|
+
// Other 3xx responses retain their own HTTP failure (strict identity:
|
|
186
|
+
// never replace the observed failure with an unrelated map).
|
|
187
|
+
if (!isFetchRedirectStatus(response.status))
|
|
167
188
|
return { response, fetchedUrl: current };
|
|
168
189
|
const location = response.headers.get("location");
|
|
169
190
|
if (location === null)
|
|
170
191
|
return { response, fetchedUrl: current };
|
|
171
192
|
await response.body?.cancel();
|
|
172
|
-
|
|
193
|
+
try {
|
|
194
|
+
current = new URL(location, current).href;
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
throw new SourceMapRedirectLocationError(current, location);
|
|
198
|
+
}
|
|
173
199
|
}
|
|
174
200
|
};
|
|
175
201
|
const readBoundedText = async (response, budget, maxBytes, signal) => {
|
|
@@ -14,9 +14,9 @@ const indexResponses = (events) => {
|
|
|
14
14
|
requests: new Map(),
|
|
15
15
|
};
|
|
16
16
|
for (const event of events) {
|
|
17
|
-
if (event.kind === "request"
|
|
17
|
+
if (event.kind === "request")
|
|
18
18
|
index.requests.set(event.transaction_id, (index.requests.get(event.transaction_id) ?? 0) + 1);
|
|
19
|
-
if (event.kind === "response"
|
|
19
|
+
if (event.kind === "response")
|
|
20
20
|
append(index.responses, event.transaction_id, event);
|
|
21
21
|
if (event.kind === "network-content" && event.phase === "response")
|
|
22
22
|
append(index.contents, event.source_event_sequence, event);
|
|
@@ -25,33 +25,29 @@ const indexResponses = (events) => {
|
|
|
25
25
|
};
|
|
26
26
|
const projectRequest = (request, index) => {
|
|
27
27
|
const id = request.transaction_id;
|
|
28
|
-
const matches =
|
|
28
|
+
const matches = index.responses.get(id) ?? [];
|
|
29
29
|
const response = matches.length === 1 ? matches[0] : undefined;
|
|
30
30
|
const bodies = response === undefined ? [] : (index.contents.get(response.sequence) ?? []);
|
|
31
31
|
const body = bodies.length === 1 ? bodies[0]?.body : undefined;
|
|
32
|
-
const ambiguous =
|
|
33
|
-
matches.length > 1 ||
|
|
34
|
-
bodies.length > 1;
|
|
32
|
+
const ambiguous = index.requests.get(id) !== 1 || matches.length > 1 || bodies.length > 1;
|
|
35
33
|
return {
|
|
36
34
|
source: {
|
|
37
35
|
kind: "scenario-response",
|
|
38
|
-
transaction_id: id
|
|
36
|
+
transaction_id: id,
|
|
39
37
|
request_sequence: request.sequence,
|
|
40
38
|
response_sequence: ambiguous ? null : (response?.sequence ?? null),
|
|
41
39
|
status: ambiguous ? null : (response?.status ?? null),
|
|
42
40
|
},
|
|
43
41
|
url: request.url.url,
|
|
44
|
-
content: projectBody(body,
|
|
42
|
+
content: projectBody(body, ambiguous),
|
|
45
43
|
};
|
|
46
44
|
};
|
|
47
45
|
const unavailable = (reason, message) => ({ state: "unavailable", reason, message });
|
|
48
|
-
const projectBody = (body,
|
|
46
|
+
const projectBody = (body, ambiguous) => {
|
|
49
47
|
if (ambiguous)
|
|
50
48
|
return unavailable("ambiguous-transaction", "The capture does not identify one request, response, and content record for this transaction.");
|
|
51
49
|
if (body === undefined)
|
|
52
|
-
return unavailable(
|
|
53
|
-
? "transaction-identity-unavailable"
|
|
54
|
-
: "response-content-not-retained", "No selected, completed script response bytes were retained for this request.");
|
|
50
|
+
return unavailable("response-content-not-retained", "No selected, completed script response bytes were retained for this request.");
|
|
55
51
|
if (body.state === "unavailable")
|
|
56
52
|
return unavailable(body.reason, body.message);
|
|
57
53
|
if (body.state !== "captured")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { webPageInspectionSchema } from "../../domain/
|
|
1
|
+
import { webPageInspectionSchema } from "../../domain/browserObservationSchemas.js";
|
|
2
2
|
import { browserScenarioCaptureSchema } from "../../domain/browserScenarioCapture.js";
|
|
3
3
|
import { parseEvidence } from "../../domain/evidence.js";
|
|
4
4
|
import { pageScripts } from "./PageScriptCapture.js";
|